libata-dev-2.6 12-byte pass thru CDB.
PATCH 1/1 libata-dev-2.6 12-byte pass thru CDB.
Patch to add 12-byte support for ATA pass-thru CDB processing.
Signature · 3 lines
[email protected] Andy Warner Voice: (612) 801-8549 Fax: (208) 575-5634
===== drivers/scsi/libata-scsi.c 1.55 vs edited =====
drivers/scsi/libata-scsi.c +69 -31
@@ -1533,9 +1533,11 @@ }/* -* ata_scsi_map_proto() - Map the protocol specified -* in the pass-thru CDB onto the -* protocol values used by taskfiles. +* ata_scsi_map_proto - Map pass-thru protocol value to taskfile value. +* @byte1: Byte 1 from pass-thru CDB. +* +* RETURNS: +* ATA_PROT_UNKNOWN if mapping failed/unimplemented, protocol otherwise. */ static u8 ata_scsi_map_proto (u8 byte1)
@@ -1571,8 +1573,18 @@return ATA_PROT_UNKNOWN ; } +/** +* ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile +* @qc: command structure to be initialized +* @cmd: SCSI command to convert +* +* Handles either 12 or 16-byte versions of the CDB. +* +* RETURNS: +* Zero on success, non-zero on failure. +*/ static unsigned int -ata_scsi_pass_thru_16 (struct ata_queued_cmd *qc,u8 *scsicmd) +ata_scsi_pass_thru (struct ata_queued_cmd *qc,u8 *scsicmd) {struct ata_taskfile *tf = &(qc->tf);struct scsi_cmnd *cmd = qc->scsicmd;
@@ -1582,45 +1594,70 @@ }/* -* If the CDB claims to contain extended -* ATA commands copy the upper byte register values. -* -* NOTE: at present copy all register fields, -* regardless of which ones are valid according -* to the .En bits. TODO: research optimal -* algorithm for this. +* 12 and 16 byte CDBs use different offsets to +* provide the various register values. */ -if (scsicmd[1 ] &0x01 ) { - tf->hob_feature = scsicmd[3 ]; - tf->hob_nsect = scsicmd[5 ]; - tf->hob_lbal = scsicmd[7 ]; - tf->hob_lbam = scsicmd[9 ]; - tf->hob_lbah = scsicmd[11 ]; - tf->flags |=ATA_TFLAG_LBA48 ; +if (scsicmd[0 ] ==ATA_16 ) { +/* +* 16-byte CDB - may contain extended commands. +* +* If that is the case, copy the upper byte register values. +*/ +if (scsicmd[1 ] &0x01 ) { + tf->hob_feature = scsicmd[3 ]; + tf->hob_nsect = scsicmd[5 ]; + tf->hob_lbal = scsicmd[7 ]; + tf->hob_lbam = scsicmd[9 ]; + tf->hob_lbah = scsicmd[11 ]; + tf->flags |=ATA_TFLAG_LBA48 ; + }else { + tf->flags &= ~ATA_TFLAG_LBA48 ; + } + +/* +* Always copy low byte, device and command registers. +*/ + tf->feature = scsicmd[4 ]; + tf->nsect = scsicmd[6 ]; + tf->lbal = scsicmd[8 ]; + tf->lbam = scsicmd[10 ]; + tf->lbah = scsicmd[12 ]; + tf->device = scsicmd[13 ]; + tf->command = scsicmd[14 ]; }else { +/* +* 12-byte CDB - incapable of extended commands. +*/ tf->flags &= ~ATA_TFLAG_LBA48 ; - } - tf->feature = scsicmd[4 ]; - tf->nsect = scsicmd[6 ]; - tf->lbal = scsicmd[8 ]; - tf->lbam = scsicmd[10 ]; - tf->lbah = scsicmd[12 ]; + tf->feature = scsicmd[3 ]; + tf->nsect = scsicmd[4 ]; + tf->lbal = scsicmd[5 ]; + tf->lbam = scsicmd[6 ]; + tf->lbah = scsicmd[7 ]; + tf->device = scsicmd[8 ]; + tf->command = scsicmd[9 ]; + } +/* +* Set flags so that all registers will be written, +* and pass on write indication (used for PIO/DMA +* setup.) +*/ tf->flags |= (ATA_TFLAG_ISADDR |ATA_TFLAG_DEVICE ) ; - tf->device = scsicmd[13 ]; - tf->command = scsicmd[14 ]; + +if (cmd->sc_data_direction ==SCSI_DATA_WRITE ) { + tf->flags |=ATA_TFLAG_WRITE ; + }/* +* Set transfer length. +* * TODO: find out if we need to do more here to * cover scatter/gather case. */ qc->nsect = cmd->bufflen /ATA_SECT_SIZE ; -if (cmd->sc_data_direction ==SCSI_DATA_WRITE ) { - tf->flags |=ATA_TFLAG_WRITE ; - } -return 0 ; }
@@ -1657,8 +1694,9 @@case VERIFY_16 :return ata_scsi_verify_xlat; +case ATA_12 :case ATA_16 : -return ata_scsi_pass_thru_16 ; +return ata_scsi_pass_thru ; }return NULL ;
Jeff Garzik
Appliedapplied both patches to libata-dev-2.6.
For future patches, please follow rules #1 and #5:
http://linux.yyz.us/patch-format.html
Jeff