libata-dev-2.6 pass-thru CDB check condition support.
PATCH 1/1 libata-dev-2.6 pass-thru CDB check condition support.
Patch to add CC 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 +82 -2
@@ -468,6 +468,85 @@ } } +/* +* ata_pass_thru_cc - Generate check condition sense block. +* @qc: Command that completed. +* +* Regardless of whether the command errored or not, return +* a sense block. Copy all controller registers into +* the sense block. Clear sense key, ASC & ASCQ if +* there is no error. +* +* LOCKING: +* spin_lock_irqsave(host_set lock) +*/ +void ata_pass_thru_cc (struct ata_queued_cmd *qc,u8 drv_stat) +{ +struct scsi_cmnd *cmd = qc->scsicmd; +struct ata_taskfile *tf = &qc->tf; +unsigned char *sb = cmd->sense_buffer; +unsigned char *desc = sb +8 ; + + cmd->result =SAM_STAT_CHECK_CONDITION ; + +/* +* Use ata_to_sense_error() to map status register bits +* onto sense key, asc & ascq. We will overwrite some +* (many) of the fields later. +* +* TODO: reorganise better, by splitting ata_to_sense_error() +*/ +if (unlikely (drv_stat & (ATA_BUSY |ATA_DF |ATA_ERR |ATA_DRQ ))) { +ata_to_sense_error (qc, drv_stat) ; + }else { + sb[3 ] = sb[2 ] = sb[1 ] =0x00 ; + } + +/* +* Sense data is current and format is +* descriptor. +*/ + sb[0 ] =0x72 ; + + desc[0 ] =0x8e ;/* TODO: replace with official value. */ + +/* +* Set length of additional sense data. +* Since we only populate descriptor 0, the total +* length is the same (fixed) length as descriptor 0. +*/ + desc[1 ] = sb[7 ] =14 ; + +/* +* Read the controller registers. +*/ + qc->ap->ops->tf_read (qc->ap, tf); + +/* +* Copy registers into sense buffer. +*/ + desc[2 ] =0x00 ; + desc[3 ] = tf->feature ;/* Note: becomes error register when read. */ + desc[5 ] = tf->nsect ; + desc[7 ] = tf->lbal ; + desc[9 ] = tf->lbam ; + desc[11 ] = tf->lbah ; + desc[12 ] = tf->device ; + desc[13 ] = drv_stat ; + +/* +* Fill in Extend bit, and the high order bytes +* if applicable. +*/ +if (tf->flags &ATA_TFLAG_LBA48 ) { + desc[2 ] |=0x01 ; + desc[4 ] = tf->hob_nsect ; + desc[6 ] = tf->hob_lbal ; + desc[8 ] = tf->hob_lbam ; + desc[10 ] = tf->hob_lbah ; + } +} +/** * ata_scsi_slave_config - Set SCSI device attributes * @sdev: SCSI device to examine
@@ -784,8 +863,9 @@* successfully or not. If there was no error, SK, ASC and * ASCQ will all be zero. */ -if ((cmd->cmnd[0 ] ==ATA_16 ) && (cmd->cmnd[2 ] &0x20 )) { -/*DWD*/ printk ("XX 0x%0lx/0x%0x\n" , qc->tf.flags, qc->tf.protocol); +if (((cmd->cmnd[0 ] ==ATA_16 ) || (cmd->cmnd[0 ] ==ATA_12 )) && + (cmd->cmnd[2 ] &0x20 )) { +ata_pass_thru_cc (qc, drv_stat) ; }else {if (unlikely (drv_stat & (ATA_ERR |ATA_BUSY |ATA_DRQ )))ata_to_sense_error (qc, drv_stat);