diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_scsi.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 272 |
1 files changed, 117 insertions, 155 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index cb000c9833bb..2a4991d6d4d5 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -30,6 +30,10 @@ module_param_named(dif, enable_dif, bool, 0600); | |||
30 | MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support"); | 30 | MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support"); |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | static bool allow_lun_scan = 1; | ||
34 | module_param(allow_lun_scan, bool, 0600); | ||
35 | MODULE_PARM_DESC(allow_lun_scan, "For NPIV, scan and attach all storage LUNs"); | ||
36 | |||
33 | static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, | 37 | static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, |
34 | int reason) | 38 | int reason) |
35 | { | 39 | { |
@@ -49,11 +53,12 @@ static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, | |||
49 | return sdev->queue_depth; | 53 | return sdev->queue_depth; |
50 | } | 54 | } |
51 | 55 | ||
52 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | 56 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdev) |
53 | { | 57 | { |
54 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; | 58 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
55 | unit->device = NULL; | 59 | |
56 | put_device(&unit->dev); | 60 | zfcp_erp_lun_shutdown_wait(sdev, "scssd_1"); |
61 | put_device(&zfcp_sdev->port->dev); | ||
57 | } | 62 | } |
58 | 63 | ||
59 | static int zfcp_scsi_slave_configure(struct scsi_device *sdp) | 64 | static int zfcp_scsi_slave_configure(struct scsi_device *sdp) |
@@ -67,47 +72,35 @@ static int zfcp_scsi_slave_configure(struct scsi_device *sdp) | |||
67 | 72 | ||
68 | static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) | 73 | static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) |
69 | { | 74 | { |
70 | struct zfcp_adapter *adapter = | ||
71 | (struct zfcp_adapter *) scpnt->device->host->hostdata[0]; | ||
72 | |||
73 | set_host_byte(scpnt, result); | 75 | set_host_byte(scpnt, result); |
74 | zfcp_dbf_scsi_fail_send(adapter->dbf, scpnt); | 76 | zfcp_dbf_scsi_fail_send(scpnt); |
75 | scpnt->scsi_done(scpnt); | 77 | scpnt->scsi_done(scpnt); |
76 | } | 78 | } |
77 | 79 | ||
78 | static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | 80 | static |
79 | void (*done) (struct scsi_cmnd *)) | 81 | int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt) |
80 | { | 82 | { |
81 | struct zfcp_unit *unit; | 83 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); |
82 | struct zfcp_adapter *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 | |||
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 | 90 | ||
98 | scsi_result = fc_remote_port_chkready(rport); | 91 | scsi_result = fc_remote_port_chkready(rport); |
99 | if (unlikely(scsi_result)) { | 92 | if (unlikely(scsi_result)) { |
100 | scpnt->result = scsi_result; | 93 | scpnt->result = scsi_result; |
101 | zfcp_dbf_scsi_fail_send(adapter->dbf, scpnt); | 94 | zfcp_dbf_scsi_fail_send(scpnt); |
102 | scpnt->scsi_done(scpnt); | 95 | scpnt->scsi_done(scpnt); |
103 | return 0; | 96 | return 0; |
104 | } | 97 | } |
105 | 98 | ||
106 | status = atomic_read(&unit->status); | 99 | status = atomic_read(&zfcp_sdev->status); |
107 | if (unlikely(status & ZFCP_STATUS_COMMON_ERP_FAILED) && | 100 | if (unlikely(status & ZFCP_STATUS_COMMON_ERP_FAILED) && |
108 | !(atomic_read(&unit->port->status) & | 101 | !(atomic_read(&zfcp_sdev->port->status) & |
109 | ZFCP_STATUS_COMMON_ERP_FAILED)) { | 102 | ZFCP_STATUS_COMMON_ERP_FAILED)) { |
110 | /* only unit access denied, but port is good | 103 | /* only LUN access denied, but port is good |
111 | * not covered by FC transport, have to fail here */ | 104 | * not covered by FC transport, have to fail here */ |
112 | zfcp_scsi_command_fail(scpnt, DID_ERROR); | 105 | zfcp_scsi_command_fail(scpnt, DID_ERROR); |
113 | return 0; | 106 | return 0; |
@@ -115,8 +108,8 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | |||
115 | 108 | ||
116 | if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) { | 109 | if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) { |
117 | /* This could be either | 110 | /* This could be either |
118 | * open unit pending: this is temporary, will result in | 111 | * open LUN pending: this is temporary, will result in |
119 | * open unit or ERP_FAILED, so retry command | 112 | * open LUN or ERP_FAILED, so retry command |
120 | * call to rport_delete pending: mimic retry from | 113 | * call to rport_delete pending: mimic retry from |
121 | * fc_remote_port_chkready until rport is BLOCKED | 114 | * fc_remote_port_chkready until rport is BLOCKED |
122 | */ | 115 | */ |
@@ -124,7 +117,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | |||
124 | return 0; | 117 | return 0; |
125 | } | 118 | } |
126 | 119 | ||
127 | ret = zfcp_fsf_send_fcp_command_task(unit, scpnt); | 120 | ret = zfcp_fsf_fcp_cmnd(scpnt); |
128 | if (unlikely(ret == -EBUSY)) | 121 | if (unlikely(ret == -EBUSY)) |
129 | return SCSI_MLQUEUE_DEVICE_BUSY; | 122 | return SCSI_MLQUEUE_DEVICE_BUSY; |
130 | else if (unlikely(ret < 0)) | 123 | else if (unlikely(ret < 0)) |
@@ -133,45 +126,43 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | |||
133 | return ret; | 126 | return ret; |
134 | } | 127 | } |
135 | 128 | ||
136 | static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter, | 129 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) |
137 | unsigned int id, u64 lun) | ||
138 | { | 130 | { |
139 | unsigned long flags; | 131 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); |
132 | struct zfcp_adapter *adapter = | ||
133 | (struct zfcp_adapter *) sdev->host->hostdata[0]; | ||
134 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); | ||
140 | struct zfcp_port *port; | 135 | struct zfcp_port *port; |
141 | struct zfcp_unit *unit = NULL; | 136 | struct zfcp_unit *unit; |
137 | int npiv = adapter->connection_features & FSF_FEATURE_NPIV_MODE; | ||
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 && !(allow_lun_scan && npiv)) { |
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"); |
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; |
@@ -193,8 +183,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
193 | old_req = zfcp_reqlist_find(adapter->req_list, old_reqid); | 183 | old_req = zfcp_reqlist_find(adapter->req_list, old_reqid); |
194 | if (!old_req) { | 184 | if (!old_req) { |
195 | write_unlock_irqrestore(&adapter->abort_lock, flags); | 185 | write_unlock_irqrestore(&adapter->abort_lock, flags); |
196 | zfcp_dbf_scsi_abort("lte1", adapter->dbf, scpnt, NULL, | 186 | zfcp_dbf_scsi_abort("abrt_or", scpnt, NULL); |
197 | old_reqid); | ||
198 | return FAILED; /* completion could be in progress */ | 187 | return FAILED; /* completion could be in progress */ |
199 | } | 188 | } |
200 | old_req->data = NULL; | 189 | old_req->data = NULL; |
@@ -203,49 +192,52 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
203 | write_unlock_irqrestore(&adapter->abort_lock, flags); | 192 | write_unlock_irqrestore(&adapter->abort_lock, flags); |
204 | 193 | ||
205 | while (retry--) { | 194 | while (retry--) { |
206 | abrt_req = zfcp_fsf_abort_fcp_command(old_reqid, unit); | 195 | abrt_req = zfcp_fsf_abort_fcp_cmnd(scpnt); |
207 | if (abrt_req) | 196 | if (abrt_req) |
208 | break; | 197 | break; |
209 | 198 | ||
210 | zfcp_erp_wait(adapter); | 199 | zfcp_erp_wait(adapter); |
211 | ret = fc_block_scsi_eh(scpnt); | 200 | ret = fc_block_scsi_eh(scpnt); |
212 | if (ret) | 201 | if (ret) { |
202 | zfcp_dbf_scsi_abort("abrt_bl", scpnt, NULL); | ||
213 | return ret; | 203 | return ret; |
204 | } | ||
214 | if (!(atomic_read(&adapter->status) & | 205 | if (!(atomic_read(&adapter->status) & |
215 | ZFCP_STATUS_COMMON_RUNNING)) { | 206 | ZFCP_STATUS_COMMON_RUNNING)) { |
216 | zfcp_dbf_scsi_abort("nres", adapter->dbf, scpnt, NULL, | 207 | zfcp_dbf_scsi_abort("abrt_ru", scpnt, NULL); |
217 | old_reqid); | ||
218 | return SUCCESS; | 208 | return SUCCESS; |
219 | } | 209 | } |
220 | } | 210 | } |
221 | if (!abrt_req) | 211 | if (!abrt_req) { |
212 | zfcp_dbf_scsi_abort("abrt_ar", scpnt, NULL); | ||
222 | return FAILED; | 213 | return FAILED; |
214 | } | ||
223 | 215 | ||
224 | wait_for_completion(&abrt_req->completion); | 216 | wait_for_completion(&abrt_req->completion); |
225 | 217 | ||
226 | if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) | 218 | if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) |
227 | dbf_tag = "okay"; | 219 | dbf_tag = "abrt_ok"; |
228 | else if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) | 220 | else if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) |
229 | dbf_tag = "lte2"; | 221 | dbf_tag = "abrt_nn"; |
230 | else { | 222 | else { |
231 | dbf_tag = "fail"; | 223 | dbf_tag = "abrt_fa"; |
232 | retval = FAILED; | 224 | retval = FAILED; |
233 | } | 225 | } |
234 | zfcp_dbf_scsi_abort(dbf_tag, adapter->dbf, scpnt, abrt_req, old_reqid); | 226 | zfcp_dbf_scsi_abort(dbf_tag, scpnt, abrt_req); |
235 | zfcp_fsf_req_free(abrt_req); | 227 | zfcp_fsf_req_free(abrt_req); |
236 | return retval; | 228 | return retval; |
237 | } | 229 | } |
238 | 230 | ||
239 | static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) | 231 | static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) |
240 | { | 232 | { |
241 | struct zfcp_unit *unit = scpnt->device->hostdata; | 233 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); |
242 | struct zfcp_adapter *adapter = unit->port->adapter; | 234 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
243 | struct zfcp_fsf_req *fsf_req = NULL; | 235 | struct zfcp_fsf_req *fsf_req = NULL; |
244 | int retval = SUCCESS, ret; | 236 | int retval = SUCCESS, ret; |
245 | int retry = 3; | 237 | int retry = 3; |
246 | 238 | ||
247 | while (retry--) { | 239 | while (retry--) { |
248 | fsf_req = zfcp_fsf_send_fcp_ctm(unit, tm_flags); | 240 | fsf_req = zfcp_fsf_fcp_task_mgmt(scpnt, tm_flags); |
249 | if (fsf_req) | 241 | if (fsf_req) |
250 | break; | 242 | break; |
251 | 243 | ||
@@ -256,7 +248,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) | |||
256 | 248 | ||
257 | if (!(atomic_read(&adapter->status) & | 249 | if (!(atomic_read(&adapter->status) & |
258 | ZFCP_STATUS_COMMON_RUNNING)) { | 250 | ZFCP_STATUS_COMMON_RUNNING)) { |
259 | zfcp_dbf_scsi_devreset("nres", tm_flags, unit, scpnt); | 251 | zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags); |
260 | return SUCCESS; | 252 | return SUCCESS; |
261 | } | 253 | } |
262 | } | 254 | } |
@@ -266,10 +258,10 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) | |||
266 | wait_for_completion(&fsf_req->completion); | 258 | wait_for_completion(&fsf_req->completion); |
267 | 259 | ||
268 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { | 260 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { |
269 | zfcp_dbf_scsi_devreset("fail", tm_flags, unit, scpnt); | 261 | zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags); |
270 | retval = FAILED; | 262 | retval = FAILED; |
271 | } else | 263 | } else |
272 | zfcp_dbf_scsi_devreset("okay", tm_flags, unit, scpnt); | 264 | zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags); |
273 | 265 | ||
274 | zfcp_fsf_req_free(fsf_req); | 266 | zfcp_fsf_req_free(fsf_req); |
275 | return retval; | 267 | return retval; |
@@ -287,11 +279,11 @@ static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) | |||
287 | 279 | ||
288 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) | 280 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) |
289 | { | 281 | { |
290 | struct zfcp_unit *unit = scpnt->device->hostdata; | 282 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); |
291 | struct zfcp_adapter *adapter = unit->port->adapter; | 283 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
292 | int ret; | 284 | int ret; |
293 | 285 | ||
294 | zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt); | 286 | zfcp_erp_adapter_reopen(adapter, 0, "schrh_1"); |
295 | zfcp_erp_wait(adapter); | 287 | zfcp_erp_wait(adapter); |
296 | ret = fc_block_scsi_eh(scpnt); | 288 | ret = fc_block_scsi_eh(scpnt); |
297 | if (ret) | 289 | if (ret) |
@@ -300,7 +292,37 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) | |||
300 | return SUCCESS; | 292 | return SUCCESS; |
301 | } | 293 | } |
302 | 294 | ||
303 | int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) | 295 | struct scsi_transport_template *zfcp_scsi_transport_template; |
296 | |||
297 | static struct scsi_host_template zfcp_scsi_host_template = { | ||
298 | .module = THIS_MODULE, | ||
299 | .name = "zfcp", | ||
300 | .queuecommand = zfcp_scsi_queuecommand, | ||
301 | .eh_abort_handler = zfcp_scsi_eh_abort_handler, | ||
302 | .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, | ||
303 | .eh_target_reset_handler = zfcp_scsi_eh_target_reset_handler, | ||
304 | .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, | ||
305 | .slave_alloc = zfcp_scsi_slave_alloc, | ||
306 | .slave_configure = zfcp_scsi_slave_configure, | ||
307 | .slave_destroy = zfcp_scsi_slave_destroy, | ||
308 | .change_queue_depth = zfcp_scsi_change_queue_depth, | ||
309 | .proc_name = "zfcp", | ||
310 | .can_queue = 4096, | ||
311 | .this_id = -1, | ||
312 | .sg_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ, | ||
313 | .max_sectors = (ZFCP_QDIO_MAX_SBALES_PER_REQ * 8), | ||
314 | .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, | ||
315 | .cmd_per_lun = 1, | ||
316 | .use_clustering = 1, | ||
317 | .shost_attrs = zfcp_sysfs_shost_attrs, | ||
318 | .sdev_attrs = zfcp_sysfs_sdev_attrs, | ||
319 | }; | ||
320 | |||
321 | /** | ||
322 | * zfcp_scsi_adapter_register - Register SCSI and FC host with SCSI midlayer | ||
323 | * @adapter: The zfcp adapter to register with the SCSI midlayer | ||
324 | */ | ||
325 | int zfcp_scsi_adapter_register(struct zfcp_adapter *adapter) | ||
304 | { | 326 | { |
305 | struct ccw_dev_id dev_id; | 327 | struct ccw_dev_id dev_id; |
306 | 328 | ||
@@ -309,7 +331,7 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) | |||
309 | 331 | ||
310 | ccw_device_get_id(adapter->ccw_device, &dev_id); | 332 | ccw_device_get_id(adapter->ccw_device, &dev_id); |
311 | /* register adapter as SCSI host with mid layer of SCSI stack */ | 333 | /* register adapter as SCSI host with mid layer of SCSI stack */ |
312 | adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template, | 334 | adapter->scsi_host = scsi_host_alloc(&zfcp_scsi_host_template, |
313 | sizeof (struct zfcp_adapter *)); | 335 | sizeof (struct zfcp_adapter *)); |
314 | if (!adapter->scsi_host) { | 336 | if (!adapter->scsi_host) { |
315 | dev_err(&adapter->ccw_device->dev, | 337 | dev_err(&adapter->ccw_device->dev, |
@@ -319,12 +341,12 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) | |||
319 | } | 341 | } |
320 | 342 | ||
321 | /* tell the SCSI stack some characteristics of this adapter */ | 343 | /* tell the SCSI stack some characteristics of this adapter */ |
322 | adapter->scsi_host->max_id = 1; | 344 | adapter->scsi_host->max_id = 511; |
323 | adapter->scsi_host->max_lun = 1; | 345 | adapter->scsi_host->max_lun = 0xFFFFFFFF; |
324 | adapter->scsi_host->max_channel = 0; | 346 | adapter->scsi_host->max_channel = 0; |
325 | adapter->scsi_host->unique_id = dev_id.devno; | 347 | adapter->scsi_host->unique_id = dev_id.devno; |
326 | adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */ | 348 | adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */ |
327 | adapter->scsi_host->transportt = zfcp_data.scsi_transport_template; | 349 | adapter->scsi_host->transportt = zfcp_scsi_transport_template; |
328 | 350 | ||
329 | adapter->scsi_host->hostdata[0] = (unsigned long) adapter; | 351 | adapter->scsi_host->hostdata[0] = (unsigned long) adapter; |
330 | 352 | ||
@@ -336,7 +358,11 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) | |||
336 | return 0; | 358 | return 0; |
337 | } | 359 | } |
338 | 360 | ||
339 | void zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter) | 361 | /** |
362 | * zfcp_scsi_adapter_unregister - Unregister SCSI and FC host from SCSI midlayer | ||
363 | * @adapter: The zfcp adapter to unregister. | ||
364 | */ | ||
365 | void zfcp_scsi_adapter_unregister(struct zfcp_adapter *adapter) | ||
340 | { | 366 | { |
341 | struct Scsi_Host *shost; | 367 | struct Scsi_Host *shost; |
342 | struct zfcp_port *port; | 368 | struct zfcp_port *port; |
@@ -354,8 +380,6 @@ void zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter) | |||
354 | scsi_remove_host(shost); | 380 | scsi_remove_host(shost); |
355 | scsi_host_put(shost); | 381 | scsi_host_put(shost); |
356 | adapter->scsi_host = NULL; | 382 | adapter->scsi_host = NULL; |
357 | |||
358 | return; | ||
359 | } | 383 | } |
360 | 384 | ||
361 | static struct fc_host_statistics* | 385 | static struct fc_host_statistics* |
@@ -529,25 +553,11 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport) | |||
529 | port = zfcp_get_port_by_wwpn(adapter, rport->port_name); | 553 | port = zfcp_get_port_by_wwpn(adapter, rport->port_name); |
530 | 554 | ||
531 | if (port) { | 555 | if (port) { |
532 | zfcp_erp_port_forced_reopen(port, 0, "sctrpi1", NULL); | 556 | zfcp_erp_port_forced_reopen(port, 0, "sctrpi1"); |
533 | put_device(&port->dev); | 557 | put_device(&port->dev); |
534 | } | 558 | } |
535 | } | 559 | } |
536 | 560 | ||
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) | 561 | static void zfcp_scsi_rport_register(struct zfcp_port *port) |
552 | { | 562 | { |
553 | struct fc_rport_identifiers ids; | 563 | struct fc_rport_identifiers ids; |
@@ -574,7 +584,7 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port) | |||
574 | port->rport = rport; | 584 | port->rport = rport; |
575 | port->starget_id = rport->scsi_target_id; | 585 | port->starget_id = rport->scsi_target_id; |
576 | 586 | ||
577 | zfcp_scsi_queue_unit_register(port); | 587 | zfcp_unit_queue_scsi_scan(port); |
578 | } | 588 | } |
579 | 589 | ||
580 | static void zfcp_scsi_rport_block(struct zfcp_port *port) | 590 | static void zfcp_scsi_rport_block(struct zfcp_port *port) |
@@ -638,29 +648,6 @@ void zfcp_scsi_rport_work(struct work_struct *work) | |||
638 | } | 648 | } |
639 | 649 | ||
640 | /** | 650 | /** |
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 | 651 | * zfcp_scsi_set_prot - Configure DIF/DIX support in scsi_host |
665 | * @adapter: The adapter where to configure DIF/DIX for the SCSI host | 652 | * @adapter: The adapter where to configure DIF/DIX for the SCSI host |
666 | */ | 653 | */ |
@@ -681,6 +668,7 @@ void zfcp_scsi_set_prot(struct zfcp_adapter *adapter) | |||
681 | adapter->adapter_features & FSF_FEATURE_DIX_PROT_TCPIP) { | 668 | adapter->adapter_features & FSF_FEATURE_DIX_PROT_TCPIP) { |
682 | mask |= SHOST_DIX_TYPE1_PROTECTION; | 669 | mask |= SHOST_DIX_TYPE1_PROTECTION; |
683 | scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP); | 670 | scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP); |
671 | shost->sg_prot_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ / 2; | ||
684 | shost->sg_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ / 2; | 672 | shost->sg_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ / 2; |
685 | shost->max_sectors = ZFCP_QDIO_MAX_SBALES_PER_REQ * 8 / 2; | 673 | shost->max_sectors = ZFCP_QDIO_MAX_SBALES_PER_REQ * 8 / 2; |
686 | } | 674 | } |
@@ -732,34 +720,8 @@ struct fc_function_template zfcp_transport_functions = { | |||
732 | /* no functions registered for following dynamic attributes but | 720 | /* no functions registered for following dynamic attributes but |
733 | directly set by LLDD */ | 721 | directly set by LLDD */ |
734 | .show_host_port_type = 1, | 722 | .show_host_port_type = 1, |
723 | .show_host_symbolic_name = 1, | ||
735 | .show_host_speed = 1, | 724 | .show_host_speed = 1, |
736 | .show_host_port_id = 1, | 725 | .show_host_port_id = 1, |
737 | .disable_target_scan = 1, | ||
738 | .dd_bsg_size = sizeof(struct zfcp_fsf_ct_els), | 726 | .dd_bsg_size = sizeof(struct zfcp_fsf_ct_els), |
739 | }; | 727 | }; |
740 | |||
741 | struct zfcp_data zfcp_data = { | ||
742 | .scsi_host_template = { | ||
743 | .name = "zfcp", | ||
744 | .module = THIS_MODULE, | ||
745 | .proc_name = "zfcp", | ||
746 | .change_queue_depth = zfcp_scsi_change_queue_depth, | ||
747 | .slave_alloc = zfcp_scsi_slave_alloc, | ||
748 | .slave_configure = zfcp_scsi_slave_configure, | ||
749 | .slave_destroy = zfcp_scsi_slave_destroy, | ||
750 | .queuecommand = zfcp_scsi_queuecommand, | ||
751 | .eh_abort_handler = zfcp_scsi_eh_abort_handler, | ||
752 | .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, | ||
753 | .eh_target_reset_handler = zfcp_scsi_eh_target_reset_handler, | ||
754 | .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, | ||
755 | .can_queue = 4096, | ||
756 | .this_id = -1, | ||
757 | .sg_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ, | ||
758 | .cmd_per_lun = 1, | ||
759 | .use_clustering = 1, | ||
760 | .sdev_attrs = zfcp_sysfs_sdev_attrs, | ||
761 | .max_sectors = (ZFCP_QDIO_MAX_SBALES_PER_REQ * 8), | ||
762 | .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, | ||
763 | .shost_attrs = zfcp_sysfs_shost_attrs, | ||
764 | }, | ||
765 | }; | ||