From: Jeff Garzik Date: Mon, 29 Aug 2005 23:24:43 +0000 (-0400) Subject: Merge libata branch 'chs-support' to latest upstream kernel. X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=76b2bf9b4dee2fb32ef17f5c84a99ce481a14be2;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git Merge libata branch 'chs-support' to latest upstream kernel. --- 76b2bf9b4dee2fb32ef17f5c84a99ce481a14be2 diff --cc drivers/scsi/libata-scsi.c index 954d1bca3b2a,346eb36b1e31..f8ddc2a29e9a --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@@ -584,111 -616,90 +649,114 @@@ static unsigned int ata_scsi_rw_xlat(st tf->flags |= ATA_TFLAG_WRITE; } + /* Calculate the SCSI LBA and transfer length. */ if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) { - if (lba48) { - tf->hob_nsect = scsicmd[7]; - tf->hob_lbal = scsicmd[2]; - - qc->nsect = ((unsigned int)scsicmd[7] << 8) | - scsicmd[8]; - } else { - /* if we don't support LBA48 addressing, the request - * -may- be too large. */ - if ((scsicmd[2] & 0xf0) || scsicmd[7]) - return 1; - - /* stores LBA27:24 in lower 4 bits of device reg */ - tf->device |= scsicmd[2]; - - qc->nsect = scsicmd[8]; - } + block |= ((u64)scsicmd[2]) << 24; + block |= ((u64)scsicmd[3]) << 16; + block |= ((u64)scsicmd[4]) << 8; + block |= ((u64)scsicmd[5]); - tf->nsect = scsicmd[8]; - tf->lbal = scsicmd[5]; - tf->lbam = scsicmd[4]; - tf->lbah = scsicmd[3]; + n_block |= ((u32)scsicmd[7]) << 8; + n_block |= ((u32)scsicmd[8]); VPRINTK("ten-byte command\n"); - if (qc->nsect == 0) /* we don't support length==0 cmds */ - return 1; - return 0; - } - - if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { - qc->nsect = tf->nsect = scsicmd[4]; - if (!qc->nsect) { - qc->nsect = 256; - if (lba48) - tf->hob_nsect = 1; - } - - tf->lbal = scsicmd[3]; - tf->lbam = scsicmd[2]; - tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */ - + } else if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { + block |= ((u64)scsicmd[2]) << 8; + block |= ((u64)scsicmd[3]); ++ + n_block |= ((u32)scsicmd[4]); ++ if (!n_block) ++ n_block = 256; + VPRINTK("six-byte command\n"); - return 0; + } else if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) { + block |= ((u64)scsicmd[2]) << 56; + block |= ((u64)scsicmd[3]) << 48; + block |= ((u64)scsicmd[4]) << 40; + block |= ((u64)scsicmd[5]) << 32; + block |= ((u64)scsicmd[6]) << 24; + block |= ((u64)scsicmd[7]) << 16; + block |= ((u64)scsicmd[8]) << 8; + block |= ((u64)scsicmd[9]); + + n_block |= ((u32)scsicmd[10]) << 24; + n_block |= ((u32)scsicmd[11]) << 16; + n_block |= ((u32)scsicmd[12]) << 8; + n_block |= ((u32)scsicmd[13]); + + VPRINTK("sixteen-byte command\n"); + } else { + DPRINTK("no-byte command\n"); + return 1; } - if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) { - /* rule out impossible LBAs and sector counts */ - if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11]) - return 1; + /* Check and compose ATA command */ + if (!n_block) + /* In ATA, sector count 0 means 256 or 65536 sectors, not 0 sectors. */ + return 1; + if (lba) { if (lba48) { - tf->hob_nsect = scsicmd[12]; - tf->hob_lbal = scsicmd[6]; - tf->hob_lbam = scsicmd[5]; - tf->hob_lbah = scsicmd[4]; - - qc->nsect = ((unsigned int)scsicmd[12] << 8) | - scsicmd[13]; - } else { - /* once again, filter out impossible non-zero values */ - if (scsicmd[4] || scsicmd[5] || scsicmd[12] || - (scsicmd[6] & 0xf0)) + /* The request -may- be too large for LBA48. */ + if ((block >> 48) || (n_block > 65536)) return 1; - /* stores LBA27:24 in lower 4 bits of device reg */ - tf->device |= scsicmd[6]; + tf->hob_nsect = (n_block >> 8) & 0xff; + + tf->hob_lbah = (block >> 40) & 0xff; + tf->hob_lbam = (block >> 32) & 0xff; + tf->hob_lbal = (block >> 24) & 0xff; + } else { + /* LBA28 */ + + /* The request -may- be too large for LBA28. */ + if ((block >> 28) || (n_block > 256)) + return 1; - qc->nsect = scsicmd[13]; + tf->device |= (block >> 24) & 0xf; } + + qc->nsect = n_block; + tf->nsect = n_block & 0xff; - tf->nsect = scsicmd[13]; - tf->lbal = scsicmd[9]; - tf->lbam = scsicmd[8]; - tf->lbah = scsicmd[7]; + tf->lbah = (block >> 16) & 0xff; + tf->lbam = (block >> 8) & 0xff; + tf->lbal = block & 0xff; - VPRINTK("sixteen-byte command\n"); - if (qc->nsect == 0) /* we don't support length==0 cmds */ + tf->device |= ATA_LBA; + } else { + /* CHS */ + u32 sect, head, cyl, track; + + /* The request -may- be too large for CHS addressing. */ + if ((block >> 28) || (n_block > 256)) return 1; - return 0; + + /* Convert LBA to CHS */ + track = (u32)block / dev->sectors; + cyl = track / dev->heads; + head = track % dev->heads; + sect = (u32)block % dev->sectors + 1; + + DPRINTK("block[%u] track[%u] cyl[%u] head[%u] sect[%u] \n", + (u32)block, track, cyl, head, sect); + + /* Check whether the converted CHS can fit. + Cylinder: 0-65535 + Head: 0-15 + Sector: 1-255*/ + if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) + return 1; + + qc->nsect = n_block; + tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ + tf->lbal = sect; + tf->lbam = cyl; + tf->lbah = cyl >> 8; + tf->device |= head; } - DPRINTK("no-byte command\n"); - return 1; + return 0; } static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)