diff options
author | Mark Haverkamp <markh@osdl.org> | 2005-11-08 17:26:33 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-11-09 16:15:11 -0500 |
commit | 07ce5eba857cb7dc8f6ae39eda74b108efe4a3f8 (patch) | |
tree | b3db0e2bd1bcb627575eba90ea3f8513c7f31c28 /drivers/scsi/aacraid/aachba.c | |
parent | f64a181d898e0518d5ae90c4870069510de977e1 (diff) |
[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>
Diffstat (limited to 'drivers/scsi/aacraid/aachba.c')
-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) | |||
1579 | break; | 1579 | break; |
1580 | { | 1580 | { |
1581 | u64 capacity; | 1581 | u64 capacity; |
1582 | char cp[12]; | 1582 | char cp[13]; |
1583 | unsigned int offset = 0; | ||
1584 | 1583 | ||
1585 | dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); | 1584 | dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); |
1586 | capacity = fsa_dev_ptr[cid].size - 1; | 1585 | capacity = fsa_dev_ptr[cid].size - 1; |
1587 | if (scsicmd->cmnd[13] > 12) { | ||
1588 | offset = scsicmd->cmnd[13] - 12; | ||
1589 | if (offset > sizeof(cp)) | ||
1590 | break; | ||
1591 | memset(cp, 0, offset); | ||
1592 | aac_internal_transfer(scsicmd, cp, 0, offset); | ||
1593 | } | ||
1594 | cp[0] = (capacity >> 56) & 0xff; | 1586 | cp[0] = (capacity >> 56) & 0xff; |
1595 | cp[1] = (capacity >> 48) & 0xff; | 1587 | cp[1] = (capacity >> 48) & 0xff; |
1596 | cp[2] = (capacity >> 40) & 0xff; | 1588 | cp[2] = (capacity >> 40) & 0xff; |
@@ -1603,7 +1595,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1603 | cp[9] = 0; | 1595 | cp[9] = 0; |
1604 | cp[10] = 2; | 1596 | cp[10] = 2; |
1605 | cp[11] = 0; | 1597 | cp[11] = 0; |
1606 | aac_internal_transfer(scsicmd, cp, offset, sizeof(cp)); | 1598 | cp[12] = 0; |
1599 | aac_internal_transfer(scsicmd, cp, 0, | ||
1600 | min((unsigned int)scsicmd->cmnd[13], sizeof(cp))); | ||
1601 | if (sizeof(cp) < scsicmd->cmnd[13]) { | ||
1602 | unsigned int len, offset = sizeof(cp); | ||
1603 | |||
1604 | memset(cp, 0, offset); | ||
1605 | do { | ||
1606 | len = min(scsicmd->cmnd[13]-offset, sizeof(cp)); | ||
1607 | aac_internal_transfer(scsicmd, cp, offset, len); | ||
1608 | } while ((offset += len) < scsicmd->cmnd[13]); | ||
1609 | } | ||
1607 | 1610 | ||
1608 | /* Do not cache partition table for arrays */ | 1611 | /* Do not cache partition table for arrays */ |
1609 | scsicmd->device->removable = 1; | 1612 | scsicmd->device->removable = 1; |