diff options
Diffstat (limited to 'drivers/message/i2o/i2o_scsi.c')
-rw-r--r-- | drivers/message/i2o/i2o_scsi.c | 505 |
1 files changed, 247 insertions, 258 deletions
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c index 43f5875e0be5..9f1744c3933b 100644 --- a/drivers/message/i2o/i2o_scsi.c +++ b/drivers/message/i2o/i2o_scsi.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
55 | #include <linux/blkdev.h> | 55 | #include <linux/blkdev.h> |
56 | #include <linux/i2o.h> | 56 | #include <linux/i2o.h> |
57 | #include <linux/scatterlist.h> | ||
57 | 58 | ||
58 | #include <asm/dma.h> | 59 | #include <asm/dma.h> |
59 | #include <asm/system.h> | 60 | #include <asm/system.h> |
@@ -64,19 +65,23 @@ | |||
64 | #include <scsi/scsi_host.h> | 65 | #include <scsi/scsi_host.h> |
65 | #include <scsi/scsi_device.h> | 66 | #include <scsi/scsi_device.h> |
66 | #include <scsi/scsi_cmnd.h> | 67 | #include <scsi/scsi_cmnd.h> |
68 | #include <scsi/scsi_request.h> | ||
69 | #include <scsi/sg.h> | ||
70 | #include <scsi/sg_request.h> | ||
67 | 71 | ||
68 | #define OSM_NAME "scsi-osm" | 72 | #define OSM_NAME "scsi-osm" |
69 | #define OSM_VERSION "$Rev$" | 73 | #define OSM_VERSION "1.282" |
70 | #define OSM_DESCRIPTION "I2O SCSI Peripheral OSM" | 74 | #define OSM_DESCRIPTION "I2O SCSI Peripheral OSM" |
71 | 75 | ||
72 | static struct i2o_driver i2o_scsi_driver; | 76 | static struct i2o_driver i2o_scsi_driver; |
73 | 77 | ||
74 | static int i2o_scsi_max_id = 16; | 78 | static unsigned int i2o_scsi_max_id = 16; |
75 | static int i2o_scsi_max_lun = 8; | 79 | static unsigned int i2o_scsi_max_lun = 255; |
76 | 80 | ||
77 | struct i2o_scsi_host { | 81 | struct i2o_scsi_host { |
78 | struct Scsi_Host *scsi_host; /* pointer to the SCSI host */ | 82 | struct Scsi_Host *scsi_host; /* pointer to the SCSI host */ |
79 | struct i2o_controller *iop; /* pointer to the I2O controller */ | 83 | struct i2o_controller *iop; /* pointer to the I2O controller */ |
84 | unsigned int lun; /* lun's used for block devices */ | ||
80 | struct i2o_device *channel[0]; /* channel->i2o_dev mapping table */ | 85 | struct i2o_device *channel[0]; /* channel->i2o_dev mapping table */ |
81 | }; | 86 | }; |
82 | 87 | ||
@@ -99,11 +104,17 @@ static struct i2o_scsi_host *i2o_scsi_host_alloc(struct i2o_controller *c) | |||
99 | u8 type; | 104 | u8 type; |
100 | int i; | 105 | int i; |
101 | size_t size; | 106 | size_t size; |
102 | i2o_status_block *sb; | 107 | u16 body_size = 6; |
108 | |||
109 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
110 | if (c->adaptec) | ||
111 | body_size = 8; | ||
112 | #endif | ||
103 | 113 | ||
104 | list_for_each_entry(i2o_dev, &c->devices, list) | 114 | list_for_each_entry(i2o_dev, &c->devices, list) |
105 | if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT) { | 115 | if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) { |
106 | if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) || (type == 1)) /* SCSI bus */ | 116 | if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) |
117 | && (type == 0x01)) /* SCSI bus */ | ||
107 | max_channel++; | 118 | max_channel++; |
108 | } | 119 | } |
109 | 120 | ||
@@ -125,20 +136,18 @@ static struct i2o_scsi_host *i2o_scsi_host_alloc(struct i2o_controller *c) | |||
125 | scsi_host->max_id = i2o_scsi_max_id; | 136 | scsi_host->max_id = i2o_scsi_max_id; |
126 | scsi_host->max_lun = i2o_scsi_max_lun; | 137 | scsi_host->max_lun = i2o_scsi_max_lun; |
127 | scsi_host->this_id = c->unit; | 138 | scsi_host->this_id = c->unit; |
128 | 139 | scsi_host->sg_tablesize = i2o_sg_tablesize(c, body_size); | |
129 | sb = c->status_block.virt; | ||
130 | |||
131 | scsi_host->sg_tablesize = (sb->inbound_frame_size - | ||
132 | sizeof(struct i2o_message) / 4 - 6) / 2; | ||
133 | 140 | ||
134 | i2o_shost = (struct i2o_scsi_host *)scsi_host->hostdata; | 141 | i2o_shost = (struct i2o_scsi_host *)scsi_host->hostdata; |
135 | i2o_shost->scsi_host = scsi_host; | 142 | i2o_shost->scsi_host = scsi_host; |
136 | i2o_shost->iop = c; | 143 | i2o_shost->iop = c; |
144 | i2o_shost->lun = 1; | ||
137 | 145 | ||
138 | i = 0; | 146 | i = 0; |
139 | list_for_each_entry(i2o_dev, &c->devices, list) | 147 | list_for_each_entry(i2o_dev, &c->devices, list) |
140 | if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT) { | 148 | if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) { |
141 | if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) || (type == 1)) /* only SCSI bus */ | 149 | if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) |
150 | && (type == 0x01)) /* only SCSI bus */ | ||
142 | i2o_shost->channel[i++] = i2o_dev; | 151 | i2o_shost->channel[i++] = i2o_dev; |
143 | 152 | ||
144 | if (i >= max_channel) | 153 | if (i >= max_channel) |
@@ -178,10 +187,13 @@ static int i2o_scsi_remove(struct device *dev) | |||
178 | struct i2o_scsi_host *i2o_shost; | 187 | struct i2o_scsi_host *i2o_shost; |
179 | struct scsi_device *scsi_dev; | 188 | struct scsi_device *scsi_dev; |
180 | 189 | ||
190 | osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid); | ||
191 | |||
181 | i2o_shost = i2o_scsi_get_host(c); | 192 | i2o_shost = i2o_scsi_get_host(c); |
182 | 193 | ||
183 | shost_for_each_device(scsi_dev, i2o_shost->scsi_host) | 194 | shost_for_each_device(scsi_dev, i2o_shost->scsi_host) |
184 | if (scsi_dev->hostdata == i2o_dev) { | 195 | if (scsi_dev->hostdata == i2o_dev) { |
196 | sysfs_remove_link(&i2o_dev->device.kobj, "scsi"); | ||
185 | scsi_remove_device(scsi_dev); | 197 | scsi_remove_device(scsi_dev); |
186 | scsi_device_put(scsi_dev); | 198 | scsi_device_put(scsi_dev); |
187 | break; | 199 | break; |
@@ -207,8 +219,8 @@ static int i2o_scsi_probe(struct device *dev) | |||
207 | struct Scsi_Host *scsi_host; | 219 | struct Scsi_Host *scsi_host; |
208 | struct i2o_device *parent; | 220 | struct i2o_device *parent; |
209 | struct scsi_device *scsi_dev; | 221 | struct scsi_device *scsi_dev; |
210 | u32 id; | 222 | u32 id = -1; |
211 | u64 lun; | 223 | u64 lun = -1; |
212 | int channel = -1; | 224 | int channel = -1; |
213 | int i; | 225 | int i; |
214 | 226 | ||
@@ -218,8 +230,56 @@ static int i2o_scsi_probe(struct device *dev) | |||
218 | 230 | ||
219 | scsi_host = i2o_shost->scsi_host; | 231 | scsi_host = i2o_shost->scsi_host; |
220 | 232 | ||
221 | if (i2o_parm_field_get(i2o_dev, 0, 3, &id, 4) < 0) | 233 | switch (i2o_dev->lct_data.class_id) { |
234 | case I2O_CLASS_RANDOM_BLOCK_STORAGE: | ||
235 | case I2O_CLASS_EXECUTIVE: | ||
236 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
237 | if (c->adaptec) { | ||
238 | u8 type; | ||
239 | struct i2o_device *d = i2o_shost->channel[0]; | ||
240 | |||
241 | if (i2o_parm_field_get(d, 0x0000, 0, &type, 1) | ||
242 | && (type == 0x01)) /* SCSI bus */ | ||
243 | if (i2o_parm_field_get(d, 0x0200, 4, &id, 4)) { | ||
244 | channel = 0; | ||
245 | if (i2o_dev->lct_data.class_id == | ||
246 | I2O_CLASS_RANDOM_BLOCK_STORAGE) | ||
247 | lun = i2o_shost->lun++; | ||
248 | else | ||
249 | lun = 0; | ||
250 | } | ||
251 | } | ||
252 | #endif | ||
253 | break; | ||
254 | |||
255 | case I2O_CLASS_SCSI_PERIPHERAL: | ||
256 | if (i2o_parm_field_get(i2o_dev, 0x0000, 3, &id, 4) < 0) | ||
257 | return -EFAULT; | ||
258 | |||
259 | if (i2o_parm_field_get(i2o_dev, 0x0000, 4, &lun, 8) < 0) | ||
260 | return -EFAULT; | ||
261 | |||
262 | parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid); | ||
263 | if (!parent) { | ||
264 | osm_warn("can not find parent of device %03x\n", | ||
265 | i2o_dev->lct_data.tid); | ||
266 | return -EFAULT; | ||
267 | } | ||
268 | |||
269 | for (i = 0; i <= i2o_shost->scsi_host->max_channel; i++) | ||
270 | if (i2o_shost->channel[i] == parent) | ||
271 | channel = i; | ||
272 | break; | ||
273 | |||
274 | default: | ||
222 | return -EFAULT; | 275 | return -EFAULT; |
276 | } | ||
277 | |||
278 | if (channel == -1) { | ||
279 | osm_warn("can not find channel of device %03x\n", | ||
280 | i2o_dev->lct_data.tid); | ||
281 | return -EFAULT; | ||
282 | } | ||
223 | 283 | ||
224 | if (id >= scsi_host->max_id) { | 284 | if (id >= scsi_host->max_id) { |
225 | osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)", id, | 285 | osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)", id, |
@@ -227,42 +287,26 @@ static int i2o_scsi_probe(struct device *dev) | |||
227 | return -EFAULT; | 287 | return -EFAULT; |
228 | } | 288 | } |
229 | 289 | ||
230 | if (i2o_parm_field_get(i2o_dev, 0, 4, &lun, 8) < 0) | ||
231 | return -EFAULT; | ||
232 | if (lun >= scsi_host->max_lun) { | 290 | if (lun >= scsi_host->max_lun) { |
233 | osm_warn("SCSI device id (%d) >= max_lun of I2O host (%d)", | 291 | osm_warn("SCSI device id (%d) >= max_lun of I2O host (%d)", |
234 | (unsigned int)lun, scsi_host->max_lun); | 292 | (unsigned int)lun, scsi_host->max_lun); |
235 | return -EFAULT; | 293 | return -EFAULT; |
236 | } | 294 | } |
237 | 295 | ||
238 | parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid); | ||
239 | if (!parent) { | ||
240 | osm_warn("can not find parent of device %03x\n", | ||
241 | i2o_dev->lct_data.tid); | ||
242 | return -EFAULT; | ||
243 | } | ||
244 | |||
245 | for (i = 0; i <= i2o_shost->scsi_host->max_channel; i++) | ||
246 | if (i2o_shost->channel[i] == parent) | ||
247 | channel = i; | ||
248 | |||
249 | if (channel == -1) { | ||
250 | osm_warn("can not find channel of device %03x\n", | ||
251 | i2o_dev->lct_data.tid); | ||
252 | return -EFAULT; | ||
253 | } | ||
254 | |||
255 | scsi_dev = | 296 | scsi_dev = |
256 | __scsi_add_device(i2o_shost->scsi_host, channel, id, lun, i2o_dev); | 297 | __scsi_add_device(i2o_shost->scsi_host, channel, id, lun, i2o_dev); |
257 | 298 | ||
258 | if (!scsi_dev) { | 299 | if (IS_ERR(scsi_dev)) { |
259 | osm_warn("can not add SCSI device %03x\n", | 300 | osm_warn("can not add SCSI device %03x\n", |
260 | i2o_dev->lct_data.tid); | 301 | i2o_dev->lct_data.tid); |
261 | return -EFAULT; | 302 | return PTR_ERR(scsi_dev); |
262 | } | 303 | } |
263 | 304 | ||
264 | osm_debug("added new SCSI device %03x (cannel: %d, id: %d, lun: %d)\n", | 305 | sysfs_create_link(&i2o_dev->device.kobj, &scsi_dev->sdev_gendev.kobj, |
265 | i2o_dev->lct_data.tid, channel, id, (unsigned int)lun); | 306 | "scsi"); |
307 | |||
308 | osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %d\n", | ||
309 | i2o_dev->lct_data.tid, channel, id, (unsigned int)lun); | ||
266 | 310 | ||
267 | return 0; | 311 | return 0; |
268 | }; | 312 | }; |
@@ -293,162 +337,89 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m, | |||
293 | struct i2o_message *msg) | 337 | struct i2o_message *msg) |
294 | { | 338 | { |
295 | struct scsi_cmnd *cmd; | 339 | struct scsi_cmnd *cmd; |
340 | u32 error; | ||
296 | struct device *dev; | 341 | struct device *dev; |
297 | u8 as, ds, st; | ||
298 | 342 | ||
299 | cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); | 343 | cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); |
300 | 344 | if (unlikely(!cmd)) { | |
301 | if (msg->u.head[0] & (1 << 13)) { | 345 | osm_err("NULL reply received!\n"); |
302 | struct i2o_message __iomem *pmsg; /* preserved message */ | 346 | return -1; |
303 | u32 pm; | ||
304 | int err = DID_ERROR; | ||
305 | |||
306 | pm = le32_to_cpu(msg->body[3]); | ||
307 | |||
308 | pmsg = i2o_msg_in_to_virt(c, pm); | ||
309 | |||
310 | osm_err("IOP fail.\n"); | ||
311 | osm_err("From %d To %d Cmd %d.\n", | ||
312 | (msg->u.head[1] >> 12) & 0xFFF, | ||
313 | msg->u.head[1] & 0xFFF, msg->u.head[1] >> 24); | ||
314 | osm_err("Failure Code %d.\n", msg->body[0] >> 24); | ||
315 | if (msg->body[0] & (1 << 16)) | ||
316 | osm_err("Format error.\n"); | ||
317 | if (msg->body[0] & (1 << 17)) | ||
318 | osm_err("Path error.\n"); | ||
319 | if (msg->body[0] & (1 << 18)) | ||
320 | osm_err("Path State.\n"); | ||
321 | if (msg->body[0] & (1 << 18)) | ||
322 | { | ||
323 | osm_err("Congestion.\n"); | ||
324 | err = DID_BUS_BUSY; | ||
325 | } | ||
326 | |||
327 | osm_debug("Failing message is %p.\n", pmsg); | ||
328 | |||
329 | cmd = i2o_cntxt_list_get(c, readl(&pmsg->u.s.tcntxt)); | ||
330 | if (!cmd) | ||
331 | return 1; | ||
332 | |||
333 | cmd->result = err << 16; | ||
334 | cmd->scsi_done(cmd); | ||
335 | |||
336 | /* Now flush the message by making it a NOP */ | ||
337 | i2o_msg_nop(c, pm); | ||
338 | |||
339 | return 1; | ||
340 | } | 347 | } |
341 | 348 | ||
342 | /* | 349 | /* |
343 | * Low byte is device status, next is adapter status, | 350 | * Low byte is device status, next is adapter status, |
344 | * (then one byte reserved), then request status. | 351 | * (then one byte reserved), then request status. |
345 | */ | 352 | */ |
346 | ds = (u8) le32_to_cpu(msg->body[0]); | 353 | error = le32_to_cpu(msg->body[0]); |
347 | as = (u8) (le32_to_cpu(msg->body[0]) >> 8); | 354 | |
348 | st = (u8) (le32_to_cpu(msg->body[0]) >> 24); | 355 | osm_debug("Completed %ld\n", cmd->serial_number); |
349 | 356 | ||
357 | cmd->result = error & 0xff; | ||
350 | /* | 358 | /* |
351 | * Is this a control request coming back - eg an abort ? | 359 | * if DeviceStatus is not SCSI_SUCCESS copy over the sense data and let |
360 | * the SCSI layer handle the error | ||
352 | */ | 361 | */ |
362 | if (cmd->result) | ||
363 | memcpy(cmd->sense_buffer, &msg->body[3], | ||
364 | min(sizeof(cmd->sense_buffer), (size_t) 40)); | ||
353 | 365 | ||
354 | if (!cmd) { | 366 | /* only output error code if AdapterStatus is not HBA_SUCCESS */ |
355 | if (st) | 367 | if ((error >> 8) & 0xff) |
356 | osm_warn("SCSI abort: %08X", le32_to_cpu(msg->body[0])); | 368 | osm_err("SCSI error %08x\n", error); |
357 | osm_info("SCSI abort completed.\n"); | ||
358 | return -EFAULT; | ||
359 | } | ||
360 | 369 | ||
361 | osm_debug("Completed %ld\n", cmd->serial_number); | 370 | dev = &c->pdev->dev; |
371 | if (cmd->use_sg) | ||
372 | dma_unmap_sg(dev, cmd->request_buffer, cmd->use_sg, | ||
373 | cmd->sc_data_direction); | ||
374 | else if (cmd->SCp.dma_handle) | ||
375 | dma_unmap_single(dev, cmd->SCp.dma_handle, cmd->request_bufflen, | ||
376 | cmd->sc_data_direction); | ||
362 | 377 | ||
363 | if (st) { | 378 | cmd->scsi_done(cmd); |
364 | u32 count, error; | ||
365 | /* An error has occurred */ | ||
366 | |||
367 | switch (st) { | ||
368 | case 0x06: | ||
369 | count = le32_to_cpu(msg->body[1]); | ||
370 | if (count < cmd->underflow) { | ||
371 | int i; | ||
372 | |||
373 | osm_err("SCSI underflow 0x%08X 0x%08X\n", count, | ||
374 | cmd->underflow); | ||
375 | osm_debug("Cmd: "); | ||
376 | for (i = 0; i < 15; i++) | ||
377 | pr_debug("%02X ", cmd->cmnd[i]); | ||
378 | pr_debug(".\n"); | ||
379 | cmd->result = (DID_ERROR << 16); | ||
380 | } | ||
381 | break; | ||
382 | 379 | ||
383 | default: | 380 | return 1; |
384 | error = le32_to_cpu(msg->body[0]); | 381 | }; |
385 | |||
386 | osm_err("SCSI error %08x\n", error); | ||
387 | |||
388 | if ((error & 0xff) == 0x02 /*CHECK_CONDITION */ ) { | ||
389 | int i; | ||
390 | u32 len = sizeof(cmd->sense_buffer); | ||
391 | len = (len > 40) ? 40 : len; | ||
392 | // Copy over the sense data | ||
393 | memcpy(cmd->sense_buffer, (void *)&msg->body[3], | ||
394 | len); | ||
395 | for (i = 0; i <= len; i++) | ||
396 | osm_info("%02x\n", | ||
397 | cmd->sense_buffer[i]); | ||
398 | if (cmd->sense_buffer[0] == 0x70 | ||
399 | && cmd->sense_buffer[2] == DATA_PROTECT) { | ||
400 | /* This is to handle an array failed */ | ||
401 | cmd->result = (DID_TIME_OUT << 16); | ||
402 | printk(KERN_WARNING "%s: SCSI Data " | ||
403 | "Protect-Device (%d,%d,%d) " | ||
404 | "hba_status=0x%x, dev_status=" | ||
405 | "0x%x, cmd=0x%x\n", c->name, | ||
406 | (u32) cmd->device->channel, | ||
407 | (u32) cmd->device->id, | ||
408 | (u32) cmd->device->lun, | ||
409 | (error >> 8) & 0xff, | ||
410 | error & 0xff, cmd->cmnd[0]); | ||
411 | } else | ||
412 | cmd->result = (DID_ERROR << 16); | ||
413 | |||
414 | break; | ||
415 | } | ||
416 | |||
417 | switch (as) { | ||
418 | case 0x0E: | ||
419 | /* SCSI Reset */ | ||
420 | cmd->result = DID_RESET << 16; | ||
421 | break; | ||
422 | |||
423 | case 0x0F: | ||
424 | cmd->result = DID_PARITY << 16; | ||
425 | break; | ||
426 | |||
427 | default: | ||
428 | cmd->result = DID_ERROR << 16; | ||
429 | break; | ||
430 | } | ||
431 | 382 | ||
432 | break; | 383 | /** |
433 | } | 384 | * i2o_scsi_notify_device_add - Retrieve notifications of added devices |
385 | * @i2o_dev: the I2O device which was added | ||
386 | * | ||
387 | * If a I2O device is added we catch the notification, because I2O classes | ||
388 | * other then SCSI peripheral will not be received through | ||
389 | * i2o_scsi_probe(). | ||
390 | */ | ||
391 | static void i2o_scsi_notify_device_add(struct i2o_device *i2o_dev) | ||
392 | { | ||
393 | switch (i2o_dev->lct_data.class_id) { | ||
394 | case I2O_CLASS_EXECUTIVE: | ||
395 | case I2O_CLASS_RANDOM_BLOCK_STORAGE: | ||
396 | i2o_scsi_probe(&i2o_dev->device); | ||
397 | break; | ||
434 | 398 | ||
435 | cmd->scsi_done(cmd); | 399 | default: |
436 | return 1; | 400 | break; |
437 | } | 401 | } |
402 | }; | ||
438 | 403 | ||
439 | cmd->result = DID_OK << 16 | ds; | 404 | /** |
440 | 405 | * i2o_scsi_notify_device_remove - Retrieve notifications of removed | |
441 | cmd->scsi_done(cmd); | 406 | * devices |
442 | 407 | * @i2o_dev: the I2O device which was removed | |
443 | dev = &c->pdev->dev; | 408 | * |
444 | if (cmd->use_sg) | 409 | * If a I2O device is removed, we catch the notification to remove the |
445 | dma_unmap_sg(dev, (struct scatterlist *)cmd->buffer, | 410 | * corresponding SCSI device. |
446 | cmd->use_sg, cmd->sc_data_direction); | 411 | */ |
447 | else if (cmd->request_bufflen) | 412 | static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev) |
448 | dma_unmap_single(dev, (dma_addr_t) ((long)cmd->SCp.ptr), | 413 | { |
449 | cmd->request_bufflen, cmd->sc_data_direction); | 414 | switch (i2o_dev->lct_data.class_id) { |
415 | case I2O_CLASS_EXECUTIVE: | ||
416 | case I2O_CLASS_RANDOM_BLOCK_STORAGE: | ||
417 | i2o_scsi_remove(&i2o_dev->device); | ||
418 | break; | ||
450 | 419 | ||
451 | return 1; | 420 | default: |
421 | break; | ||
422 | } | ||
452 | }; | 423 | }; |
453 | 424 | ||
454 | /** | 425 | /** |
@@ -501,7 +472,7 @@ static void i2o_scsi_notify_controller_remove(struct i2o_controller *c) | |||
501 | 472 | ||
502 | scsi_remove_host(i2o_shost->scsi_host); | 473 | scsi_remove_host(i2o_shost->scsi_host); |
503 | scsi_host_put(i2o_shost->scsi_host); | 474 | scsi_host_put(i2o_shost->scsi_host); |
504 | pr_info("I2O SCSI host removed\n"); | 475 | osm_debug("I2O SCSI host removed\n"); |
505 | }; | 476 | }; |
506 | 477 | ||
507 | /* SCSI OSM driver struct */ | 478 | /* SCSI OSM driver struct */ |
@@ -509,6 +480,8 @@ static struct i2o_driver i2o_scsi_driver = { | |||
509 | .name = OSM_NAME, | 480 | .name = OSM_NAME, |
510 | .reply = i2o_scsi_reply, | 481 | .reply = i2o_scsi_reply, |
511 | .classes = i2o_scsi_class_id, | 482 | .classes = i2o_scsi_class_id, |
483 | .notify_device_add = i2o_scsi_notify_device_add, | ||
484 | .notify_device_remove = i2o_scsi_notify_device_remove, | ||
512 | .notify_controller_add = i2o_scsi_notify_controller_add, | 485 | .notify_controller_add = i2o_scsi_notify_controller_add, |
513 | .notify_controller_remove = i2o_scsi_notify_controller_remove, | 486 | .notify_controller_remove = i2o_scsi_notify_controller_remove, |
514 | .driver = { | 487 | .driver = { |
@@ -535,26 +508,26 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
535 | void (*done) (struct scsi_cmnd *)) | 508 | void (*done) (struct scsi_cmnd *)) |
536 | { | 509 | { |
537 | struct i2o_controller *c; | 510 | struct i2o_controller *c; |
538 | struct Scsi_Host *host; | ||
539 | struct i2o_device *i2o_dev; | 511 | struct i2o_device *i2o_dev; |
540 | struct device *dev; | ||
541 | int tid; | 512 | int tid; |
542 | struct i2o_message __iomem *msg; | 513 | struct i2o_message __iomem *msg; |
543 | u32 m; | 514 | u32 m; |
544 | u32 scsi_flags, sg_flags; | 515 | /* |
516 | * ENABLE_DISCONNECT | ||
517 | * SIMPLE_TAG | ||
518 | * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME | ||
519 | */ | ||
520 | u32 scsi_flags = 0x20a00000; | ||
521 | u32 sgl_offset; | ||
545 | u32 __iomem *mptr; | 522 | u32 __iomem *mptr; |
546 | u32 __iomem *lenptr; | 523 | u32 cmd = I2O_CMD_SCSI_EXEC << 24; |
547 | u32 len, reqlen; | 524 | int rc = 0; |
548 | int i; | ||
549 | 525 | ||
550 | /* | 526 | /* |
551 | * Do the incoming paperwork | 527 | * Do the incoming paperwork |
552 | */ | 528 | */ |
553 | |||
554 | i2o_dev = SCpnt->device->hostdata; | 529 | i2o_dev = SCpnt->device->hostdata; |
555 | host = SCpnt->device->host; | ||
556 | c = i2o_dev->iop; | 530 | c = i2o_dev->iop; |
557 | dev = &c->pdev->dev; | ||
558 | 531 | ||
559 | SCpnt->scsi_done = done; | 532 | SCpnt->scsi_done = done; |
560 | 533 | ||
@@ -562,7 +535,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
562 | osm_warn("no I2O device in request\n"); | 535 | osm_warn("no I2O device in request\n"); |
563 | SCpnt->result = DID_NO_CONNECT << 16; | 536 | SCpnt->result = DID_NO_CONNECT << 16; |
564 | done(SCpnt); | 537 | done(SCpnt); |
565 | return 0; | 538 | goto exit; |
566 | } | 539 | } |
567 | 540 | ||
568 | tid = i2o_dev->lct_data.tid; | 541 | tid = i2o_dev->lct_data.tid; |
@@ -571,44 +544,85 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
571 | osm_debug("Real scsi messages.\n"); | 544 | osm_debug("Real scsi messages.\n"); |
572 | 545 | ||
573 | /* | 546 | /* |
574 | * Obtain an I2O message. If there are none free then | ||
575 | * throw it back to the scsi layer | ||
576 | */ | ||
577 | |||
578 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | ||
579 | if (m == I2O_QUEUE_EMPTY) | ||
580 | return SCSI_MLQUEUE_HOST_BUSY; | ||
581 | |||
582 | /* | ||
583 | * Put together a scsi execscb message | 547 | * Put together a scsi execscb message |
584 | */ | 548 | */ |
585 | |||
586 | len = SCpnt->request_bufflen; | ||
587 | |||
588 | switch (SCpnt->sc_data_direction) { | 549 | switch (SCpnt->sc_data_direction) { |
589 | case PCI_DMA_NONE: | 550 | case PCI_DMA_NONE: |
590 | scsi_flags = 0x00000000; // DATA NO XFER | 551 | /* DATA NO XFER */ |
591 | sg_flags = 0x00000000; | 552 | sgl_offset = SGL_OFFSET_0; |
592 | break; | 553 | break; |
593 | 554 | ||
594 | case PCI_DMA_TODEVICE: | 555 | case PCI_DMA_TODEVICE: |
595 | scsi_flags = 0x80000000; // DATA OUT (iop-->dev) | 556 | /* DATA OUT (iop-->dev) */ |
596 | sg_flags = 0x14000000; | 557 | scsi_flags |= 0x80000000; |
558 | sgl_offset = SGL_OFFSET_10; | ||
597 | break; | 559 | break; |
598 | 560 | ||
599 | case PCI_DMA_FROMDEVICE: | 561 | case PCI_DMA_FROMDEVICE: |
600 | scsi_flags = 0x40000000; // DATA IN (iop<--dev) | 562 | /* DATA IN (iop<--dev) */ |
601 | sg_flags = 0x10000000; | 563 | scsi_flags |= 0x40000000; |
564 | sgl_offset = SGL_OFFSET_10; | ||
602 | break; | 565 | break; |
603 | 566 | ||
604 | default: | 567 | default: |
605 | /* Unknown - kill the command */ | 568 | /* Unknown - kill the command */ |
606 | SCpnt->result = DID_NO_CONNECT << 16; | 569 | SCpnt->result = DID_NO_CONNECT << 16; |
607 | done(SCpnt); | 570 | done(SCpnt); |
608 | return 0; | 571 | goto exit; |
609 | } | 572 | } |
610 | 573 | ||
611 | writel(I2O_CMD_SCSI_EXEC << 24 | HOST_TID << 12 | tid, &msg->u.head[1]); | 574 | /* |
575 | * Obtain an I2O message. If there are none free then | ||
576 | * throw it back to the scsi layer | ||
577 | */ | ||
578 | |||
579 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | ||
580 | if (m == I2O_QUEUE_EMPTY) { | ||
581 | rc = SCSI_MLQUEUE_HOST_BUSY; | ||
582 | goto exit; | ||
583 | } | ||
584 | |||
585 | mptr = &msg->body[0]; | ||
586 | |||
587 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
588 | if (c->adaptec) { | ||
589 | u32 adpt_flags = 0; | ||
590 | |||
591 | if (SCpnt->sc_request && SCpnt->sc_request->upper_private_data) { | ||
592 | i2o_sg_io_hdr_t __user *usr_ptr = | ||
593 | ((Sg_request *) (SCpnt->sc_request-> | ||
594 | upper_private_data))->header. | ||
595 | usr_ptr; | ||
596 | |||
597 | if (usr_ptr) | ||
598 | get_user(adpt_flags, &usr_ptr->flags); | ||
599 | } | ||
600 | |||
601 | switch (i2o_dev->lct_data.class_id) { | ||
602 | case I2O_CLASS_EXECUTIVE: | ||
603 | case I2O_CLASS_RANDOM_BLOCK_STORAGE: | ||
604 | /* interpret flag has to be set for executive */ | ||
605 | adpt_flags ^= I2O_DPT_SG_FLAG_INTERPRET; | ||
606 | break; | ||
607 | |||
608 | default: | ||
609 | break; | ||
610 | } | ||
611 | |||
612 | /* | ||
613 | * for Adaptec controllers we use the PRIVATE command, because | ||
614 | * the normal SCSI EXEC doesn't support all SCSI commands on | ||
615 | * all controllers (for example READ CAPACITY). | ||
616 | */ | ||
617 | if (sgl_offset == SGL_OFFSET_10) | ||
618 | sgl_offset = SGL_OFFSET_12; | ||
619 | cmd = I2O_CMD_PRIVATE << 24; | ||
620 | writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++); | ||
621 | writel(adpt_flags | tid, mptr++); | ||
622 | } | ||
623 | #endif | ||
624 | |||
625 | writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]); | ||
612 | writel(i2o_scsi_driver.context, &msg->u.s.icntxt); | 626 | writel(i2o_scsi_driver.context, &msg->u.s.icntxt); |
613 | 627 | ||
614 | /* We want the SCSI control block back */ | 628 | /* We want the SCSI control block back */ |
@@ -626,7 +640,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
626 | */ | 640 | */ |
627 | 641 | ||
628 | /* Attach tags to the devices */ | 642 | /* Attach tags to the devices */ |
629 | /* | 643 | /* FIXME: implement |
630 | if(SCpnt->device->tagged_supported) { | 644 | if(SCpnt->device->tagged_supported) { |
631 | if(SCpnt->tag == HEAD_OF_QUEUE_TAG) | 645 | if(SCpnt->tag == HEAD_OF_QUEUE_TAG) |
632 | scsi_flags |= 0x01000000; | 646 | scsi_flags |= 0x01000000; |
@@ -635,67 +649,35 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
635 | } | 649 | } |
636 | */ | 650 | */ |
637 | 651 | ||
638 | /* Direction, disconnect ok, tag, CDBLen */ | 652 | writel(scsi_flags | SCpnt->cmd_len, mptr++); |
639 | writel(scsi_flags | 0x20200000 | SCpnt->cmd_len, &msg->body[0]); | ||
640 | |||
641 | mptr = &msg->body[1]; | ||
642 | 653 | ||
643 | /* Write SCSI command into the message - always 16 byte block */ | 654 | /* Write SCSI command into the message - always 16 byte block */ |
644 | memcpy_toio(mptr, SCpnt->cmnd, 16); | 655 | memcpy_toio(mptr, SCpnt->cmnd, 16); |
645 | mptr += 4; | 656 | mptr += 4; |
646 | lenptr = mptr++; /* Remember me - fill in when we know */ | ||
647 | |||
648 | reqlen = 12; // SINGLE SGE | ||
649 | |||
650 | /* Now fill in the SGList and command */ | ||
651 | if (SCpnt->use_sg) { | ||
652 | struct scatterlist *sg; | ||
653 | int sg_count; | ||
654 | |||
655 | sg = SCpnt->request_buffer; | ||
656 | len = 0; | ||
657 | |||
658 | sg_count = dma_map_sg(dev, sg, SCpnt->use_sg, | ||
659 | SCpnt->sc_data_direction); | ||
660 | 657 | ||
661 | if (unlikely(sg_count <= 0)) | 658 | if (sgl_offset != SGL_OFFSET_0) { |
662 | return -ENOMEM; | 659 | /* write size of data addressed by SGL */ |
663 | 660 | writel(SCpnt->request_bufflen, mptr++); | |
664 | for (i = SCpnt->use_sg; i > 0; i--) { | 661 | |
665 | if (i == 1) | 662 | /* Now fill in the SGList and command */ |
666 | sg_flags |= 0xC0000000; | 663 | if (SCpnt->use_sg) { |
667 | writel(sg_flags | sg_dma_len(sg), mptr++); | 664 | if (!i2o_dma_map_sg(c, SCpnt->request_buffer, |
668 | writel(sg_dma_address(sg), mptr++); | 665 | SCpnt->use_sg, |
669 | len += sg_dma_len(sg); | 666 | SCpnt->sc_data_direction, &mptr)) |
670 | sg++; | 667 | goto nomem; |
668 | } else { | ||
669 | SCpnt->SCp.dma_handle = | ||
670 | i2o_dma_map_single(c, SCpnt->request_buffer, | ||
671 | SCpnt->request_bufflen, | ||
672 | SCpnt->sc_data_direction, &mptr); | ||
673 | if (dma_mapping_error(SCpnt->SCp.dma_handle)) | ||
674 | goto nomem; | ||
671 | } | 675 | } |
672 | |||
673 | reqlen = mptr - &msg->u.head[0]; | ||
674 | writel(len, lenptr); | ||
675 | } else { | ||
676 | len = SCpnt->request_bufflen; | ||
677 | |||
678 | writel(len, lenptr); | ||
679 | |||
680 | if (len > 0) { | ||
681 | dma_addr_t dma_addr; | ||
682 | |||
683 | dma_addr = dma_map_single(dev, SCpnt->request_buffer, | ||
684 | SCpnt->request_bufflen, | ||
685 | SCpnt->sc_data_direction); | ||
686 | if (!dma_addr) | ||
687 | return -ENOMEM; | ||
688 | |||
689 | SCpnt->SCp.ptr = (void *)(unsigned long)dma_addr; | ||
690 | sg_flags |= 0xC0000000; | ||
691 | writel(sg_flags | SCpnt->request_bufflen, mptr++); | ||
692 | writel(dma_addr, mptr++); | ||
693 | } else | ||
694 | reqlen = 9; | ||
695 | } | 676 | } |
696 | 677 | ||
697 | /* Stick the headers on */ | 678 | /* Stick the headers on */ |
698 | writel(reqlen << 16 | SGL_OFFSET_10, &msg->u.head[0]); | 679 | writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset, |
680 | &msg->u.head[0]); | ||
699 | 681 | ||
700 | /* Queue the message */ | 682 | /* Queue the message */ |
701 | i2o_msg_post(c, m); | 683 | i2o_msg_post(c, m); |
@@ -703,6 +685,13 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
703 | osm_debug("Issued %ld\n", SCpnt->serial_number); | 685 | osm_debug("Issued %ld\n", SCpnt->serial_number); |
704 | 686 | ||
705 | return 0; | 687 | return 0; |
688 | |||
689 | nomem: | ||
690 | rc = -ENOMEM; | ||
691 | i2o_msg_nop(c, m); | ||
692 | |||
693 | exit: | ||
694 | return rc; | ||
706 | }; | 695 | }; |
707 | 696 | ||
708 | /** | 697 | /** |