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 3df74a08fe2..25a47d7afa2 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -608,7 +608,7 @@ static void ahci_eng_timeout(struct ata_port *ap) | |||
608 | * not being called from the SCSI EH. | 608 | * not being called from the SCSI EH. |
609 | */ | 609 | */ |
610 | qc->scsidone = scsi_finish_command; | 610 | qc->scsidone = scsi_finish_command; |
611 | ata_qc_complete(qc, ATA_ERR); | 611 | ata_qc_complete(qc, AC_ERR_OTHER); |
612 | } | 612 | } |
613 | 613 | ||
614 | spin_unlock_irqrestore(&host_set->lock, flags); | 614 | spin_unlock_irqrestore(&host_set->lock, flags); |
@@ -637,7 +637,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
637 | if (status & PORT_IRQ_FATAL) { | 637 | if (status & PORT_IRQ_FATAL) { |
638 | ahci_intr_error(ap, status); | 638 | ahci_intr_error(ap, status); |
639 | if (qc) | 639 | if (qc) |
640 | ata_qc_complete(qc, ATA_ERR); | 640 | ata_qc_complete(qc, AC_ERR_OTHER); |
641 | } | 641 | } |
642 | 642 | ||
643 | return 1; | 643 | return 1; |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 0d58f4d3e5c..6cab14965cc 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -2750,7 +2750,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) | |||
2750 | * None. (grabs host lock) | 2750 | * None. (grabs host lock) |
2751 | */ | 2751 | */ |
2752 | 2752 | ||
2753 | void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 2753 | void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) |
2754 | { | 2754 | { |
2755 | struct ata_port *ap = qc->ap; | 2755 | struct ata_port *ap = qc->ap; |
2756 | unsigned long flags; | 2756 | unsigned long flags; |
@@ -2758,7 +2758,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
2758 | spin_lock_irqsave(&ap->host_set->lock, flags); | 2758 | spin_lock_irqsave(&ap->host_set->lock, flags); |
2759 | ap->flags &= ~ATA_FLAG_NOINTR; | 2759 | ap->flags &= ~ATA_FLAG_NOINTR; |
2760 | ata_irq_on(ap); | 2760 | ata_irq_on(ap); |
2761 | ata_qc_complete(qc, drv_stat); | 2761 | ata_qc_complete(qc, err_mask); |
2762 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | 2762 | spin_unlock_irqrestore(&ap->host_set->lock, flags); |
2763 | } | 2763 | } |
2764 | 2764 | ||
@@ -2855,7 +2855,7 @@ static int ata_pio_complete (struct ata_port *ap) | |||
2855 | 2855 | ||
2856 | ap->hsm_task_state = HSM_ST_IDLE; | 2856 | ap->hsm_task_state = HSM_ST_IDLE; |
2857 | 2857 | ||
2858 | ata_poll_qc_complete(qc, drv_stat); | 2858 | ata_poll_qc_complete(qc, 0); |
2859 | 2859 | ||
2860 | /* another command may start at this point */ | 2860 | /* another command may start at this point */ |
2861 | 2861 | ||
@@ -3223,18 +3223,15 @@ static void ata_pio_block(struct ata_port *ap) | |||
3223 | static void ata_pio_error(struct ata_port *ap) | 3223 | static void ata_pio_error(struct ata_port *ap) |
3224 | { | 3224 | { |
3225 | struct ata_queued_cmd *qc; | 3225 | struct ata_queued_cmd *qc; |
3226 | u8 drv_stat; | 3226 | |
3227 | printk(KERN_WARNING "ata%u: PIO error\n", ap->id); | ||
3227 | 3228 | ||
3228 | qc = ata_qc_from_tag(ap, ap->active_tag); | 3229 | qc = ata_qc_from_tag(ap, ap->active_tag); |
3229 | assert(qc != NULL); | 3230 | assert(qc != NULL); |
3230 | 3231 | ||
3231 | drv_stat = ata_chk_status(ap); | ||
3232 | printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n", | ||
3233 | ap->id, drv_stat); | ||
3234 | |||
3235 | ap->hsm_task_state = HSM_ST_IDLE; | 3232 | ap->hsm_task_state = HSM_ST_IDLE; |
3236 | 3233 | ||
3237 | ata_poll_qc_complete(qc, drv_stat | ATA_ERR); | 3234 | ata_poll_qc_complete(qc, AC_ERR_ATA_BUS); |
3238 | } | 3235 | } |
3239 | 3236 | ||
3240 | static void ata_pio_task(void *_data) | 3237 | static void ata_pio_task(void *_data) |
@@ -3357,7 +3354,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
3357 | ap->id, qc->tf.command, drv_stat, host_stat); | 3354 | ap->id, qc->tf.command, drv_stat, host_stat); |
3358 | 3355 | ||
3359 | /* complete taskfile transaction */ | 3356 | /* complete taskfile transaction */ |
3360 | ata_qc_complete(qc, drv_stat); | 3357 | ata_qc_complete(qc, ac_err_mask(drv_stat)); |
3361 | break; | 3358 | break; |
3362 | } | 3359 | } |
3363 | 3360 | ||
@@ -3462,7 +3459,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | |||
3462 | return qc; | 3459 | return qc; |
3463 | } | 3460 | } |
3464 | 3461 | ||
3465 | int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat) | 3462 | int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask) |
3466 | { | 3463 | { |
3467 | return 0; | 3464 | return 0; |
3468 | } | 3465 | } |
@@ -3521,7 +3518,7 @@ void ata_qc_free(struct ata_queued_cmd *qc) | |||
3521 | * spin_lock_irqsave(host_set lock) | 3518 | * spin_lock_irqsave(host_set lock) |
3522 | */ | 3519 | */ |
3523 | 3520 | ||
3524 | void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 3521 | void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) |
3525 | { | 3522 | { |
3526 | int rc; | 3523 | int rc; |
3527 | 3524 | ||
@@ -3538,7 +3535,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
3538 | qc->flags &= ~ATA_QCFLAG_ACTIVE; | 3535 | qc->flags &= ~ATA_QCFLAG_ACTIVE; |
3539 | 3536 | ||
3540 | /* call completion callback */ | 3537 | /* call completion callback */ |
3541 | rc = qc->complete_fn(qc, drv_stat); | 3538 | rc = qc->complete_fn(qc, err_mask); |
3542 | 3539 | ||
3543 | /* if callback indicates not to complete command (non-zero), | 3540 | /* if callback indicates not to complete command (non-zero), |
3544 | * return immediately | 3541 | * return immediately |
@@ -3976,7 +3973,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, | |||
3976 | ap->ops->irq_clear(ap); | 3973 | ap->ops->irq_clear(ap); |
3977 | 3974 | ||
3978 | /* complete taskfile transaction */ | 3975 | /* complete taskfile transaction */ |
3979 | ata_qc_complete(qc, status); | 3976 | ata_qc_complete(qc, ac_err_mask(status)); |
3980 | break; | 3977 | break; |
3981 | 3978 | ||
3982 | default: | 3979 | default: |
@@ -4071,7 +4068,7 @@ static void atapi_packet_task(void *_data) | |||
4071 | /* sleep-wait for BSY to clear */ | 4068 | /* sleep-wait for BSY to clear */ |
4072 | DPRINTK("busy wait\n"); | 4069 | DPRINTK("busy wait\n"); |
4073 | if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) | 4070 | if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) |
4074 | goto err_out; | 4071 | goto err_out_status; |
4075 | 4072 | ||
4076 | /* make sure DRQ is set */ | 4073 | /* make sure DRQ is set */ |
4077 | status = ata_chk_status(ap); | 4074 | status = ata_chk_status(ap); |
@@ -4108,8 +4105,10 @@ static void atapi_packet_task(void *_data) | |||
4108 | 4105 | ||
4109 | return; | 4106 | return; |
4110 | 4107 | ||
4108 | err_out_status: | ||
4109 | status = ata_chk_status(ap); | ||
4111 | err_out: | 4110 | err_out: |
4112 | ata_poll_qc_complete(qc, ATA_ERR); | 4111 | ata_poll_qc_complete(qc, __ac_err_mask(status)); |
4113 | } | 4112 | } |
4114 | 4113 | ||
4115 | 4114 | ||
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 69058510f43..5574520bf1c 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 | /** |
@@ -1209,10 +1217,12 @@ nothing_to_do: | |||
1209 | return 1; | 1217 | return 1; |
1210 | } | 1218 | } |
1211 | 1219 | ||
1212 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 1220 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, |
1221 | unsigned int err_mask) | ||
1213 | { | 1222 | { |
1214 | struct scsi_cmnd *cmd = qc->scsicmd; | 1223 | struct scsi_cmnd *cmd = qc->scsicmd; |
1215 | int need_sense = drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ); | 1224 | u8 *cdb = cmd->cmnd; |
1225 | int need_sense = (err_mask != 0); | ||
1216 | 1226 | ||
1217 | /* For ATA pass thru (SAT) commands, generate a sense block if | 1227 | /* For ATA pass thru (SAT) commands, generate a sense block if |
1218 | * user mandated it or if there's an error. Note that if we | 1228 | * user mandated it or if there's an error. Note that if we |
@@ -1221,8 +1231,8 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
1221 | * whether the command completed successfully or not. If there | 1231 | * whether the command completed successfully or not. If there |
1222 | * was no error, SK, ASC and ASCQ will all be zero. | 1232 | * was no error, SK, ASC and ASCQ will all be zero. |
1223 | */ | 1233 | */ |
1224 | if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) && | 1234 | if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && |
1225 | ((cmd->cmnd[2] & 0x20) || need_sense)) { | 1235 | ((cdb[2] & 0x20) || need_sense)) { |
1226 | ata_gen_ata_desc_sense(qc); | 1236 | ata_gen_ata_desc_sense(qc); |
1227 | } else { | 1237 | } else { |
1228 | if (!need_sense) { | 1238 | if (!need_sense) { |
@@ -2005,21 +2015,13 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | |||
2005 | DPRINTK("EXIT\n"); | 2015 | DPRINTK("EXIT\n"); |
2006 | } | 2016 | } |
2007 | 2017 | ||
2008 | static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 2018 | static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) |
2009 | { | 2019 | { |
2010 | struct scsi_cmnd *cmd = qc->scsicmd; | 2020 | struct scsi_cmnd *cmd = qc->scsicmd; |
2011 | 2021 | ||
2012 | VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat); | 2022 | VPRINTK("ENTER, err_mask 0x%X\n", err_mask); |
2013 | |||
2014 | if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ))) | ||
2015 | /* FIXME: not quite right; we don't want the | ||
2016 | * translation of taskfile registers into | ||
2017 | * a sense descriptors, since that's only | ||
2018 | * correct for ATA, not ATAPI | ||
2019 | */ | ||
2020 | ata_gen_ata_desc_sense(qc); | ||
2021 | 2023 | ||
2022 | else if (unlikely(drv_stat & ATA_ERR)) { | 2024 | if (unlikely(err_mask & AC_ERR_DEV)) { |
2023 | DPRINTK("request check condition\n"); | 2025 | DPRINTK("request check condition\n"); |
2024 | 2026 | ||
2025 | /* FIXME: command completion with check condition | 2027 | /* FIXME: command completion with check condition |
@@ -2036,6 +2038,14 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
2036 | return 1; | 2038 | return 1; |
2037 | } | 2039 | } |
2038 | 2040 | ||
2041 | else if (unlikely(err_mask)) | ||
2042 | /* FIXME: not quite right; we don't want the | ||
2043 | * translation of taskfile registers into | ||
2044 | * a sense descriptors, since that's only | ||
2045 | * correct for ATA, not ATAPI | ||
2046 | */ | ||
2047 | ata_gen_ata_desc_sense(qc); | ||
2048 | |||
2039 | else { | 2049 | else { |
2040 | u8 *scsicmd = cmd->cmnd; | 2050 | u8 *scsicmd = cmd->cmnd; |
2041 | 2051 | ||
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 65c264b9113..10ecd9e15e4 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 5c0f90677d0..988d0d70a27 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 ad4808ef71d..a3ab14c79cd 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -1066,6 +1066,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1066 | struct ata_queued_cmd *qc; | 1066 | struct ata_queued_cmd *qc; |
1067 | u32 hc_irq_cause; | 1067 | u32 hc_irq_cause; |
1068 | int shift, port, port0, hard_port, handled; | 1068 | int shift, port, port0, hard_port, handled; |
1069 | unsigned int err_mask; | ||
1069 | u8 ata_status = 0; | 1070 | u8 ata_status = 0; |
1070 | 1071 | ||
1071 | if (hc == 0) { | 1072 | if (hc == 0) { |
@@ -1101,15 +1102,15 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1101 | handled++; | 1102 | handled++; |
1102 | } | 1103 | } |
1103 | 1104 | ||
1105 | err_mask = ac_err_mask(ata_status); | ||
1106 | |||
1104 | shift = port << 1; /* (port * 2) */ | 1107 | shift = port << 1; /* (port * 2) */ |
1105 | if (port >= MV_PORTS_PER_HC) { | 1108 | if (port >= MV_PORTS_PER_HC) { |
1106 | shift++; /* skip bit 8 in the HC Main IRQ reg */ | 1109 | shift++; /* skip bit 8 in the HC Main IRQ reg */ |
1107 | } | 1110 | } |
1108 | if ((PORT0_ERR << shift) & relevant) { | 1111 | if ((PORT0_ERR << shift) & relevant) { |
1109 | mv_err_intr(ap); | 1112 | mv_err_intr(ap); |
1110 | /* OR in ATA_ERR to ensure libata knows we took one */ | 1113 | err_mask |= AC_ERR_OTHER; |
1111 | ata_status = readb((void __iomem *) | ||
1112 | ap->ioaddr.status_addr) | ATA_ERR; | ||
1113 | handled++; | 1114 | handled++; |
1114 | } | 1115 | } |
1115 | 1116 | ||
@@ -1119,7 +1120,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1119 | VPRINTK("port %u IRQ found for qc, " | 1120 | VPRINTK("port %u IRQ found for qc, " |
1120 | "ata_status 0x%x\n", port,ata_status); | 1121 | "ata_status 0x%x\n", port,ata_status); |
1121 | /* mark qc status appropriately */ | 1122 | /* mark qc status appropriately */ |
1122 | ata_qc_complete(qc, ata_status); | 1123 | ata_qc_complete(qc, err_mask); |
1123 | } | 1124 | } |
1124 | } | 1125 | } |
1125 | } | 1126 | } |
@@ -1295,7 +1296,7 @@ static void mv_eng_timeout(struct ata_port *ap) | |||
1295 | */ | 1296 | */ |
1296 | spin_lock_irqsave(&ap->host_set->lock, flags); | 1297 | spin_lock_irqsave(&ap->host_set->lock, flags); |
1297 | qc->scsidone = scsi_finish_command; | 1298 | qc->scsidone = scsi_finish_command; |
1298 | ata_qc_complete(qc, ATA_ERR); | 1299 | ata_qc_complete(qc, AC_ERR_OTHER); |
1299 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | 1300 | spin_unlock_irqrestore(&ap->host_set->lock, flags); |
1300 | } | 1301 | } |
1301 | } | 1302 | } |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 63911f16b6e..8f41702275d 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 f2c599f08fa..8c20229b01b 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
@@ -402,11 +402,12 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set) | |||
402 | qc = ata_qc_from_tag(ap, ap->active_tag); | 402 | qc = ata_qc_from_tag(ap, ap->active_tag); |
403 | if (qc && (!(qc->tf.ctl & ATA_NIEN))) { | 403 | if (qc && (!(qc->tf.ctl & ATA_NIEN))) { |
404 | switch (sHST) { | 404 | switch (sHST) { |
405 | case 0: /* sucessful CPB */ | 405 | case 0: /* successful CPB */ |
406 | case 3: /* device error */ | 406 | case 3: /* device error */ |
407 | pp->state = qs_state_idle; | 407 | pp->state = qs_state_idle; |
408 | qs_enter_reg_mode(qc->ap); | 408 | qs_enter_reg_mode(qc->ap); |
409 | ata_qc_complete(qc, sDST); | 409 | ata_qc_complete(qc, |
410 | ac_err_mask(sDST)); | ||
410 | break; | 411 | break; |
411 | default: | 412 | default: |
412 | break; | 413 | break; |
@@ -443,7 +444,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) | |||
443 | 444 | ||
444 | /* complete taskfile transaction */ | 445 | /* complete taskfile transaction */ |
445 | pp->state = qs_state_idle; | 446 | pp->state = qs_state_idle; |
446 | ata_qc_complete(qc, status); | 447 | ata_qc_complete(qc, ac_err_mask(status)); |
447 | handled = 1; | 448 | handled = 1; |
448 | } | 449 | } |
449 | } | 450 | } |
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 7e6e5c049b7..05ce84286ae 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -503,7 +503,7 @@ static void sil24_eng_timeout(struct ata_port *ap) | |||
503 | 503 | ||
504 | qc = ata_qc_from_tag(ap, ap->active_tag); | 504 | qc = ata_qc_from_tag(ap, ap->active_tag); |
505 | if (!qc) { | 505 | if (!qc) { |
506 | printk(KERN_ERR "ata%u: BUG: tiemout without command\n", | 506 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", |
507 | ap->id); | 507 | ap->id); |
508 | return; | 508 | return; |
509 | } | 509 | } |
@@ -517,7 +517,7 @@ static void sil24_eng_timeout(struct ata_port *ap) | |||
517 | */ | 517 | */ |
518 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); | 518 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); |
519 | qc->scsidone = scsi_finish_command; | 519 | qc->scsidone = scsi_finish_command; |
520 | ata_qc_complete(qc, ATA_ERR); | 520 | ata_qc_complete(qc, AC_ERR_OTHER); |
521 | 521 | ||
522 | sil24_reset_controller(ap); | 522 | sil24_reset_controller(ap); |
523 | } | 523 | } |
@@ -528,6 +528,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) | |||
528 | struct sil24_port_priv *pp = ap->private_data; | 528 | struct sil24_port_priv *pp = ap->private_data; |
529 | void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; | 529 | void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; |
530 | u32 irq_stat, cmd_err, sstatus, serror; | 530 | u32 irq_stat, cmd_err, sstatus, serror; |
531 | unsigned int err_mask; | ||
531 | 532 | ||
532 | irq_stat = readl(port + PORT_IRQ_STAT); | 533 | irq_stat = readl(port + PORT_IRQ_STAT); |
533 | writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */ | 534 | writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */ |
@@ -555,17 +556,18 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) | |||
555 | * Device is reporting error, tf registers are valid. | 556 | * Device is reporting error, tf registers are valid. |
556 | */ | 557 | */ |
557 | sil24_update_tf(ap); | 558 | sil24_update_tf(ap); |
559 | err_mask = ac_err_mask(pp->tf.command); | ||
558 | } else { | 560 | } else { |
559 | /* | 561 | /* |
560 | * Other errors. libata currently doesn't have any | 562 | * Other errors. libata currently doesn't have any |
561 | * mechanism to report these errors. Just turn on | 563 | * mechanism to report these errors. Just turn on |
562 | * ATA_ERR. | 564 | * ATA_ERR. |
563 | */ | 565 | */ |
564 | pp->tf.command = ATA_ERR; | 566 | err_mask = AC_ERR_OTHER; |
565 | } | 567 | } |
566 | 568 | ||
567 | if (qc) | 569 | if (qc) |
568 | ata_qc_complete(qc, pp->tf.command); | 570 | ata_qc_complete(qc, err_mask); |
569 | 571 | ||
570 | sil24_reset_controller(ap); | 572 | sil24_reset_controller(ap); |
571 | } | 573 | } |
@@ -590,7 +592,7 @@ static inline void sil24_host_intr(struct ata_port *ap) | |||
590 | sil24_update_tf(ap); | 592 | sil24_update_tf(ap); |
591 | 593 | ||
592 | if (qc) | 594 | if (qc) |
593 | ata_qc_complete(qc, pp->tf.command); | 595 | ata_qc_complete(qc, ac_err_mask(pp->tf.command)); |
594 | } else | 596 | } else |
595 | sil24_error_intr(ap, slot_stat); | 597 | sil24_error_intr(ap, slot_stat); |
596 | } | 598 | } |
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 8710d0f14f9..8e2e7b8308c 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
@@ -717,7 +717,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, | |||
717 | VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id, | 717 | VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id, |
718 | readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); | 718 | readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); |
719 | /* get drive status; clear intr; complete txn */ | 719 | /* get drive status; clear intr; complete txn */ |
720 | ata_qc_complete(qc, ata_wait_idle(ap)); | 720 | ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap))); |
721 | pdc20621_pop_hdma(qc); | 721 | pdc20621_pop_hdma(qc); |
722 | } | 722 | } |
723 | 723 | ||
@@ -755,7 +755,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, | |||
755 | VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id, | 755 | VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id, |
756 | readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); | 756 | readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); |
757 | /* get drive status; clear intr; complete txn */ | 757 | /* get drive status; clear intr; complete txn */ |
758 | ata_qc_complete(qc, ata_wait_idle(ap)); | 758 | ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap))); |
759 | pdc20621_pop_hdma(qc); | 759 | pdc20621_pop_hdma(qc); |
760 | } | 760 | } |
761 | handled = 1; | 761 | handled = 1; |
@@ -765,7 +765,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, | |||
765 | 765 | ||
766 | status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); | 766 | status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); |
767 | DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); | 767 | DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); |
768 | ata_qc_complete(qc, status); | 768 | ata_qc_complete(qc, ac_err_mask(status)); |
769 | handled = 1; | 769 | handled = 1; |
770 | 770 | ||
771 | } else { | 771 | } else { |
@@ -880,7 +880,7 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
880 | case ATA_PROT_DMA: | 880 | case ATA_PROT_DMA: |
881 | case ATA_PROT_NODATA: | 881 | case ATA_PROT_NODATA: |
882 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); | 882 | printk(KERN_ERR "ata%u: command timeout\n", ap->id); |
883 | ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR); | 883 | ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap))); |
884 | break; | 884 | break; |
885 | 885 | ||
886 | default: | 886 | default: |
@@ -889,7 +889,7 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
889 | printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", | 889 | printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", |
890 | ap->id, qc->tf.command, drv_stat); | 890 | ap->id, qc->tf.command, drv_stat); |
891 | 891 | ||
892 | ata_qc_complete(qc, drv_stat); | 892 | ata_qc_complete(qc, ac_err_mask(drv_stat)); |
893 | break; | 893 | break; |
894 | } | 894 | } |
895 | 895 | ||
diff --git a/include/linux/libata.h b/include/linux/libata.h index 364cd11456f..6225b78fa65 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -176,6 +176,13 @@ enum hsm_task_states { | |||
176 | HSM_ST_ERR, | 176 | HSM_ST_ERR, |
177 | }; | 177 | }; |
178 | 178 | ||
179 | enum ata_completion_errors { | ||
180 | AC_ERR_OTHER = (1 << 0), | ||
181 | AC_ERR_DEV = (1 << 1), | ||
182 | AC_ERR_ATA_BUS = (1 << 2), | ||
183 | AC_ERR_HOST_BUS = (1 << 3), | ||
184 | }; | ||
185 | |||
179 | /* forward declarations */ | 186 | /* forward declarations */ |
180 | struct scsi_device; | 187 | struct scsi_device; |
181 | struct ata_port_operations; | 188 | struct ata_port_operations; |
@@ -183,7 +190,7 @@ struct ata_port; | |||
183 | struct ata_queued_cmd; | 190 | struct ata_queued_cmd; |
184 | 191 | ||
185 | /* typedefs */ | 192 | /* typedefs */ |
186 | typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat); | 193 | typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask); |
187 | 194 | ||
188 | struct ata_ioports { | 195 | struct ata_ioports { |
189 | unsigned long cmd_addr; | 196 | unsigned long cmd_addr; |
@@ -465,7 +472,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc); | |||
465 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); | 472 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); |
466 | extern u8 ata_bmdma_status(struct ata_port *ap); | 473 | extern u8 ata_bmdma_status(struct ata_port *ap); |
467 | extern void ata_bmdma_irq_clear(struct ata_port *ap); | 474 | extern void ata_bmdma_irq_clear(struct ata_port *ap); |
468 | extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat); | 475 | extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask); |
469 | extern void ata_eng_timeout(struct ata_port *ap); | 476 | extern void ata_eng_timeout(struct ata_port *ap); |
470 | extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd, | 477 | extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd, |
471 | void (*done)(struct scsi_cmnd *)); | 478 | void (*done)(struct scsi_cmnd *)); |
@@ -753,4 +760,21 @@ static inline int ata_try_flush_cache(const struct ata_device *dev) | |||
753 | ata_id_has_flush_ext(dev->id); | 760 | ata_id_has_flush_ext(dev->id); |
754 | } | 761 | } |
755 | 762 | ||
763 | static inline unsigned int ac_err_mask(u8 status) | ||
764 | { | ||
765 | if (status & ATA_BUSY) | ||
766 | return AC_ERR_ATA_BUS; | ||
767 | if (status & (ATA_ERR | ATA_DF)) | ||
768 | return AC_ERR_DEV; | ||
769 | return 0; | ||
770 | } | ||
771 | |||
772 | static inline unsigned int __ac_err_mask(u8 status) | ||
773 | { | ||
774 | unsigned int mask = ac_err_mask(status); | ||
775 | if (mask == 0) | ||
776 | return AC_ERR_OTHER; | ||
777 | return mask; | ||
778 | } | ||
779 | |||
756 | #endif /* __LINUX_LIBATA_H__ */ | 780 | #endif /* __LINUX_LIBATA_H__ */ |