diff options
author | Mark Haverkamp <markh@osdl.org> | 2005-11-08 14:26:33 -0800 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-11-09 16:15:11 -0500 |
commit | 07ce5eba857cb7dc8f6ae39eda74b108efe4a3f8 (patch) | |
tree | b3db0e2bd1bcb627575eba90ea3f8513c7f31c28 | |
parent | f64a181d898e0518d5ae90c4870069510de977e1 (diff) | |
download | linux-stable-07ce5eba857cb7dc8f6ae39eda74b108efe4a3f8.tar.gz linux-stable-07ce5eba857cb7dc8f6ae39eda74b108efe4a3f8.tar.bz2 linux-stable-07ce5eba857cb7dc8f6ae39eda74b108efe4a3f8.zip |
[SCSI] aacraid: Fix read capacity 16 return data
Received from Mark Salyzyn.
The return data from a read capacity 16 needs to have RTO_EN and PROT_EN
zeroed out.
Signed-off-by: Mark Haverkamp <markh@osdl.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 2a128a156aa1..7139659dd952 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1579,18 +1579,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) break; { u64 capacity; - char cp[12]; - unsigned int offset = 0; + char cp[13]; dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); capacity = fsa_dev_ptr[cid].size - 1; - if (scsicmd->cmnd[13] > 12) { - offset = scsicmd->cmnd[13] - 12; - if (offset > sizeof(cp)) - break; - memset(cp, 0, offset); - aac_internal_transfer(scsicmd, cp, 0, offset); - } cp[0] = (capacity >> 56) & 0xff; cp[1] = (capacity >> 48) & 0xff; cp[2] = (capacity >> 40) & 0xff; @@ -1603,7 +1595,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) cp[9] = 0; cp[10] = 2; cp[11] = 0; - aac_internal_transfer(scsicmd, cp, offset, sizeof(cp)); + cp[12] = 0; + aac_internal_transfer(scsicmd, cp, 0, + min((unsigned int)scsicmd->cmnd[13], sizeof(cp))); + if (sizeof(cp) < scsicmd->cmnd[13]) { + unsigned int len, offset = sizeof(cp); + + memset(cp, 0, offset); + do { + len = min(scsicmd->cmnd[13]-offset, sizeof(cp)); + aac_internal_transfer(scsicmd, cp, offset, len); + } while ((offset += len) < scsicmd->cmnd[13]); + } /* Do not cache partition table for arrays */ scsicmd->device->removable = 1; |