diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 20:34:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 20:34:15 -0400 |
commit | c70b5296e775cde46cfcb2d860ba160108a5ec7a (patch) | |
tree | 30419cb982acca44499236adcca65f2f87698c74 /drivers/s390/scsi/zfcp_scsi.c | |
parent | 80c226fbef56576946c9655fcb2ab62e63404d12 (diff) | |
parent | 58ff4bd042adf8013c8f70fd03c2c0f8d022e387 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (84 commits)
[SCSI] be2iscsi: SGE Len == 64K
[SCSI] be2iscsi: Remove premature free of cid
[SCSI] be2iscsi: More time for FW
[SCSI] libsas: fix bug for vacant phy
[SCSI] sd: Fix overflow with big physical blocks
[SCSI] st: add MTWEOFI to write filemarks without flushing drive buffer
[SCSI] libsas: Don't issue commands to devices that have been hot-removed
[SCSI] megaraid_sas: Add Online Controller Reset to MegaRAID SAS drive
[SCSI] lpfc 8.3.17: Update lpfc driver version to 8.3.17
[SCSI] lpfc 8.3.17: Replace function reset methodology
[SCSI] lpfc 8.3.17: SCSI fixes
[SCSI] lpfc 8.3.17: BSG fixes
[SCSI] lpfc 8.3.17: SLI Additions and Fixes
[SCSI] lpfc 8.3.17: Code Cleanup and Locking fixes
[SCSI] zfcp: Remove scsi_cmnd->serial_number from debug traces
[SCSI] ipr: fix array error logging
[SCSI] aha152x: enable PCMCIA on 64bit
[SCSI] scsi_dh_alua: Handle all states correctly
[SCSI] cxgb4i: connection and ddp setting update
[SCSI] cxgb3i: fixed connection over vlan
...
Diffstat (limited to 'drivers/s390/scsi/zfcp_scsi.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 158 |
1 files changed, 55 insertions, 103 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 208256e39def..50286d8707f3 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -49,11 +49,12 @@ static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, | |||
49 | return sdev->queue_depth; | 49 | return sdev->queue_depth; |
50 | } | 50 | } |
51 | 51 | ||
52 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | 52 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdev) |
53 | { | 53 | { |
54 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; | 54 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
55 | unit->device = NULL; | 55 | |
56 | put_device(&unit->dev); | 56 | zfcp_erp_lun_shutdown_wait(sdev, "scssd_1"); |
57 | put_device(&zfcp_sdev->port->dev); | ||
57 | } | 58 | } |
58 | 59 | ||
59 | static int zfcp_scsi_slave_configure(struct scsi_device *sdp) | 60 | static int zfcp_scsi_slave_configure(struct scsi_device *sdp) |
@@ -78,23 +79,16 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) | |||
78 | static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | 79 | static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, |
79 | void (*done) (struct scsi_cmnd *)) | 80 | void (*done) (struct scsi_cmnd *)) |
80 | { | 81 | { |
81 | struct zfcp_unit *unit; | 82 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); |
82 | struct zfcp_adapter *adapter; | 83 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
83 | int status, scsi_result, ret; | ||
84 | struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device)); | 84 | struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device)); |
85 | int status, scsi_result, ret; | ||
85 | 86 | ||
86 | /* reset the status for this request */ | 87 | /* reset the status for this request */ |
87 | scpnt->result = 0; | 88 | scpnt->result = 0; |
88 | scpnt->host_scribble = NULL; | 89 | scpnt->host_scribble = NULL; |
89 | scpnt->scsi_done = done; | 90 | scpnt->scsi_done = done; |
90 | 91 | ||
91 | /* | ||
92 | * figure out adapter and target device | ||
93 | * (stored there by zfcp_scsi_slave_alloc) | ||
94 | */ | ||
95 | adapter = (struct zfcp_adapter *) scpnt->device->host->hostdata[0]; | ||
96 | unit = scpnt->device->hostdata; | ||
97 | |||
98 | scsi_result = fc_remote_port_chkready(rport); | 92 | scsi_result = fc_remote_port_chkready(rport); |
99 | if (unlikely(scsi_result)) { | 93 | if (unlikely(scsi_result)) { |
100 | scpnt->result = scsi_result; | 94 | scpnt->result = scsi_result; |
@@ -103,11 +97,11 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | |||
103 | return 0; | 97 | return 0; |
104 | } | 98 | } |
105 | 99 | ||
106 | status = atomic_read(&unit->status); | 100 | status = atomic_read(&zfcp_sdev->status); |
107 | if (unlikely(status & ZFCP_STATUS_COMMON_ERP_FAILED) && | 101 | if (unlikely(status & ZFCP_STATUS_COMMON_ERP_FAILED) && |
108 | !(atomic_read(&unit->port->status) & | 102 | !(atomic_read(&zfcp_sdev->port->status) & |
109 | ZFCP_STATUS_COMMON_ERP_FAILED)) { | 103 | ZFCP_STATUS_COMMON_ERP_FAILED)) { |
110 | /* only unit access denied, but port is good | 104 | /* only LUN access denied, but port is good |
111 | * not covered by FC transport, have to fail here */ | 105 | * not covered by FC transport, have to fail here */ |
112 | zfcp_scsi_command_fail(scpnt, DID_ERROR); | 106 | zfcp_scsi_command_fail(scpnt, DID_ERROR); |
113 | return 0; | 107 | return 0; |
@@ -115,8 +109,8 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | |||
115 | 109 | ||
116 | if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) { | 110 | if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) { |
117 | /* This could be either | 111 | /* This could be either |
118 | * open unit pending: this is temporary, will result in | 112 | * open LUN pending: this is temporary, will result in |
119 | * open unit or ERP_FAILED, so retry command | 113 | * open LUN or ERP_FAILED, so retry command |
120 | * call to rport_delete pending: mimic retry from | 114 | * call to rport_delete pending: mimic retry from |
121 | * fc_remote_port_chkready until rport is BLOCKED | 115 | * fc_remote_port_chkready until rport is BLOCKED |
122 | */ | 116 | */ |
@@ -124,7 +118,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | |||
124 | return 0; | 118 | return 0; |
125 | } | 119 | } |
126 | 120 | ||
127 | ret = zfcp_fsf_send_fcp_command_task(unit, scpnt); | 121 | ret = zfcp_fsf_fcp_cmnd(scpnt); |
128 | if (unlikely(ret == -EBUSY)) | 122 | if (unlikely(ret == -EBUSY)) |
129 | return SCSI_MLQUEUE_DEVICE_BUSY; | 123 | return SCSI_MLQUEUE_DEVICE_BUSY; |
130 | else if (unlikely(ret < 0)) | 124 | else if (unlikely(ret < 0)) |
@@ -133,45 +127,42 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | |||
133 | return ret; | 127 | return ret; |
134 | } | 128 | } |
135 | 129 | ||
136 | static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter, | 130 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) |
137 | unsigned int id, u64 lun) | ||
138 | { | 131 | { |
139 | unsigned long flags; | 132 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); |
133 | struct zfcp_adapter *adapter = | ||
134 | (struct zfcp_adapter *) sdev->host->hostdata[0]; | ||
135 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); | ||
140 | struct zfcp_port *port; | 136 | struct zfcp_port *port; |
141 | struct zfcp_unit *unit = NULL; | 137 | struct zfcp_unit *unit; |
142 | 138 | ||
143 | read_lock_irqsave(&adapter->port_list_lock, flags); | 139 | port = zfcp_get_port_by_wwpn(adapter, rport->port_name); |
144 | list_for_each_entry(port, &adapter->port_list, list) { | 140 | if (!port) |
145 | if (!port->rport || (id != port->rport->scsi_target_id)) | 141 | return -ENXIO; |
146 | continue; | ||
147 | unit = zfcp_get_unit_by_lun(port, lun); | ||
148 | if (unit) | ||
149 | break; | ||
150 | } | ||
151 | read_unlock_irqrestore(&adapter->port_list_lock, flags); | ||
152 | 142 | ||
153 | return unit; | 143 | unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev)); |
154 | } | 144 | if (unit) |
145 | put_device(&unit->dev); | ||
155 | 146 | ||
156 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdp) | 147 | if (!unit && !(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) { |
157 | { | 148 | put_device(&port->dev); |
158 | struct zfcp_adapter *adapter; | 149 | return -ENXIO; |
159 | struct zfcp_unit *unit; | 150 | } |
160 | u64 lun; | ||
161 | 151 | ||
162 | adapter = (struct zfcp_adapter *) sdp->host->hostdata[0]; | 152 | zfcp_sdev->port = port; |
163 | if (!adapter) | 153 | zfcp_sdev->latencies.write.channel.min = 0xFFFFFFFF; |
164 | goto out; | 154 | zfcp_sdev->latencies.write.fabric.min = 0xFFFFFFFF; |
155 | zfcp_sdev->latencies.read.channel.min = 0xFFFFFFFF; | ||
156 | zfcp_sdev->latencies.read.fabric.min = 0xFFFFFFFF; | ||
157 | zfcp_sdev->latencies.cmd.channel.min = 0xFFFFFFFF; | ||
158 | zfcp_sdev->latencies.cmd.fabric.min = 0xFFFFFFFF; | ||
159 | spin_lock_init(&zfcp_sdev->latencies.lock); | ||
165 | 160 | ||
166 | int_to_scsilun(sdp->lun, (struct scsi_lun *)&lun); | 161 | zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING); |
167 | unit = zfcp_unit_lookup(adapter, sdp->id, lun); | 162 | zfcp_erp_lun_reopen(sdev, 0, "scsla_1", NULL); |
168 | if (unit) { | 163 | zfcp_erp_wait(port->adapter); |
169 | sdp->hostdata = unit; | 164 | |
170 | unit->device = sdp; | 165 | return 0; |
171 | return 0; | ||
172 | } | ||
173 | out: | ||
174 | return -ENXIO; | ||
175 | } | 166 | } |
176 | 167 | ||
177 | static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | 168 | static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) |
@@ -179,7 +170,6 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
179 | struct Scsi_Host *scsi_host = scpnt->device->host; | 170 | struct Scsi_Host *scsi_host = scpnt->device->host; |
180 | struct zfcp_adapter *adapter = | 171 | struct zfcp_adapter *adapter = |
181 | (struct zfcp_adapter *) scsi_host->hostdata[0]; | 172 | (struct zfcp_adapter *) scsi_host->hostdata[0]; |
182 | struct zfcp_unit *unit = scpnt->device->hostdata; | ||
183 | struct zfcp_fsf_req *old_req, *abrt_req; | 173 | struct zfcp_fsf_req *old_req, *abrt_req; |
184 | unsigned long flags; | 174 | unsigned long flags; |
185 | unsigned long old_reqid = (unsigned long) scpnt->host_scribble; | 175 | unsigned long old_reqid = (unsigned long) scpnt->host_scribble; |
@@ -203,7 +193,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
203 | write_unlock_irqrestore(&adapter->abort_lock, flags); | 193 | write_unlock_irqrestore(&adapter->abort_lock, flags); |
204 | 194 | ||
205 | while (retry--) { | 195 | while (retry--) { |
206 | abrt_req = zfcp_fsf_abort_fcp_command(old_reqid, unit); | 196 | abrt_req = zfcp_fsf_abort_fcp_cmnd(scpnt); |
207 | if (abrt_req) | 197 | if (abrt_req) |
208 | break; | 198 | break; |
209 | 199 | ||
@@ -238,14 +228,14 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
238 | 228 | ||
239 | static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) | 229 | static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) |
240 | { | 230 | { |
241 | struct zfcp_unit *unit = scpnt->device->hostdata; | 231 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); |
242 | struct zfcp_adapter *adapter = unit->port->adapter; | 232 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
243 | struct zfcp_fsf_req *fsf_req = NULL; | 233 | struct zfcp_fsf_req *fsf_req = NULL; |
244 | int retval = SUCCESS, ret; | 234 | int retval = SUCCESS, ret; |
245 | int retry = 3; | 235 | int retry = 3; |
246 | 236 | ||
247 | while (retry--) { | 237 | while (retry--) { |
248 | fsf_req = zfcp_fsf_send_fcp_ctm(unit, tm_flags); | 238 | fsf_req = zfcp_fsf_fcp_task_mgmt(scpnt, tm_flags); |
249 | if (fsf_req) | 239 | if (fsf_req) |
250 | break; | 240 | break; |
251 | 241 | ||
@@ -256,7 +246,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) | |||
256 | 246 | ||
257 | if (!(atomic_read(&adapter->status) & | 247 | if (!(atomic_read(&adapter->status) & |
258 | ZFCP_STATUS_COMMON_RUNNING)) { | 248 | ZFCP_STATUS_COMMON_RUNNING)) { |
259 | zfcp_dbf_scsi_devreset("nres", tm_flags, unit, scpnt); | 249 | zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags); |
260 | return SUCCESS; | 250 | return SUCCESS; |
261 | } | 251 | } |
262 | } | 252 | } |
@@ -266,10 +256,10 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) | |||
266 | wait_for_completion(&fsf_req->completion); | 256 | wait_for_completion(&fsf_req->completion); |
267 | 257 | ||
268 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { | 258 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { |
269 | zfcp_dbf_scsi_devreset("fail", tm_flags, unit, scpnt); | 259 | zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags); |
270 | retval = FAILED; | 260 | retval = FAILED; |
271 | } else | 261 | } else |
272 | zfcp_dbf_scsi_devreset("okay", tm_flags, unit, scpnt); | 262 | zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags); |
273 | 263 | ||
274 | zfcp_fsf_req_free(fsf_req); | 264 | zfcp_fsf_req_free(fsf_req); |
275 | return retval; | 265 | return retval; |
@@ -287,8 +277,8 @@ static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) | |||
287 | 277 | ||
288 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) | 278 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) |
289 | { | 279 | { |
290 | struct zfcp_unit *unit = scpnt->device->hostdata; | 280 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); |
291 | struct zfcp_adapter *adapter = unit->port->adapter; | 281 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
292 | int ret; | 282 | int ret; |
293 | 283 | ||
294 | zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt); | 284 | zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt); |
@@ -319,8 +309,8 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) | |||
319 | } | 309 | } |
320 | 310 | ||
321 | /* tell the SCSI stack some characteristics of this adapter */ | 311 | /* tell the SCSI stack some characteristics of this adapter */ |
322 | adapter->scsi_host->max_id = 1; | 312 | adapter->scsi_host->max_id = 511; |
323 | adapter->scsi_host->max_lun = 1; | 313 | adapter->scsi_host->max_lun = 0xFFFFFFFF; |
324 | adapter->scsi_host->max_channel = 0; | 314 | adapter->scsi_host->max_channel = 0; |
325 | adapter->scsi_host->unique_id = dev_id.devno; | 315 | adapter->scsi_host->unique_id = dev_id.devno; |
326 | adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */ | 316 | adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */ |
@@ -534,20 +524,6 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport) | |||
534 | } | 524 | } |
535 | } | 525 | } |
536 | 526 | ||
537 | static void zfcp_scsi_queue_unit_register(struct zfcp_port *port) | ||
538 | { | ||
539 | struct zfcp_unit *unit; | ||
540 | |||
541 | read_lock_irq(&port->unit_list_lock); | ||
542 | list_for_each_entry(unit, &port->unit_list, list) { | ||
543 | get_device(&unit->dev); | ||
544 | if (scsi_queue_work(port->adapter->scsi_host, | ||
545 | &unit->scsi_work) <= 0) | ||
546 | put_device(&unit->dev); | ||
547 | } | ||
548 | read_unlock_irq(&port->unit_list_lock); | ||
549 | } | ||
550 | |||
551 | static void zfcp_scsi_rport_register(struct zfcp_port *port) | 527 | static void zfcp_scsi_rport_register(struct zfcp_port *port) |
552 | { | 528 | { |
553 | struct fc_rport_identifiers ids; | 529 | struct fc_rport_identifiers ids; |
@@ -574,7 +550,7 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port) | |||
574 | port->rport = rport; | 550 | port->rport = rport; |
575 | port->starget_id = rport->scsi_target_id; | 551 | port->starget_id = rport->scsi_target_id; |
576 | 552 | ||
577 | zfcp_scsi_queue_unit_register(port); | 553 | zfcp_unit_queue_scsi_scan(port); |
578 | } | 554 | } |
579 | 555 | ||
580 | static void zfcp_scsi_rport_block(struct zfcp_port *port) | 556 | static void zfcp_scsi_rport_block(struct zfcp_port *port) |
@@ -638,29 +614,6 @@ void zfcp_scsi_rport_work(struct work_struct *work) | |||
638 | } | 614 | } |
639 | 615 | ||
640 | /** | 616 | /** |
641 | * zfcp_scsi_scan - Register LUN with SCSI midlayer | ||
642 | * @unit: The LUN/unit to register | ||
643 | */ | ||
644 | void zfcp_scsi_scan(struct zfcp_unit *unit) | ||
645 | { | ||
646 | struct fc_rport *rport = unit->port->rport; | ||
647 | |||
648 | if (rport && rport->port_state == FC_PORTSTATE_ONLINE) | ||
649 | scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, | ||
650 | scsilun_to_int((struct scsi_lun *) | ||
651 | &unit->fcp_lun), 0); | ||
652 | } | ||
653 | |||
654 | void zfcp_scsi_scan_work(struct work_struct *work) | ||
655 | { | ||
656 | struct zfcp_unit *unit = container_of(work, struct zfcp_unit, | ||
657 | scsi_work); | ||
658 | |||
659 | zfcp_scsi_scan(unit); | ||
660 | put_device(&unit->dev); | ||
661 | } | ||
662 | |||
663 | /** | ||
664 | * zfcp_scsi_set_prot - Configure DIF/DIX support in scsi_host | 617 | * zfcp_scsi_set_prot - Configure DIF/DIX support in scsi_host |
665 | * @adapter: The adapter where to configure DIF/DIX for the SCSI host | 618 | * @adapter: The adapter where to configure DIF/DIX for the SCSI host |
666 | */ | 619 | */ |
@@ -735,7 +688,6 @@ struct fc_function_template zfcp_transport_functions = { | |||
735 | .show_host_port_type = 1, | 688 | .show_host_port_type = 1, |
736 | .show_host_speed = 1, | 689 | .show_host_speed = 1, |
737 | .show_host_port_id = 1, | 690 | .show_host_port_id = 1, |
738 | .disable_target_scan = 1, | ||
739 | .dd_bsg_size = sizeof(struct zfcp_fsf_ct_els), | 691 | .dd_bsg_size = sizeof(struct zfcp_fsf_ct_els), |
740 | }; | 692 | }; |
741 | 693 | ||