|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Copyright (c) 2008, Intel Corporation.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* This program is free software; you can redistribute it and/or modify it
|
|
Packit |
2e24a8 |
* under the terms and conditions of the GNU Lesser General Public License,
|
|
Packit |
2e24a8 |
* version 2.1, as published by the Free Software Foundation.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
Packit |
2e24a8 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
Packit |
2e24a8 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
Packit |
2e24a8 |
* for more details.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
2e24a8 |
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit |
2e24a8 |
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
#include "utils.h"
|
|
Packit |
2e24a8 |
#include "api_lib.h"
|
|
Packit |
2e24a8 |
#include "adapt_impl.h"
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
static struct sa_table adapter_table;
|
|
Packit |
2e24a8 |
static const u_int32_t adapter_handle_offset = 0x100;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
#define HBA_SHORT_NAME_LIMIT 64
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Support for adapter information.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
HBA_UINT32
|
|
Packit |
2e24a8 |
adapter_get_count(void)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
return adapter_table.st_limit;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Get adapter name.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
HBA_STATUS
|
|
Packit |
2e24a8 |
adapter_get_name(HBA_UINT32 index, char *buf)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
HBA_STATUS status;
|
|
Packit |
2e24a8 |
struct adapter_info *ap;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
status = HBA_STATUS_ERROR_ILLEGAL_INDEX;
|
|
Packit |
2e24a8 |
ap = sa_table_lookup(&adapter_table, index);
|
|
Packit |
2e24a8 |
if (ap != NULL) {
|
|
Packit |
2e24a8 |
snprintf(buf, HBA_SHORT_NAME_LIMIT,
|
|
Packit |
2e24a8 |
"%s-%u", ap->ad_name, index);
|
|
Packit |
2e24a8 |
status = HBA_STATUS_OK;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return status;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Add an adapter to the table.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
HBA_STATUS
|
|
Packit |
2e24a8 |
adapter_create(struct adapter_info *ap)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
int index;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
index = sa_table_append(&adapter_table, ap);
|
|
Packit |
2e24a8 |
if (index < 0)
|
|
Packit |
2e24a8 |
return HBA_STATUS_ERROR;
|
|
Packit |
2e24a8 |
ap->ad_index = index;
|
|
Packit |
2e24a8 |
return HBA_STATUS_OK;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
void
|
|
Packit |
2e24a8 |
adapter_destroy(struct adapter_info *ap)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
sa_table_destroy_all(&ap->ad_ports);
|
|
Packit |
2e24a8 |
free(ap);
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
void
|
|
Packit |
2e24a8 |
adapter_destroy_all(void)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct adapter_info *ap;
|
|
Packit |
2e24a8 |
int i;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
for (i = 0; i < adapter_table.st_limit; i++) {
|
|
Packit |
2e24a8 |
ap = adapter_table.st_table[i];
|
|
Packit |
2e24a8 |
if (ap) {
|
|
Packit |
2e24a8 |
adapter_table.st_table[i] = NULL;
|
|
Packit |
2e24a8 |
adapter_destroy(ap);
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
sa_table_destroy(&adapter_table);
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
struct adapter_info *
|
|
Packit |
2e24a8 |
adapter_open_handle(HBA_HANDLE handle)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
return sa_table_lookup(&adapter_table, handle -
|
|
Packit |
2e24a8 |
adapter_handle_offset);
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
struct port_info *
|
|
Packit |
2e24a8 |
adapter_get_port(HBA_HANDLE handle, HBA_UINT32 port)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct adapter_info *ap;
|
|
Packit |
2e24a8 |
struct port_info *pp = NULL;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
ap = adapter_open_handle(handle);
|
|
Packit |
2e24a8 |
if (ap)
|
|
Packit |
2e24a8 |
pp = sa_table_lookup(&ap->ad_ports, port);
|
|
Packit |
2e24a8 |
return pp;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
struct port_info *
|
|
Packit |
2e24a8 |
adapter_get_rport(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 rport)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct port_info *pp;
|
|
Packit |
2e24a8 |
struct port_info *rp = NULL;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
pp = adapter_get_port(handle, port);
|
|
Packit |
2e24a8 |
if (pp) {
|
|
Packit |
2e24a8 |
get_rport_info(pp);
|
|
Packit |
2e24a8 |
rp = sa_table_lookup(&pp->ap_rports, rport);
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return rp;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Get the Nth discovered port information.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
struct port_info *
|
|
Packit |
2e24a8 |
adapter_get_rport_n(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 n)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct port_info *pp;
|
|
Packit |
2e24a8 |
struct port_info *rp = NULL;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
pp = adapter_get_port(handle, port);
|
|
Packit |
2e24a8 |
if (pp) {
|
|
Packit |
2e24a8 |
get_rport_info(pp);
|
|
Packit |
2e24a8 |
rp = sa_table_lookup_n(&pp->ap_rports, n);
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return rp;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
static void *
|
|
Packit |
2e24a8 |
adapter_target_match(void *rp_arg, void *target_arg)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct port_info *rp = rp_arg;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
if (rp->ap_scsi_target != *(u_int32_t *)target_arg)
|
|
Packit |
2e24a8 |
rp_arg = NULL;
|
|
Packit |
2e24a8 |
return rp_arg;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Get the rport by scsi_target number.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
struct port_info *
|
|
Packit |
2e24a8 |
adapter_get_rport_target(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 n)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct port_info *pp;
|
|
Packit |
2e24a8 |
struct port_info *rp = NULL;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
pp = adapter_get_port(handle, port);
|
|
Packit |
2e24a8 |
if (pp) {
|
|
Packit |
2e24a8 |
get_rport_info(pp);
|
|
Packit |
2e24a8 |
rp = sa_table_search(&pp->ap_rports,
|
|
Packit |
2e24a8 |
adapter_target_match, &n);
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return rp;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
static void *
|
|
Packit |
2e24a8 |
adapter_wwpn_match(void *rp_arg, void *wwpn_arg)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct port_info *rp = rp_arg;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
if (memcmp(&rp->ap_attr.PortWWN, wwpn_arg, sizeof(HBA_WWN)) != 0)
|
|
Packit |
2e24a8 |
rp_arg = NULL;
|
|
Packit |
2e24a8 |
return rp_arg;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
struct port_info *
|
|
Packit |
2e24a8 |
adapter_get_rport_by_wwn(struct port_info *pp, HBA_WWN wwpn)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct port_info *rp;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
get_rport_info(pp);
|
|
Packit |
2e24a8 |
rp = sa_table_search(&pp->ap_rports, adapter_wwpn_match, &wwpn);
|
|
Packit |
2e24a8 |
return rp;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
static void *
|
|
Packit |
2e24a8 |
adapter_fcid_match(void *rp_arg, void *fcid_arg)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct port_info *rp = rp_arg;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
if (rp->ap_attr.PortFcId != *(fc_fid_t *)fcid_arg)
|
|
Packit |
2e24a8 |
rp_arg = NULL;
|
|
Packit |
2e24a8 |
return rp_arg;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
struct port_info *
|
|
Packit |
2e24a8 |
adapter_get_rport_by_fcid(struct port_info *pp, fc_fid_t fcid)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct port_info *rp;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
get_rport_info(pp);
|
|
Packit |
2e24a8 |
rp = sa_table_search(&pp->ap_rports, adapter_fcid_match, &fcid);
|
|
Packit |
2e24a8 |
return rp;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Open adapter by name.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
HBA_HANDLE
|
|
Packit |
2e24a8 |
adapter_open(char *name)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
char buf[256];
|
|
Packit |
2e24a8 |
HBA_HANDLE i;
|
|
Packit |
2e24a8 |
HBA_STATUS status;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
for (i = 0; i < adapter_table.st_limit; i++) {
|
|
Packit |
2e24a8 |
status = adapter_get_name(i, buf);
|
|
Packit |
2e24a8 |
if (status != HBA_STATUS_OK)
|
|
Packit |
2e24a8 |
return 0;
|
|
Packit |
2e24a8 |
if (!strcmp(buf, name))
|
|
Packit |
2e24a8 |
return adapter_handle_offset + i;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return 0;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Get port by WWPN.
|
|
Packit |
2e24a8 |
* Returns NULL if WWN not unique.
|
|
Packit |
2e24a8 |
* If countp is non-NULL, the int it points to will be set to the
|
|
Packit |
2e24a8 |
* number found so that the caller can tell if the WWN was ambiguous.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
struct port_info *
|
|
Packit |
2e24a8 |
adapter_get_port_by_wwn(HBA_HANDLE handle, HBA_WWN wwn, int *countp)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct adapter_info *ap;
|
|
Packit |
2e24a8 |
struct port_info *pp_found = NULL;
|
|
Packit |
2e24a8 |
struct port_info *pp;
|
|
Packit |
2e24a8 |
int count = 0;
|
|
Packit |
2e24a8 |
int p;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
ap = adapter_open_handle(handle);
|
|
Packit |
2e24a8 |
if (ap != NULL) {
|
|
Packit |
2e24a8 |
for (p = 0; p < ap->ad_ports.st_limit; p++) {
|
|
Packit |
2e24a8 |
pp = ap->ad_ports.st_table[p];
|
|
Packit |
2e24a8 |
if (pp &&
|
|
Packit |
2e24a8 |
!memcmp(&pp->ap_attr.PortWWN, &wwn, sizeof(wwn))) {
|
|
Packit |
2e24a8 |
count++;
|
|
Packit |
2e24a8 |
pp_found = pp;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
if (count > 1)
|
|
Packit |
2e24a8 |
pp_found = NULL;
|
|
Packit |
2e24a8 |
if (countp != NULL)
|
|
Packit |
2e24a8 |
*countp = count;
|
|
Packit |
2e24a8 |
return pp_found;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Open adapter by WWN.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
HBA_STATUS
|
|
Packit |
2e24a8 |
adapter_open_by_wwn(HBA_HANDLE *phandle, HBA_WWN wwn)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct adapter_info *ap;
|
|
Packit |
2e24a8 |
struct port_info *pp;
|
|
Packit |
2e24a8 |
HBA_HANDLE found_handle = 0;
|
|
Packit |
2e24a8 |
int count = 0;
|
|
Packit |
2e24a8 |
HBA_STATUS status;
|
|
Packit |
2e24a8 |
int i;
|
|
Packit |
2e24a8 |
int p;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
for (i = 0; i < adapter_table.st_limit; i++) {
|
|
Packit |
2e24a8 |
ap = adapter_table.st_table[i];
|
|
Packit |
2e24a8 |
if (!ap)
|
|
Packit |
2e24a8 |
continue;
|
|
Packit |
2e24a8 |
if (memcmp(&ap->ad_attr.NodeWWN, &wwn, sizeof(wwn)) == 0) {
|
|
Packit |
2e24a8 |
count++;
|
|
Packit |
2e24a8 |
found_handle = ap->ad_index + adapter_handle_offset;
|
|
Packit |
2e24a8 |
} else {
|
|
Packit |
2e24a8 |
for (p = 0; p < ap->ad_ports.st_limit; p++) {
|
|
Packit |
2e24a8 |
pp = ap->ad_ports.st_table[p];
|
|
Packit |
2e24a8 |
if (!pp)
|
|
Packit |
2e24a8 |
continue;
|
|
Packit |
2e24a8 |
if (memcmp(&pp->ap_attr.PortWWN,
|
|
Packit |
2e24a8 |
&wwn, sizeof(wwn)) == 0) {
|
|
Packit |
2e24a8 |
count++;
|
|
Packit |
2e24a8 |
found_handle = ap->ad_index +
|
|
Packit |
2e24a8 |
adapter_handle_offset;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
*phandle = HBA_HANDLE_INVALID;
|
|
Packit |
2e24a8 |
if (count == 1) {
|
|
Packit |
2e24a8 |
status = HBA_STATUS_OK;
|
|
Packit |
2e24a8 |
*phandle = found_handle;
|
|
Packit |
2e24a8 |
} else if (count > 1) {
|
|
Packit |
2e24a8 |
status = HBA_STATUS_ERROR_AMBIGUOUS_WWN;
|
|
Packit |
2e24a8 |
} else {
|
|
Packit |
2e24a8 |
status = HBA_STATUS_ERROR_ILLEGAL_WWN;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return status;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Close adapter.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
void
|
|
Packit |
2e24a8 |
adapter_close(HBA_HANDLE handle)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Get adapter attributes.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
HBA_STATUS
|
|
Packit |
2e24a8 |
adapter_get_attr(HBA_HANDLE handle, HBA_ADAPTERATTRIBUTES *pattr)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct adapter_info *ap;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
ap = adapter_open_handle(handle);
|
|
Packit |
2e24a8 |
if (ap) {
|
|
Packit |
2e24a8 |
*pattr = ap->ad_attr; /* struct copy */
|
|
Packit |
2e24a8 |
return HBA_STATUS_OK;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return HBA_STATUS_ERROR;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Get adapter port attributes.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
HBA_STATUS
|
|
Packit |
2e24a8 |
adapter_get_port_attr(HBA_HANDLE handle, HBA_UINT32 port,
|
|
Packit |
2e24a8 |
HBA_PORTATTRIBUTES *pattr)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct port_info *pp;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
pp = adapter_get_port(handle, port);
|
|
Packit |
2e24a8 |
if (pp) {
|
|
Packit |
2e24a8 |
*pattr = pp->ap_attr; /* struct copy */
|
|
Packit |
2e24a8 |
return HBA_STATUS_OK;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return HBA_STATUS_ERROR;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Get discovered (remote) port attributes.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
HBA_STATUS
|
|
Packit |
2e24a8 |
adapter_get_rport_attr(HBA_HANDLE handle, HBA_UINT32 port, HBA_UINT32 rport,
|
|
Packit |
2e24a8 |
HBA_PORTATTRIBUTES *pattr)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct port_info *rp;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
rp = adapter_get_rport_n(handle, port, rport);
|
|
Packit |
2e24a8 |
if (rp) {
|
|
Packit |
2e24a8 |
*pattr = rp->ap_attr; /* struct copy */
|
|
Packit |
2e24a8 |
return HBA_STATUS_OK;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return HBA_STATUS_ERROR;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Get adapter port attributes.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
HBA_STATUS
|
|
Packit |
2e24a8 |
adapter_get_port_attr_by_wwn(HBA_HANDLE handle, HBA_WWN wwn,
|
|
Packit |
2e24a8 |
HBA_PORTATTRIBUTES *pattr)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
struct adapter_info *ap;
|
|
Packit |
2e24a8 |
struct port_info *pp;
|
|
Packit |
2e24a8 |
struct port_info *pp_found = NULL;
|
|
Packit |
2e24a8 |
u_int32_t p;
|
|
Packit |
2e24a8 |
int count = 0;
|
|
Packit |
2e24a8 |
HBA_STATUS status;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
ap = adapter_open_handle(handle);
|
|
Packit |
2e24a8 |
if (ap != NULL) {
|
|
Packit |
2e24a8 |
for (p = 0; p < ap->ad_ports.st_limit; p++) {
|
|
Packit |
2e24a8 |
pp = ap->ad_ports.st_table[p];
|
|
Packit |
2e24a8 |
if (pp == NULL)
|
|
Packit |
2e24a8 |
continue;
|
|
Packit |
2e24a8 |
if (!memcmp(&pp->ap_attr.PortWWN, &wwn, sizeof(wwn))) {
|
|
Packit |
2e24a8 |
count++;
|
|
Packit |
2e24a8 |
pp_found = pp;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
pp = sa_table_search(&pp->ap_rports,
|
|
Packit |
2e24a8 |
adapter_wwpn_match,
|
|
Packit |
2e24a8 |
&wwn);
|
|
Packit |
2e24a8 |
if (pp) {
|
|
Packit |
2e24a8 |
count++;
|
|
Packit |
2e24a8 |
pp_found = pp;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
pp = pp_found;
|
|
Packit |
2e24a8 |
if (pp != NULL) {
|
|
Packit |
2e24a8 |
if (count > 1) {
|
|
Packit |
2e24a8 |
status = HBA_STATUS_ERROR_AMBIGUOUS_WWN;
|
|
Packit |
2e24a8 |
} else {
|
|
Packit |
2e24a8 |
*pattr = pp->ap_attr; /* struct copy */
|
|
Packit |
2e24a8 |
status = HBA_STATUS_OK;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
} else {
|
|
Packit |
2e24a8 |
status = HBA_STATUS_ERROR_ILLEGAL_WWN;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return status;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|