diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2005-10-27 19:03:37 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-10-28 20:35:25 -0400 |
commit | 91ca7b01ecc916632202180569a7ddbfccfc3f05 (patch) | |
tree | d26c8af7ba9d06f6b04e85270dbce0dad0624668 | |
parent | f9a2d2e0c89f73f0203fa796101089c2bce31974 (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.c | 16 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 10 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 7 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_fc.c | 28 | ||||
-rw-r--r-- | include/scsi/scsi_transport_fc.h | 2 |
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 | ||
203 | static ssize_t | 203 | static int |
204 | lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count) | 204 | lpfc_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 | ||
240 | static ssize_t | 234 | static ssize_t |
@@ -364,7 +358,6 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, | |||
364 | NULL); | 358 | NULL); |
365 | static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, | 359 | static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, |
366 | NULL); | 360 | NULL); |
367 | static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip); | ||
368 | static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, | 361 | static 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 | ||
1239 | void | 1233 | void |
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 | ||
506 | static int | ||
507 | qla2x00_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 | |||
506 | struct fc_function_template qla2xxx_transport_functions = { | 515 | struct 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 | ||
531 | void | 541 | void |
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 | ||
225 | struct fc_internal { | 225 | struct 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 | ||
858 | static ssize_t | ||
859 | store_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 | |||
875 | static 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 | ||