Skip to content

Commit

Permalink
[SCSI] fcoe: Move common functions to fcoe_transport library
Browse files Browse the repository at this point in the history
Export fcoe_get_wwn, fcoe_validate_vport_create and fcoe_wwn_to_str so that all
LLDs can use these common function.

Signed-off-by: Bhanu Prakash Gollapudi <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
  • Loading branch information
Bhanu Prakash Gollapudi authored and James Bottomley committed Aug 27, 2011
1 parent 3f8744d commit d834895
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 75 deletions.
66 changes: 1 addition & 65 deletions drivers/scsi/fcoe/fcoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ static int fcoe_vport_create(struct fc_vport *, bool disabled);
static int fcoe_vport_disable(struct fc_vport *, bool disable);
static void fcoe_set_vport_symbolic_name(struct fc_vport *);
static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *);
static int fcoe_validate_vport_create(struct fc_vport *);

static struct libfc_function_template fcoe_libfc_fcn_templ = {
.frame_send = fcoe_xmit,
Expand Down Expand Up @@ -576,23 +575,6 @@ static int fcoe_lport_config(struct fc_lport *lport)
return 0;
}

/**
* fcoe_get_wwn() - Get the world wide name from LLD if it supports it
* @netdev: the associated net device
* @wwn: the output WWN
* @type: the type of WWN (WWPN or WWNN)
*
* Returns: 0 for success
*/
static int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)
{
const struct net_device_ops *ops = netdev->netdev_ops;

if (ops->ndo_fcoe_get_wwn)
return ops->ndo_fcoe_get_wwn(netdev, wwn, type);
return -EINVAL;
}

/**
* fcoe_netdev_features_change - Updates the lport's offload flags based
* on the LLD netdev's FCoE feature flags
Expand Down Expand Up @@ -2444,7 +2426,7 @@ static int fcoe_vport_create(struct fc_vport *vport, bool disabled)

rc = fcoe_validate_vport_create(vport);
if (rc) {
wwn_to_str(vport->port_name, buf, sizeof(buf));
fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf));
printk(KERN_ERR "fcoe: Failed to create vport, "
"WWPN (0x%s) already exists\n",
buf);
Expand Down Expand Up @@ -2596,49 +2578,3 @@ static void fcoe_set_port_id(struct fc_lport *lport,
if (fp && fc_frame_payload_op(fp) == ELS_FLOGI)
fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp);
}

/**
* fcoe_validate_vport_create() - Validate a vport before creating it
* @vport: NPIV port to be created
*
* This routine is meant to add validation for a vport before creating it
* via fcoe_vport_create().
* Current validations are:
* - WWPN supplied is unique for given lport
*
*
*/
static int fcoe_validate_vport_create(struct fc_vport *vport)
{
struct Scsi_Host *shost = vport_to_shost(vport);
struct fc_lport *n_port = shost_priv(shost);
struct fc_lport *vn_port;
int rc = 0;
char buf[32];

mutex_lock(&n_port->lp_mutex);

wwn_to_str(vport->port_name, buf, sizeof(buf));
/* Check if the wwpn is not same as that of the lport */
if (!memcmp(&n_port->wwpn, &vport->port_name, sizeof(u64))) {
FCOE_DBG("vport WWPN 0x%s is same as that of the "
"base port WWPN\n", buf);
rc = -EINVAL;
goto out;
}

/* Check if there is any existing vport with same wwpn */
list_for_each_entry(vn_port, &n_port->vports, list) {
if (!memcmp(&vn_port->wwpn, &vport->port_name, sizeof(u64))) {
FCOE_DBG("vport with given WWPN 0x%s already "
"exists\n", buf);
rc = -EINVAL;
break;
}
}

out:
mutex_unlock(&n_port->lp_mutex);

return rc;
}
10 changes: 0 additions & 10 deletions drivers/scsi/fcoe/fcoe.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,4 @@ static inline struct net_device *fcoe_netdev(const struct fc_lport *lport)
((struct fcoe_port *)lport_priv(lport))->priv)->netdev;
}

static inline void wwn_to_str(u64 wwn, char *buf, int len)
{
u8 wwpn[8];

u64_to_wwn(wwn, wwpn);
snprintf(buf, len, "%02x%02x%02x%02x%02x%02x%02x%02x",
wwpn[0], wwpn[1], wwpn[2], wwpn[3],
wwpn[4], wwpn[5], wwpn[6], wwpn[7]);
}

#endif /* _FCOE_H_ */
72 changes: 72 additions & 0 deletions drivers/scsi/fcoe/fcoe_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,78 @@ static struct notifier_block libfcoe_notifier = {
.notifier_call = libfcoe_device_notification,
};

void fcoe_wwn_to_str(u64 wwn, char *buf, int len)
{
u8 wwpn[8];

u64_to_wwn(wwn, wwpn);
snprintf(buf, len, "%02x%02x%02x%02x%02x%02x%02x%02x",
wwpn[0], wwpn[1], wwpn[2], wwpn[3],
wwpn[4], wwpn[5], wwpn[6], wwpn[7]);
}
EXPORT_SYMBOL_GPL(fcoe_wwn_to_str);

/**
* fcoe_validate_vport_create() - Validate a vport before creating it
* @vport: NPIV port to be created
*
* This routine is meant to add validation for a vport before creating it
* via fcoe_vport_create().
* Current validations are:
* - WWPN supplied is unique for given lport
*/
int fcoe_validate_vport_create(struct fc_vport *vport)
{
struct Scsi_Host *shost = vport_to_shost(vport);
struct fc_lport *n_port = shost_priv(shost);
struct fc_lport *vn_port;
int rc = 0;
char buf[32];

mutex_lock(&n_port->lp_mutex);

fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf));
/* Check if the wwpn is not same as that of the lport */
if (!memcmp(&n_port->wwpn, &vport->port_name, sizeof(u64))) {
LIBFCOE_TRANSPORT_DBG("vport WWPN 0x%s is same as that of the "
"base port WWPN\n", buf);
rc = -EINVAL;
goto out;
}

/* Check if there is any existing vport with same wwpn */
list_for_each_entry(vn_port, &n_port->vports, list) {
if (!memcmp(&vn_port->wwpn, &vport->port_name, sizeof(u64))) {
LIBFCOE_TRANSPORT_DBG("vport with given WWPN 0x%s "
"already exists\n", buf);
rc = -EINVAL;
break;
}
}
out:
mutex_unlock(&n_port->lp_mutex);
return rc;
}
EXPORT_SYMBOL_GPL(fcoe_validate_vport_create);

/**
* fcoe_get_wwn() - Get the world wide name from LLD if it supports it
* @netdev: the associated net device
* @wwn: the output WWN
* @type: the type of WWN (WWPN or WWNN)
*
* Returns: 0 for success
*/
int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)
{
const struct net_device_ops *ops = netdev->netdev_ops;

if (ops->ndo_fcoe_get_wwn)
return ops->ndo_fcoe_get_wwn(netdev, wwn, type);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(fcoe_get_wwn);

/**
* fcoe_fc_crc() - Calculates the CRC for a given frame
* @fp: The frame to be checksumed
Expand Down
3 changes: 3 additions & 0 deletions include/scsi/libfcoe.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *,
const struct libfc_function_template *, int init_fcp);
u32 fcoe_fc_crc(struct fc_frame *fp);
int fcoe_start_io(struct sk_buff *skb);
int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type);
void fcoe_wwn_to_str(u64 wwn, char *buf, int len);
int fcoe_validate_vport_create(struct fc_vport *vport);

/**
* is_fip_mode() - returns true if FIP mode selected.
Expand Down

0 comments on commit d834895

Please sign in to comment.