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 3df74a08fe22..25a47d7afa28 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 0d58f4d3e5ce..6cab14965cc8 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 69058510f43a..5574520bf1c2 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 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 5c0f90677d00..988d0d70a277 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 ad4808ef71d4..a3ab14c79cdd 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 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 f2c599f08fa2..8c20229b01b4 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 7e6e5c049b7d..05ce84286aea 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 8710d0f14f93..8e2e7b8308c0 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 364cd11456f6..6225b78fa65b 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__ */ |
