libata: CHS follow-up patches (revise #6)
cover libata: CHS follow-up patches (revise #6)
Dear all,
CHS follow-up patches. (Keep sync with the scsi error handling patch. Also added patch 3/4.)
patch 1/4: move the initialization of ATA_TFLAG_LBA and ATA_TFLAG_LBA48 flags to the SCSI translation functions
patch 2/4: calculate read/write commands and protocols on the fly
patch 3/4: reread device identify info after initializing device CHS settings
patch 4/4: LBA28/LBA48 optimization
(revised to check ending block number per Mark's advice)
Patch against libata-dev upstream branch
(edea3ab58f8edd5f72d31f891ab4f34382e97e3a).
For your review, thanks.
Albert
PATCH 1/4 CHS: move the initialization of taskfile LBA flags (revise #6)
Patch 1/4:
move the initialization of taskfile LBA flags
"ATA_TFLAG_LBA" and "ATA_TFLAG_LBA48 flags"
to the SCSI translation functions
=============
drivers/scsi/libata-core.c +0 -7
@@ -3195,13 +3195,6 @@ struct ata_queued_cmd *ata_qc_new_init(s qc->nbytes = qc->curbytes =0 ;ata_tf_init (ap, &qc->tf, dev->devno); - -if (dev->flags &ATA_DFLAG_LBA ) { - qc->tf.flags |=ATA_TFLAG_LBA ; - -if (dev->flags &ATA_DFLAG_LBA48 ) - qc->tf.flags |=ATA_TFLAG_LBA48 ; - } }return qc;
drivers/scsi/libata-scsi.c +25 -17
95 lines not on this page · raw message
PATCH 2/4 CHS: calculate read/write commands and protocol on the fly (revise #6)
In reply to Albert LeePatch 2/4: calculate read/write commands and protocols on the fly
changes:
- merge ata_prot_to_cmd() and ata_dev_set_protocol() as ata_rwcmd_protocol()
- pave road for read/write multiple support
- remove usage of pre-cached command and protocol values and call ata_rwcmd_protocol() instead
==============
include/linux/ata.h +4 -0
@@ -128,6 +128,10 @@ enum {ATA_CMD_PIO_READ_EXT =0x24 ,ATA_CMD_PIO_WRITE =0x30 ,ATA_CMD_PIO_WRITE_EXT =0x34 , +ATA_CMD_READ_MULTI =0xC4 , +ATA_CMD_READ_MULTI_EXT =0x29 , +ATA_CMD_WRITE_MULTI =0xC5 , +ATA_CMD_WRITE_MULTI_EXT =0x39 ,ATA_CMD_SET_FEATURES =0xEF ,ATA_CMD_PACKET =0xA0 , ATA_CMD_VERIFY = 0x40,
include/linux/libata.h +2 -4
@@ -283,10 +283,8 @@ struct ata_device {u8 xfer_mode;unsigned int xfer_shift;/* ATA_SHIFT_xxx */ -/* cache info about current transfer mode */ -u8 xfer_protocol;/* taskfile xfer protocol */ -u8 read_cmd;/* opcode to use on read */ -u8 write_cmd;/* opcode to use on write */ +unsigned int multi_count;/* sectors count for +READ/WRITE MULTIPLE */ /* for CHS addressing */ u16 cylinders;/* Number of cylinders */
drivers/scsi/libata.h +1 -0
@@ -42,6 +42,7 @@ extern int atapi_enabled;extern int ata_qc_complete_noop (struct ata_queued_cmd *qc,u8 drv_stat);extern struct ata_queued_cmd *ata_qc_new_init (struct ata_port *ap,struct ata_device *dev); +extern void ata_rwcmd_protocol (struct ata_queued_cmd *qc);extern void ata_qc_free (struct ata_queued_cmd *qc);extern int ata_qc_issue (struct ata_queued_cmd *qc);extern int ata_check_atapi_dma (struct ata_queued_cmd *qc);
drivers/scsi/libata-core.c +38 -69
135 lines not on this page · raw message
drivers/scsi/libata-scsi.c +6 -7
@@ -742,15 +742,10 @@ static unsigned int ata_scsi_rw_xlat(stru32 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 ]) {
@@ -812,6 +807,8 @@ static unsigned int ata_scsi_rw_xlat(str tf->device |= (block >>24 ) &0xf ; } +ata_rwcmd_protocol (qc); + qc->nsect = n_block; tf->nsect = n_block &0xff ;
@@ -828,6 +825,8 @@ static unsigned int ata_scsi_rw_xlat(strif ((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;
PATCH 4/4 CHS: LBA28/LBA48 optimization (revise #6)
In reply to Albert LeePatch 4/4: LBA28/LBA48 optimization per Mark's advice.
Changes:
- add lba_28_ok() and lba_48_ok() to ata.h.
- check ending block number instead of staring block number.
- use lba_28_ok() for CHS range check
- LBA28/LBA48 optimization
=====
include/linux/ata.h +12 -0
@@ -291,4 +291,16 @@ static inline int ata_ok(u8 status) == ATA_DRDY); } +static inline int lba_28_ok (u64 block,u32 n_block) +{ +/* check the ending block number */ +return ((block + n_block -1 ) < ((u64 )1 <<28 )) && (n_block <=256 ); +} + +static inline int lba_48_ok (u64 block,u32 n_block) +{ +/* check the ending block number */ +return ((block + n_block -1 ) < ((u64 )1 <<48 )) && (n_block <=65536 ); +} +#endif /* __LINUX_ATA_H__ */
drivers/scsi/libata-scsi.c +21 -27
84 lines not on this page · raw message
Jeff Garzik
AppliedRe: [PATCH 1/4] CHS: move the initialization of taskfile LBA flags (revise #6)
In reply to Albert Leeapplied patches 1-3 to upstream branch
Jeff Garzik
AppliedRe: [PATCH 4/4] CHS: LBA28/LBA48 optimization (revise #6)
In reply to Albert LeeQuoted 9 lines · Albert Lee
Patch 4/4: LBA28/LBA48 optimization per Mark's advice.
Changes:
- addlba_28_ok()andlba_48_ok()toata.h.
- check ending block number instead of staring block number.
- uselba_28_ok()for CHS range check
- LBA28/LBA48 optimizationSigned-off-by Albert Lee <[email protected]>
applied to the new lba48-opt branch of libata-dev.
We'll probably merge this into the 'upstream' branch after 2.6.15-rc1 is released, to enable lots of testing.
Jeff