diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-18 21:52:42 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-18 21:52:42 -0400 |
commit | b194b4250c2b7e9d762823ac6045316fcd4bf4f9 (patch) | |
tree | 8c54b5004822958ef0a7603e76a4868582e26d7f /drivers/scsi/libata-scsi.c | |
parent | c4052da6f0c01a0b059d125d72bb934d0980b798 (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 4cf43de4060..9944adbe5a1 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -502,7 +502,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 @@ -622,8 +622,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; @@ -644,16 +642,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; @@ -662,6 +660,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; @@ -678,6 +680,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; @@ -743,21 +748,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]) { @@ -793,19 +791,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)) @@ -814,6 +817,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; @@ -830,6 +835,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; |