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__ */ |