diff options
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 11 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 22 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 11 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 13 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 1 | ||||
-rw-r--r-- | drivers/scsi/scsi_scan.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 7 |
8 files changed, 43 insertions, 25 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 0f79f3af4f54..2889e5f2dfd3 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -128,12 +128,13 @@ out_ccwdev: | |||
128 | static void __init zfcp_init_device_setup(char *devstr) | 128 | static void __init zfcp_init_device_setup(char *devstr) |
129 | { | 129 | { |
130 | char *token; | 130 | char *token; |
131 | char *str; | 131 | char *str, *str_saved; |
132 | char busid[ZFCP_BUS_ID_SIZE]; | 132 | char busid[ZFCP_BUS_ID_SIZE]; |
133 | u64 wwpn, lun; | 133 | u64 wwpn, lun; |
134 | 134 | ||
135 | /* duplicate devstr and keep the original for sysfs presentation*/ | 135 | /* duplicate devstr and keep the original for sysfs presentation*/ |
136 | str = kmalloc(strlen(devstr) + 1, GFP_KERNEL); | 136 | str_saved = kmalloc(strlen(devstr) + 1, GFP_KERNEL); |
137 | str = str_saved; | ||
137 | if (!str) | 138 | if (!str) |
138 | return; | 139 | return; |
139 | 140 | ||
@@ -152,12 +153,12 @@ static void __init zfcp_init_device_setup(char *devstr) | |||
152 | if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun)) | 153 | if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun)) |
153 | goto err_out; | 154 | goto err_out; |
154 | 155 | ||
155 | kfree(str); | 156 | kfree(str_saved); |
156 | zfcp_init_device_configure(busid, wwpn, lun); | 157 | zfcp_init_device_configure(busid, wwpn, lun); |
157 | return; | 158 | return; |
158 | 159 | ||
159 | err_out: | 160 | err_out: |
160 | kfree(str); | 161 | kfree(str_saved); |
161 | pr_err("%s is not a valid SCSI device\n", devstr); | 162 | pr_err("%s is not a valid SCSI device\n", devstr); |
162 | } | 163 | } |
163 | 164 | ||
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 73d366ba31e5..f73e2180f333 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -858,10 +858,7 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |||
858 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) | 858 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) |
859 | return zfcp_erp_open_ptp_port(act); | 859 | return zfcp_erp_open_ptp_port(act); |
860 | if (!port->d_id) { | 860 | if (!port->d_id) { |
861 | zfcp_port_get(port); | 861 | zfcp_fc_trigger_did_lookup(port); |
862 | if (!queue_work(adapter->work_queue, | ||
863 | &port->gid_pn_work)) | ||
864 | zfcp_port_put(port); | ||
865 | return ZFCP_ERP_EXIT; | 862 | return ZFCP_ERP_EXIT; |
866 | } | 863 | } |
867 | return zfcp_erp_port_strategy_open_port(act); | 864 | return zfcp_erp_port_strategy_open_port(act); |
@@ -869,12 +866,11 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |||
869 | case ZFCP_ERP_STEP_PORT_OPENING: | 866 | case ZFCP_ERP_STEP_PORT_OPENING: |
870 | /* D_ID might have changed during open */ | 867 | /* D_ID might have changed during open */ |
871 | if (p_status & ZFCP_STATUS_COMMON_OPEN) { | 868 | if (p_status & ZFCP_STATUS_COMMON_OPEN) { |
872 | if (port->d_id) | 869 | if (!port->d_id) { |
873 | return ZFCP_ERP_SUCCEEDED; | 870 | zfcp_fc_trigger_did_lookup(port); |
874 | else { | 871 | return ZFCP_ERP_EXIT; |
875 | act->step = ZFCP_ERP_STEP_PORT_CLOSING; | ||
876 | return ZFCP_ERP_CONTINUES; | ||
877 | } | 872 | } |
873 | return ZFCP_ERP_SUCCEEDED; | ||
878 | } | 874 | } |
879 | if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) { | 875 | if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) { |
880 | port->d_id = 0; | 876 | port->d_id = 0; |
@@ -889,19 +885,21 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |||
889 | static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) | 885 | static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) |
890 | { | 886 | { |
891 | struct zfcp_port *port = erp_action->port; | 887 | struct zfcp_port *port = erp_action->port; |
888 | int p_status = atomic_read(&port->status); | ||
892 | 889 | ||
893 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC) | 890 | if ((p_status & ZFCP_STATUS_COMMON_NOESC) && |
891 | !(p_status & ZFCP_STATUS_COMMON_OPEN)) | ||
894 | goto close_init_done; | 892 | goto close_init_done; |
895 | 893 | ||
896 | switch (erp_action->step) { | 894 | switch (erp_action->step) { |
897 | case ZFCP_ERP_STEP_UNINITIALIZED: | 895 | case ZFCP_ERP_STEP_UNINITIALIZED: |
898 | zfcp_erp_port_strategy_clearstati(port); | 896 | zfcp_erp_port_strategy_clearstati(port); |
899 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN) | 897 | if (p_status & ZFCP_STATUS_COMMON_OPEN) |
900 | return zfcp_erp_port_strategy_close(erp_action); | 898 | return zfcp_erp_port_strategy_close(erp_action); |
901 | break; | 899 | break; |
902 | 900 | ||
903 | case ZFCP_ERP_STEP_PORT_CLOSING: | 901 | case ZFCP_ERP_STEP_PORT_CLOSING: |
904 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN) | 902 | if (p_status & ZFCP_STATUS_COMMON_OPEN) |
905 | return ZFCP_ERP_FAILED; | 903 | return ZFCP_ERP_FAILED; |
906 | break; | 904 | break; |
907 | } | 905 | } |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 629edec70405..b3f28deb4505 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -96,6 +96,7 @@ extern int zfcp_fc_scan_ports(struct zfcp_adapter *); | |||
96 | extern void _zfcp_fc_scan_ports_later(struct work_struct *); | 96 | extern void _zfcp_fc_scan_ports_later(struct work_struct *); |
97 | extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); | 97 | extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); |
98 | extern void zfcp_fc_port_did_lookup(struct work_struct *); | 98 | extern void zfcp_fc_port_did_lookup(struct work_struct *); |
99 | extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *); | ||
99 | extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); | 100 | extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); |
100 | extern void zfcp_fc_test_link(struct zfcp_port *); | 101 | extern void zfcp_fc_test_link(struct zfcp_port *); |
101 | extern void zfcp_fc_link_test_work(struct work_struct *); | 102 | extern void zfcp_fc_link_test_work(struct work_struct *); |
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 722f22de8753..df23bcead23d 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -361,6 +361,17 @@ out: | |||
361 | } | 361 | } |
362 | 362 | ||
363 | /** | 363 | /** |
364 | * zfcp_fc_trigger_did_lookup - trigger the d_id lookup using a GID_PN request | ||
365 | * @port: The zfcp_port to lookup the d_id for. | ||
366 | */ | ||
367 | void zfcp_fc_trigger_did_lookup(struct zfcp_port *port) | ||
368 | { | ||
369 | zfcp_port_get(port); | ||
370 | if (!queue_work(port->adapter->work_queue, &port->gid_pn_work)) | ||
371 | zfcp_port_put(port); | ||
372 | } | ||
373 | |||
374 | /** | ||
364 | * zfcp_fc_plogi_evaluate - evaluate PLOGI playload | 375 | * zfcp_fc_plogi_evaluate - evaluate PLOGI playload |
365 | * @port: zfcp_port structure | 376 | * @port: zfcp_port structure |
366 | * @plogi: plogi payload | 377 | * @plogi: plogi payload |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 38a7e4a6b639..4e41baa0c141 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -1079,7 +1079,7 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, | |||
1079 | /* common settings for ct/gs and els requests */ | 1079 | /* common settings for ct/gs and els requests */ |
1080 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; | 1080 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; |
1081 | req->qtcb->bottom.support.timeout = 2 * R_A_TOV; | 1081 | req->qtcb->bottom.support.timeout = 2 * R_A_TOV; |
1082 | zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10); | 1082 | zfcp_fsf_start_timer(req, (2 * R_A_TOV + 10) * HZ); |
1083 | 1083 | ||
1084 | return 0; | 1084 | return 0; |
1085 | } | 1085 | } |
@@ -1475,9 +1475,16 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1475 | plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; | 1475 | plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; |
1476 | if (req->qtcb->bottom.support.els1_length >= | 1476 | if (req->qtcb->bottom.support.els1_length >= |
1477 | FSF_PLOGI_MIN_LEN) { | 1477 | FSF_PLOGI_MIN_LEN) { |
1478 | if (plogi->serv_param.wwpn != port->wwpn) | 1478 | if (plogi->serv_param.wwpn != port->wwpn) { |
1479 | port->d_id = 0; | 1479 | port->d_id = 0; |
1480 | else { | 1480 | dev_warn(&port->adapter->ccw_device->dev, |
1481 | "A port opened with WWPN 0x%016Lx " | ||
1482 | "returned data that identifies it as " | ||
1483 | "WWPN 0x%016Lx\n", | ||
1484 | (unsigned long long) port->wwpn, | ||
1485 | (unsigned long long) | ||
1486 | plogi->serv_param.wwpn); | ||
1487 | } else { | ||
1481 | port->wwnn = plogi->serv_param.wwnn; | 1488 | port->wwnn = plogi->serv_param.wwnn; |
1482 | zfcp_fc_plogi_evaluate(port, plogi); | 1489 | zfcp_fc_plogi_evaluate(port, plogi); |
1483 | } | 1490 | } |
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 079a8cf518a3..d31000886ca8 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c | |||
@@ -224,6 +224,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, | |||
224 | 224 | ||
225 | zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); | 225 | zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); |
226 | zfcp_erp_wait(unit->port->adapter); | 226 | zfcp_erp_wait(unit->port->adapter); |
227 | flush_work(&unit->scsi_work); | ||
227 | zfcp_unit_put(unit); | 228 | zfcp_unit_put(unit); |
228 | out: | 229 | out: |
229 | mutex_unlock(&zfcp_data.config_mutex); | 230 | mutex_unlock(&zfcp_data.config_mutex); |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index c44783801402..0547a7f44d42 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -317,6 +317,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, | |||
317 | out_device_destroy: | 317 | out_device_destroy: |
318 | scsi_device_set_state(sdev, SDEV_DEL); | 318 | scsi_device_set_state(sdev, SDEV_DEL); |
319 | transport_destroy_device(&sdev->sdev_gendev); | 319 | transport_destroy_device(&sdev->sdev_gendev); |
320 | put_device(&sdev->sdev_dev); | ||
320 | put_device(&sdev->sdev_gendev); | 321 | put_device(&sdev->sdev_gendev); |
321 | out: | 322 | out: |
322 | if (display_failure_msg) | 323 | if (display_failure_msg) |
@@ -957,6 +958,7 @@ static inline void scsi_destroy_sdev(struct scsi_device *sdev) | |||
957 | if (sdev->host->hostt->slave_destroy) | 958 | if (sdev->host->hostt->slave_destroy) |
958 | sdev->host->hostt->slave_destroy(sdev); | 959 | sdev->host->hostt->slave_destroy(sdev); |
959 | transport_destroy_device(&sdev->sdev_gendev); | 960 | transport_destroy_device(&sdev->sdev_gendev); |
961 | put_device(&sdev->sdev_dev); | ||
960 | put_device(&sdev->sdev_gendev); | 962 | put_device(&sdev->sdev_gendev); |
961 | } | 963 | } |
962 | 964 | ||
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index fde54537d715..5c7eb63a19d1 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -864,10 +864,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
864 | goto clean_device; | 864 | goto clean_device; |
865 | } | 865 | } |
866 | 866 | ||
867 | /* take a reference for the sdev_dev; this is | ||
868 | * released by the sdev_class .release */ | ||
869 | get_device(&sdev->sdev_gendev); | ||
870 | |||
871 | /* create queue files, which may be writable, depending on the host */ | 867 | /* create queue files, which may be writable, depending on the host */ |
872 | if (sdev->host->hostt->change_queue_depth) | 868 | if (sdev->host->hostt->change_queue_depth) |
873 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); | 869 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); |
@@ -917,6 +913,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
917 | 913 | ||
918 | device_del(&sdev->sdev_gendev); | 914 | device_del(&sdev->sdev_gendev); |
919 | transport_destroy_device(&sdev->sdev_gendev); | 915 | transport_destroy_device(&sdev->sdev_gendev); |
916 | put_device(&sdev->sdev_dev); | ||
920 | put_device(&sdev->sdev_gendev); | 917 | put_device(&sdev->sdev_gendev); |
921 | 918 | ||
922 | return error; | 919 | return error; |
@@ -1065,7 +1062,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) | |||
1065 | sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); | 1062 | sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); |
1066 | 1063 | ||
1067 | device_initialize(&sdev->sdev_dev); | 1064 | device_initialize(&sdev->sdev_dev); |
1068 | sdev->sdev_dev.parent = &sdev->sdev_gendev; | 1065 | sdev->sdev_dev.parent = get_device(&sdev->sdev_gendev); |
1069 | sdev->sdev_dev.class = &sdev_class; | 1066 | sdev->sdev_dev.class = &sdev_class; |
1070 | dev_set_name(&sdev->sdev_dev, "%d:%d:%d:%d", | 1067 | dev_set_name(&sdev->sdev_dev, "%d:%d:%d:%d", |
1071 | sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); | 1068 | sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); |