|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Copyright (C) IBM Corporation. 2007
|
|
Packit Service |
646995 |
* Author: Doug Maxey <dwm@austin.ibm.com>
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* This program is free software: you can redistribute it and/or modify
|
|
Packit Service |
646995 |
* it under the terms of the GNU General Public License as published by
|
|
Packit Service |
646995 |
* the Free Software Foundation, either version 2 of the License, or
|
|
Packit Service |
646995 |
* (at your option) any later version.
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
646995 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
646995 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
646995 |
* GNU General Public License for more details.
|
|
Packit Service |
646995 |
*
|
|
Packit Service |
646995 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
646995 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
#define _XOPEN_SOURCE 500
|
|
Packit Service |
646995 |
#include <ftw.h>
|
|
Packit Service |
646995 |
#include <stdio.h>
|
|
Packit Service |
646995 |
#include <stdlib.h>
|
|
Packit Service |
646995 |
#include <string.h>
|
|
Packit Service |
646995 |
#include <unistd.h>
|
|
Packit Service |
646995 |
#include <fcntl.h>
|
|
Packit Service |
646995 |
#include <errno.h>
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
#include "fwparam.h"
|
|
Packit Service |
646995 |
#include "fw_context.h"
|
|
Packit Service |
646995 |
#include "iscsi_obp.h"
|
|
Packit Service |
646995 |
#include "prom_parse.h"
|
|
Packit Service |
646995 |
#include "sysdeps.h"
|
|
Packit Service |
646995 |
#include "iscsi_err.h"
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
void* yy_scan_string(const char *str);
|
|
Packit Service |
646995 |
int yyparse(struct ofw_dev *ofwdev);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
#define BOOTPATH "/chosen/bootpath"
|
|
Packit Service |
646995 |
#define DT_TOP "/proc/device-tree"
|
|
Packit Service |
646995 |
#define LOCAL_MAC_FILE "/local-mac-address"
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int devtree_offset;
|
|
Packit Service |
646995 |
static char *bootpath_val;
|
|
Packit Service |
646995 |
static int bytes_read;
|
|
Packit Service |
646995 |
#define OFWDEV_MAX (10)
|
|
Packit Service |
646995 |
static struct ofw_dev *ofwdevs[OFWDEV_MAX];
|
|
Packit Service |
646995 |
static char *niclist[OFWDEV_MAX];
|
|
Packit Service |
646995 |
static int nic_count;
|
|
Packit Service |
646995 |
static int debug;
|
|
Packit Service |
646995 |
static int dev_count;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void cp_param(char *dest, const char *name, struct ofw_dev *dev,
|
|
Packit Service |
646995 |
enum obp_param item, int len)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (dev->param[item])
|
|
Packit Service |
646995 |
strlcpy(dest, dev->param[item]->val, len);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void cp_int_param(int *dest, const char *name, struct ofw_dev *dev,
|
|
Packit Service |
646995 |
enum obp_param item)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (dev->param[item])
|
|
Packit Service |
646995 |
*dest = strtol(dev->param[item]->val, NULL, 10);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static char *find_devtree(const char *filename)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
char *devtree = strdup(filename);
|
|
Packit Service |
646995 |
char *chop_at;
|
|
Packit Service |
646995 |
struct stat dt_stat;
|
|
Packit Service |
646995 |
int error;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* What is the path to the device-tree? The only valid
|
|
Packit Service |
646995 |
* directories to locate the property are under /aliases or
|
|
Packit Service |
646995 |
* /chosen.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
chop_at = strstr(devtree, "/chosen");
|
|
Packit Service |
646995 |
if (!chop_at)
|
|
Packit Service |
646995 |
chop_at = strstr(devtree, "/aliases");
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!chop_at) {
|
|
Packit Service |
646995 |
char *vdev = malloc(strlen(filename) + strlen("/vdevice") + 1);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* test to see if there is /vdevice dir
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
if (vdev) {
|
|
Packit Service |
646995 |
sprintf(vdev, "%s%s", filename, "/vdevice");
|
|
Packit Service |
646995 |
error = stat(vdev, &dt_stat);
|
|
Packit Service |
646995 |
free(vdev);
|
|
Packit Service |
646995 |
if (error) {
|
|
Packit Service |
646995 |
free(devtree);
|
|
Packit Service |
646995 |
return NULL;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
} else
|
|
Packit Service |
646995 |
devtree[chop_at - devtree] = 0;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (devtree)
|
|
Packit Service |
646995 |
devtree_offset = strlen(devtree);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return devtree;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Take the path to the property under chosen, and swizzle to make that
|
|
Packit Service |
646995 |
* the base for the device path discovered.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
static int locate_mac(const char *devtree, struct ofw_dev *ofwdev)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int error = 0;
|
|
Packit Service |
646995 |
int mac_path_len = strlen(ofwdev->dev_path) + strlen(LOCAL_MAC_FILE) +
|
|
Packit Service |
646995 |
2;
|
|
Packit Service |
646995 |
char *mac_file;
|
|
Packit Service |
646995 |
int mac_fd;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
mac_path_len += strlen(devtree);
|
|
Packit Service |
646995 |
mac_file = malloc(mac_path_len);
|
|
Packit Service |
646995 |
if (!mac_file) {
|
|
Packit Service |
646995 |
error = ENOMEM;
|
|
Packit Service |
646995 |
fprintf(stderr, "%s: malloc , %s\n", __func__,
|
|
Packit Service |
646995 |
strerror(errno));
|
|
Packit Service |
646995 |
goto lpm_bail;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
snprintf(mac_file, mac_path_len, "%s%s%s", devtree, ofwdev->dev_path,
|
|
Packit Service |
646995 |
LOCAL_MAC_FILE);
|
|
Packit Service |
646995 |
mac_fd = open(mac_file, O_RDONLY);
|
|
Packit Service |
646995 |
if (mac_fd < 0) {
|
|
Packit Service |
646995 |
error = errno;
|
|
Packit Service |
646995 |
fprintf(stderr, "%s: open %s, %s\n", __func__, mac_file,
|
|
Packit Service |
646995 |
strerror(errno));
|
|
Packit Service |
646995 |
free(mac_file);
|
|
Packit Service |
646995 |
goto lpm_bail;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
bytes_read = read(mac_fd, ofwdev->mac, 6);
|
|
Packit Service |
646995 |
if (bytes_read != 6) {
|
|
Packit Service |
646995 |
error = EIO;
|
|
Packit Service |
646995 |
fprintf(stderr, "%s: read %s, %s\n", __func__, mac_file,
|
|
Packit Service |
646995 |
strerror(errno));
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
free(mac_file);
|
|
Packit Service |
646995 |
close(mac_fd);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
lpm_bail:
|
|
Packit Service |
646995 |
return error;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
const char *obp_qual_set(struct ofw_dev *ofwdev, const char *qual)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (!strcmp("bootp", qual))
|
|
Packit Service |
646995 |
ofwdev->quals[ofwdev->qual_count++] = OBP_QUAL_BOOTP;
|
|
Packit Service |
646995 |
else if (!strcmp("dhcpv6", qual))
|
|
Packit Service |
646995 |
ofwdev->quals[ofwdev->qual_count++] = OBP_QUAL_DHCPV6;
|
|
Packit Service |
646995 |
else if (!strcmp("ipv6", qual))
|
|
Packit Service |
646995 |
ofwdev->quals[ofwdev->qual_count++] = OBP_QUAL_IPV6;
|
|
Packit Service |
646995 |
else if (!strcmp("iscsi", qual)) {
|
|
Packit Service |
646995 |
ofwdev->type = OFW_DT_ISCSI;
|
|
Packit Service |
646995 |
ofwdev->quals[ofwdev->qual_count++] = OBP_QUAL_ISCSI;
|
|
Packit Service |
646995 |
} else if (!strcmp("ping", qual))
|
|
Packit Service |
646995 |
ofwdev->quals[ofwdev->qual_count++] = OBP_QUAL_PING;
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
printf("%s: %s UNKNOWN\n", __func__, qual);
|
|
Packit Service |
646995 |
return qual;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
void add_obp_parm(struct ofw_dev *ofwdev, enum obp_param parm, const char *str)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int psz = sizeof(struct ofw_obp_param) + strlen(str);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
ofwdev->param[parm] = malloc(psz);
|
|
Packit Service |
646995 |
if (ofwdev->param[parm] == NULL) {
|
|
Packit Service |
646995 |
printf("%s: ENOMEM!\n", __func__);
|
|
Packit Service |
646995 |
return;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
memset(ofwdev->param[parm], 0, psz);
|
|
Packit Service |
646995 |
ofwdev->param[parm]->len = psz;
|
|
Packit Service |
646995 |
strcpy(ofwdev->param[parm]->val, str);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
void obp_parm_addr(struct ofw_dev *ofwdev, const char *parm, const char *addr)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (!strcmp("ciaddr", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_CIADDR, addr);
|
|
Packit Service |
646995 |
else if (!strcmp("dhcp", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_DHCP, addr);
|
|
Packit Service |
646995 |
else if (!strcmp("giaddr", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_GIADDR, addr);
|
|
Packit Service |
646995 |
else if (!strcmp("isns", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_ISNS, addr);
|
|
Packit Service |
646995 |
else if (!strcmp("siaddr", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_SIADDR, addr);
|
|
Packit Service |
646995 |
else if (!strcmp("slp", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_SLP, addr);
|
|
Packit Service |
646995 |
else if (!strcmp("subnet-mask", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_SUBNET_MASK, addr);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
printf("%s: %s UNKNOWN\n", __func__, parm);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
void obp_parm_iqn(struct ofw_dev *ofwdev, const char *parm, const char *iqn)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (!strcmp("itname", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_ITNAME, iqn);
|
|
Packit Service |
646995 |
else if (!strcmp("iname", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_INAME, iqn);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
printf("%s: %s UNKNOWN\n", __func__, parm);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
void obp_parm_hexnum(struct ofw_dev *ofwdev, const char *parm,
|
|
Packit Service |
646995 |
const char *numstr)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (!strcmp("bootp-retries", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_BOOTP_RETRIES, numstr);
|
|
Packit Service |
646995 |
else if (!strcmp("tftp-retries", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_TFTP_RETRIES, numstr);
|
|
Packit Service |
646995 |
else if (!strcmp("iport", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_IPORT, numstr);
|
|
Packit Service |
646995 |
else if (!strcmp("ilun", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_ILUN, numstr);
|
|
Packit Service |
646995 |
else if (!strcmp("isid", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_ISID, numstr);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
printf("%s: %s UNKNOWN <%s>\n", __func__, parm, numstr);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
void obp_parm_str(struct ofw_dev *ofwdev, const char *parm, const char *str)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (!strcmp("filename", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_FILENAME, str);
|
|
Packit Service |
646995 |
else if (!strcmp("ichapid", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_ICHAPID, str);
|
|
Packit Service |
646995 |
else if (!strcmp("ichappw", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_ICHAPPW, str);
|
|
Packit Service |
646995 |
else if (!strcmp("chapid", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_CHAPID, str);
|
|
Packit Service |
646995 |
else if (!strcmp("chappw", parm))
|
|
Packit Service |
646995 |
add_obp_parm(ofwdev, OBP_PARAM_CHAPPW, str);
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
printf("%s: %s UNKNOWN <%s>\n", __func__, parm, str);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
void yyerror(struct ofw_dev *ofwdev, const char *msg)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
fprintf(stderr, "%s: error in <%s> at l%d.c%d\n", "fwparam_ppc",
|
|
Packit Service |
646995 |
ofwdev->prop_path, yylloc.last_line, yylloc.last_column);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int parse_params(const char *buf, struct ofw_dev *ofwdev)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int error = 0;
|
|
Packit Service |
646995 |
#if YYDEBUG
|
|
Packit Service |
646995 |
yydebug = 1;
|
|
Packit Service |
646995 |
#endif
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (yy_scan_string(buf))
|
|
Packit Service |
646995 |
error = yyparse(ofwdev);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return error;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int find_file(const char *filename)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int error, fd;
|
|
Packit Service |
646995 |
struct stat bootpath_stat;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
error = stat(filename, &bootpath_stat);
|
|
Packit Service |
646995 |
if (error < 0) {
|
|
Packit Service |
646995 |
fprintf(stderr, "%s: stat %s, %s\n", __func__, filename,
|
|
Packit Service |
646995 |
strerror(errno));
|
|
Packit Service |
646995 |
return error;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
bootpath_val = malloc(bootpath_stat.st_size);
|
|
Packit Service |
646995 |
if (!bootpath_val) {
|
|
Packit Service |
646995 |
error = ENOMEM;
|
|
Packit Service |
646995 |
fprintf(stderr, "%s: Could not open %s: %s (%d)\n",
|
|
Packit Service |
646995 |
__func__, filename, strerror(error), error);
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
fd = open(filename, O_RDONLY);
|
|
Packit Service |
646995 |
if (fd < 0) {
|
|
Packit Service |
646995 |
fprintf(stderr, "%s: Could not open %s: %s (%d)\n",
|
|
Packit Service |
646995 |
__func__, filename, strerror(errno), errno);
|
|
Packit Service |
646995 |
free(bootpath_val);
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
bytes_read = read(fd, bootpath_val, bootpath_stat.st_size);
|
|
Packit Service |
646995 |
close(fd);
|
|
Packit Service |
646995 |
free(bootpath_val);
|
|
Packit Service |
646995 |
if (bytes_read != bootpath_stat.st_size) {
|
|
Packit Service |
646995 |
fprintf(stderr, "%s: Could not open %s: %s (%d)\n",
|
|
Packit Service |
646995 |
__func__, filename, strerror(EIO), EIO);
|
|
Packit Service |
646995 |
return -1;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
return 1;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int find_nics(const char *fpath, const struct stat *sb, int tflag,
|
|
Packit Service |
646995 |
struct FTW *ftw)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
if (tflag == FTW_D &&
|
|
Packit Service |
646995 |
(strstr(fpath + ftw->base, "iscsi-toe") ||
|
|
Packit Service |
646995 |
strstr(fpath + ftw->base, "ethernet"))) {
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (nic_count < OFWDEV_MAX)
|
|
Packit Service |
646995 |
niclist[nic_count++] = strdup(fpath + devtree_offset);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int nic_cmp(const void *a, const void *b)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
return strcmp(a, b);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int find_initiator(const char *fpath, const struct stat *sb, int tflag,
|
|
Packit Service |
646995 |
struct FTW *ftw)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
struct ofw_dev *dev;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (tflag == FTW_F && (strstr(fpath + ftw->base,
|
|
Packit Service |
646995 |
"/aliases/iscsi-disk"))) {
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (dev_count < OFWDEV_MAX) {
|
|
Packit Service |
646995 |
ofwdevs[dev_count++] = dev =
|
|
Packit Service |
646995 |
calloc(sizeof(struct ofw_dev), 1);
|
|
Packit Service |
646995 |
dev->prop_path = strdup(fpath + devtree_offset);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
return 0;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static int loop_devs(const char *devtree)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int error;
|
|
Packit Service |
646995 |
int i;
|
|
Packit Service |
646995 |
char prefix[256];
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
nic_count = 0;
|
|
Packit Service |
646995 |
error = nftw(devtree, find_nics, 20, 0);
|
|
Packit Service |
646995 |
if (error)
|
|
Packit Service |
646995 |
return error;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Sort the nics into "natural" order. The proc fs
|
|
Packit Service |
646995 |
* device-tree has them in somewhat random, or reversed order.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
qsort(niclist, nic_count, sizeof(char *), nic_cmp);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
snprintf(prefix, sizeof(prefix), "%s/%s", devtree, "aliases");
|
|
Packit Service |
646995 |
dev_count = 0;
|
|
Packit Service |
646995 |
error = nftw(prefix, find_initiator, 20, 0);
|
|
Packit Service |
646995 |
if (error)
|
|
Packit Service |
646995 |
return error;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
for (i = 0; i < dev_count; i++) {
|
|
Packit Service |
646995 |
snprintf(prefix, sizeof(prefix), "%s%s", devtree,
|
|
Packit Service |
646995 |
ofwdevs[i]->prop_path);
|
|
Packit Service |
646995 |
if (find_file(prefix) > 0) {
|
|
Packit Service |
646995 |
error = parse_params(bootpath_val, ofwdevs[i]);
|
|
Packit Service |
646995 |
if (!error)
|
|
Packit Service |
646995 |
error = locate_mac(devtree, ofwdevs[i]);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
return error;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
#define set_context(fld,abrv,item) \
|
|
Packit Service |
646995 |
cp_param(context->fld, (abrv), ofwdev, (item), sizeof(context->fld))
|
|
Packit Service |
646995 |
#define set_int_context(fld,abrv,item) \
|
|
Packit Service |
646995 |
cp_int_param(&context->fld, (abrv), ofwdev, (item))
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
static void fill_context(struct boot_context *context, struct ofw_dev *ofwdev)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
int ndx;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
memset(context, 0, sizeof(*context));
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
set_context(initiatorname, "NAME", OBP_PARAM_ITNAME);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
snprintf(context->mac, sizeof(context->mac),
|
|
Packit Service |
646995 |
"%02x:%02x:%02x:%02x:%02x:%02x",
|
|
Packit Service |
646995 |
ofwdev->mac[0], ofwdev->mac[1], ofwdev->mac[2],
|
|
Packit Service |
646995 |
ofwdev->mac[3], ofwdev->mac[4], ofwdev->mac[5]);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* nic parameters
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
for (ndx = 0; ndx < nic_count; ndx++) {
|
|
Packit Service |
646995 |
if (!strcmp(niclist[ndx], ofwdev->dev_path)) {
|
|
Packit Service |
646995 |
snprintf(context->iface, sizeof(context->iface),
|
|
Packit Service |
646995 |
"eth%d", ndx);
|
|
Packit Service |
646995 |
break;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
set_context(ipaddr, "IPADDR", OBP_PARAM_CIADDR);
|
|
Packit Service |
646995 |
set_context(mask, "MASK", OBP_PARAM_SUBNET_MASK);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* target parameters
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
set_context(target_ipaddr, "IPADDR", OBP_PARAM_SIADDR);
|
|
Packit Service |
646995 |
set_int_context(target_port, "PORT", OBP_PARAM_IPORT);
|
|
Packit Service |
646995 |
set_context(lun, "LUN", OBP_PARAM_ILUN);
|
|
Packit Service |
646995 |
set_context(targetname, "NAME", OBP_PARAM_INAME);
|
|
Packit Service |
646995 |
set_context(isid, "ISID", OBP_PARAM_ISID);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* chap stuff is always associated with the target
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
set_context(chap_name, "CHAP_NAME", OBP_PARAM_ICHAPID);
|
|
Packit Service |
646995 |
set_context(chap_password, "CHAP_PASSWORD", OBP_PARAM_ICHAPPW);
|
|
Packit Service |
646995 |
set_context(chap_name_in, "CHAP_NAME_IN", OBP_PARAM_CHAPID);
|
|
Packit Service |
646995 |
set_context(chap_password_in, "CHAP_PASSWORD_IN", OBP_PARAM_CHAPPW);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
int fwparam_ppc_boot_info(struct boot_context *context)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
char filename[FILENAMESZ];
|
|
Packit Service |
646995 |
int error;
|
|
Packit Service |
646995 |
char *devtree;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* For powerpc, our operations are fundamentally to locate
|
|
Packit Service |
646995 |
* either the one boot target (the singleton disk), or to find
|
|
Packit Service |
646995 |
* the nics that support iscsi boot. The only nics in IBM
|
|
Packit Service |
646995 |
* systems that can support iscsi are the ones that provide
|
|
Packit Service |
646995 |
* the appropriate FCODE with a load method.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
memset(filename, 0, FILENAMESZ);
|
|
Packit Service |
646995 |
snprintf(filename, FILENAMESZ, "%s%s", DT_TOP, BOOTPATH);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (debug)
|
|
Packit Service |
646995 |
fprintf(stderr, "%s: file:%s; debug:%d\n", __func__, filename,
|
|
Packit Service |
646995 |
debug);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
devtree = find_devtree(filename);
|
|
Packit Service |
646995 |
if (!devtree)
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Always search the device-tree to find the capable nic devices.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
error = loop_devs(devtree);
|
|
Packit Service |
646995 |
if (error)
|
|
Packit Service |
646995 |
goto free_devtree;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (find_file(filename) < 1)
|
|
Packit Service |
646995 |
error = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
else {
|
|
Packit Service |
646995 |
if (debug)
|
|
Packit Service |
646995 |
printf("%s:\n%s\n\n", filename, bootpath_val);
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* We find *almost* everything we need in the
|
|
Packit Service |
646995 |
* bootpath, save the mac-address.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strstr(bootpath_val, "iscsi")) {
|
|
Packit Service |
646995 |
error = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto free_devtree;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
ofwdevs[0] = calloc(1, sizeof(struct ofw_dev));
|
|
Packit Service |
646995 |
if (!ofwdevs[0]) {
|
|
Packit Service |
646995 |
error = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto free_devtree;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
error = parse_params(bootpath_val, ofwdevs[0]);
|
|
Packit Service |
646995 |
if (!error)
|
|
Packit Service |
646995 |
error = locate_mac(devtree, ofwdevs[0]);
|
|
Packit Service |
646995 |
if (!error) {
|
|
Packit Service |
646995 |
if (!context)
|
|
Packit Service |
646995 |
error = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
else
|
|
Packit Service |
646995 |
fill_context(context, ofwdevs[0]);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
free(ofwdevs[0]);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
free_devtree:
|
|
Packit Service |
646995 |
free(devtree);
|
|
Packit Service |
646995 |
return error;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Due to lack of time this is just fwparam_ppc_boot_info which
|
|
Packit Service |
646995 |
* adds the target used for boot to the list. It does not add
|
|
Packit Service |
646995 |
* all possible targets (IBM please add).
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
int fwparam_ppc_get_targets(struct list_head *list)
|
|
Packit Service |
646995 |
{
|
|
Packit Service |
646995 |
char filename[FILENAMESZ];
|
|
Packit Service |
646995 |
struct boot_context *context;
|
|
Packit Service |
646995 |
int error;
|
|
Packit Service |
646995 |
char *devtree;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* For powerpc, our operations are fundamentally to locate
|
|
Packit Service |
646995 |
* either the one boot target (the singleton disk), or to find
|
|
Packit Service |
646995 |
* the nics that support iscsi boot. The only nics in IBM
|
|
Packit Service |
646995 |
* systems that can support iscsi are the ones that provide
|
|
Packit Service |
646995 |
* the appropriate FCODE with a load method.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
memset(filename, 0, FILENAMESZ);
|
|
Packit Service |
646995 |
snprintf(filename, FILENAMESZ, "%s%s", DT_TOP, BOOTPATH);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (debug)
|
|
Packit Service |
646995 |
fprintf(stderr, "%s: file:%s; debug:%d\n", __func__, filename,
|
|
Packit Service |
646995 |
debug);
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
devtree = find_devtree(filename);
|
|
Packit Service |
646995 |
if (!devtree)
|
|
Packit Service |
646995 |
return ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* Always search the device-tree to find the capable nic devices.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
error = loop_devs(devtree);
|
|
Packit Service |
646995 |
if (error)
|
|
Packit Service |
646995 |
goto free_devtree;
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (find_file(filename) < 1)
|
|
Packit Service |
646995 |
error = ISCSI_ERR_NO_OBJS_FOUND;
|
|
Packit Service |
646995 |
else {
|
|
Packit Service |
646995 |
if (debug)
|
|
Packit Service |
646995 |
printf("%s:\n%s\n\n", filename, bootpath_val);
|
|
Packit Service |
646995 |
/*
|
|
Packit Service |
646995 |
* We find *almost* everything we need in the
|
|
Packit Service |
646995 |
* bootpath, save the mac-address.
|
|
Packit Service |
646995 |
*/
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
if (!strstr(bootpath_val, "iscsi")) {
|
|
Packit Service |
646995 |
error = ISCSI_ERR_INVAL;
|
|
Packit Service |
646995 |
goto free_devtree;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
ofwdevs[0] = calloc(1, sizeof(struct ofw_dev));
|
|
Packit Service |
646995 |
if (!ofwdevs[0]) {
|
|
Packit Service |
646995 |
error = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
goto free_devtree;
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
error = parse_params(bootpath_val, ofwdevs[0]);
|
|
Packit Service |
646995 |
if (!error)
|
|
Packit Service |
646995 |
error = locate_mac(devtree, ofwdevs[0]);
|
|
Packit Service |
646995 |
if (!error) {
|
|
Packit Service |
646995 |
context = calloc(1, sizeof(*context));
|
|
Packit Service |
646995 |
if (!context)
|
|
Packit Service |
646995 |
error = ISCSI_ERR_NOMEM;
|
|
Packit Service |
646995 |
else {
|
|
Packit Service |
646995 |
fill_context(context, ofwdevs[0]);
|
|
Packit Service |
646995 |
list_add_tail(&context->list, list);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
free(ofwdevs[0]);
|
|
Packit Service |
646995 |
}
|
|
Packit Service |
646995 |
|
|
Packit Service |
646995 |
free_devtree:
|
|
Packit Service |
646995 |
free(devtree);
|
|
Packit Service |
646995 |
return error;
|
|
Packit Service |
646995 |
}
|