aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2005-10-27 19:03:37 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-10-28 20:35:25 -0400
commit91ca7b01ecc916632202180569a7ddbfccfc3f05 (patch)
treed26c8af7ba9d06f6b04e85270dbce0dad0624668
parentf9a2d2e0c89f73f0203fa796101089c2bce31974 (diff)
[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>
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c16
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c7
-rw-r--r--drivers/scsi/scsi_transport_fc.c28
-rw-r--r--include/scsi/scsi_transport_fc.h2
5 files changed, 50 insertions, 13 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index acae7c48ef7d..445da1d0cc88 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -200,19 +200,13 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
200} 200}
201 201
202 202
203static ssize_t 203static int
204lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count) 204lpfc_issue_lip(struct Scsi_Host *host)
205{ 205{
206 struct Scsi_Host *host = class_to_shost(cdev);
207 struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0]; 206 struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
208 int val = 0;
209 LPFC_MBOXQ_t *pmboxq; 207 LPFC_MBOXQ_t *pmboxq;
210 int mbxstatus = MBXERR_ERROR; 208 int mbxstatus = MBXERR_ERROR;
211 209
212 if ((sscanf(buf, "%d", &val) != 1) ||
213 (val != 1))
214 return -EINVAL;
215
216 if ((phba->fc_flag & FC_OFFLINE_MODE) || 210 if ((phba->fc_flag & FC_OFFLINE_MODE) ||
217 (phba->hba_state != LPFC_HBA_READY)) 211 (phba->hba_state != LPFC_HBA_READY))
218 return -EPERM; 212 return -EPERM;
@@ -234,7 +228,7 @@ lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
234 if (mbxstatus == MBXERR_ERROR) 228 if (mbxstatus == MBXERR_ERROR)
235 return -EIO; 229 return -EIO;
236 230
237 return strlen(buf); 231 return 0;
238} 232}
239 233
240static ssize_t 234static ssize_t
@@ -364,7 +358,6 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
364 NULL); 358 NULL);
365static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, 359static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
366 NULL); 360 NULL);
367static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip);
368static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, 361static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
369 lpfc_board_online_show, lpfc_board_online_store); 362 lpfc_board_online_show, lpfc_board_online_store);
370 363
@@ -537,7 +530,6 @@ struct class_device_attribute *lpfc_host_attrs[] = {
537 &class_device_attr_lpfc_max_luns, 530 &class_device_attr_lpfc_max_luns,
538 &class_device_attr_nport_evt_cnt, 531 &class_device_attr_nport_evt_cnt,
539 &class_device_attr_management_version, 532 &class_device_attr_management_version,
540 &class_device_attr_issue_lip,
541 &class_device_attr_board_online, 533 &class_device_attr_board_online,
542 NULL, 534 NULL,
543}; 535};
@@ -1234,6 +1226,8 @@ struct fc_function_template lpfc_transport_functions = {
1234 1226
1235 .get_starget_port_name = lpfc_get_starget_port_name, 1227 .get_starget_port_name = lpfc_get_starget_port_name,
1236 .show_starget_port_name = 1, 1228 .show_starget_port_name = 1,
1229
1230 .issue_fc_host_lip = lpfc_issue_lip,
1237}; 1231};
1238 1232
1239void 1233void
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 49696faa24fa..48e460eef05a 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -503,6 +503,15 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
503 rport->dev_loss_tmo = ha->port_down_retry_count + 5; 503 rport->dev_loss_tmo = ha->port_down_retry_count + 5;
504} 504}
505 505
506static int
507qla2x00_issue_lip(struct Scsi_Host *shost)
508{
509 scsi_qla_host_t *ha = to_qla_host(shost);
510
511 set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags);
512 return 0;
513}
514
506struct fc_function_template qla2xxx_transport_functions = { 515struct fc_function_template qla2xxx_transport_functions = {
507 516
508 .show_host_node_name = 1, 517 .show_host_node_name = 1,
@@ -526,6 +535,7 @@ struct fc_function_template qla2xxx_transport_functions = {
526 .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, 535 .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
527 .show_rport_dev_loss_tmo = 1, 536 .show_rport_dev_loss_tmo = 1,
528 537
538 .issue_fc_host_lip = qla2x00_issue_lip,
529}; 539};
530 540
531void 541void
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index d9eccdf4f403..b899282a856e 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2141,6 +2141,12 @@ qla2x00_do_dpc(void *data)
2141 ha->host_no)); 2141 ha->host_no));
2142 } 2142 }
2143 2143
2144 if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
2145 DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
2146 ha->host_no));
2147 qla2x00_loop_reset(ha);
2148 }
2149
2144 if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && 2150 if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
2145 (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { 2151 (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {
2146 2152
@@ -2442,6 +2448,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
2442 /* Schedule the DPC routine if needed */ 2448 /* Schedule the DPC routine if needed */
2443 if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || 2449 if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
2444 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || 2450 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
2451 test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
2445 start_dpc || 2452 start_dpc ||
2446 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || 2453 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
2447 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || 2454 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 473a82d5e3e2..27702097b7fc 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -220,7 +220,7 @@ static void fc_rport_terminate(struct fc_rport *rport);
220 */ 220 */
221#define FC_STARGET_NUM_ATTRS 3 221#define FC_STARGET_NUM_ATTRS 3
222#define FC_RPORT_NUM_ATTRS 9 222#define FC_RPORT_NUM_ATTRS 9
223#define FC_HOST_NUM_ATTRS 15 223#define FC_HOST_NUM_ATTRS 16
224 224
225struct fc_internal { 225struct fc_internal {
226 struct scsi_transport_template t; 226 struct scsi_transport_template t;
@@ -713,9 +713,11 @@ static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \
713 count++ 713 count++
714 714
715#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \ 715#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \
716{ \
716 i->private_host_attrs[count] = class_device_attr_host_##field; \ 717 i->private_host_attrs[count] = class_device_attr_host_##field; \
717 i->host_attrs[count] = &i->private_host_attrs[count]; \ 718 i->host_attrs[count] = &i->private_host_attrs[count]; \
718 count++ 719 count++; \
720}
719 721
720 722
721/* Fixed Host Attributes */ 723/* Fixed Host Attributes */
@@ -853,6 +855,26 @@ static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR,
853 show_fc_private_host_tgtid_bind_type, 855 show_fc_private_host_tgtid_bind_type,
854 store_fc_private_host_tgtid_bind_type); 856 store_fc_private_host_tgtid_bind_type);
855 857
858static ssize_t
859store_fc_private_host_issue_lip(struct class_device *cdev,
860 const char *buf, size_t count)
861{
862 struct Scsi_Host *shost = transport_class_to_shost(cdev);
863 struct fc_internal *i = to_fc_internal(shost->transportt);
864 int ret;
865
866 /* ignore any data value written to the attribute */
867 if (i->f->issue_fc_host_lip) {
868 ret = i->f->issue_fc_host_lip(shost);
869 return ret ? ret: count;
870 }
871
872 return -ENOENT;
873}
874
875static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
876 store_fc_private_host_issue_lip);
877
856/* 878/*
857 * Host Statistics Management 879 * Host Statistics Management
858 */ 880 */
@@ -1119,6 +1141,8 @@ fc_attach_transport(struct fc_function_template *ft)
1119 1141
1120 /* Transport-managed attributes */ 1142 /* Transport-managed attributes */
1121 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type); 1143 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
1144 if (ft->issue_fc_host_lip)
1145 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
1122 1146
1123 BUG_ON(count > FC_HOST_NUM_ATTRS); 1147 BUG_ON(count > FC_HOST_NUM_ATTRS);
1124 1148
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index b0d445437372..4496b32972e5 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -384,6 +384,8 @@ struct fc_function_template {
384 struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *); 384 struct fc_host_statistics * (*get_fc_host_stats)(struct Scsi_Host *);
385 void (*reset_fc_host_stats)(struct Scsi_Host *); 385 void (*reset_fc_host_stats)(struct Scsi_Host *);
386 386
387 int (*issue_fc_host_lip)(struct Scsi_Host *);
388
387 /* allocation lengths for host-specific data */ 389 /* allocation lengths for host-specific data */
388 u32 dd_fcrport_size; 390 u32 dd_fcrport_size;
389 391