diff options
author | Stephen M. Cameron <scameron@beardog.cca.cpqcorp.net> | 2009-06-02 08:48:11 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-06-02 08:48:11 -0400 |
commit | 88f627ae394eadd75ada669904269f1a4a77b3bd (patch) | |
tree | 679356d2253914ae93132c3d0116111e63284cba /drivers/block/cciss.c | |
parent | 4a4b2d7684c66dbd8ed04eb284bc94a78e061d29 (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.c | 14 |
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; |