[SCSI] Add an 'Issue LIP' device attribute in fc_transport class
Ok, here's a patch to add such a common API for fc transport users. Relevant LLD changes (lpfc and qla2xxx) also present. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
f9a2d2e0c8
commit
91ca7b01ec
|
@ -200,19 +200,13 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ssize_t
|
static int
|
||||||
lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
|
lpfc_issue_lip(struct Scsi_Host *host)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
|
||||||
int val = 0;
|
|
||||||
LPFC_MBOXQ_t *pmboxq;
|
LPFC_MBOXQ_t *pmboxq;
|
||||||
int mbxstatus = MBXERR_ERROR;
|
int mbxstatus = MBXERR_ERROR;
|
||||||
|
|
||||||
if ((sscanf(buf, "%d", &val) != 1) ||
|
|
||||||
(val != 1))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if ((phba->fc_flag & FC_OFFLINE_MODE) ||
|
if ((phba->fc_flag & FC_OFFLINE_MODE) ||
|
||||||
(phba->hba_state != LPFC_HBA_READY))
|
(phba->hba_state != LPFC_HBA_READY))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -234,7 +228,7 @@ lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
|
||||||
if (mbxstatus == MBXERR_ERROR)
|
if (mbxstatus == MBXERR_ERROR)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
return strlen(buf);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
|
@ -364,7 +358,6 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
|
||||||
NULL);
|
NULL);
|
||||||
static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
|
static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
|
||||||
NULL);
|
NULL);
|
||||||
static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip);
|
|
||||||
static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
|
static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
|
||||||
lpfc_board_online_show, lpfc_board_online_store);
|
lpfc_board_online_show, lpfc_board_online_store);
|
||||||
|
|
||||||
|
@ -537,7 +530,6 @@ struct class_device_attribute *lpfc_host_attrs[] = {
|
||||||
&class_device_attr_lpfc_max_luns,
|
&class_device_attr_lpfc_max_luns,
|
||||||
&class_device_attr_nport_evt_cnt,
|
&class_device_attr_nport_evt_cnt,
|
||||||
&class_device_attr_management_version,
|
&class_device_attr_management_version,
|
||||||
&class_device_attr_issue_lip,
|
|
||||||
&class_device_attr_board_online,
|
&class_device_attr_board_online,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
@ -1234,6 +1226,8 @@ struct fc_function_template lpfc_transport_functions = {
|
||||||
|
|
||||||
.get_starget_port_name = lpfc_get_starget_port_name,
|
.get_starget_port_name = lpfc_get_starget_port_name,
|
||||||
.show_starget_port_name = 1,
|
.show_starget_port_name = 1,
|
||||||
|
|
||||||
|
.issue_fc_host_lip = lpfc_issue_lip,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -503,6 +503,15 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
|
||||||
rport->dev_loss_tmo = ha->port_down_retry_count + 5;
|
rport->dev_loss_tmo = ha->port_down_retry_count + 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla2x00_issue_lip(struct Scsi_Host *shost)
|
||||||
|
{
|
||||||
|
scsi_qla_host_t *ha = to_qla_host(shost);
|
||||||
|
|
||||||
|
set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct fc_function_template qla2xxx_transport_functions = {
|
struct fc_function_template qla2xxx_transport_functions = {
|
||||||
|
|
||||||
.show_host_node_name = 1,
|
.show_host_node_name = 1,
|
||||||
|
@ -526,6 +535,7 @@ struct fc_function_template qla2xxx_transport_functions = {
|
||||||
.set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
|
.set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
|
||||||
.show_rport_dev_loss_tmo = 1,
|
.show_rport_dev_loss_tmo = 1,
|
||||||
|
|
||||||
|
.issue_fc_host_lip = qla2x00_issue_lip,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -2141,6 +2141,12 @@ qla2x00_do_dpc(void *data)
|
||||||
ha->host_no));
|
ha->host_no));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
|
||||||
|
DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
|
||||||
|
ha->host_no));
|
||||||
|
qla2x00_loop_reset(ha);
|
||||||
|
}
|
||||||
|
|
||||||
if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
|
if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
|
||||||
(!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {
|
(!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {
|
||||||
|
|
||||||
|
@ -2442,6 +2448,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
|
||||||
/* Schedule the DPC routine if needed */
|
/* Schedule the DPC routine if needed */
|
||||||
if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
|
if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
|
||||||
test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
|
test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
|
||||||
|
test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
|
||||||
start_dpc ||
|
start_dpc ||
|
||||||
test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
|
test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
|
||||||
test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
|
test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
|
||||||
|
|
|
@ -220,7 +220,7 @@ static void fc_rport_terminate(struct fc_rport *rport);
|
||||||
*/
|
*/
|
||||||
#define FC_STARGET_NUM_ATTRS 3
|
#define FC_STARGET_NUM_ATTRS 3
|
||||||
#define FC_RPORT_NUM_ATTRS 9
|
#define FC_RPORT_NUM_ATTRS 9
|
||||||
#define FC_HOST_NUM_ATTRS 15
|
#define FC_HOST_NUM_ATTRS 16
|
||||||
|
|
||||||
struct fc_internal {
|
struct fc_internal {
|
||||||
struct scsi_transport_template t;
|
struct scsi_transport_template t;
|
||||||
|
@ -713,9 +713,11 @@ static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \
|
||||||
count++
|
count++
|
||||||
|
|
||||||
#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \
|
#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \
|
||||||
|
{ \
|
||||||
i->private_host_attrs[count] = class_device_attr_host_##field; \
|
i->private_host_attrs[count] = class_device_attr_host_##field; \
|
||||||
i->host_attrs[count] = &i->private_host_attrs[count]; \
|
i->host_attrs[count] = &i->private_host_attrs[count]; \
|
||||||
count++
|
count++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Fixed Host Attributes */
|
/* Fixed Host Attributes */
|
||||||
|
@ -853,6 +855,26 @@ static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR,
|
||||||
show_fc_private_host_tgtid_bind_type,
|
show_fc_private_host_tgtid_bind_type,
|
||||||
store_fc_private_host_tgtid_bind_type);
|
store_fc_private_host_tgtid_bind_type);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
store_fc_private_host_issue_lip(struct class_device *cdev,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct Scsi_Host *shost = transport_class_to_shost(cdev);
|
||||||
|
struct fc_internal *i = to_fc_internal(shost->transportt);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* ignore any data value written to the attribute */
|
||||||
|
if (i->f->issue_fc_host_lip) {
|
||||||
|
ret = i->f->issue_fc_host_lip(shost);
|
||||||
|
return ret ? ret: count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
|
||||||
|
store_fc_private_host_issue_lip);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Host Statistics Management
|
* Host Statistics Management
|
||||||
*/
|
*/
|
||||||
|
@ -1119,6 +1141,8 @@ fc_attach_transport(struct fc_function_template *ft)
|
||||||
|
|
||||||
/* Transport-managed attributes */
|
/* Transport-managed attributes */
|
||||||
SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
|
SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
|
||||||
|
if (ft->issue_fc_host_lip)
|
||||||
|
SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
|
||||||
|
|
||||||
BUG_ON(count > FC_HOST_NUM_ATTRS);
|
BUG_ON(count > FC_HOST_NUM_ATTRS);
|
||||||
|
|
||||||
|
|
|
@ -384,6 +384,8 @@ struct fc_function_template {
|
||||||
struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *);
|
struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *);
|
||||||
void (*reset_fc_host_stats)(struct Scsi_Host *);
|
void (*reset_fc_host_stats)(struct Scsi_Host *);
|
||||||
|
|
||||||
|
int (*issue_fc_host_lip)(struct Scsi_Host *);
|
||||||
|
|
||||||
/* allocation lengths for host-specific data */
|
/* allocation lengths for host-specific data */
|
||||||
u32 dd_fcrport_size;
|
u32 dd_fcrport_size;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue