diff options
| -rw-r--r-- | drivers/scsi/ahci.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/libata-core.c | 31 | ||||
| -rw-r--r-- | drivers/scsi/libata-scsi.c | 46 | ||||
| -rw-r--r-- | drivers/scsi/libata.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/pdc_adma.c | 13 | ||||
| -rw-r--r-- | drivers/scsi/sata_mv.c | 11 | ||||
| -rw-r--r-- | drivers/scsi/sata_promise.c | 16 | ||||
| -rw-r--r-- | drivers/scsi/sata_qstor.c | 7 | ||||
| -rw-r--r-- | drivers/scsi/sata_sil24.c | 12 | ||||
| -rw-r--r-- | drivers/scsi/sata_sx4.c | 10 | ||||
| -rw-r--r-- | include/linux/libata.h | 28 |
11 files changed, 109 insertions, 71 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 03829aedfd39..5efb3c50aa8a 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
| @@ -600,7 +600,7 @@ static void ahci_eng_timeout(struct ata_port *ap) | |||
| 600 | * not being called from the SCSI EH. | 600 | * not being called from the SCSI EH. |
| 601 | */ | 601 | */ |
| 602 | qc->scsidone = scsi_finish_command; | 602 | qc->scsidone = scsi_finish_command; |
| 603 | ata_qc_complete(qc, ATA_ERR); | 603 | ata_qc_complete(qc, AC_ERR_OTHER); |
| 604 | } | 604 | } |
| 605 | 605 | ||
| 606 | spin_unlock_irqrestore(&host_set->lock, flags); | 606 | spin_unlock_irqrestore(&host_set->lock, flags); |
| @@ -629,7 +629,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
| 629 | if (status & PORT_IRQ_FATAL) { | 629 | if (status & PORT_IRQ_FATAL) { |
| 630 | ahci_intr_error(ap, status); | 630 | ahci_intr_error(ap, status); |
| 631 | if (qc) | 631 | if (qc) |
| 632 | ata_qc_complete(qc, ATA_ERR); | 632 | ata_qc_complete(qc, AC_ERR_OTHER); |
| 633 | } | 633 | } |
| 634 | 634 | ||
| 635 | return 1; | 635 | return 1; |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 771bc7d376bc..cc089f1fb114 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
| @@ -2663,7 +2663,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) | |||
| 2663 | * None. (grabs host lock) | 2663 | * None. (grabs host lock) |
| 2664 | */ | 2664 | */ |
| 2665 | 2665 | ||
| 2666 | void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 2666 | void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) |
| 2667 | { | 2667 | { |
| 2668 | struct ata_port *ap = qc->ap; | 2668 | struct ata_port *ap = qc->ap; |
| 2669 | unsigned long flags; | 2669 | unsigned long flags; |
| @@ -2671,7 +2671,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
| 2671 | spin_lock_irqsave(&ap->host_set->lock, flags); | 2671 | spin_lock_irqsave(&ap->host_set->lock, flags); |
| 2672 | ap->flags &= ~ATA_FLAG_NOINTR; | 2672 | ap->flags &= ~ATA_FLAG_NOINTR; |
| 2673 | ata_irq_on(ap); | 2673 | ata_irq_on(ap); |
| 2674 | ata_qc_complete(qc, drv_stat); | 2674 | ata_qc_complete(qc, err_mask); |
| 2675 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | 2675 | spin_unlock_irqrestore(&ap->host_set->lock, flags); |
| 2676 | } | 2676 | } |
| 2677 | 2677 | ||
| @@ -2768,7 +2768,7 @@ static int ata_pio_complete (struct ata_port *ap) | |||
| 2768 | 2768 | ||
| 2769 | ap->hsm_task_state = HSM_ST_IDLE; | 2769 | ap->hsm_task_state = HSM_ST_IDLE; |
| 2770 | 2770 | ||
| 2771 | ata_poll_qc_complete(qc, drv_stat); | 2771 | ata_poll_qc_complete(qc, 0); |
| 2772 | 2772 | ||
| 2773 | /* another command may start at this point */ | 2773 | /* another command may start at this point */ |
| 2774 | 2774 | ||
| @@ -3136,18 +3136,15 @@ static void ata_pio_block(struct ata_port *ap) | |||
| 3136 | static void ata_pio_error(struct ata_port *ap) | 3136 | static void ata_pio_error(struct ata_port *ap) |
| 3137 | { | 3137 | { |
| 3138 | struct ata_queued_cmd *qc; | 3138 | struct ata_queued_cmd *qc; |
| 3139 | u8 drv_stat; | 3139 | |
| 3140 | printk(KERN_WARNING "ata%u: PIO error\n", ap->id); | ||
| 3140 | 3141 | ||
| 3141 | qc = ata_qc_from_tag(ap, ap->active_tag); | 3142 | qc = ata_qc_from_tag(ap, ap->active_tag); |
| 3142 | assert(qc != NULL); | 3143 | assert(qc != NULL); |
| 3143 | 3144 | ||
| 3144 | drv_stat = ata_chk_status(ap); | ||
| 3145 | printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n", | ||
| 3146 | ap->id, drv_stat); | ||
| 3147 | |||
| 3148 | ap->hsm_task_state = HSM_ST_IDLE; | 3145 | ap->hsm_task_state = HSM_ST_IDLE; |
| 3149 | 3146 | ||
| 3150 | ata_poll_qc_complete(qc, drv_stat | ATA_ERR); | 3147 | ata_poll_qc_complete(qc, AC_ERR_ATA_BUS); |
| 3151 | } | 3148 | } |
| 3152 | 3149 | ||
| 3153 | static void ata_pio_task(void *_data) | 3150 | static void ata_pio_task(void *_data) |
| @@ -3270,7 +3267,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
| 3270 | ap->id, qc->tf.command, drv_stat, host_stat); | 3267 | ap->id, qc->tf.command, drv_stat, host_stat); |
| 3271 | 3268 | ||
| 3272 | /* complete taskfile transaction */ | 3269 | /* complete taskfile transaction */ |
| 3273 | ata_qc_complete(qc, drv_stat); | 3270 | ata_qc_complete(qc, ac_err_mask(drv_stat)); |
| 3274 | break; | 3271 | break; |
| 3275 | } | 3272 | } |
| 3276 | 3273 | ||
| @@ -3375,7 +3372,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | |||
| 3375 | return qc; | 3372 | return qc; |
| 3376 | } | 3373 | } |
| 3377 | 3374 | ||
| 3378 | int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat) | 3375 | int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask) |
| 3379 | { | 3376 | { |
| 3380 | return 0; | 3377 | return 0; |
| 3381 | } | 3378 | } |
| @@ -3434,7 +3431,7 @@ void ata_qc_free(struct ata_queued_cmd *qc) | |||
| 3434 | * spin_lock_irqsave(host_set lock) | 3431 | * spin_lock_irqsave(host_set lock) |
| 3435 | */ | 3432 | */ |
| 3436 | 3433 | ||
| 3437 | void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 3434 | void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) |
| 3438 | { | 3435 | { |
| 3439 | int rc; | 3436 | int rc; |
| 3440 | 3437 | ||
| @@ -3451,7 +3448,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
| 3451 | qc->flags &= ~ATA_QCFLAG_ACTIVE; | 3448 | qc->flags &= ~ATA_QCFLAG_ACTIVE; |
| 3452 | 3449 | ||
| 3453 | /* call completion callback */ | 3450 | /* call completion callback */ |
| 3454 | rc = qc->complete_fn(qc, drv_stat); | 3451 | rc = qc->complete_fn(qc, err_mask); |
| 3455 | 3452 | ||
| 3456 | /* if callback indicates not to complete command (non-zero), | 3453 | /* if callback indicates not to complete command (non-zero), |
| 3457 | * return immediately | 3454 | * return immediately |
| @@ -3889,7 +3886,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, | |||
| 3889 | ap->ops->irq_clear(ap); | 3886 | ap->ops->irq_clear(ap); |
| 3890 | 3887 | ||
| 3891 | /* complete taskfile transaction */ | 3888 | /* complete taskfile transaction */ |
| 3892 | ata_qc_complete(qc, status); | 3889 | ata_qc_complete(qc, ac_err_mask(status)); |
| 3893 | break; | 3890 | break; |
| 3894 | 3891 | ||
| 3895 | default: | 3892 | default: |
| @@ -3984,7 +3981,7 @@ static void atapi_packet_task(void *_data) | |||
| 3984 | /* sleep-wait for BSY to clear */ | 3981 | /* sleep-wait for BSY to clear */ |
| 3985 | DPRINTK("busy wait\n"); | 3982 | DPRINTK("busy wait\n"); |
| 3986 | if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) | 3983 | if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) |
| 3987 | goto err_out; | 3984 | goto err_out_status; |
| 3988 | 3985 | ||
| 3989 | /* make sure DRQ is set */ | 3986 | /* make sure DRQ is set */ |
| 3990 | status = ata_chk_status(ap); | 3987 | status = ata_chk_status(ap); |
| @@ -4021,8 +4018,10 @@ static void atapi_packet_task(void *_data) | |||
| 4021 | 4018 | ||
| 4022 | return; | 4019 | return; |
| 4023 | 4020 | ||
| 4021 | err_out_status: | ||
| 4022 | status = ata_chk_status(ap); | ||
| 4024 | err_out: | 4023 | err_out: |
| 4025 | ata_poll_qc_complete(qc, ATA_ERR); | 4024 | ata_poll_qc_complete(qc, __ac_err_mask(status)); |
| 4026 | } | 4025 | } |
| 4027 | 4026 | ||
| 4028 | 4027 | ||
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 89a04b1a5a0e..1e3792f86fcf 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
| @@ -560,7 +560,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) | |||
| 560 | * Use ata_to_sense_error() to map status register bits | 560 | * Use ata_to_sense_error() to map status register bits |
| 561 | * onto sense key, asc & ascq. | 561 | * onto sense key, asc & ascq. |
| 562 | */ | 562 | */ |
| 563 | if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) { | 563 | if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { |
| 564 | ata_to_sense_error(qc->ap->id, tf->command, tf->feature, | 564 | ata_to_sense_error(qc->ap->id, tf->command, tf->feature, |
| 565 | &sb[1], &sb[2], &sb[3]); | 565 | &sb[1], &sb[2], &sb[3]); |
| 566 | sb[1] &= 0x0f; | 566 | sb[1] &= 0x0f; |
| @@ -635,7 +635,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) | |||
| 635 | * Use ata_to_sense_error() to map status register bits | 635 | * Use ata_to_sense_error() to map status register bits |
| 636 | * onto sense key, asc & ascq. | 636 | * onto sense key, asc & ascq. |
| 637 | */ | 637 | */ |
| 638 | if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) { | 638 | if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { |
| 639 | ata_to_sense_error(qc->ap->id, tf->command, tf->feature, | 639 | ata_to_sense_error(qc->ap->id, tf->command, tf->feature, |
| 640 | &sb[2], &sb[12], &sb[13]); | 640 | &sb[2], &sb[12], &sb[13]); |
| 641 | sb[2] &= 0x0f; | 641 | sb[2] &= 0x0f; |
| @@ -644,7 +644,11 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) | |||
| 644 | sb[0] = 0x70; | 644 | sb[0] = 0x70; |
| 645 | sb[7] = 0x0a; | 645 | sb[7] = 0x0a; |
| 646 | 646 | ||
| 647 | if (tf->flags & ATA_TFLAG_LBA && !(tf->flags & ATA_TFLAG_LBA48)) { | 647 | if (tf->flags & ATA_TFLAG_LBA48) { |
| 648 | /* TODO: find solution for LBA48 descriptors */ | ||
| 649 | } | ||
| 650 | |||
| 651 | else if (tf->flags & ATA_TFLAG_LBA) { | ||
| 648 | /* A small (28b) LBA will fit in the 32b info field */ | 652 | /* A small (28b) LBA will fit in the 32b info field */ |
| 649 | sb[0] |= 0x80; /* set valid bit */ | 653 | sb[0] |= 0x80; /* set valid bit */ |
| 650 | sb[3] = tf->device & 0x0f; | 654 | sb[3] = tf->device & 0x0f; |
| @@ -652,6 +656,10 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) | |||
| 652 | sb[5] = tf->lbam; | 656 | sb[5] = tf->lbam; |
| 653 | sb[6] = tf->lbal; | 657 | sb[6] = tf->lbal; |
| 654 | } | 658 | } |
| 659 | |||
| 660 | else { | ||
| 661 | /* TODO: C/H/S */ | ||
| 662 | } | ||
| 655 | } | 663 | } |
| 656 | 664 | ||
| 657 | /** | 665 | /** |
| @@ -1199,10 +1207,12 @@ nothing_to_do: | |||
| 1199 | return 1; | 1207 | return 1; |
| 1200 | } | 1208 | } |
| 1201 | 1209 | ||
| 1202 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 1210 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, |
| 1211 | unsigned int err_mask) | ||
| 1203 | { | 1212 | { |
| 1204 | struct scsi_cmnd *cmd = qc->scsicmd; | 1213 | struct scsi_cmnd *cmd = qc->scsicmd; |
| 1205 | int need_sense = drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ); | 1214 | u8 *cdb = cmd->cmnd; |
| 1215 | int need_sense = (err_mask != 0); | ||
| 1206 | 1216 | ||
| 1207 | /* For ATA pass thru (SAT) commands, generate a sense block if | 1217 | /* For ATA pass thru (SAT) commands, generate a sense block if |
| 1208 | * user mandated it or if there's an error. Note that if we | 1218 | * user mandated it or if there's an error. Note that if we |
| @@ -1211,8 +1221,8 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
| 1211 | * whether the command completed successfully or not. If there | 1221 | * whether the command completed successfully or not. If there |
| 1212 | * was no error, SK, ASC and ASCQ will all be zero. | 1222 | * was no error, SK, ASC and ASCQ will all be zero. |
| 1213 | */ | 1223 | */ |
| 1214 | if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) && | 1224 | if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && |
| 1215 | ((cmd->cmnd[2] & 0x20) || need_sense)) { | 1225 | ((cdb[2] & 0x20) || need_sense)) { |
| 1216 | ata_gen_ata_desc_sense(qc); | 1226 | ata_gen_ata_desc_sense(qc); |
| 1217 | } else { | 1227 | } else { |
| 1218 | if (!need_sense) { | 1228 | if (!need_sense) { |
| @@ -1995,21 +2005,13 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | |||
| 1995 | DPRINTK("EXIT\n"); | 2005 | DPRINTK("EXIT\n"); |
| 1996 | } | 2006 | } |
| 1997 | 2007 | ||
| 1998 | static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 2008 | static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) |
| 1999 | { | 2009 | { |
| 2000 | struct scsi_cmnd *cmd = qc->scsicmd; | 2010 | struct scsi_cmnd *cmd = qc->scsicmd; |
| 2001 | 2011 | ||
| 2002 | VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat); | 2012 | VPRINTK("ENTER, err_mask 0x%X\n", err_mask); |
| 2003 | |||
| 2004 | if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ))) | ||
| 2005 | /* FIXME: not quite right; we don't want the | ||
| 2006 | * translation of taskfile registers into | ||
| 2007 | * a sense descriptors, since that's only | ||
| 2008 | * correct for ATA, not ATAPI | ||
| 2009 | */ | ||
| 2010 | ata_gen_ata_desc_sense(qc); | ||
| 2011 | 2013 | ||
| 2012 | else if (unlikely(drv_stat & ATA_ERR)) { | 2014 | if (unlikely(err_mask & AC_ERR_DEV)) { |
| 2013 | DPRINTK("request check condition\n"); | 2015 | DPRINTK("request check condition\n"); |
| 2014 | 2016 | ||
| 2015 | /* FIXME: command completion with check condition | 2017 | /* FIXME: command completion with check condition |
| @@ -2026,6 +2028,14 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
| 2026 | return 1; | 2028 | return 1; |
| 2027 | } | 2029 | } |
| 2028 | 2030 | ||
| 2031 | else if (unlikely(err_mask)) | ||
| 2032 | /* FIXME: not quite right; we don't want the | ||
| 2033 | * translation of taskfile registers into | ||
| 2034 | * a sense descriptors, since that's only | ||
| 2035 | * correct for ATA, not ATAPI | ||
| 2036 | */ | ||
| 2037 | ata_gen_ata_desc_sense(qc); | ||
| 2038 | |||
| 2029 | else { | 2039 | else { |
| 2030 | u8 *scsicmd = cmd->cmnd; | 2040 | u8 *scsicmd = cmd->cmnd; |
| 2031 | 2041 | ||
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 65c264b91136..10ecd9e15e4f 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h | |||
| @@ -39,7 +39,7 @@ struct ata_scsi_args { | |||
| 39 | 39 | ||
| 40 | /* libata-core.c */ | 40 | /* libata-core.c */ |
| 41 | extern int atapi_enabled; | 41 | extern int atapi_enabled; |
| 42 | extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat); | 42 | extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask); |
| 43 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | 43 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, |
| 44 | struct ata_device *dev); | 44 | struct ata_device *dev); |
| 45 | extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc); | 45 | extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc); |
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c index af99feb9d237..74b3b2c629b6 100644 --- a/drivers/scsi/pdc_adma.c +++ b/drivers/scsi/pdc_adma.c | |||
| @@ -451,7 +451,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) | |||
| 451 | struct adma_port_priv *pp; | 451 | struct adma_port_priv *pp; |
| 452 | struct ata_queued_cmd *qc; | 452 | struct ata_queued_cmd *qc; |
| 453 | void __iomem *chan = ADMA_REGS(mmio_base, port_no); | 453 | void __iomem *chan = ADMA_REGS(mmio_base, port_no); |
| 454 | u8 drv_stat = 0, status = readb(chan + ADMA_STATUS); | 454 | u8 status = readb(chan + ADMA_STATUS); |
| 455 | 455 | ||
| 456 | if (status == 0) | 456 | if (status == 0) |
| 457 | continue; | 457 | continue; |
| @@ -464,11 +464,14 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) | |||
| 464 | continue; | 464 | continue; |
| 465 | qc = ata_qc_from_tag(ap, ap->active_tag); | 465 | qc = ata_qc_from_tag(ap, ap->active_tag); |
| 466 | if (qc && (!(qc->tf.ctl & ATA_NIEN))) { | 466 | if (qc && (!(qc->tf.ctl & ATA_NIEN))) { |
| 467 | unsigned int err_mask = 0; | ||
| 468 | |||
| 467 | if ((status & (aPERR | aPSD | aUIRQ))) | 469 | if ((status & (aPERR | aPSD | aUIRQ))) |
| 468 | drv_stat = ATA_ERR; | 470 | err_mask = AC_ERR_OTHER; |
| 469 | else if (pp->pkt[0] != cDONE) | 471 | else if (pp->pkt[0] != cDONE) |
| 470 | drv_stat = ATA_ERR; | 472 | err_mask = AC_ERR_OTHER; |
| 471 | ata_qc_complete(qc, drv_stat); | 473 | |
| 474 | ata_qc_complete(qc, err_mask); | ||
| 472 | } | 475 | } |
| 473 | } | 476 | } |
| 474 | return handled; | 477 | return handled; |
| @@ -498,7 +501,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set) | |||
| 498 | 501 | ||
| 499 | /* complete taskfile transaction */ | 502 | /* complete taskfile transaction */ |
| 500 | pp->state = adma_state_idle; | 503 | pp->state = adma_state_idle; |
| 501 | ata_qc_complete(qc, status); | 504 | ata_qc_complete(qc, ac_err_mask(status)); |
| 502 | handled = 1; | 505 | handled = 1; |
| 503 | } | 506 | } |
| 504 | } | 507 | } |
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index dcef5fe8600b..936d1ce5575f 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
| @@ -1065,6 +1065,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
| 1065 | struct ata_queued_cmd *qc; | 1065 | struct ata_queued_cmd *qc; |
| 1066 | u32 hc_irq_cause; | 1066 | u32 hc_irq_cause; |
| 1067 | int shift, port, port0, hard_port, handled; | 1067 | int shift, port, port0, hard_port, handled; |
| 1068 | unsigned int err_mask; | ||
| 1068 | u8 ata_status = 0; | 1069 | u8 ata_status = 0; |
| 1069 | 1070 | ||
| 1070 | if (hc == 0) { | 1071 | if (hc == 0) { |
| @@ -1100,15 +1101,15 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
| 1100 | handled++; | 1101 | handled++; |
| 1101 | } | 1102 | } |
| 1102 | 1103 | ||
| 1104 | err_mask = ac_err_mask(ata_status); | ||
| 1105 | |||
| 1103 | shift = port << 1; /* (port * 2) */ | 1106 | shift = port << 1; /* (port * 2) */ |
| 1104 | if (port >= MV_PORTS_PER_HC) { | 1107 | if (port >= MV_PORTS_PER_HC) { |
| 1105 | shift++; /* skip bit 8 in the HC Main IRQ reg */ | 1108 | shift++; /* skip bit 8 in the HC Main IRQ reg */ |
| 1106 | } | 1109 | } |
| 1107 | if ((PORT0_ERR << shift) & relevant) { | 1110 | if ((PORT0_ERR << shift) & relevant) { |
| 1108 | mv_err_intr(ap); | 1111 | mv_err_intr(ap); |
| 1109 | /* OR in ATA_ERR to ensure libata knows we took one */ | 1112 | err_mask |= AC_ERR_OTHER; |
| 1110 | ata_status = readb((void __iomem *) | ||
| 1111 | ap->ioaddr.status_addr) | ATA_ERR; | ||
| 1112 | handled++; | 1113 | handled++; |
| 1113 | } | 1114 | } |
| 1114 | 1115 | ||
| @@ -1118,7 +1119,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
| 1118 | VPRINTK("port %u IRQ found for qc, " | 1119 | VPRINTK("port %u IRQ found for qc, " |
| 1119 | "ata_status 0x%x\n", port,ata_status); | 1120 | "ata_status 0x%x\n", port,ata_status); |
| 1120 | /* mark qc status appropriately */ | 1121 | /* mark qc status appropriately */ |
| 1121 | ata_qc_complete(qc, ata_status); | 1122 | ata_qc_complete(qc, err_mask); |
| 1122 | } | 1123 | } |
| 1123 | } | 1124 | } |
| 1124 | } | 1125 | } |
| @@ -1294,7 +1295,7 @@ static void mv_eng_timeout(struct ata_port *ap) | |||
| 1294 | */ | 1295 | */ |
| 1295 | spin_lock_irqsave(&ap->host_set->lock, flags); | 1296 | spin_lock_irqsave(&ap->host_set->lock, flags); |
| 1296 | qc->scsidone = scsi_finish_command; | 1297 | qc->scsidone = scsi_finish_command; |
| 1297 | ata_qc_complete(qc, ATA_ERR); | 1298 | ata_qc_complete(qc, AC_ERR_OTHER); |
| 1298 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | 1299 | spin_unlock_irqrestore(&ap->host_set->lock, flags); |
| 1299 | } | 1300 | } |
| 1300 | } | 1301 | } |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 63911f16b6ec..8f41702275db 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
| @@ -399,7 +399,8 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
| 399 | case ATA_PROT_DMA: | 399 | case ATA_PROT_DMA: |
| 400 | case ATA_PROT_NODATA: | 400 | case ATA_PROT_NODATA: |
| 401 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); | 401 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); |
| 402 | ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR); | 402 | drv_stat = ata_wait_idle(ap); |
| 403 | ata_qc_complete(qc, __ac_err_mask(drv_stat)); | ||
| 403 | break; | 404 | break; |
| 404 | 405 | ||
| 405 | default: | 406 | default: |
| @@ -408,7 +409,7 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
| 408 | printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", | 409 | printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", |
| 409 | ap->id, qc->tf.command, drv_stat); | 410 | ap->id, qc->tf.command, drv_stat); |
| 410 | 411 | ||
| 411 | ata_qc_complete(qc, drv_stat); | 412 | ata_qc_complete(qc, ac_err_mask(drv_stat)); |
| 412 | break; | 413 | break; |
| 413 | } | 414 | } |
| 414 | 415 | ||
| @@ -420,24 +421,21 @@ out: | |||
| 420 | static inline unsigned int pdc_host_intr( struct ata_port *ap, | 421 | static inline unsigned int pdc_host_intr( struct ata_port *ap, |
| 421 | struct ata_queued_cmd *qc) | 422 | struct ata_queued_cmd *qc) |
| 422 | { | 423 | { |
| 423 | u8 status; | 424 | unsigned int handled = 0, err_mask = 0; |
| 424 | unsigned int handled = 0, have_err = 0; | ||
| 425 | u32 tmp; | 425 | u32 tmp; |
| 426 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL; | 426 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL; |
| 427 | 427 | ||
| 428 | tmp = readl(mmio); | 428 | tmp = readl(mmio); |
| 429 | if (tmp & PDC_ERR_MASK) { | 429 | if (tmp & PDC_ERR_MASK) { |
| 430 | have_err = 1; | 430 | err_mask = AC_ERR_DEV; |
| 431 | pdc_reset_port(ap); | 431 | pdc_reset_port(ap); |
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | switch (qc->tf.protocol) { | 434 | switch (qc->tf.protocol) { |
| 435 | case ATA_PROT_DMA: | 435 | case ATA_PROT_DMA: |
| 436 | case ATA_PROT_NODATA: | 436 | case ATA_PROT_NODATA: |
| 437 | status = ata_wait_idle(ap); | 437 | err_mask |= ac_err_mask(ata_wait_idle(ap)); |
| 438 | if (have_err) | 438 | ata_qc_complete(qc, err_mask); |
| 439 | status |= ATA_ERR; | ||
| 440 | ata_qc_complete(qc, status); | ||
| 441 | handled = 1; | 439 | handled = 1; |
| 442 | break; | 440 | break; |
| 443 | 441 | ||
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index 1aaf3304d397..d95a02fa7afb 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
| @@ -400,11 +400,12 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set) | |||
| 400 | qc = ata_qc_from_tag(ap, ap->active_tag); | 400 | qc = ata_qc_from_tag(ap, ap->active_tag); |
| 401 | if (qc && (!(qc->tf.ctl & ATA_NIEN))) { | 401 | if (qc && (!(qc->tf.ctl & ATA_NIEN))) { |
| 402 | switch (sHST) { | 402 | switch (sHST) { |
| 403 | case 0: /* sucessful CPB */ | 403 | case 0: /* successful CPB */ |
| 404 | case 3: /* device error */ | 404 | case 3: /* device error */ |
| 405 | pp->state = qs_state_idle; | 405 | pp->state = qs_state_idle; |
| 406 | qs_enter_reg_mode(qc->ap); | 406 | qs_enter_reg_mode(qc->ap); |
| 407 | ata_qc_complete(qc, sDST); | 407 | ata_qc_complete(qc, |
| 408 | ac_err_mask(sDST)); | ||
| 408 | break; | 409 | break; |
| 409 | default: | 410 | default: |
| 410 | break; | 411 | break; |
| @@ -441,7 +442,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) | |||
| 441 | 442 | ||
| 442 | /* complete taskfile transaction */ | 443 | /* complete taskfile transaction */ |
| 443 | pp->state = qs_state_idle; | 444 | pp->state = qs_state_idle; |
| 444 | ata_qc_complete(qc, status); | 445 | ata_qc_complete(qc, ac_err_mask(status)); |
| 445 | handled = 1; | 446 | handled = 1; |
| 446 | } | 447 | } |
| 447 | } | 448 | } |
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index e18a1e2bb65e..4afe2b15b803 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
| @@ -498,7 +498,7 @@ static void sil24_eng_timeout(struct ata_port *ap) | |||
| 498 | 498 | ||
| 499 | qc = ata_qc_from_tag(ap, ap->active_tag); | 499 | qc = ata_qc_from_tag(ap, ap->active_tag); |
| 500 | if (!qc) { | 500 | if (!qc) { |
| 501 | printk(KERN_ERR "ata%u: BUG: tiemout without command\n", | 501 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", |
| 502 | ap->id); | 502 | ap->id); |
| 503 | return; | 503 | return; |
| 504 | } | 504 | } |
| @@ -512,7 +512,7 @@ static void sil24_eng_timeout(struct ata_port *ap) | |||
| 512 | */ | 512 | */ |
| 513 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); | 513 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); |
| 514 | qc->scsidone = scsi_finish_command; | 514 | qc->scsidone = scsi_finish_command; |
| 515 | ata_qc_complete(qc, ATA_ERR); | 515 | ata_qc_complete(qc, AC_ERR_OTHER); |
| 516 | 516 | ||
| 517 | sil24_reset_controller(ap); | 517 | sil24_reset_controller(ap); |
| 518 | } | 518 | } |
| @@ -523,6 +523,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) | |||
| 523 | struct sil24_port_priv *pp = ap->private_data; | 523 | struct sil24_port_priv *pp = ap->private_data; |
| 524 | void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; | 524 | void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; |
| 525 | u32 irq_stat, cmd_err, sstatus, serror; | 525 | u32 irq_stat, cmd_err, sstatus, serror; |
| 526 | unsigned int err_mask; | ||
| 526 | 527 | ||
| 527 | irq_stat = readl(port + PORT_IRQ_STAT); | 528 | irq_stat = readl(port + PORT_IRQ_STAT); |
| 528 | writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */ | 529 | writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */ |
| @@ -550,17 +551,18 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) | |||
| 550 | * Device is reporting error, tf registers are valid. | 551 | * Device is reporting error, tf registers are valid. |
| 551 | */ | 552 | */ |
| 552 | sil24_update_tf(ap); | 553 | sil24_update_tf(ap); |
| 554 | err_mask = ac_err_mask(pp->tf.command); | ||
| 553 | } else { | 555 | } else { |
| 554 | /* | 556 | /* |
| 555 | * Other errors. libata currently doesn't have any | 557 | * Other errors. libata currently doesn't have any |
| 556 | * mechanism to report these errors. Just turn on | 558 | * mechanism to report these errors. Just turn on |
| 557 | * ATA_ERR. | 559 | * ATA_ERR. |
| 558 | */ | 560 | */ |
| 559 | pp->tf.command = ATA_ERR; | 561 | err_mask = AC_ERR_OTHER; |
| 560 | } | 562 | } |
| 561 | 563 | ||
| 562 | if (qc) | 564 | if (qc) |
| 563 | ata_qc_complete(qc, pp->tf.command); | 565 | ata_qc_complete(qc, err_mask); |
| 564 | 566 | ||
| 565 | sil24_reset_controller(ap); | 567 | sil24_reset_controller(ap); |
| 566 | } | 568 | } |
| @@ -585,7 +587,7 @@ static inline void sil24_host_intr(struct ata_port *ap) | |||
| 585 | sil24_update_tf(ap); | 587 | sil24_update_tf(ap); |
| 586 | 588 | ||
| 587 | if (qc) | 589 | if (qc) |
| 588 | ata_qc_complete(qc, pp->tf.command); | 590 | ata_qc_complete(qc, ac_err_mask(pp->tf.command)); |
| 589 | } else | 591 | } else |
| 590 | sil24_error_intr(ap, slot_stat); | 592 | sil24_error_intr(ap, slot_stat); |
| 591 | } | 593 | } |
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index af08f4f650c1..d9a8baff0d4d 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
| @@ -718,7 +718,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, | |||
| 718 | VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id, | 718 | VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id, |
| 719 | readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); | 719 | readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); |
| 720 | /* get drive status; clear intr; complete txn */ | 720 | /* get drive status; clear intr; complete txn */ |
| 721 | ata_qc_complete(qc, ata_wait_idle(ap)); | 721 | ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap))); |
| 722 | pdc20621_pop_hdma(qc); | 722 | pdc20621_pop_hdma(qc); |
| 723 | } | 723 | } |
| 724 | 724 | ||
| @@ -756,7 +756,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, | |||
| 756 | VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id, | 756 | VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id, |
| 757 | readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); | 757 | readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); |
| 758 | /* get drive status; clear intr; complete txn */ | 758 | /* get drive status; clear intr; complete txn */ |
| 759 | ata_qc_complete(qc, ata_wait_idle(ap)); | 759 | ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap))); |
| 760 | pdc20621_pop_hdma(qc); | 760 | pdc20621_pop_hdma(qc); |
| 761 | } | 761 | } |
| 762 | handled = 1; | 762 | handled = 1; |
| @@ -766,7 +766,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, | |||
| 766 | 766 | ||
| 767 | status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); | 767 | status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); |
| 768 | DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); | 768 | DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); |
| 769 | ata_qc_complete(qc, status); | 769 | ata_qc_complete(qc, ac_err_mask(status)); |
| 770 | handled = 1; | 770 | handled = 1; |
| 771 | 771 | ||
| 772 | } else { | 772 | } else { |
| @@ -881,7 +881,7 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
| 881 | case ATA_PROT_DMA: | 881 | case ATA_PROT_DMA: |
| 882 | case ATA_PROT_NODATA: | 882 | case ATA_PROT_NODATA: |
| 883 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); | 883 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); |
| 884 | ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR); | 884 | ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap))); |
| 885 | break; | 885 | break; |
| 886 | 886 | ||
| 887 | default: | 887 | default: |
| @@ -890,7 +890,7 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
| 890 | printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", | 890 | printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", |
| 891 | ap->id, qc->tf.command, drv_stat); | 891 | ap->id, qc->tf.command, drv_stat); |
| 892 | 892 | ||
| 893 | ata_qc_complete(qc, drv_stat); | 893 | ata_qc_complete(qc, ac_err_mask(drv_stat)); |
| 894 | break; | 894 | break; |
| 895 | } | 895 | } |
| 896 | 896 | ||
diff --git a/include/linux/libata.h b/include/linux/libata.h index a4cce9936a80..0ba3af7a1236 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -172,6 +172,13 @@ enum hsm_task_states { | |||
| 172 | HSM_ST_ERR, | 172 | HSM_ST_ERR, |
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | enum ata_completion_errors { | ||
| 176 | AC_ERR_OTHER = (1 << 0), | ||
| 177 | AC_ERR_DEV = (1 << 1), | ||
| 178 | AC_ERR_ATA_BUS = (1 << 2), | ||
| 179 | AC_ERR_HOST_BUS = (1 << 3), | ||
| 180 | }; | ||
| 181 | |||
| 175 | /* forward declarations */ | 182 | /* forward declarations */ |
| 176 | struct scsi_device; | 183 | struct scsi_device; |
| 177 | struct ata_port_operations; | 184 | struct ata_port_operations; |
| @@ -179,7 +186,7 @@ struct ata_port; | |||
| 179 | struct ata_queued_cmd; | 186 | struct ata_queued_cmd; |
| 180 | 187 | ||
| 181 | /* typedefs */ | 188 | /* typedefs */ |
| 182 | typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat); | 189 | typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask); |
| 183 | 190 | ||
| 184 | struct ata_ioports { | 191 | struct ata_ioports { |
| 185 | unsigned long cmd_addr; | 192 | unsigned long cmd_addr; |
| @@ -453,7 +460,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc); | |||
| 453 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); | 460 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); |
| 454 | extern u8 ata_bmdma_status(struct ata_port *ap); | 461 | extern u8 ata_bmdma_status(struct ata_port *ap); |
| 455 | extern void ata_bmdma_irq_clear(struct ata_port *ap); | 462 | extern void ata_bmdma_irq_clear(struct ata_port *ap); |
| 456 | extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat); | 463 | extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask); |
| 457 | extern void ata_eng_timeout(struct ata_port *ap); | 464 | extern void ata_eng_timeout(struct ata_port *ap); |
| 458 | extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd, | 465 | extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd, |
| 459 | void (*done)(struct scsi_cmnd *)); | 466 | void (*done)(struct scsi_cmnd *)); |
| @@ -716,4 +723,21 @@ static inline int ata_try_flush_cache(const struct ata_device *dev) | |||
| 716 | ata_id_has_flush_ext(dev->id); | 723 | ata_id_has_flush_ext(dev->id); |
| 717 | } | 724 | } |
| 718 | 725 | ||
| 726 | static inline unsigned int ac_err_mask(u8 status) | ||
| 727 | { | ||
| 728 | if (status & ATA_BUSY) | ||
| 729 | return AC_ERR_ATA_BUS; | ||
| 730 | if (status & (ATA_ERR | ATA_DF)) | ||
| 731 | return AC_ERR_DEV; | ||
| 732 | return 0; | ||
| 733 | } | ||
| 734 | |||
| 735 | static inline unsigned int __ac_err_mask(u8 status) | ||
| 736 | { | ||
| 737 | unsigned int mask = ac_err_mask(status); | ||
| 738 | if (mask == 0) | ||
| 739 | return AC_ERR_OTHER; | ||
| 740 | return mask; | ||
| 741 | } | ||
| 742 | |||
| 719 | #endif /* __LINUX_LIBATA_H__ */ | 743 | #endif /* __LINUX_LIBATA_H__ */ |
