[SCSI] Add an 'Issue LIP' device attribute in fc_transport class
Andrew Vasquez [Thu, 27 Oct 2005 23:03:37 +0000 (16:03 -0700)]
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>

drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/scsi_transport_fc.c
include/scsi/scsi_transport_fc.h

index acae7c4..445da1d 100644 (file)
@@ -200,19 +200,13 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
 }
 
 
-static ssize_t
-lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
+static int
+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];
-       int val = 0;
        LPFC_MBOXQ_t *pmboxq;
        int mbxstatus = MBXERR_ERROR;
 
-       if ((sscanf(buf, "%d", &val) != 1) ||
-           (val != 1))
-               return -EINVAL;
-
        if ((phba->fc_flag & FC_OFFLINE_MODE) ||
            (phba->hba_state != LPFC_HBA_READY))
                return -EPERM;
@@ -234,7 +228,7 @@ lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
        if (mbxstatus == MBXERR_ERROR)
                return -EIO;
 
-       return strlen(buf);
+       return 0;
 }
 
 static ssize_t
@@ -364,7 +358,6 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
                         NULL);
 static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
                         NULL);
-static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip);
 static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
                         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_nport_evt_cnt,
        &class_device_attr_management_version,
-       &class_device_attr_issue_lip,
        &class_device_attr_board_online,
        NULL,
 };
@@ -1234,6 +1226,8 @@ struct fc_function_template lpfc_transport_functions = {
 
        .get_starget_port_name = lpfc_get_starget_port_name,
        .show_starget_port_name = 1,
+
+       .issue_fc_host_lip = lpfc_issue_lip,
 };
 
 void
index 49696fa..48e460e 100644 (file)
@@ -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;
 }
 
+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 = {
 
        .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,
        .show_rport_dev_loss_tmo = 1,
 
+       .issue_fc_host_lip = qla2x00_issue_lip,
 };
 
 void
index d9eccdf..b899282 100644 (file)
@@ -2141,6 +2141,12 @@ qla2x00_do_dpc(void *data)
                            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) &&
                    (!(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 */
        if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
            test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
+           test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
            start_dpc ||
            test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
            test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
index 473a82d..2770209 100644 (file)
@@ -220,7 +220,7 @@ static void fc_rport_terminate(struct fc_rport  *rport);
  */
 #define FC_STARGET_NUM_ATTRS   3
 #define FC_RPORT_NUM_ATTRS     9
-#define FC_HOST_NUM_ATTRS      15
+#define FC_HOST_NUM_ATTRS      16
 
 struct fc_internal {
        struct scsi_transport_template t;
@@ -713,9 +713,11 @@ static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO,                  \
        count++
 
 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field)                 \
+{                                                                      \
        i->private_host_attrs[count] = class_device_attr_host_##field;  \
        i->host_attrs[count] = &i->private_host_attrs[count];           \
-       count++
+       count++;                                                        \
+}
 
 
 /* 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,
                        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
  */
@@ -1119,6 +1141,8 @@ fc_attach_transport(struct fc_function_template *ft)
 
        /* Transport-managed attributes */
        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);
 
index b0d4454..4496b32 100644 (file)
@@ -384,6 +384,8 @@ struct fc_function_template {
        struct fc_host_statistics * (*get_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 */
        u32                             dd_fcrport_size;