diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-18 18:30:58 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-18 18:30:58 -0400 |
commit | 77501f3cb648e18733509a951ed31eddd7ef2c0b (patch) | |
tree | 82624caa354394df2422562bf6dda56a2c088704 /drivers/scsi/libata-scsi.c | |
parent | 422fa08e538b649a9b80258950d2f8a202f45f19 (diff) | |
parent | 59a10b172fccaea793352c00fd9065f0a5b4ef70 (diff) |
Merge branch 'upstream'
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r-- | drivers/scsi/libata-scsi.c | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 617534b7a25..1ad75d58c30 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -784,7 +784,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) tf->flags |= ATA_TFLAG_DEVICE; tf->protocol = ATA_PROT_NODATA; - if ((tf->flags & ATA_TFLAG_LBA48) && + if ((qc->dev->flags & ATA_DFLAG_LBA48) && (ata_id_has_flush_ext(qc->dev->id))) tf->command = ATA_CMD_FLUSH_EXT; else @@ -904,8 +904,6 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) { struct ata_taskfile *tf = &qc->tf; struct ata_device *dev = qc->dev; - unsigned int lba = tf->flags & ATA_TFLAG_LBA; - unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; u64 dev_sectors = qc->dev->n_sectors; u64 block; u32 n_block; @@ -926,16 +924,16 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) goto out_of_range; if ((block + n_block) > dev_sectors) goto out_of_range; - if (lba48) { - if (n_block > (64 * 1024)) - goto invalid_fld; - } else { - if (n_block > 256) - goto invalid_fld; - } - if (lba) { - if (lba48) { + if (dev->flags & ATA_DFLAG_LBA) { + tf->flags |= ATA_TFLAG_LBA; + + if (dev->flags & ATA_DFLAG_LBA48) { + if (n_block > (64 * 1024)) + goto invalid_fld; + + /* use LBA48 */ + tf->flags |= ATA_TFLAG_LBA48; tf->command = ATA_CMD_VERIFY_EXT; tf->hob_nsect = (n_block >> 8) & 0xff; @@ -944,6 +942,10 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) tf->hob_lbam = (block >> 32) & 0xff; tf->hob_lbal = (block >> 24) & 0xff; } else { + if (n_block > 256) + goto invalid_fld; + + /* use LBA28 */ tf->command = ATA_CMD_VERIFY; tf->device |= (block >> 24) & 0xf; @@ -960,6 +962,9 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) /* CHS */ u32 sect, head, cyl, track; + if (n_block > 256) + goto invalid_fld; + /* Convert LBA to CHS */ track = (u32)block / dev->sectors; cyl = track / dev->heads; @@ -1025,21 +1030,14 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) { struct ata_taskfile *tf = &qc->tf; struct ata_device *dev = qc->dev; - unsigned int lba = tf->flags & ATA_TFLAG_LBA; - unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; u64 block; u32 n_block; tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; - tf->protocol = qc->dev->xfer_protocol; - if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 || - scsicmd[0] == READ_16) { - tf->command = qc->dev->read_cmd; - } else { - tf->command = qc->dev->write_cmd; + if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 || + scsicmd[0] == WRITE_16) tf->flags |= ATA_TFLAG_WRITE; - } /* Calculate the SCSI LBA and transfer length. */ switch (scsicmd[0]) { @@ -1075,19 +1073,24 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) */ goto nothing_to_do; - if (lba) { - if (lba48) { + if (dev->flags & ATA_DFLAG_LBA) { + tf->flags |= ATA_TFLAG_LBA; + + if (dev->flags & ATA_DFLAG_LBA48) { /* The request -may- be too large for LBA48. */ if ((block >> 48) || (n_block > 65536)) goto out_of_range; + /* use LBA48 */ + tf->flags |= ATA_TFLAG_LBA48; + 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 */ + /* use LBA28 */ /* The request -may- be too large for LBA28. */ if ((block >> 28) || (n_block > 256)) @@ -1096,6 +1099,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) tf->device |= (block >> 24) & 0xf; } + ata_rwcmd_protocol(qc); + qc->nsect = n_block; tf->nsect = n_block & 0xff; @@ -1112,6 +1117,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) if ((block >> 28) || (n_block > 256)) goto out_of_range; + ata_rwcmd_protocol(qc); + /* Convert LBA to CHS */ track = (u32)block / dev->sectors; cyl = track / dev->heads; |