|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* Copyright (c) 2008, Intel Corporation.
|
|
Packit Service |
35c908 |
*
|
|
Packit Service |
35c908 |
* This program is free software; you can redistribute it and/or modify it
|
|
Packit Service |
35c908 |
* under the terms and conditions of the GNU Lesser General Public License,
|
|
Packit Service |
35c908 |
* version 2.1, as published by the Free Software Foundation.
|
|
Packit Service |
35c908 |
*
|
|
Packit Service |
35c908 |
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
Packit Service |
35c908 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
Packit Service |
35c908 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
Packit Service |
35c908 |
* for more details.
|
|
Packit Service |
35c908 |
*
|
|
Packit Service |
35c908 |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
35c908 |
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit Service |
35c908 |
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit Service |
35c908 |
*
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
#include "utils.h"
|
|
Packit Service |
35c908 |
#include "api_lib.h"
|
|
Packit Service |
35c908 |
#include "adapt_impl.h"
|
|
Packit Service |
35c908 |
|
|
Packit Service |
39ee31 |
#include <libudev.h>
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
35c908 |
#ifndef HBA_STATUS_ERROR_ILLEGAL_FCID
|
|
Packit Service |
35c908 |
#define HBA_STATUS_ERROR_ILLEGAL_FCID 33 /* defined after HBA-API 2.2 */
|
|
Packit Service |
35c908 |
#endif
|
|
Packit Service |
35c908 |
#define SEND_CT_TIMEOUT (3 * 1000) /* timeout in milliseconds */
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* The following are temporary settings until we can find a way to
|
|
Packit Service |
35c908 |
* collect these information.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
#define HBA_ROM_VERSION ""
|
|
Packit Service |
35c908 |
#define HBA_FW_VERSION ""
|
|
Packit Service |
35c908 |
#define HBA_VENDOR_SPECIFIC_ID 0
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* table of /sys port types strings to HBA-API values.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
struct sa_nameval port_types_table[] = {
|
|
Packit Service |
35c908 |
{ "Unknown", HBA_PORTTYPE_UNKNOWN },
|
|
Packit Service |
35c908 |
{ "Other", HBA_PORTTYPE_OTHER },
|
|
Packit Service |
35c908 |
{ "Not Present", HBA_PORTTYPE_NOTPRESENT },
|
|
Packit Service |
35c908 |
{ "NPort (fabric via point-to-point)", HBA_PORTTYPE_NPORT },
|
|
Packit Service |
35c908 |
{ "NLPort (fabric via loop)", HBA_PORTTYPE_NLPORT },
|
|
Packit Service |
35c908 |
{ "LPort (private loop)", HBA_PORTTYPE_LPORT },
|
|
Packit Service |
35c908 |
{ "Point-To-Point (direct nport connection)", HBA_PORTTYPE_PTP },
|
|
Packit Service |
35c908 |
{ "NPIV VPORT", HBA_PORTTYPE_NPORT },
|
|
Packit Service |
35c908 |
{ NULL, 0 }
|
|
Packit Service |
35c908 |
};
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* table of /sys port state strings to HBA-API values.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
struct sa_nameval port_states_table[] = {
|
|
Packit Service |
35c908 |
{ "Not Present", HBA_PORTSTATE_UNKNOWN },
|
|
Packit Service |
35c908 |
{ "Online", HBA_PORTSTATE_ONLINE },
|
|
Packit Service |
35c908 |
{ "Offline", HBA_PORTSTATE_OFFLINE },
|
|
Packit Service |
35c908 |
{ "Blocked", HBA_PORTSTATE_UNKNOWN },
|
|
Packit Service |
35c908 |
{ "Bypassed", HBA_PORTSTATE_BYPASSED },
|
|
Packit Service |
35c908 |
{ "Diagnostics", HBA_PORTSTATE_DIAGNOSTICS },
|
|
Packit Service |
35c908 |
{ "Linkdown", HBA_PORTSTATE_LINKDOWN },
|
|
Packit Service |
35c908 |
{ "Error", HBA_PORTSTATE_ERROR },
|
|
Packit Service |
35c908 |
{ "Loopback", HBA_PORTSTATE_LOOPBACK },
|
|
Packit Service |
35c908 |
{ "Deleted", HBA_PORTSTATE_UNKNOWN },
|
|
Packit Service |
35c908 |
{ NULL, 0 }
|
|
Packit Service |
35c908 |
};
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* table of /sys port speed strings to HBA-API values.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
struct sa_nameval port_speeds_table[] = {
|
|
Packit Service |
35c908 |
{ "Unknown", HBA_PORTSPEED_UNKNOWN },
|
|
Packit Service |
35c908 |
{ "1 Gbit", HBA_PORTSPEED_1GBIT },
|
|
Packit Service |
35c908 |
{ "2 Gbit", HBA_PORTSPEED_2GBIT },
|
|
Packit Service |
35c908 |
{ "4 Gbit", HBA_PORTSPEED_4GBIT },
|
|
Packit Service |
35c908 |
{ "10 Gbit", HBA_PORTSPEED_10GBIT },
|
|
Packit Service |
35c908 |
{ "8 Gbit", HBA_PORTSPEED_8GBIT },
|
|
Packit Service |
35c908 |
{ "16 Gbit", HBA_PORTSPEED_16GBIT },
|
|
Packit Service |
35c908 |
{ "32 Gbit", HBA_PORTSPEED_32GBIT },
|
|
Packit Service |
35c908 |
{ "20 Gbit", HBA_PORTSPEED_20GBIT },
|
|
Packit Service |
35c908 |
{ "40 Gbit", HBA_PORTSPEED_40GBIT },
|
|
Packit Service |
35c908 |
{ "Not Negotiated", HBA_PORTSPEED_NOT_NEGOTIATED },
|
|
Packit Service |
35c908 |
{ NULL, 0 }
|
|
Packit Service |
35c908 |
};
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* parse strings from /sys port speed/support_speeds files
|
|
Packit Service |
35c908 |
* and convert them to bitmasks for the HBA_PORTSPEED supported
|
|
Packit Service |
35c908 |
* Format expected: "1 Gbit[, 10 Gbit]", etc.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
39ee31 |
static int sys_read_speed(const char *speedstr, HBA_PORTSPEED *speeds)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
int rc = 0;
|
|
Packit Service |
35c908 |
u_int32_t val = 0;
|
|
Packit Service |
35c908 |
int len = 0;
|
|
Packit Service |
39ee31 |
const char *cp;
|
|
Packit Service |
35c908 |
struct sa_nameval *tp = port_speeds_table;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
39ee31 |
if (rc == 0 && strstr(speedstr, "Unknown") == NULL) {
|
|
Packit Service |
39ee31 |
for (cp = speedstr; *cp != '\0';) {
|
|
Packit Service |
35c908 |
for (; tp->nv_name != NULL; tp++) {
|
|
Packit Service |
35c908 |
len = strlen(tp->nv_name);
|
|
Packit Service |
35c908 |
if (strncasecmp(tp->nv_name, cp, len) == 0) {
|
|
Packit Service |
35c908 |
val |= tp->nv_val;
|
|
Packit Service |
35c908 |
cp += len;
|
|
Packit Service |
35c908 |
break;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
if (*cp == '\0')
|
|
Packit Service |
35c908 |
break;
|
|
Packit Service |
35c908 |
if (*cp == ',') {
|
|
Packit Service |
35c908 |
cp++;
|
|
Packit Service |
35c908 |
if (*cp == ' ')
|
|
Packit Service |
35c908 |
cp++;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
else
|
|
Packit Service |
35c908 |
break; /* invalid string */
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
*speeds = val;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
return rc;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* Code for OpenFC-supported adapters.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
static int
|
|
Packit Service |
35c908 |
counting_rports(struct dirent *dp, void *arg)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
int *count = (int *)arg;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
if (!strstr(dp->d_name, "rport-"))
|
|
Packit Service |
35c908 |
return HBA_STATUS_OK;
|
|
Packit Service |
35c908 |
(*count)++;
|
|
Packit Service |
35c908 |
return HBA_STATUS_OK;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
39ee31 |
static void
|
|
Packit Service |
39ee31 |
sysfs_scan_pci(struct udev_device *pci,
|
|
Packit Service |
39ee31 |
struct hba_info *hba_info,
|
|
Packit Service |
39ee31 |
HBA_ADAPTERATTRIBUTES *atp
|
|
Packit Service |
39ee31 |
)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
39ee31 |
const char *attr;
|
|
Packit Service |
39ee31 |
const char *hba_dir;
|
|
Packit Service |
35c908 |
char buf[256];
|
|
Packit Service |
39ee31 |
char *saveptr; /* for strtok_r */
|
|
Packit Service |
35c908 |
|
|
Packit Service |
39ee31 |
/* Get vendor_id */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(pci, "vendor");
|
|
Packit Service |
39ee31 |
hba_info->vendor_id = strtoul(attr, NULL, 0);
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get device_id */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(pci, "device");
|
|
Packit Service |
39ee31 |
hba_info->device_id = strtoul(attr, NULL, 0);
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get subsystem_vendor_id */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(pci, "subsystem_vendor");
|
|
Packit Service |
39ee31 |
hba_info->subsystem_vendor_id = strtoul(attr, NULL, 0);
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get subsystem_device_id */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(pci, "subsystem_device");
|
|
Packit Service |
39ee31 |
hba_info->subsystem_device_id = strtoul(attr, NULL, 0);
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get device_class */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(pci, "class");
|
|
Packit Service |
39ee31 |
hba_info->device_class = strtoul(attr, NULL, 0);
|
|
Packit Service |
39ee31 |
hba_info->device_class = hba_info->device_class>>8;
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/*
|
|
Packit Service |
39ee31 |
* Get Hardware Information via PCI Library
|
|
Packit Service |
39ee31 |
*/
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
sscanf(udev_device_get_sysname(pci), "%x:%x:%x:%x",
|
|
Packit Service |
39ee31 |
&hba_info->domain, &hba_info->bus,
|
|
Packit Service |
39ee31 |
&hba_info->dev, &hba_info->func);
|
|
Packit Service |
39ee31 |
(void) find_pci_device(hba_info);
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get Number of Ports */
|
|
Packit Service |
39ee31 |
atp->NumberOfPorts = hba_info->NumberOfPorts;
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get Manufacturer */
|
|
Packit Service |
39ee31 |
sa_strncpy_safe(atp->Manufacturer, sizeof(atp->Manufacturer),
|
|
Packit Service |
39ee31 |
hba_info->Manufacturer, sizeof(hba_info->Manufacturer));
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get SerialNumber */
|
|
Packit Service |
39ee31 |
sa_strncpy_safe(atp->SerialNumber, sizeof(atp->SerialNumber),
|
|
Packit Service |
39ee31 |
hba_info->SerialNumber, sizeof(hba_info->SerialNumber));
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get ModelDescription */
|
|
Packit Service |
39ee31 |
sa_strncpy_safe(atp->ModelDescription, sizeof(atp->ModelDescription),
|
|
Packit Service |
39ee31 |
hba_info->ModelDescription,
|
|
Packit Service |
39ee31 |
sizeof(hba_info->ModelDescription));
|
|
Packit Service |
39ee31 |
if (!strncmp(hba_info->ModelDescription, "Unknown",
|
|
Packit Service |
39ee31 |
sizeof(hba_info->ModelDescription))) {
|
|
Packit Service |
39ee31 |
snprintf(atp->ModelDescription, sizeof(atp->ModelDescription),
|
|
Packit Service |
39ee31 |
"[%04x:%04x]-[%04x:%04x]-(%04x)",
|
|
Packit Service |
39ee31 |
hba_info->vendor_id, hba_info->device_id,
|
|
Packit Service |
39ee31 |
hba_info->subsystem_vendor_id,
|
|
Packit Service |
39ee31 |
hba_info->subsystem_device_id,
|
|
Packit Service |
39ee31 |
hba_info->device_class);
|
|
Packit Service |
39ee31 |
/*
|
|
Packit Service |
39ee31 |
* Get Model
|
|
Packit Service |
39ee31 |
*
|
|
Packit Service |
39ee31 |
* If the device is a newly developed product, and
|
|
Packit Service |
39ee31 |
* the model description is not in pci.ids yet, use
|
|
Packit Service |
39ee31 |
* the model description constructed above as the
|
|
Packit Service |
39ee31 |
* model string.
|
|
Packit Service |
39ee31 |
*/
|
|
Packit Service |
39ee31 |
sa_strncpy_safe(atp->Model, sizeof(atp->Model),
|
|
Packit Service |
39ee31 |
atp->ModelDescription,
|
|
Packit Service |
39ee31 |
sizeof(atp->ModelDescription));
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/*
|
|
Packit Service |
39ee31 |
* Get Model
|
|
Packit Service |
39ee31 |
*
|
|
Packit Service |
39ee31 |
* If the device name has already been added into
|
|
Packit Service |
39ee31 |
* the pci.ids file, use the first word of the model
|
|
Packit Service |
39ee31 |
* description as the model. If the space after the
|
|
Packit Service |
39ee31 |
* first word is not found (new product), use the
|
|
Packit Service |
39ee31 |
* model description as the model.
|
|
Packit Service |
39ee31 |
*/
|
|
Packit Service |
39ee31 |
sa_strncpy_safe(buf, sizeof(buf), atp->ModelDescription,
|
|
Packit Service |
39ee31 |
sizeof(atp->ModelDescription));
|
|
Packit Service |
39ee31 |
if (strtok_r(buf, " ", &saveptr))
|
|
Packit Service |
39ee31 |
sa_strncpy_safe(atp->Model, sizeof(atp->Model),
|
|
Packit Service |
39ee31 |
buf, strnlen(buf, sizeof(buf)));
|
|
Packit Service |
39ee31 |
else
|
|
Packit Service |
39ee31 |
sa_strncpy_safe(atp->Model, sizeof(atp->Model),
|
|
Packit Service |
39ee31 |
atp->ModelDescription,
|
|
Packit Service |
39ee31 |
sizeof(atp->ModelDescription));
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get HardwareVersion */
|
|
Packit Service |
39ee31 |
sa_strncpy_safe(atp->HardwareVersion, sizeof(atp->HardwareVersion),
|
|
Packit Service |
39ee31 |
hba_info->HardwareVersion,
|
|
Packit Service |
39ee31 |
sizeof(hba_info->HardwareVersion));
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get OptionROMVersion (TODO) */
|
|
Packit Service |
39ee31 |
sa_strncpy_safe(atp->OptionROMVersion, sizeof(atp->OptionROMVersion),
|
|
Packit Service |
39ee31 |
HBA_ROM_VERSION, sizeof(HBA_ROM_VERSION));
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get FirmwareVersion (TODO) */
|
|
Packit Service |
39ee31 |
sa_strncpy_safe(atp->FirmwareVersion, sizeof(atp->FirmwareVersion),
|
|
Packit Service |
39ee31 |
HBA_FW_VERSION, sizeof(HBA_FW_VERSION));
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get VendorSpecificID (TODO) */
|
|
Packit Service |
39ee31 |
atp->VendorSpecificID = HBA_VENDOR_SPECIFIC_ID;
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
/* Get DriverVersion */
|
|
Packit Service |
39ee31 |
hba_dir = udev_device_get_syspath(pci);
|
|
Packit Service |
39ee31 |
sa_sys_read_line(hba_dir, SYSFS_MODULE_VER,
|
|
Packit Service |
39ee31 |
atp->DriverVersion, sizeof(atp->DriverVersion));
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
39ee31 |
struct udev_device *
|
|
Packit Service |
39ee31 |
find_netdev_by_ifindex(struct udev *udev, const char *ifindex)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
39ee31 |
struct udev_enumerate *ue;
|
|
Packit Service |
39ee31 |
struct udev_list_entry *head;
|
|
Packit Service |
39ee31 |
struct udev_device *newnet = NULL;
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
ue = udev_enumerate_new(udev);
|
|
Packit Service |
39ee31 |
udev_enumerate_add_match_subsystem(ue, "net");
|
|
Packit Service |
39ee31 |
udev_enumerate_add_match_sysattr(ue, "ifindex", ifindex);
|
|
Packit Service |
39ee31 |
udev_enumerate_scan_devices(ue);
|
|
Packit Service |
39ee31 |
/* enumerate returns a list, but there should only ever be one device
|
|
Packit Service |
39ee31 |
* with a given ifindex */
|
|
Packit Service |
39ee31 |
head = udev_enumerate_get_list_entry(ue);
|
|
Packit Service |
39ee31 |
if (head)
|
|
Packit Service |
39ee31 |
newnet = udev_device_new_from_syspath(udev, udev_list_entry_get_name(head));
|
|
Packit Service |
39ee31 |
udev_enumerate_unref(ue);
|
|
Packit Service |
39ee31 |
return newnet;
|
|
Packit Service |
39ee31 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
39ee31 |
struct udev_device *
|
|
Packit Service |
39ee31 |
find_phys_if(struct udev_device *net)
|
|
Packit Service |
39ee31 |
{
|
|
Packit Service |
39ee31 |
const char *ifindex;
|
|
Packit Service |
39ee31 |
const char *iflink;
|
|
Packit Service |
39ee31 |
struct udev *udev;
|
|
Packit Service |
39ee31 |
struct udev_device *lower = NULL;
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
ifindex = udev_device_get_sysattr_value(net, "ifindex");
|
|
Packit Service |
39ee31 |
iflink = udev_device_get_sysattr_value(net, "iflink");
|
|
Packit Service |
39ee31 |
if (strcmp(ifindex, iflink)) {
|
|
Packit Service |
39ee31 |
udev = udev_device_get_udev(net);
|
|
Packit Service |
39ee31 |
lower = find_netdev_by_ifindex(udev, iflink);
|
|
Packit Service |
39ee31 |
}
|
|
Packit Service |
39ee31 |
if (lower) {
|
|
Packit Service |
39ee31 |
return lower;
|
|
Packit Service |
39ee31 |
} else {
|
|
Packit Service |
39ee31 |
udev_device_ref(net);
|
|
Packit Service |
39ee31 |
return net;
|
|
Packit Service |
39ee31 |
}
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
static int
|
|
Packit Service |
39ee31 |
sysfs_scan(struct udev_device *fc_host)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
HBA_ADAPTERATTRIBUTES *atp;
|
|
Packit Service |
35c908 |
HBA_PORTATTRIBUTES *pap;
|
|
Packit Service |
39ee31 |
uint64_t wwnn;
|
|
Packit Service |
35c908 |
struct hba_info hba_info;
|
|
Packit Service |
35c908 |
struct adapter_info *ap;
|
|
Packit Service |
35c908 |
struct port_info *pp;
|
|
Packit Service |
39ee31 |
const char *hba_dir;
|
|
Packit Service |
39ee31 |
char drv_dir[80];
|
|
Packit Service |
35c908 |
char ifname[20], buf[256];
|
|
Packit Service |
35c908 |
char *driverName;
|
|
Packit Service |
35c908 |
int data[32], rc, i;
|
|
Packit Service |
35c908 |
char *cp;
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
const char *sysname = udev_device_get_sysname(fc_host);
|
|
Packit Service |
39ee31 |
const char *syspath = udev_device_get_syspath(fc_host);
|
|
Packit Service |
39ee31 |
struct udev_device *pci;
|
|
Packit Service |
39ee31 |
struct udev_device *net;
|
|
Packit Service |
39ee31 |
const char *ptr = NULL;
|
|
Packit Service |
39ee31 |
const char *attr;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
memset(&hba_info, 0, sizeof(hba_info));
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* Create a new HBA entry (ap) for the local port
|
|
Packit Service |
35c908 |
* We will create a new HBA entry for each local port.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
ap = malloc(sizeof(*ap));
|
|
Packit Service |
35c908 |
if (!ap) {
|
|
Packit Service |
35c908 |
fprintf(stderr, "%s: malloc failed, errno=0x%x\n",
|
|
Packit Service |
35c908 |
__func__, errno);
|
|
Packit Service |
35c908 |
return HBA_STATUS_ERROR;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
memset(ap, 0, sizeof(*ap));
|
|
Packit Service |
39ee31 |
ap->ad_kern_index = atoi(sysname + sizeof("host") - 1);
|
|
Packit Service |
35c908 |
ap->ad_port_count = 1;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* atp points to the HBA attributes structure */
|
|
Packit Service |
35c908 |
atp = &ap->ad_attr;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* Create a new local port entry
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
pp = malloc(sizeof(*pp));
|
|
Packit Service |
35c908 |
if (pp == NULL) {
|
|
Packit Service |
35c908 |
fprintf(stderr,
|
|
Packit Service |
35c908 |
"%s: malloc for local port %d failed,"
|
|
Packit Service |
35c908 |
" errno=0x%x\n", __func__,
|
|
Packit Service |
35c908 |
ap->ad_port_count - 1, errno);
|
|
Packit Service |
35c908 |
free(ap);
|
|
Packit Service |
35c908 |
return 0;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
memset(pp, 0, sizeof(*pp));
|
|
Packit Service |
35c908 |
pp->ap_adapt = ap;
|
|
Packit Service |
35c908 |
pp->ap_index = ap->ad_port_count - 1;
|
|
Packit Service |
39ee31 |
pp->ap_kern_hba = atoi(sysname + sizeof("host") - 1);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* pap points to the local port attributes structure */
|
|
Packit Service |
35c908 |
pap = &pp->ap_attr;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortSymbolicName */
|
|
Packit Service |
39ee31 |
ptr = udev_device_get_sysattr_value(fc_host, "symbolic_name");
|
|
Packit Service |
35c908 |
sa_strncpy_safe(pap->PortSymbolicName, sizeof(pap->PortSymbolicName),
|
|
Packit Service |
39ee31 |
ptr, strlen(ptr));
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Skip the HBA if it isn't OpenFC */
|
|
Packit Service |
35c908 |
cp = strstr(pap->PortSymbolicName, " over ");
|
|
Packit Service |
35c908 |
if (!cp)
|
|
Packit Service |
35c908 |
goto skip;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
39ee31 |
pci = udev_device_get_parent_with_subsystem_devtype(fc_host, "pci", NULL);
|
|
Packit Service |
39ee31 |
net = udev_device_get_parent_with_subsystem_devtype(fc_host, "net", NULL);
|
|
Packit Service |
39ee31 |
if (!pci && net) {
|
|
Packit Service |
39ee31 |
/* check for a vlan device, stacked on a real PCI network device */
|
|
Packit Service |
39ee31 |
net = find_phys_if(net);
|
|
Packit Service |
39ee31 |
pci = udev_device_get_parent_with_subsystem_devtype(net, "pci", NULL);
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* Save the host directory and the hba directory
|
|
Packit Service |
35c908 |
* in local port structure
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
sa_strncpy_safe(pp->host_dir, sizeof(pp->host_dir),
|
|
Packit Service |
39ee31 |
syspath, strlen(syspath));
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get NodeWWN */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "node_name");
|
|
Packit Service |
39ee31 |
wwnn = strtoull(attr, NULL, 16);
|
|
Packit Service |
39ee31 |
copy_wwn(&pap->NodeWWN, wwnn);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortWWN */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "port_name");
|
|
Packit Service |
39ee31 |
wwnn = strtoull(attr, NULL, 16);
|
|
Packit Service |
39ee31 |
copy_wwn(&pap->PortWWN, wwnn);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortFcId */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "port_id");
|
|
Packit Service |
39ee31 |
pap->PortFcId = strtoul(attr, NULL, 0);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortType */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "port_type");
|
|
Packit Service |
39ee31 |
rc = sa_enum_encode(port_types_table, attr, &pap->PortType);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortState */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "port_state");
|
|
Packit Service |
39ee31 |
rc = sa_enum_encode(port_states_table, attr, &pap->PortState);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortSpeed */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "speed");
|
|
Packit Service |
39ee31 |
rc = sys_read_speed(attr, &pap->PortSpeed);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortSupportedSpeed */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "supported_speeds");
|
|
Packit Service |
39ee31 |
rc = sys_read_speed(attr, &pap->PortSupportedSpeed);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortMaxFrameSize */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "maxframe_size");
|
|
Packit Service |
39ee31 |
sscanf(attr, "%d", &pap->PortMaxFrameSize);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortSupportedFc4Types */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "supported_fc4s");
|
|
Packit Service |
39ee31 |
sscanf(attr, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
|
|
Packit Service |
39ee31 |
"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
|
|
Packit Service |
39ee31 |
"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
|
|
Packit Service |
39ee31 |
"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
|
|
Packit Service |
35c908 |
&data[0], &data[1], &data[2], &data[3], &data[4], &data[5],
|
|
Packit Service |
35c908 |
&data[6], &data[7], &data[8], &data[9], &data[10], &data[11],
|
|
Packit Service |
35c908 |
&data[12], &data[13], &data[14], &data[15], &data[16],
|
|
Packit Service |
35c908 |
&data[17], &data[18], &data[19], &data[20], &data[21],
|
|
Packit Service |
35c908 |
&data[22], &data[23], &data[24], &data[25], &data[26],
|
|
Packit Service |
35c908 |
&data[27], &data[28], &data[29], &data[30], &data[31]);
|
|
Packit Service |
35c908 |
for (i = 0; i < 32; i++)
|
|
Packit Service |
35c908 |
pap->PortSupportedFc4Types.bits[i] = data[i];
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortActiveFc4Types */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "active_fc4s");
|
|
Packit Service |
39ee31 |
sscanf(attr, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
|
|
Packit Service |
39ee31 |
"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
|
|
Packit Service |
39ee31 |
"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
|
|
Packit Service |
39ee31 |
"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
|
|
Packit Service |
35c908 |
&data[0], &data[1], &data[2], &data[3], &data[4], &data[5],
|
|
Packit Service |
35c908 |
&data[6], &data[7], &data[8], &data[9], &data[10], &data[11],
|
|
Packit Service |
35c908 |
&data[12], &data[13], &data[14], &data[15], &data[16],
|
|
Packit Service |
35c908 |
&data[17], &data[18], &data[19], &data[20], &data[21],
|
|
Packit Service |
35c908 |
&data[22], &data[23], &data[24], &data[25], &data[26],
|
|
Packit Service |
35c908 |
&data[27], &data[28], &data[29], &data[30], &data[31]);
|
|
Packit Service |
35c908 |
for (i = 0; i < 32; i++)
|
|
Packit Service |
35c908 |
pap->PortActiveFc4Types.bits[i] = data[i];
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get FabricName */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "fabric_name");
|
|
Packit Service |
39ee31 |
wwnn = strtoull(attr, NULL, 16);
|
|
Packit Service |
39ee31 |
copy_wwn(&pap->FabricName, wwnn);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get PortSupportedClassofService */
|
|
Packit Service |
39ee31 |
attr = udev_device_get_sysattr_value(fc_host, "supported_classes");
|
|
Packit Service |
39ee31 |
cp = strstr(attr, "Class");
|
|
Packit Service |
35c908 |
if (cp)
|
|
Packit Service |
35c908 |
pap->PortSupportedClassofService = *(cp + 6) - '0';
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get OSDeviceName */
|
|
Packit Service |
35c908 |
sa_strncpy_safe(pap->OSDeviceName, sizeof(pap->OSDeviceName),
|
|
Packit Service |
39ee31 |
sysname, sizeof(sysname));
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get NumberofDiscoveredPorts */
|
|
Packit Service |
35c908 |
snprintf(buf, sizeof(buf), "%s/device", pp->host_dir);
|
|
Packit Service |
35c908 |
sa_dir_read(buf, counting_rports, &pap->NumberofDiscoveredPorts);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* Add the local port structure into local port table within
|
|
Packit Service |
35c908 |
* the HBA structure.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
if (sa_table_insert(&ap->ad_ports, pp->ap_index, pp) < 0) {
|
|
Packit Service |
35c908 |
fprintf(stderr,
|
|
Packit Service |
35c908 |
"%s: insert of HBA %d port %d failed\n",
|
|
Packit Service |
35c908 |
__func__, ap->ad_kern_index, pp->ap_index);
|
|
Packit Service |
35c908 |
goto skip;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Create adapter name */
|
|
Packit Service |
35c908 |
snprintf(buf, sizeof(buf), "fcoe:%s", ifname);
|
|
Packit Service |
35c908 |
ap->ad_name = strdup(buf);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
39ee31 |
if (pci)
|
|
Packit Service |
39ee31 |
sysfs_scan_pci(pci, &hba_info, atp);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get NodeSymbolicName */
|
|
Packit Service |
35c908 |
sa_strncpy_safe(atp->NodeSymbolicName, sizeof(atp->NodeSymbolicName),
|
|
Packit Service |
35c908 |
ap->ad_name, sizeof(atp->NodeSymbolicName));
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get NodeWWN - The NodeWWN is the same as
|
|
Packit Service |
35c908 |
* the NodeWWN of the local port.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
memcpy((char *)&atp->NodeWWN, (char *)&pap->NodeWWN,
|
|
Packit Service |
35c908 |
sizeof(pap->NodeWWN));
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Get DriverName */
|
|
Packit Service |
39ee31 |
hba_dir = udev_device_get_syspath(pci);
|
|
Packit Service |
35c908 |
snprintf(drv_dir, sizeof(drv_dir), "%s" SYSFS_MODULE , hba_dir);
|
|
Packit Service |
35c908 |
i = readlink(drv_dir, buf, sizeof(buf));
|
|
Packit Service |
35c908 |
if (i < 0)
|
|
Packit Service |
35c908 |
i = 0;
|
|
Packit Service |
35c908 |
buf[i] = '\0';
|
|
Packit Service |
35c908 |
if (!strstr(buf, "module")) {
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* Does not find "module" in the string.
|
|
Packit Service |
35c908 |
* This should not happen. In this case, set
|
|
Packit Service |
35c908 |
* the driver name to "Unknown".
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
driverName = "Unknown";
|
|
Packit Service |
35c908 |
} else
|
|
Packit Service |
35c908 |
driverName = strstr(buf, "module") + 7;
|
|
Packit Service |
35c908 |
sa_strncpy_safe(atp->DriverName, sizeof(atp->DriverName),
|
|
Packit Service |
35c908 |
driverName, sizeof(atp->DriverName));
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* Give HBA to library
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
rc = adapter_create(ap);
|
|
Packit Service |
35c908 |
if (rc != HBA_STATUS_OK) {
|
|
Packit Service |
35c908 |
fprintf(stderr, "%s: adapter_create failed, status=%d\n",
|
|
Packit Service |
35c908 |
__func__, rc);
|
|
Packit Service |
35c908 |
adapter_destroy(ap); /* free adapter and ports */
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
return 0;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
skip:
|
|
Packit Service |
35c908 |
free(pp);
|
|
Packit Service |
35c908 |
free(ap);
|
|
Packit Service |
35c908 |
return 0;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
void
|
|
Packit Service |
35c908 |
copy_wwn(HBA_WWN *dest, fc_wwn_t src)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
dest->wwn[0] = (u_char) (src >> 56);
|
|
Packit Service |
35c908 |
dest->wwn[1] = (u_char) (src >> 48);
|
|
Packit Service |
35c908 |
dest->wwn[2] = (u_char) (src >> 40);
|
|
Packit Service |
35c908 |
dest->wwn[3] = (u_char) (src >> 32);
|
|
Packit Service |
35c908 |
dest->wwn[4] = (u_char) (src >> 24);
|
|
Packit Service |
35c908 |
dest->wwn[5] = (u_char) (src >> 16);
|
|
Packit Service |
35c908 |
dest->wwn[6] = (u_char) (src >> 8);
|
|
Packit Service |
35c908 |
dest->wwn[7] = (u_char) src;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Test for a non-zero WWN */
|
|
Packit Service |
35c908 |
int
|
|
Packit Service |
35c908 |
is_wwn_nonzero(HBA_WWN *wwn)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
return (wwn->wwn[0] | wwn->wwn[1] | wwn->wwn[2] | wwn->wwn[3] |
|
|
Packit Service |
35c908 |
wwn->wwn[4] | wwn->wwn[5] | wwn->wwn[6] | wwn->wwn[7]) != 0;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
int
|
|
Packit Service |
35c908 |
sys_read_wwn(const char *dir, const char *file, HBA_WWN *wwn)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
int rc;
|
|
Packit Service |
35c908 |
u_int64_t val;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
rc = sa_sys_read_u64(dir, file, &val;;
|
|
Packit Service |
35c908 |
if (rc == 0)
|
|
Packit Service |
35c908 |
copy_wwn(wwn, val);
|
|
Packit Service |
35c908 |
return rc;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Port Statistics */
|
|
Packit Service |
35c908 |
HBA_STATUS
|
|
Packit Service |
35c908 |
sysfs_get_port_stats(char *dir, HBA_PORTSTATISTICS *sp)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
int rc;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
rc = sa_sys_read_u64(dir, "seconds_since_last_reset",
|
|
Packit Service |
35c908 |
(u_int64_t *)&sp->SecondsSinceLastReset);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "tx_frames", (u_int64_t *)&sp->TxFrames);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "tx_words", (u_int64_t *)&sp->TxWords);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "rx_frames", (u_int64_t *)&sp->RxFrames);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "rx_words", (u_int64_t *)&sp->RxWords);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "lip_count", (u_int64_t *)&sp->LIPCount);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "nos_count", (u_int64_t *)&sp->NOSCount);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "error_frames",
|
|
Packit Service |
35c908 |
(u_int64_t *)&sp->ErrorFrames);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "dumped_frames",
|
|
Packit Service |
35c908 |
(u_int64_t *)&sp->DumpedFrames);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "link_failure_count",
|
|
Packit Service |
35c908 |
(u_int64_t *)&sp->LinkFailureCount);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "loss_of_sync_count",
|
|
Packit Service |
35c908 |
(u_int64_t *)&sp->LossOfSyncCount);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "loss_of_signal_count",
|
|
Packit Service |
35c908 |
(u_int64_t *)&sp->LossOfSignalCount);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "prim_seq_protocol_err_count",
|
|
Packit Service |
35c908 |
(u_int64_t *)&sp->PrimitiveSeqProtocolErrCount);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "invalid_tx_word_count",
|
|
Packit Service |
35c908 |
(u_int64_t *)&sp->InvalidTxWordCount);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "invalid_crc_count",
|
|
Packit Service |
35c908 |
(u_int64_t *)&sp->InvalidCRCCount);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
return rc;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/* Port FC-4 Statistics */
|
|
Packit Service |
35c908 |
HBA_STATUS
|
|
Packit Service |
35c908 |
sysfs_get_port_fc4stats(char *dir, HBA_FC4STATISTICS *fc4sp)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
int rc;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
rc = sa_sys_read_u64(dir, "fcp_input_requests",
|
|
Packit Service |
35c908 |
(u_int64_t *)&fc4sp->InputRequests);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "fcp_output_requests",
|
|
Packit Service |
35c908 |
(u_int64_t *)&fc4sp->OutputRequests);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "fcp_control_requests",
|
|
Packit Service |
35c908 |
(u_int64_t *)&fc4sp->ControlRequests);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "fcp_input_megabytes",
|
|
Packit Service |
35c908 |
(u_int64_t *)&fc4sp->InputMegabytes);
|
|
Packit Service |
35c908 |
rc |= sa_sys_read_u64(dir, "fcp_output_megabytes",
|
|
Packit Service |
35c908 |
(u_int64_t *)&fc4sp->OutputMegabytes);
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
return rc;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* Open device and read adapter info if available.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
39ee31 |
int
|
|
Packit Service |
35c908 |
adapter_init(void)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
39ee31 |
struct udev *udev;
|
|
Packit Service |
39ee31 |
struct udev_enumerate *ue;
|
|
Packit Service |
39ee31 |
struct udev_list_entry *head, *ul;
|
|
Packit Service |
39ee31 |
struct udev_device *fc_host;
|
|
Packit Service |
39ee31 |
const char *syspath;
|
|
Packit Service |
39ee31 |
int re = 0;
|
|
Packit Service |
39ee31 |
|
|
Packit Service |
39ee31 |
udev = udev_new();
|
|
Packit Service |
39ee31 |
if (!udev) {
|
|
Packit Service |
39ee31 |
return -ENOMEM;
|
|
Packit Service |
39ee31 |
}
|
|
Packit Service |
39ee31 |
ue = udev_enumerate_new(udev);
|
|
Packit Service |
39ee31 |
if (!ue) {
|
|
Packit Service |
39ee31 |
re = -ENOMEM;
|
|
Packit Service |
39ee31 |
goto err_enum_new;
|
|
Packit Service |
39ee31 |
}
|
|
Packit Service |
39ee31 |
re = udev_enumerate_add_match_subsystem(ue, "fc_host");
|
|
Packit Service |
39ee31 |
if (re) {
|
|
Packit Service |
39ee31 |
goto err_add_match;
|
|
Packit Service |
39ee31 |
}
|
|
Packit Service |
39ee31 |
re = udev_enumerate_scan_devices(ue);
|
|
Packit Service |
39ee31 |
if (re) {
|
|
Packit Service |
39ee31 |
goto err_scan_devs;
|
|
Packit Service |
39ee31 |
}
|
|
Packit Service |
39ee31 |
head = udev_enumerate_get_list_entry(ue);
|
|
Packit Service |
39ee31 |
udev_list_entry_foreach(ul, head) {
|
|
Packit Service |
39ee31 |
syspath = udev_list_entry_get_name(ul);
|
|
Packit Service |
39ee31 |
fc_host = udev_device_new_from_syspath(udev, syspath);
|
|
Packit Service |
39ee31 |
if (!fc_host)
|
|
Packit Service |
39ee31 |
continue;
|
|
Packit Service |
39ee31 |
sysfs_scan(fc_host);
|
|
Packit Service |
39ee31 |
udev_device_unref(fc_host);
|
|
Packit Service |
39ee31 |
}
|
|
Packit Service |
39ee31 |
err_scan_devs:
|
|
Packit Service |
39ee31 |
err_add_match:
|
|
Packit Service |
39ee31 |
udev_enumerate_unref(ue);
|
|
Packit Service |
39ee31 |
err_enum_new:
|
|
Packit Service |
39ee31 |
udev_unref(udev);
|
|
Packit Service |
39ee31 |
return re;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
void
|
|
Packit Service |
35c908 |
adapter_shutdown(void)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
HBA_STATUS
|
|
Packit Service |
35c908 |
get_port_statistics(HBA_HANDLE handle, HBA_UINT32 port, HBA_PORTSTATISTICS *sp)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
struct port_info *pp;
|
|
Packit Service |
35c908 |
char dir[80];
|
|
Packit Service |
35c908 |
int rc;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
memset(sp, 0xff, sizeof(*sp)); /* unsupported statistics give -1 */
|
|
Packit Service |
35c908 |
pp = adapter_get_port(handle, port);
|
|
Packit Service |
35c908 |
if (pp == NULL) {
|
|
Packit Service |
35c908 |
fprintf(stderr, "%s: lookup failed. handle 0x%x port 0x%x\n",
|
|
Packit Service |
35c908 |
__func__, handle, port);
|
|
Packit Service |
35c908 |
return HBA_STATUS_ERROR;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
snprintf(dir, sizeof(dir), "%s/statistics", pp->host_dir);
|
|
Packit Service |
35c908 |
rc = sysfs_get_port_stats(dir, sp);
|
|
Packit Service |
35c908 |
if (rc != 0) {
|
|
Packit Service |
35c908 |
fprintf(stderr, "%s: sysfs_get_port_stats() failed,"
|
|
Packit Service |
35c908 |
" hba index=%d port index=%d, -rc=0x%x\n",
|
|
Packit Service |
35c908 |
__func__, pp->ap_adapt->ad_kern_index,
|
|
Packit Service |
35c908 |
pp->ap_index, -rc);
|
|
Packit Service |
35c908 |
return HBA_STATUS_ERROR;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
return HBA_STATUS_OK;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
/*
|
|
Packit Service |
35c908 |
* Get FC4 statistics.
|
|
Packit Service |
35c908 |
*/
|
|
Packit Service |
35c908 |
HBA_STATUS
|
|
Packit Service |
35c908 |
get_port_fc4_statistics(HBA_HANDLE handle, HBA_WWN wwn,
|
|
Packit Service |
35c908 |
HBA_UINT8 fc4_type, HBA_FC4STATISTICS *sp)
|
|
Packit Service |
35c908 |
{
|
|
Packit Service |
35c908 |
struct port_info *pp;
|
|
Packit Service |
35c908 |
char dir[80];
|
|
Packit Service |
35c908 |
int count;
|
|
Packit Service |
35c908 |
int rc;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
memset(sp, 0xff, sizeof(*sp)); /* unsupported statistics give -1 */
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
pp = adapter_get_port_by_wwn(handle, wwn, &count);
|
|
Packit Service |
35c908 |
if (count > 1)
|
|
Packit Service |
35c908 |
return HBA_STATUS_ERROR_AMBIGUOUS_WWN;
|
|
Packit Service |
35c908 |
else if (pp == NULL)
|
|
Packit Service |
35c908 |
return HBA_STATUS_ERROR_ILLEGAL_WWN;
|
|
Packit Service |
35c908 |
|
|
Packit Service |
35c908 |
snprintf(dir, sizeof(dir), "%s/statistics", pp->host_dir);
|
|
Packit Service |
35c908 |
rc = sysfs_get_port_fc4stats(dir, sp);
|
|
Packit Service |
35c908 |
if (rc != 0) {
|
|
Packit Service |
35c908 |
fprintf(stderr, "%s: sysfs_get_port_fc4stats() failed,"
|
|
Packit Service |
35c908 |
" hba index=%d port index=%d, -rc=0x%x\n",
|
|
Packit Service |
35c908 |
__func__, pp->ap_adapt->ad_kern_index,
|
|
Packit Service |
35c908 |
pp->ap_index, -rc);
|
|
Packit Service |
35c908 |
return HBA_STATUS_ERROR;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
return HBA_STATUS_OK;
|
|
Packit Service |
35c908 |
}
|
|
Packit Service |
35c908 |
|