aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/cciss.c
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cca.cpqcorp.net>2009-06-02 08:48:11 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-06-02 08:48:11 -0400
commit88f627ae394eadd75ada669904269f1a4a77b3bd (patch)
tree679356d2253914ae93132c3d0116111e63284cba /drivers/block/cciss.c
parent4a4b2d7684c66dbd8ed04eb284bc94a78e061d29 (diff)
cciss: fix SCSI device reset handler
Fix the SCSI reset error handler to send a working, properly addressed reset message to the target device and add code to wait for the target device to become ready by polling it with Test Unit Ready. The existing reset code was broken in that it didn't bother to set the 8-byte LUN address to anything besides zero, so the command was addressed to the controller, which pretended to the driver that the command succeeded, while doing nothing. Ages ago I tested this code, but unbeknownst to me, my test was flawed, and what I thought was a tape drive getting reset was actually nothing of the sort. Unfortunately, there is still lots of Smartarray firmware that doesn't handle doing target resets right, and this code won't help in those cases, but it also shouldn't make things worse in those cases than they already are. Signed-off-by: Stephen M. Cameron <scameron@beardog.cca.cpqcorp.net> Cc: Mike Miller <mikem@beardog.cca.cpqcorp.net> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/block/cciss.c')
-rw-r--r--drivers/block/cciss.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 8d0f8932fee7..cb43fb3af159 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1974,6 +1974,13 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_
1974 c->Request.CDB[0] = BMIC_WRITE; 1974 c->Request.CDB[0] = BMIC_WRITE;
1975 c->Request.CDB[6] = BMIC_CACHE_FLUSH; 1975 c->Request.CDB[6] = BMIC_CACHE_FLUSH;
1976 break; 1976 break;
1977 case TEST_UNIT_READY:
1978 memcpy(c->Header. LUN.LunAddrBytes, scsi3addr, 8);
1979 c->Request.CDBLen = 6;
1980 c->Request.Type.Attribute = ATTR_SIMPLE;
1981 c->Request.Type.Direction = XFER_NONE;
1982 c->Request.Timeout = 0;
1983 break;
1977 default: 1984 default:
1978 printk(KERN_WARNING 1985 printk(KERN_WARNING
1979 "cciss%d: Unknown Command 0x%c\n", ctlr, cmd); 1986 "cciss%d: Unknown Command 0x%c\n", ctlr, cmd);
@@ -1992,13 +1999,14 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_
1992 memcpy(&c->Request.CDB[4], buff, 8); 1999 memcpy(&c->Request.CDB[4], buff, 8);
1993 break; 2000 break;
1994 case 1: /* RESET message */ 2001 case 1: /* RESET message */
1995 c->Request.CDBLen = 12; 2002 memcpy(c->Header.LUN.LunAddrBytes, scsi3addr, 8);
2003 c->Request.CDBLen = 16;
1996 c->Request.Type.Attribute = ATTR_SIMPLE; 2004 c->Request.Type.Attribute = ATTR_SIMPLE;
1997 c->Request.Type.Direction = XFER_WRITE; 2005 c->Request.Type.Direction = XFER_NONE;
1998 c->Request.Timeout = 0; 2006 c->Request.Timeout = 0;
1999 memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB)); 2007 memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
2000 c->Request.CDB[0] = cmd; /* reset */ 2008 c->Request.CDB[0] = cmd; /* reset */
2001 c->Request.CDB[1] = 0x04; /* reset a LUN */ 2009 c->Request.CDB[1] = 0x03; /* reset a target */
2002 break; 2010 break;
2003 case 3: /* No-Op message */ 2011 case 3: /* No-Op message */
2004 c->Request.CDBLen = 1; 2012 c->Request.CDBLen = 1;