Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Mark Haverkamp and committed by
James Bottomley
07ce5eba f64a181d

+13 -10
+13 -10
drivers/scsi/aacraid/aachba.c
··· 1579 1579 break; 1580 1580 { 1581 1581 u64 capacity; 1582 - char cp[12]; 1583 - unsigned int offset = 0; 1582 + char cp[13]; 1584 1583 1585 1584 dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); 1586 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 1586 cp[0] = (capacity >> 56) & 0xff; 1595 1587 cp[1] = (capacity >> 48) & 0xff; 1596 1588 cp[2] = (capacity >> 40) & 0xff; ··· 1595 1603 cp[9] = 0; 1596 1604 cp[10] = 2; 1597 1605 cp[11] = 0; 1598 - aac_internal_transfer(scsicmd, cp, offset, sizeof(cp)); 1606 + cp[12] = 0; 1607 + aac_internal_transfer(scsicmd, cp, 0, 1608 + min((unsigned int)scsicmd->cmnd[13], sizeof(cp))); 1609 + if (sizeof(cp) < scsicmd->cmnd[13]) { 1610 + unsigned int len, offset = sizeof(cp); 1611 + 1612 + memset(cp, 0, offset); 1613 + do { 1614 + len = min(scsicmd->cmnd[13]-offset, sizeof(cp)); 1615 + aac_internal_transfer(scsicmd, cp, offset, len); 1616 + } while ((offset += len) < scsicmd->cmnd[13]); 1617 + } 1599 1618 1600 1619 /* Do not cache partition table for arrays */ 1601 1620 scsicmd->device->removable = 1;