Loading drivers/scsi/ahci.c +2 −2 Original line number Original line Diff line number Diff line Loading @@ -608,7 +608,7 @@ static void ahci_eng_timeout(struct ata_port *ap) * not being called from the SCSI EH. * not being called from the SCSI EH. */ */ qc->scsidone = scsi_finish_command; qc->scsidone = scsi_finish_command; ata_qc_complete(qc, ATA_ERR); ata_qc_complete(qc, AC_ERR_OTHER); } } spin_unlock_irqrestore(&host_set->lock, flags); spin_unlock_irqrestore(&host_set->lock, flags); Loading Loading @@ -637,7 +637,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) if (status & PORT_IRQ_FATAL) { if (status & PORT_IRQ_FATAL) { ahci_intr_error(ap, status); ahci_intr_error(ap, status); if (qc) if (qc) ata_qc_complete(qc, ATA_ERR); ata_qc_complete(qc, AC_ERR_OTHER); } } return 1; return 1; Loading drivers/scsi/libata-core.c +15 −16 Original line number Original line Diff line number Diff line Loading @@ -2750,7 +2750,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) * None. (grabs host lock) * None. (grabs host lock) */ */ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) { { struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap; unsigned long flags; unsigned long flags; Loading @@ -2758,7 +2758,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) spin_lock_irqsave(&ap->host_set->lock, flags); spin_lock_irqsave(&ap->host_set->lock, flags); ap->flags &= ~ATA_FLAG_NOINTR; ap->flags &= ~ATA_FLAG_NOINTR; ata_irq_on(ap); ata_irq_on(ap); ata_qc_complete(qc, drv_stat); ata_qc_complete(qc, err_mask); spin_unlock_irqrestore(&ap->host_set->lock, flags); spin_unlock_irqrestore(&ap->host_set->lock, flags); } } Loading Loading @@ -2855,7 +2855,7 @@ static int ata_pio_complete (struct ata_port *ap) ap->hsm_task_state = HSM_ST_IDLE; ap->hsm_task_state = HSM_ST_IDLE; ata_poll_qc_complete(qc, drv_stat); ata_poll_qc_complete(qc, 0); /* another command may start at this point */ /* another command may start at this point */ Loading Loading @@ -3223,18 +3223,15 @@ static void ata_pio_block(struct ata_port *ap) static void ata_pio_error(struct ata_port *ap) static void ata_pio_error(struct ata_port *ap) { { struct ata_queued_cmd *qc; struct ata_queued_cmd *qc; u8 drv_stat; printk(KERN_WARNING "ata%u: PIO error\n", ap->id); qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag); assert(qc != NULL); assert(qc != NULL); drv_stat = ata_chk_status(ap); printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n", ap->id, drv_stat); ap->hsm_task_state = HSM_ST_IDLE; ap->hsm_task_state = HSM_ST_IDLE; ata_poll_qc_complete(qc, drv_stat | ATA_ERR); ata_poll_qc_complete(qc, AC_ERR_ATA_BUS); } } static void ata_pio_task(void *_data) static void ata_pio_task(void *_data) Loading Loading @@ -3357,7 +3354,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) ap->id, qc->tf.command, drv_stat, host_stat); ap->id, qc->tf.command, drv_stat, host_stat); /* complete taskfile transaction */ /* complete taskfile transaction */ ata_qc_complete(qc, drv_stat); ata_qc_complete(qc, ac_err_mask(drv_stat)); break; break; } } Loading Loading @@ -3462,7 +3459,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, return qc; return qc; } } int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat) int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask) { { return 0; return 0; } } Loading Loading @@ -3521,7 +3518,7 @@ void ata_qc_free(struct ata_queued_cmd *qc) * spin_lock_irqsave(host_set lock) * spin_lock_irqsave(host_set lock) */ */ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) { { int rc; int rc; Loading @@ -3538,7 +3535,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) qc->flags &= ~ATA_QCFLAG_ACTIVE; qc->flags &= ~ATA_QCFLAG_ACTIVE; /* call completion callback */ /* call completion callback */ rc = qc->complete_fn(qc, drv_stat); rc = qc->complete_fn(qc, err_mask); /* if callback indicates not to complete command (non-zero), /* if callback indicates not to complete command (non-zero), * return immediately * return immediately Loading Loading @@ -3976,7 +3973,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, ap->ops->irq_clear(ap); ap->ops->irq_clear(ap); /* complete taskfile transaction */ /* complete taskfile transaction */ ata_qc_complete(qc, status); ata_qc_complete(qc, ac_err_mask(status)); break; break; default: default: Loading Loading @@ -4071,7 +4068,7 @@ static void atapi_packet_task(void *_data) /* sleep-wait for BSY to clear */ /* sleep-wait for BSY to clear */ DPRINTK("busy wait\n"); DPRINTK("busy wait\n"); if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) goto err_out; goto err_out_status; /* make sure DRQ is set */ /* make sure DRQ is set */ status = ata_chk_status(ap); status = ata_chk_status(ap); Loading Loading @@ -4108,8 +4105,10 @@ static void atapi_packet_task(void *_data) return; return; err_out_status: status = ata_chk_status(ap); err_out: err_out: ata_poll_qc_complete(qc, ATA_ERR); ata_poll_qc_complete(qc, __ac_err_mask(status)); } } Loading drivers/scsi/libata-scsi.c +28 −18 Original line number Original line Diff line number Diff line Loading @@ -560,7 +560,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) * Use ata_to_sense_error() to map status register bits * Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. * onto sense key, asc & ascq. */ */ if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) { if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(qc->ap->id, tf->command, tf->feature, ata_to_sense_error(qc->ap->id, tf->command, tf->feature, &sb[1], &sb[2], &sb[3]); &sb[1], &sb[2], &sb[3]); sb[1] &= 0x0f; sb[1] &= 0x0f; Loading Loading @@ -635,7 +635,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) * Use ata_to_sense_error() to map status register bits * Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. * onto sense key, asc & ascq. */ */ if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) { if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(qc->ap->id, tf->command, tf->feature, ata_to_sense_error(qc->ap->id, tf->command, tf->feature, &sb[2], &sb[12], &sb[13]); &sb[2], &sb[12], &sb[13]); sb[2] &= 0x0f; sb[2] &= 0x0f; Loading @@ -644,7 +644,11 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) sb[0] = 0x70; sb[0] = 0x70; sb[7] = 0x0a; sb[7] = 0x0a; if (tf->flags & ATA_TFLAG_LBA && !(tf->flags & ATA_TFLAG_LBA48)) { if (tf->flags & ATA_TFLAG_LBA48) { /* TODO: find solution for LBA48 descriptors */ } else if (tf->flags & ATA_TFLAG_LBA) { /* A small (28b) LBA will fit in the 32b info field */ /* A small (28b) LBA will fit in the 32b info field */ sb[0] |= 0x80; /* set valid bit */ sb[0] |= 0x80; /* set valid bit */ sb[3] = tf->device & 0x0f; sb[3] = tf->device & 0x0f; Loading @@ -652,6 +656,10 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) sb[5] = tf->lbam; sb[5] = tf->lbam; sb[6] = tf->lbal; sb[6] = tf->lbal; } } else { /* TODO: C/H/S */ } } } /** /** Loading Loading @@ -1209,10 +1217,12 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm return 1; return 1; } } static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) { { struct scsi_cmnd *cmd = qc->scsicmd; struct scsi_cmnd *cmd = qc->scsicmd; int need_sense = drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ); u8 *cdb = cmd->cmnd; int need_sense = (err_mask != 0); /* For ATA pass thru (SAT) commands, generate a sense block if /* For ATA pass thru (SAT) commands, generate a sense block if * user mandated it or if there's an error. Note that if we * user mandated it or if there's an error. Note that if we Loading @@ -1221,8 +1231,8 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) * whether the command completed successfully or not. If there * whether the command completed successfully or not. If there * was no error, SK, ASC and ASCQ will all be zero. * was no error, SK, ASC and ASCQ will all be zero. */ */ if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) && if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && ((cmd->cmnd[2] & 0x20) || need_sense)) { ((cdb[2] & 0x20) || need_sense)) { ata_gen_ata_desc_sense(qc); ata_gen_ata_desc_sense(qc); } else { } else { if (!need_sense) { if (!need_sense) { Loading Loading @@ -2005,21 +2015,13 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, DPRINTK("EXIT\n"); DPRINTK("EXIT\n"); } } static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) { { struct scsi_cmnd *cmd = qc->scsicmd; struct scsi_cmnd *cmd = qc->scsicmd; VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat); VPRINTK("ENTER, err_mask 0x%X\n", err_mask); if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ))) /* FIXME: not quite right; we don't want the * translation of taskfile registers into * a sense descriptors, since that's only * correct for ATA, not ATAPI */ ata_gen_ata_desc_sense(qc); else if (unlikely(drv_stat & ATA_ERR)) { if (unlikely(err_mask & AC_ERR_DEV)) { DPRINTK("request check condition\n"); DPRINTK("request check condition\n"); /* FIXME: command completion with check condition /* FIXME: command completion with check condition Loading @@ -2036,6 +2038,14 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) return 1; return 1; } } else if (unlikely(err_mask)) /* FIXME: not quite right; we don't want the * translation of taskfile registers into * a sense descriptors, since that's only * correct for ATA, not ATAPI */ ata_gen_ata_desc_sense(qc); else { else { u8 *scsicmd = cmd->cmnd; u8 *scsicmd = cmd->cmnd; Loading drivers/scsi/libata.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -39,7 +39,7 @@ struct ata_scsi_args { /* libata-core.c */ /* libata-core.c */ extern int atapi_enabled; extern int atapi_enabled; extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat); extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask); extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, struct ata_device *dev); struct ata_device *dev); extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc); extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc); Loading drivers/scsi/pdc_adma.c +8 −5 Original line number Original line Diff line number Diff line Loading @@ -451,7 +451,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) struct adma_port_priv *pp; struct adma_port_priv *pp; struct ata_queued_cmd *qc; struct ata_queued_cmd *qc; void __iomem *chan = ADMA_REGS(mmio_base, port_no); void __iomem *chan = ADMA_REGS(mmio_base, port_no); u8 drv_stat = 0, status = readb(chan + ADMA_STATUS); u8 status = readb(chan + ADMA_STATUS); if (status == 0) if (status == 0) continue; continue; Loading @@ -464,11 +464,14 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) continue; continue; qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && (!(qc->tf.ctl & ATA_NIEN))) { if (qc && (!(qc->tf.ctl & ATA_NIEN))) { unsigned int err_mask = 0; if ((status & (aPERR | aPSD | aUIRQ))) if ((status & (aPERR | aPSD | aUIRQ))) drv_stat = ATA_ERR; err_mask = AC_ERR_OTHER; else if (pp->pkt[0] != cDONE) else if (pp->pkt[0] != cDONE) drv_stat = ATA_ERR; err_mask = AC_ERR_OTHER; ata_qc_complete(qc, drv_stat); ata_qc_complete(qc, err_mask); } } } } return handled; return handled; Loading Loading @@ -498,7 +501,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set) /* complete taskfile transaction */ /* complete taskfile transaction */ pp->state = adma_state_idle; pp->state = adma_state_idle; ata_qc_complete(qc, status); ata_qc_complete(qc, ac_err_mask(status)); handled = 1; handled = 1; } } } } Loading Loading
drivers/scsi/ahci.c +2 −2 Original line number Original line Diff line number Diff line Loading @@ -608,7 +608,7 @@ static void ahci_eng_timeout(struct ata_port *ap) * not being called from the SCSI EH. * not being called from the SCSI EH. */ */ qc->scsidone = scsi_finish_command; qc->scsidone = scsi_finish_command; ata_qc_complete(qc, ATA_ERR); ata_qc_complete(qc, AC_ERR_OTHER); } } spin_unlock_irqrestore(&host_set->lock, flags); spin_unlock_irqrestore(&host_set->lock, flags); Loading Loading @@ -637,7 +637,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) if (status & PORT_IRQ_FATAL) { if (status & PORT_IRQ_FATAL) { ahci_intr_error(ap, status); ahci_intr_error(ap, status); if (qc) if (qc) ata_qc_complete(qc, ATA_ERR); ata_qc_complete(qc, AC_ERR_OTHER); } } return 1; return 1; Loading
drivers/scsi/libata-core.c +15 −16 Original line number Original line Diff line number Diff line Loading @@ -2750,7 +2750,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) * None. (grabs host lock) * None. (grabs host lock) */ */ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) { { struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap; unsigned long flags; unsigned long flags; Loading @@ -2758,7 +2758,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) spin_lock_irqsave(&ap->host_set->lock, flags); spin_lock_irqsave(&ap->host_set->lock, flags); ap->flags &= ~ATA_FLAG_NOINTR; ap->flags &= ~ATA_FLAG_NOINTR; ata_irq_on(ap); ata_irq_on(ap); ata_qc_complete(qc, drv_stat); ata_qc_complete(qc, err_mask); spin_unlock_irqrestore(&ap->host_set->lock, flags); spin_unlock_irqrestore(&ap->host_set->lock, flags); } } Loading Loading @@ -2855,7 +2855,7 @@ static int ata_pio_complete (struct ata_port *ap) ap->hsm_task_state = HSM_ST_IDLE; ap->hsm_task_state = HSM_ST_IDLE; ata_poll_qc_complete(qc, drv_stat); ata_poll_qc_complete(qc, 0); /* another command may start at this point */ /* another command may start at this point */ Loading Loading @@ -3223,18 +3223,15 @@ static void ata_pio_block(struct ata_port *ap) static void ata_pio_error(struct ata_port *ap) static void ata_pio_error(struct ata_port *ap) { { struct ata_queued_cmd *qc; struct ata_queued_cmd *qc; u8 drv_stat; printk(KERN_WARNING "ata%u: PIO error\n", ap->id); qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag); assert(qc != NULL); assert(qc != NULL); drv_stat = ata_chk_status(ap); printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n", ap->id, drv_stat); ap->hsm_task_state = HSM_ST_IDLE; ap->hsm_task_state = HSM_ST_IDLE; ata_poll_qc_complete(qc, drv_stat | ATA_ERR); ata_poll_qc_complete(qc, AC_ERR_ATA_BUS); } } static void ata_pio_task(void *_data) static void ata_pio_task(void *_data) Loading Loading @@ -3357,7 +3354,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) ap->id, qc->tf.command, drv_stat, host_stat); ap->id, qc->tf.command, drv_stat, host_stat); /* complete taskfile transaction */ /* complete taskfile transaction */ ata_qc_complete(qc, drv_stat); ata_qc_complete(qc, ac_err_mask(drv_stat)); break; break; } } Loading Loading @@ -3462,7 +3459,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, return qc; return qc; } } int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat) int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask) { { return 0; return 0; } } Loading Loading @@ -3521,7 +3518,7 @@ void ata_qc_free(struct ata_queued_cmd *qc) * spin_lock_irqsave(host_set lock) * spin_lock_irqsave(host_set lock) */ */ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) { { int rc; int rc; Loading @@ -3538,7 +3535,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) qc->flags &= ~ATA_QCFLAG_ACTIVE; qc->flags &= ~ATA_QCFLAG_ACTIVE; /* call completion callback */ /* call completion callback */ rc = qc->complete_fn(qc, drv_stat); rc = qc->complete_fn(qc, err_mask); /* if callback indicates not to complete command (non-zero), /* if callback indicates not to complete command (non-zero), * return immediately * return immediately Loading Loading @@ -3976,7 +3973,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, ap->ops->irq_clear(ap); ap->ops->irq_clear(ap); /* complete taskfile transaction */ /* complete taskfile transaction */ ata_qc_complete(qc, status); ata_qc_complete(qc, ac_err_mask(status)); break; break; default: default: Loading Loading @@ -4071,7 +4068,7 @@ static void atapi_packet_task(void *_data) /* sleep-wait for BSY to clear */ /* sleep-wait for BSY to clear */ DPRINTK("busy wait\n"); DPRINTK("busy wait\n"); if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) goto err_out; goto err_out_status; /* make sure DRQ is set */ /* make sure DRQ is set */ status = ata_chk_status(ap); status = ata_chk_status(ap); Loading Loading @@ -4108,8 +4105,10 @@ static void atapi_packet_task(void *_data) return; return; err_out_status: status = ata_chk_status(ap); err_out: err_out: ata_poll_qc_complete(qc, ATA_ERR); ata_poll_qc_complete(qc, __ac_err_mask(status)); } } Loading
drivers/scsi/libata-scsi.c +28 −18 Original line number Original line Diff line number Diff line Loading @@ -560,7 +560,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) * Use ata_to_sense_error() to map status register bits * Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. * onto sense key, asc & ascq. */ */ if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) { if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(qc->ap->id, tf->command, tf->feature, ata_to_sense_error(qc->ap->id, tf->command, tf->feature, &sb[1], &sb[2], &sb[3]); &sb[1], &sb[2], &sb[3]); sb[1] &= 0x0f; sb[1] &= 0x0f; Loading Loading @@ -635,7 +635,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) * Use ata_to_sense_error() to map status register bits * Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. * onto sense key, asc & ascq. */ */ if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) { if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(qc->ap->id, tf->command, tf->feature, ata_to_sense_error(qc->ap->id, tf->command, tf->feature, &sb[2], &sb[12], &sb[13]); &sb[2], &sb[12], &sb[13]); sb[2] &= 0x0f; sb[2] &= 0x0f; Loading @@ -644,7 +644,11 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) sb[0] = 0x70; sb[0] = 0x70; sb[7] = 0x0a; sb[7] = 0x0a; if (tf->flags & ATA_TFLAG_LBA && !(tf->flags & ATA_TFLAG_LBA48)) { if (tf->flags & ATA_TFLAG_LBA48) { /* TODO: find solution for LBA48 descriptors */ } else if (tf->flags & ATA_TFLAG_LBA) { /* A small (28b) LBA will fit in the 32b info field */ /* A small (28b) LBA will fit in the 32b info field */ sb[0] |= 0x80; /* set valid bit */ sb[0] |= 0x80; /* set valid bit */ sb[3] = tf->device & 0x0f; sb[3] = tf->device & 0x0f; Loading @@ -652,6 +656,10 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) sb[5] = tf->lbam; sb[5] = tf->lbam; sb[6] = tf->lbal; sb[6] = tf->lbal; } } else { /* TODO: C/H/S */ } } } /** /** Loading Loading @@ -1209,10 +1217,12 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm return 1; return 1; } } static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) { { struct scsi_cmnd *cmd = qc->scsicmd; struct scsi_cmnd *cmd = qc->scsicmd; int need_sense = drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ); u8 *cdb = cmd->cmnd; int need_sense = (err_mask != 0); /* For ATA pass thru (SAT) commands, generate a sense block if /* For ATA pass thru (SAT) commands, generate a sense block if * user mandated it or if there's an error. Note that if we * user mandated it or if there's an error. Note that if we Loading @@ -1221,8 +1231,8 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) * whether the command completed successfully or not. If there * whether the command completed successfully or not. If there * was no error, SK, ASC and ASCQ will all be zero. * was no error, SK, ASC and ASCQ will all be zero. */ */ if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) && if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && ((cmd->cmnd[2] & 0x20) || need_sense)) { ((cdb[2] & 0x20) || need_sense)) { ata_gen_ata_desc_sense(qc); ata_gen_ata_desc_sense(qc); } else { } else { if (!need_sense) { if (!need_sense) { Loading Loading @@ -2005,21 +2015,13 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, DPRINTK("EXIT\n"); DPRINTK("EXIT\n"); } } static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) { { struct scsi_cmnd *cmd = qc->scsicmd; struct scsi_cmnd *cmd = qc->scsicmd; VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat); VPRINTK("ENTER, err_mask 0x%X\n", err_mask); if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ))) /* FIXME: not quite right; we don't want the * translation of taskfile registers into * a sense descriptors, since that's only * correct for ATA, not ATAPI */ ata_gen_ata_desc_sense(qc); else if (unlikely(drv_stat & ATA_ERR)) { if (unlikely(err_mask & AC_ERR_DEV)) { DPRINTK("request check condition\n"); DPRINTK("request check condition\n"); /* FIXME: command completion with check condition /* FIXME: command completion with check condition Loading @@ -2036,6 +2038,14 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) return 1; return 1; } } else if (unlikely(err_mask)) /* FIXME: not quite right; we don't want the * translation of taskfile registers into * a sense descriptors, since that's only * correct for ATA, not ATAPI */ ata_gen_ata_desc_sense(qc); else { else { u8 *scsicmd = cmd->cmnd; u8 *scsicmd = cmd->cmnd; Loading
drivers/scsi/libata.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -39,7 +39,7 @@ struct ata_scsi_args { /* libata-core.c */ /* libata-core.c */ extern int atapi_enabled; extern int atapi_enabled; extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat); extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask); extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, struct ata_device *dev); struct ata_device *dev); extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc); extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc); Loading
drivers/scsi/pdc_adma.c +8 −5 Original line number Original line Diff line number Diff line Loading @@ -451,7 +451,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) struct adma_port_priv *pp; struct adma_port_priv *pp; struct ata_queued_cmd *qc; struct ata_queued_cmd *qc; void __iomem *chan = ADMA_REGS(mmio_base, port_no); void __iomem *chan = ADMA_REGS(mmio_base, port_no); u8 drv_stat = 0, status = readb(chan + ADMA_STATUS); u8 status = readb(chan + ADMA_STATUS); if (status == 0) if (status == 0) continue; continue; Loading @@ -464,11 +464,14 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) continue; continue; qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && (!(qc->tf.ctl & ATA_NIEN))) { if (qc && (!(qc->tf.ctl & ATA_NIEN))) { unsigned int err_mask = 0; if ((status & (aPERR | aPSD | aUIRQ))) if ((status & (aPERR | aPSD | aUIRQ))) drv_stat = ATA_ERR; err_mask = AC_ERR_OTHER; else if (pp->pkt[0] != cDONE) else if (pp->pkt[0] != cDONE) drv_stat = ATA_ERR; err_mask = AC_ERR_OTHER; ata_qc_complete(qc, drv_stat); ata_qc_complete(qc, err_mask); } } } } return handled; return handled; Loading Loading @@ -498,7 +501,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set) /* complete taskfile transaction */ /* complete taskfile transaction */ pp->state = adma_state_idle; pp->state = adma_state_idle; ata_qc_complete(qc, status); ata_qc_complete(qc, ac_err_mask(status)); handled = 1; handled = 1; } } } } Loading