aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/i2o/i2o_scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/i2o/i2o_scsi.c')
-rw-r--r--drivers/message/i2o/i2o_scsi.c202
1 files changed, 65 insertions, 137 deletions
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index fef53b509a61..9f1744c3933b 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -40,7 +40,6 @@
40 * Fix the resource management problems. 40 * Fix the resource management problems.
41 */ 41 */
42 42
43#define DEBUG 1
44#include <linux/module.h> 43#include <linux/module.h>
45#include <linux/kernel.h> 44#include <linux/kernel.h>
46#include <linux/types.h> 45#include <linux/types.h>
@@ -338,162 +337,89 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
338 struct i2o_message *msg) 337 struct i2o_message *msg)
339{ 338{
340 struct scsi_cmnd *cmd; 339 struct scsi_cmnd *cmd;
340 u32 error;
341 struct device *dev; 341 struct device *dev;
342 u8 as, ds, st;
343 342
344 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));
345 344 if (unlikely(!cmd)) {
346 if (msg->u.head[0] & (1 << 13)) { 345 osm_err("NULL reply received!\n");
347 struct i2o_message __iomem *pmsg; /* preserved message */ 346 return -1;
348 u32 pm;
349 int err = DID_ERROR;
350
351 pm = le32_to_cpu(msg->body[3]);
352
353 pmsg = i2o_msg_in_to_virt(c, pm);
354
355 osm_err("IOP fail.\n");
356 osm_err("From %d To %d Cmd %d.\n",
357 (msg->u.head[1] >> 12) & 0xFFF,
358 msg->u.head[1] & 0xFFF, msg->u.head[1] >> 24);
359 osm_err("Failure Code %d.\n", msg->body[0] >> 24);
360 if (msg->body[0] & (1 << 16))
361 osm_err("Format error.\n");
362 if (msg->body[0] & (1 << 17))
363 osm_err("Path error.\n");
364 if (msg->body[0] & (1 << 18))
365 osm_err("Path State.\n");
366 if (msg->body[0] & (1 << 18))
367 {
368 osm_err("Congestion.\n");
369 err = DID_BUS_BUSY;
370 }
371
372 osm_debug("Failing message is %p.\n", pmsg);
373
374 cmd = i2o_cntxt_list_get(c, readl(&pmsg->u.s.tcntxt));
375 if (!cmd)
376 return 1;
377
378 cmd->result = err << 16;
379 cmd->scsi_done(cmd);
380
381 /* Now flush the message by making it a NOP */
382 i2o_msg_nop(c, pm);
383
384 return 1;
385 } 347 }
386 348
387 /* 349 /*
388 * Low byte is device status, next is adapter status, 350 * Low byte is device status, next is adapter status,
389 * (then one byte reserved), then request status. 351 * (then one byte reserved), then request status.
390 */ 352 */
391 ds = (u8) le32_to_cpu(msg->body[0]); 353 error = le32_to_cpu(msg->body[0]);
392 as = (u8) (le32_to_cpu(msg->body[0]) >> 8);
393 st = (u8) (le32_to_cpu(msg->body[0]) >> 24);
394 354
355 osm_debug("Completed %ld\n", cmd->serial_number);
356
357 cmd->result = error & 0xff;
395 /* 358 /*
396 * 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
397 */ 361 */
362 if (cmd->result)
363 memcpy(cmd->sense_buffer, &msg->body[3],
364 min(sizeof(cmd->sense_buffer), (size_t) 40));
398 365
399 if (!cmd) { 366 /* only output error code if AdapterStatus is not HBA_SUCCESS */
400 if (st) 367 if ((error >> 8) & 0xff)
401 osm_warn("SCSI abort: %08X", le32_to_cpu(msg->body[0])); 368 osm_err("SCSI error %08x\n", error);
402 osm_info("SCSI abort completed.\n");
403 return -EFAULT;
404 }
405 369
406 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);
407 377
408 if (st) { 378 cmd->scsi_done(cmd);
409 u32 count, error;
410 /* An error has occurred */
411
412 switch (st) {
413 case 0x06:
414 count = le32_to_cpu(msg->body[1]);
415 if (count < cmd->underflow) {
416 int i;
417
418 osm_err("SCSI underflow 0x%08X 0x%08X\n", count,
419 cmd->underflow);
420 osm_debug("Cmd: ");
421 for (i = 0; i < 15; i++)
422 pr_debug("%02X ", cmd->cmnd[i]);
423 pr_debug(".\n");
424 cmd->result = (DID_ERROR << 16);
425 }
426 break;
427 379
428 default: 380 return 1;
429 error = le32_to_cpu(msg->body[0]); 381};
430
431 osm_err("SCSI error %08x\n", error);
432
433 if ((error & 0xff) == 0x02 /*CHECK_CONDITION */ ) {
434 int i;
435 u32 len = sizeof(cmd->sense_buffer);
436 len = (len > 40) ? 40 : len;
437 // Copy over the sense data
438 memcpy(cmd->sense_buffer, (void *)&msg->body[3],
439 len);
440 for (i = 0; i <= len; i++)
441 osm_info("%02x\n",
442 cmd->sense_buffer[i]);
443 if (cmd->sense_buffer[0] == 0x70
444 && cmd->sense_buffer[2] == DATA_PROTECT) {
445 /* This is to handle an array failed */
446 cmd->result = (DID_TIME_OUT << 16);
447 printk(KERN_WARNING "%s: SCSI Data "
448 "Protect-Device (%d,%d,%d) "
449 "hba_status=0x%x, dev_status="
450 "0x%x, cmd=0x%x\n", c->name,
451 (u32) cmd->device->channel,
452 (u32) cmd->device->id,
453 (u32) cmd->device->lun,
454 (error >> 8) & 0xff,
455 error & 0xff, cmd->cmnd[0]);
456 } else
457 cmd->result = (DID_ERROR << 16);
458
459 break;
460 }
461
462 switch (as) {
463 case 0x0E:
464 /* SCSI Reset */
465 cmd->result = DID_RESET << 16;
466 break;
467
468 case 0x0F:
469 cmd->result = DID_PARITY << 16;
470 break;
471
472 default:
473 cmd->result = DID_ERROR << 16;
474 break;
475 }
476 382
477 break; 383/**
478 } 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 */
391static 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;
479 398
480 cmd->scsi_done(cmd); 399 default:
481 return 1; 400 break;
482 } 401 }
402};
483 403
484 cmd->result = DID_OK << 16 | ds; 404/**
485 405 * i2o_scsi_notify_device_remove - Retrieve notifications of removed
486 dev = &c->pdev->dev; 406 * devices
487 if (cmd->use_sg) 407 * @i2o_dev: the I2O device which was removed
488 dma_unmap_sg(dev, (struct scatterlist *)cmd->buffer, 408 *
489 cmd->use_sg, cmd->sc_data_direction); 409 * If a I2O device is removed, we catch the notification to remove the
490 else if (cmd->request_bufflen) 410 * corresponding SCSI device.
491 dma_unmap_single(dev, (dma_addr_t) ((long)cmd->SCp.ptr), 411 */
492 cmd->request_bufflen, cmd->sc_data_direction); 412static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev)
493 413{
494 cmd->scsi_done(cmd); 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;
495 419
496 return 1; 420 default:
421 break;
422 }
497}; 423};
498 424
499/** 425/**
@@ -554,6 +480,8 @@ static struct i2o_driver i2o_scsi_driver = {
554 .name = OSM_NAME, 480 .name = OSM_NAME,
555 .reply = i2o_scsi_reply, 481 .reply = i2o_scsi_reply,
556 .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,
557 .notify_controller_add = i2o_scsi_notify_controller_add, 485 .notify_controller_add = i2o_scsi_notify_controller_add,
558 .notify_controller_remove = i2o_scsi_notify_controller_remove, 486 .notify_controller_remove = i2o_scsi_notify_controller_remove,
559 .driver = { 487 .driver = {
@@ -712,7 +640,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
712 */ 640 */
713 641
714 /* Attach tags to the devices */ 642 /* Attach tags to the devices */
715 /* 643 /* FIXME: implement
716 if(SCpnt->device->tagged_supported) { 644 if(SCpnt->device->tagged_supported) {
717 if(SCpnt->tag == HEAD_OF_QUEUE_TAG) 645 if(SCpnt->tag == HEAD_OF_QUEUE_TAG)
718 scsi_flags |= 0x01000000; 646 scsi_flags |= 0x01000000;