diff options
-rw-r--r-- | drivers/scsi/ahci.c | 14 | ||||
-rw-r--r-- | drivers/scsi/libata-core.c | 69 | ||||
-rw-r--r-- | drivers/scsi/libata-scsi.c | 24 | ||||
-rw-r--r-- | drivers/scsi/libata.h | 2 | ||||
-rw-r--r-- | drivers/scsi/pdc_adma.c | 11 | ||||
-rw-r--r-- | drivers/scsi/sata_mv.c | 9 | ||||
-rw-r--r-- | drivers/scsi/sata_promise.c | 20 | ||||
-rw-r--r-- | drivers/scsi/sata_qstor.c | 9 | ||||
-rw-r--r-- | drivers/scsi/sata_sil.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sata_sil24.c | 15 | ||||
-rw-r--r-- | drivers/scsi/sata_sx4.c | 17 | ||||
-rw-r--r-- | include/linux/libata.h | 7 |
12 files changed, 124 insertions, 75 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 83467a05dc8..887eaa2a3eb 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -243,7 +243,7 @@ static const struct ata_port_operations ahci_ops = { .port_stop = ahci_port_stop, }; -static struct ata_port_info ahci_port_info[] = { +static const struct ata_port_info ahci_port_info[] = { /* board_ahci */ { .sht = &ahci_sht, @@ -643,7 +643,8 @@ static void ahci_eng_timeout(struct ata_port *ap) * not being called from the SCSI EH. */ qc->scsidone = scsi_finish_command; - ata_qc_complete(qc, AC_ERR_OTHER); + qc->err_mask |= AC_ERR_OTHER; + ata_qc_complete(qc); } spin_unlock_irqrestore(&host_set->lock, flags); @@ -664,7 +665,8 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) ci = readl(port_mmio + PORT_CMD_ISSUE); if (likely((ci & 0x1) == 0)) { if (qc) { - ata_qc_complete(qc, 0); + assert(qc->err_mask == 0); + ata_qc_complete(qc); qc = NULL; } } @@ -681,8 +683,10 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) /* command processing has stopped due to error; restart */ ahci_restart_port(ap, status); - if (qc) - ata_qc_complete(qc, err_mask); + if (qc) { + qc->err_mask |= AC_ERR_OTHER; + ata_qc_complete(qc); + } } return 1; diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index f37cc01e8db..82f566cf75c 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -606,7 +606,7 @@ void ata_rwcmd_protocol(struct ata_queued_cmd *qc) tf->command = ata_rw_cmds[index + lba48 + write]; } -static const char * xfer_mode_str[] = { +static const char * const xfer_mode_str[] = { "UDMA/16", "UDMA/25", "UDMA/33", @@ -1054,9 +1054,9 @@ static int ata_qc_wait_err(struct ata_queued_cmd *qc, if (wait_for_completion_timeout(wait, 30 * HZ) < 1) { /* timeout handling */ - unsigned int err_mask = ac_err_mask(ata_chk_status(qc->ap)); + qc->err_mask |= ac_err_mask(ata_chk_status(qc->ap)); - if (!err_mask) { + if (!qc->err_mask) { printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n", qc->ap->id, qc->tf.command); } else { @@ -1065,7 +1065,7 @@ static int ata_qc_wait_err(struct ata_queued_cmd *qc, rc = -EIO; } - ata_qc_complete(qc, err_mask); + ata_qc_complete(qc); } return rc; @@ -1176,6 +1176,7 @@ retry: qc->cursg_ofs = 0; qc->cursect = 0; qc->nsect = 1; + qc->err_mask = 0; goto retry; } } @@ -2093,7 +2094,7 @@ static void ata_pr_blacklisted(const struct ata_port *ap, ap->id, dev->devno); } -static const char * ata_dma_blacklist [] = { +static const char * const ata_dma_blacklist [] = { "WDC AC11000H", "WDC AC22100H", "WDC AC32500H", @@ -2787,14 +2788,14 @@ skip_map: * None. (grabs host lock) */ -void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) +void ata_poll_qc_complete(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; unsigned long flags; spin_lock_irqsave(&ap->host_set->lock, flags); ata_irq_on(ap); - ata_qc_complete(qc, err_mask); + ata_qc_complete(qc); spin_unlock_irqrestore(&ap->host_set->lock, flags); } @@ -2811,10 +2812,14 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) static unsigned long ata_pio_poll(struct ata_port *ap) { + struct ata_queued_cmd *qc; u8 status; unsigned int poll_state = HSM_ST_UNKNOWN; unsigned int reg_state = HSM_ST_UNKNOWN; + qc = ata_qc_from_tag(ap, ap->active_tag); + assert(qc != NULL); + switch (ap->hsm_task_state) { case HSM_ST: case HSM_ST_POLL: @@ -2834,6 +2839,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap) status = ata_chk_status(ap); if (status & ATA_BUSY) { if (time_after(jiffies, ap->pio_task_timeout)) { + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_TMOUT; return 0; } @@ -2869,29 +2875,31 @@ static int ata_pio_complete (struct ata_port *ap) * msecs, then chk-status again. If still busy, fall back to * HSM_ST_LAST_POLL state. */ - drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10); - if (drv_stat & (ATA_BUSY | ATA_DRQ)) { + drv_stat = ata_busy_wait(ap, ATA_BUSY, 10); + if (drv_stat & ATA_BUSY) { msleep(2); - drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10); - if (drv_stat & (ATA_BUSY | ATA_DRQ)) { + drv_stat = ata_busy_wait(ap, ATA_BUSY, 10); + if (drv_stat & ATA_BUSY) { ap->hsm_task_state = HSM_ST_LAST_POLL; ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; return 1; } } + qc = ata_qc_from_tag(ap, ap->active_tag); + assert(qc != NULL); + drv_stat = ata_wait_idle(ap); if (!ata_ok(drv_stat)) { + qc->err_mask |= __ac_err_mask(drv_stat); ap->hsm_task_state = HSM_ST_ERR; return 1; } - qc = ata_qc_from_tag(ap, ap->active_tag); - assert(qc != NULL); - ap->hsm_task_state = HSM_ST_IDLE; - ata_poll_qc_complete(qc, 0); + assert(qc->err_mask == 0); + ata_poll_qc_complete(qc); /* another command may start at this point */ @@ -3363,6 +3371,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) err_out: printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n", ap->id, dev->devno); + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_ERR; } @@ -3401,8 +3410,16 @@ static void ata_pio_block(struct ata_port *ap) qc = ata_qc_from_tag(ap, ap->active_tag); assert(qc != NULL); + /* check error */ + if (status & (ATA_ERR | ATA_DF)) { + qc->err_mask |= AC_ERR_DEV; + ap->hsm_task_state = HSM_ST_ERR; + return; + } + + /* transfer data if any */ if (is_atapi_taskfile(&qc->tf)) { - /* no more data to transfer or unsupported ATAPI command */ + /* DRQ=0 means no more data to transfer */ if ((status & ATA_DRQ) == 0) { ap->hsm_task_state = HSM_ST_LAST; return; @@ -3412,6 +3429,7 @@ static void ata_pio_block(struct ata_port *ap) } else { /* handle BSY=0, DRQ=0 as error */ if ((status & ATA_DRQ) == 0) { + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_ERR; return; } @@ -3431,9 +3449,14 @@ static void ata_pio_error(struct ata_port *ap) qc = ata_qc_from_tag(ap, ap->active_tag); assert(qc != NULL); + /* make sure qc->err_mask is available to + * know what's wrong and recover + */ + assert(qc->err_mask); + ap->hsm_task_state = HSM_ST_IDLE; - ata_poll_qc_complete(qc, AC_ERR_ATA_BUS); + ata_poll_qc_complete(qc); } static void ata_pio_task(void *_data) @@ -3542,7 +3565,8 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) ap->hsm_task_state = HSM_ST_IDLE; /* complete taskfile transaction */ - ata_qc_complete(qc, ac_err_mask(drv_stat)); + qc->err_mask |= ac_err_mask(drv_stat); + ata_qc_complete(qc); break; } @@ -3641,7 +3665,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, return qc; } -int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask) +int ata_qc_complete_noop(struct ata_queued_cmd *qc) { return 0; } @@ -3700,7 +3724,7 @@ void ata_qc_free(struct ata_queued_cmd *qc) * spin_lock_irqsave(host_set lock) */ -void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) +void ata_qc_complete(struct ata_queued_cmd *qc) { int rc; @@ -3717,7 +3741,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) qc->flags &= ~ATA_QCFLAG_ACTIVE; /* call completion callback */ - rc = qc->complete_fn(qc, err_mask); + rc = qc->complete_fn(qc); /* if callback indicates not to complete command (non-zero), * return immediately @@ -4303,7 +4327,8 @@ fsm_start: ap->hsm_task_state = HSM_ST_IDLE; /* complete taskfile transaction */ - ata_qc_complete(qc, ac_err_mask(status)); + qc->err_mask |= ac_err_mask(status); + ata_qc_complete(qc); break; case HSM_ST_ERR: diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 379e8708976..2aef41112c4 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -418,7 +418,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, int i; /* Based on the 3ware driver translation table */ - static unsigned char sense_table[][4] = { + static const unsigned char sense_table[][4] = { /* BBD|ECC|ID|MAR */ {0xd1, ABORTED_COMMAND, 0x00, 0x00}, // Device busy Aborted command /* BBD|ECC|ID */ @@ -449,7 +449,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, {0x80, MEDIUM_ERROR, 0x11, 0x04}, // Block marked bad Medium error, unrecovered read error {0xFF, 0xFF, 0xFF, 0xFF}, // END mark }; - static unsigned char stat_table[][4] = { + static const unsigned char stat_table[][4] = { /* Must be first because BUSY means no other bits valid */ {0x80, ABORTED_COMMAND, 0x47, 0x00}, // Busy, fake parity for now {0x20, HARDWARE_ERROR, 0x00, 0x00}, // Device fault @@ -1203,12 +1203,11 @@ nothing_to_do: return 1; } -static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, - unsigned int err_mask) +static int ata_scsi_qc_complete(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; u8 *cdb = cmd->cmnd; - int need_sense = (err_mask != 0); + int need_sense = (qc->err_mask != 0); /* For ATA pass thru (SAT) commands, generate a sense block if * user mandated it or if there's an error. Note that if we @@ -1532,7 +1531,7 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf, return 0; } -static const char *inq_83_str = "Linux ATA-SCSI simulator"; +static const char * const inq_83_str = "Linux ATA-SCSI simulator"; /** * ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity @@ -1955,9 +1954,9 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 done(cmd); } -static int atapi_sense_complete(struct ata_queued_cmd *qc,unsigned int err_mask) +static int atapi_sense_complete(struct ata_queued_cmd *qc) { - if (err_mask && ((err_mask & AC_ERR_DEV) == 0)) + if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) /* FIXME: not quite right; we don't want the * translation of taskfile registers into * a sense descriptors, since that's only @@ -2015,15 +2014,18 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) qc->complete_fn = atapi_sense_complete; - if (ata_qc_issue(qc)) - ata_qc_complete(qc, AC_ERR_OTHER); + if (ata_qc_issue(qc)) { + qc->err_mask |= AC_ERR_OTHER; + ata_qc_complete(qc); + } DPRINTK("EXIT\n"); } -static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) +static int atapi_qc_complete(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; + unsigned int err_mask = qc->err_mask; VPRINTK("ENTER, err_mask 0x%X\n", err_mask); diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 8ebaa694d18..686255df76b 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -39,7 +39,7 @@ struct ata_scsi_args { /* libata-core.c */ extern int atapi_enabled; -extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask); +extern int ata_qc_complete_noop(struct ata_queued_cmd *qc); extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, struct ata_device *dev); 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 e254f1e1bb1..4daede86f00 100644 --- a/drivers/scsi/pdc_adma.c +++ b/drivers/scsi/pdc_adma.c @@ -464,14 +464,12 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) continue; qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { - unsigned int err_mask = 0; - if ((status & (aPERR | aPSD | aUIRQ))) - err_mask = AC_ERR_OTHER; + qc->err_mask |= AC_ERR_OTHER; else if (pp->pkt[0] != cDONE) - err_mask = AC_ERR_OTHER; + qc->err_mask |= AC_ERR_OTHER; - ata_qc_complete(qc, err_mask); + ata_qc_complete(qc); } } return handled; @@ -501,7 +499,8 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set) /* complete taskfile transaction */ pp->state = adma_state_idle; - ata_qc_complete(qc, ac_err_mask(status)); + qc->err_mask |= ac_err_mask(status); + ata_qc_complete(qc); handled = 1; } } diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index edd0afa852e..ef148acb5ee 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -431,7 +431,7 @@ static const struct ata_port_operations mv6_ops = { .host_stop = mv_host_stop, }; -static struct ata_port_info mv_port_info[] = { +static const struct ata_port_info mv_port_info[] = { { /* chip_504x */ .sht = &mv_sht, .host_flags = MV_COMMON_FLAGS, @@ -1242,8 +1242,10 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, VPRINTK("port %u IRQ found for qc, " "ata_status 0x%x\n", port,ata_status); /* mark qc status appropriately */ - if (!(qc->tf.flags & ATA_TFLAG_POLLING)) + if (!(qc->tf.flags & ATA_TFLAG_POLLING)) { + qc->err_mask |= err_mask; ata_qc_complete(qc, err_mask); + } } } } @@ -1864,7 +1866,8 @@ static void mv_eng_timeout(struct ata_port *ap) */ spin_lock_irqsave(&ap->host_set->lock, flags); qc->scsidone = scsi_finish_command; - ata_qc_complete(qc, AC_ERR_OTHER); + qc->err_mask |= AC_ERR_OTHER; + ata_qc_complete(qc); spin_unlock_irqrestore(&ap->host_set->lock, flags); } } diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index e9ffc27a049..b4cbc9d6be1 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -158,7 +158,7 @@ static const struct ata_port_operations pdc_pata_ops = { .host_stop = ata_pci_host_stop, }; -static struct ata_port_info pdc_port_info[] = { +static const struct ata_port_info pdc_port_info[] = { /* board_2037x */ { .sht = &pdc_ata_sht, @@ -404,7 +404,8 @@ static void pdc_eng_timeout(struct ata_port *ap) case ATA_PROT_NODATA: printk(KERN_ERR "ata%u: command timeout\n", ap->id); drv_stat = ata_wait_idle(ap); - ata_qc_complete(qc, __ac_err_mask(drv_stat)); + qc->err_mask |= __ac_err_mask(drv_stat); + ata_qc_complete(qc); break; default: @@ -413,7 +414,8 @@ static void pdc_eng_timeout(struct ata_port *ap) printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", ap->id, qc->tf.command, drv_stat); - ata_qc_complete(qc, ac_err_mask(drv_stat)); + qc->err_mask |= ac_err_mask(drv_stat); + ata_qc_complete(qc); break; } @@ -425,21 +427,21 @@ out: static inline unsigned int pdc_host_intr( struct ata_port *ap, struct ata_queued_cmd *qc) { - unsigned int handled = 0, err_mask = 0; + unsigned int handled = 0; u32 tmp; void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL; tmp = readl(mmio); if (tmp & PDC_ERR_MASK) { - err_mask = AC_ERR_DEV; + qc->err_mask |= AC_ERR_DEV; pdc_reset_port(ap); } switch (qc->tf.protocol) { case ATA_PROT_DMA: case ATA_PROT_NODATA: - err_mask |= ac_err_mask(ata_wait_idle(ap)); - ata_qc_complete(qc, err_mask); + qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); + ata_qc_complete(qc); handled = 1; break; @@ -706,7 +708,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e probe_ent->port[3].scr_addr = base + 0x700; break; case board_2037x: - probe_ent->n_ports = 2; + probe_ent->n_ports = 2; break; case board_20619: probe_ent->n_ports = 4; @@ -716,7 +718,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e probe_ent->port[2].scr_addr = base + 0x600; probe_ent->port[3].scr_addr = base + 0x700; - break; + break; default: BUG(); break; diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index 17a39ed6230..6367966941d 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c @@ -170,7 +170,7 @@ static const struct ata_port_operations qs_ata_ops = { .bmdma_status = qs_bmdma_status, }; -static struct ata_port_info qs_port_info[] = { +static const struct ata_port_info qs_port_info[] = { /* board_2068_idx */ { .sht = &qs_ata_sht, @@ -408,8 +408,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set) case 3: /* device error */ pp->state = qs_state_idle; qs_enter_reg_mode(qc->ap); - ata_qc_complete(qc, - ac_err_mask(sDST)); + qc->err_mask |= ac_err_mask(sDST); + ata_qc_complete(qc); break; default: break; @@ -446,7 +446,8 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) /* complete taskfile transaction */ pp->state = qs_state_idle; - ata_qc_complete(qc, ac_err_mask(status)); + qc->err_mask |= ac_err_mask(status); + ata_qc_complete(qc); handled = 1; } } diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 36091868560..d2053487c73 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -176,7 +176,7 @@ static const struct ata_port_operations sil_ops = { .host_stop = ata_pci_host_stop, }; -static struct ata_port_info sil_port_info[] = { +static const struct ata_port_info sil_port_info[] = { /* sil_3112 */ { .sht = &sil_sht, diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index e0d6f194f54..a0ad3ed2200 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -654,7 +654,8 @@ static void sil24_eng_timeout(struct ata_port *ap) */ printk(KERN_ERR "ata%u: command timeout\n", ap->id); qc->scsidone = scsi_finish_command; - ata_qc_complete(qc, AC_ERR_OTHER); + qc->err_mask |= AC_ERR_OTHER; + ata_qc_complete(qc); sil24_reset_controller(ap); } @@ -711,8 +712,10 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) sil24_reset_controller(ap); } - if (qc) - ata_qc_complete(qc, err_mask); + if (qc) { + qc->err_mask |= err_mask; + ata_qc_complete(qc); + } } static inline void sil24_host_intr(struct ata_port *ap) @@ -734,8 +737,10 @@ static inline void sil24_host_intr(struct ata_port *ap) */ sil24_update_tf(ap); - if (qc) - ata_qc_complete(qc, ac_err_mask(pp->tf.command)); + if (qc) { + qc->err_mask |= ac_err_mask(pp->tf.command); + ata_qc_complete(qc); + } } else sil24_error_intr(ap, slot_stat); } diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 2eea6de12d7..a33862d2b63 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c @@ -215,7 +215,7 @@ static const struct ata_port_operations pdc_20621_ops = { .host_stop = pdc20621_host_stop, }; -static struct ata_port_info pdc_port_info[] = { +static const struct ata_port_info pdc_port_info[] = { /* board_20621 */ { .sht = &pdc_sata_sht, @@ -719,7 +719,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* get drive status; clear intr; complete txn */ - ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap))); + qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); + ata_qc_complete(qc); pdc20621_pop_hdma(qc); } @@ -757,7 +758,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* get drive status; clear intr; complete txn */ - ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap))); + qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); + ata_qc_complete(qc); pdc20621_pop_hdma(qc); } handled = 1; @@ -767,7 +769,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); - ata_qc_complete(qc, ac_err_mask(status)); + qc->err_mask |= ac_err_mask(status); + ata_qc_complete(qc); handled = 1; } else { @@ -882,7 +885,8 @@ static void pdc_eng_timeout(struct ata_port *ap) case ATA_PROT_DMA: case ATA_PROT_NODATA: printk(KERN_ERR "ata%u: command timeout\n", ap->id); - ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap))); + qc->err_mask |= __ac_err_mask(ata_wait_idle(ap)); + ata_qc_complete(qc); break; default: @@ -891,7 +895,8 @@ static void pdc_eng_timeout(struct ata_port *ap) printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", ap->id, qc->tf.command, drv_stat); - ata_qc_complete(qc, ac_err_mask(drv_stat)); + qc->err_mask |= ac_err_mask(drv_stat); + ata_qc_complete(qc); break; } diff --git a/include/linux/libata.h b/include/linux/libata.h index 2929282beb4..1be43be5b1d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -197,7 +197,7 @@ struct ata_port; struct ata_queued_cmd; /* typedefs */ -typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask); +typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc); struct ata_ioports { unsigned long cmd_addr; @@ -282,6 +282,8 @@ struct ata_queued_cmd { /* DO NOT iterate over __sg manually, use ata_for_each_sg() */ struct scatterlist *__sg; + unsigned int err_mask; + ata_qc_cb_t complete_fn; struct completion *waiting; @@ -476,7 +478,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc); extern void ata_bmdma_stop(struct ata_queued_cmd *qc); extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); -extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask); +extern void ata_qc_complete(struct ata_queued_cmd *qc); extern void ata_eng_timeout(struct ata_port *ap); extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); @@ -668,6 +670,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) qc->cursect = qc->cursg = qc->cursg_ofs = 0; qc->nsect = 0; qc->nbytes = qc->curbytes = 0; + qc->err_mask = 0; ata_tf_init(qc->ap, &qc->tf, qc->dev->devno); } |