Commit a22e2eb0 authored by Albert Lee's avatar Albert Lee Committed by Jeff Garzik

[PATCH] libata: move err_mask to ata_queued_cmd

  - remove err_mask from the parameter list of the complete functions
  - move err_mask to ata_queued_cmd
  - initialize qc->err_mask when needed
  - for each function call to ata_qc_complete(), replace the err_mask parameter with qc->err_mask.
Signed-off-by: default avatarAlbert Lee <albertcc@tw.ibm.com>

===============
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent c14b8331
...@@ -643,7 +643,8 @@ static void ahci_eng_timeout(struct ata_port *ap) ...@@ -643,7 +643,8 @@ static void ahci_eng_timeout(struct ata_port *ap)
* not being called from the SCSI EH. * not being called from the SCSI EH.
*/ */
qc->scsidone = scsi_finish_command; 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); 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) ...@@ -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); ci = readl(port_mmio + PORT_CMD_ISSUE);
if (likely((ci & 0x1) == 0)) { if (likely((ci & 0x1) == 0)) {
if (qc) { if (qc) {
ata_qc_complete(qc, 0); assert(qc->err_mask == 0);
ata_qc_complete(qc);
qc = NULL; qc = NULL;
} }
} }
...@@ -681,8 +683,10 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) ...@@ -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 */ /* command processing has stopped due to error; restart */
ahci_restart_port(ap, status); ahci_restart_port(ap, status);
if (qc) if (qc) {
ata_qc_complete(qc, err_mask); qc->err_mask |= AC_ERR_OTHER;
ata_qc_complete(qc);
}
} }
return 1; return 1;
......
...@@ -1053,9 +1053,9 @@ static int ata_qc_wait_err(struct ata_queued_cmd *qc, ...@@ -1053,9 +1053,9 @@ static int ata_qc_wait_err(struct ata_queued_cmd *qc,
if (wait_for_completion_timeout(wait, 30 * HZ) < 1) { if (wait_for_completion_timeout(wait, 30 * HZ) < 1) {
/* timeout handling */ /* 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", printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n",
qc->ap->id, qc->tf.command); qc->ap->id, qc->tf.command);
} else { } else {
...@@ -1064,7 +1064,7 @@ static int ata_qc_wait_err(struct ata_queued_cmd *qc, ...@@ -1064,7 +1064,7 @@ static int ata_qc_wait_err(struct ata_queued_cmd *qc,
rc = -EIO; rc = -EIO;
} }
ata_qc_complete(qc, err_mask); ata_qc_complete(qc);
} }
return rc; return rc;
...@@ -1175,6 +1175,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device) ...@@ -1175,6 +1175,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
qc->cursg_ofs = 0; qc->cursg_ofs = 0;
qc->cursect = 0; qc->cursect = 0;
qc->nsect = 1; qc->nsect = 1;
qc->err_mask = 0;
goto retry; goto retry;
} }
} }
...@@ -2777,7 +2778,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) ...@@ -2777,7 +2778,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
* None. (grabs host lock) * 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; struct ata_port *ap = qc->ap;
unsigned long flags; unsigned long flags;
...@@ -2785,7 +2786,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) ...@@ -2785,7 +2786,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
spin_lock_irqsave(&ap->host_set->lock, flags); spin_lock_irqsave(&ap->host_set->lock, flags);
ap->flags &= ~ATA_FLAG_NOINTR; ap->flags &= ~ATA_FLAG_NOINTR;
ata_irq_on(ap); ata_irq_on(ap);
ata_qc_complete(qc, err_mask); ata_qc_complete(qc);
spin_unlock_irqrestore(&ap->host_set->lock, flags); spin_unlock_irqrestore(&ap->host_set->lock, flags);
} }
...@@ -2885,7 +2886,8 @@ static int ata_pio_complete (struct ata_port *ap) ...@@ -2885,7 +2886,8 @@ static int ata_pio_complete (struct ata_port *ap)
ap->hsm_task_state = HSM_ST_IDLE; 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 */ /* another command may start at this point */
...@@ -3261,7 +3263,8 @@ static void ata_pio_error(struct ata_port *ap) ...@@ -3261,7 +3263,8 @@ static void ata_pio_error(struct ata_port *ap)
ap->hsm_task_state = HSM_ST_IDLE; ap->hsm_task_state = HSM_ST_IDLE;
ata_poll_qc_complete(qc, AC_ERR_ATA_BUS); qc->err_mask |= AC_ERR_ATA_BUS;
ata_poll_qc_complete(qc);
} }
static void ata_pio_task(void *_data) static void ata_pio_task(void *_data)
...@@ -3363,7 +3366,8 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) ...@@ -3363,7 +3366,8 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
ap->id, qc->tf.command, drv_stat, host_stat); ap->id, qc->tf.command, drv_stat, host_stat);
/* complete taskfile transaction */ /* 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; break;
} }
...@@ -3462,7 +3466,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, ...@@ -3462,7 +3466,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
return qc; 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; return 0;
} }
...@@ -3521,7 +3525,7 @@ void ata_qc_free(struct ata_queued_cmd *qc) ...@@ -3521,7 +3525,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
* spin_lock_irqsave(host_set lock) * 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; int rc;
...@@ -3538,7 +3542,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) ...@@ -3538,7 +3542,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
qc->flags &= ~ATA_QCFLAG_ACTIVE; qc->flags &= ~ATA_QCFLAG_ACTIVE;
/* call completion callback */ /* call completion callback */
rc = qc->complete_fn(qc, err_mask); rc = qc->complete_fn(qc);
/* if callback indicates not to complete command (non-zero), /* if callback indicates not to complete command (non-zero),
* return immediately * return immediately
...@@ -3976,7 +3980,8 @@ inline unsigned int ata_host_intr (struct ata_port *ap, ...@@ -3976,7 +3980,8 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
ap->ops->irq_clear(ap); ap->ops->irq_clear(ap);
/* complete taskfile transaction */ /* complete taskfile transaction */
ata_qc_complete(qc, ac_err_mask(status)); qc->err_mask |= ac_err_mask(status);
ata_qc_complete(qc);
break; break;
default: default:
...@@ -4111,7 +4116,8 @@ static void atapi_packet_task(void *_data) ...@@ -4111,7 +4116,8 @@ static void atapi_packet_task(void *_data)
err_out_status: err_out_status:
status = ata_chk_status(ap); status = ata_chk_status(ap);
err_out: err_out:
ata_poll_qc_complete(qc, __ac_err_mask(status)); qc->err_mask |= __ac_err_mask(status);
ata_poll_qc_complete(qc);
} }
......
...@@ -1203,12 +1203,11 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm ...@@ -1203,12 +1203,11 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
return 1; return 1;
} }
static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, static int ata_scsi_qc_complete(struct ata_queued_cmd *qc)
unsigned int err_mask)
{ {
struct scsi_cmnd *cmd = qc->scsicmd; struct scsi_cmnd *cmd = qc->scsicmd;
u8 *cdb = cmd->cmnd; 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 /* For ATA pass thru (SAT) commands, generate a sense block if
* user mandated it or if there's an error. Note that if we * user mandated it or if there's an error. Note that if we
...@@ -1955,9 +1954,9 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 ...@@ -1955,9 +1954,9 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8
done(cmd); 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 /* FIXME: not quite right; we don't want the
* translation of taskfile registers into * translation of taskfile registers into
* a sense descriptors, since that's only * a sense descriptors, since that's only
...@@ -2015,15 +2014,18 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) ...@@ -2015,15 +2014,18 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
qc->complete_fn = atapi_sense_complete; qc->complete_fn = atapi_sense_complete;
if (ata_qc_issue(qc)) if (ata_qc_issue(qc)) {
ata_qc_complete(qc, AC_ERR_OTHER); qc->err_mask |= AC_ERR_OTHER;
ata_qc_complete(qc);
}
DPRINTK("EXIT\n"); 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; struct scsi_cmnd *cmd = qc->scsicmd;
unsigned int err_mask = qc->err_mask;
VPRINTK("ENTER, err_mask 0x%X\n", err_mask); VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
......
...@@ -39,7 +39,7 @@ struct ata_scsi_args { ...@@ -39,7 +39,7 @@ struct ata_scsi_args {
/* libata-core.c */ /* libata-core.c */
extern int atapi_enabled; 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, extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev); struct ata_device *dev);
extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc); extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
......
...@@ -464,14 +464,12 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) ...@@ -464,14 +464,12 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
continue; continue;
qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && (!(qc->tf.ctl & ATA_NIEN))) { if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
unsigned int err_mask = 0;
if ((status & (aPERR | aPSD | aUIRQ))) if ((status & (aPERR | aPSD | aUIRQ)))
err_mask = AC_ERR_OTHER; qc->err_mask |= AC_ERR_OTHER;
else if (pp->pkt[0] != cDONE) 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; return handled;
...@@ -501,7 +499,8 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set) ...@@ -501,7 +499,8 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
/* complete taskfile transaction */ /* complete taskfile transaction */
pp->state = adma_state_idle; 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; handled = 1;
} }
} }
......
...@@ -1242,8 +1242,10 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, ...@@ -1242,8 +1242,10 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
VPRINTK("port %u IRQ found for qc, " VPRINTK("port %u IRQ found for qc, "
"ata_status 0x%x\n", port,ata_status); "ata_status 0x%x\n", port,ata_status);
/* mark qc status appropriately */ /* mark qc status appropriately */
if (!(qc->tf.ctl & ATA_NIEN)) if (!(qc->tf.ctl & ATA_NIEN)) {
ata_qc_complete(qc, err_mask); qc->err_mask |= err_mask;
ata_qc_complete(qc);
}
} }
} }
} }
...@@ -1864,7 +1866,8 @@ static void mv_eng_timeout(struct ata_port *ap) ...@@ -1864,7 +1866,8 @@ static void mv_eng_timeout(struct ata_port *ap)
*/ */
spin_lock_irqsave(&ap->host_set->lock, flags); spin_lock_irqsave(&ap->host_set->lock, flags);
qc->scsidone = scsi_finish_command; 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); spin_unlock_irqrestore(&ap->host_set->lock, flags);
} }
} }
......
...@@ -401,7 +401,8 @@ static void pdc_eng_timeout(struct ata_port *ap) ...@@ -401,7 +401,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
case ATA_PROT_NODATA: case ATA_PROT_NODATA:
printk(KERN_ERR "ata%u: command timeout\n", ap->id); printk(KERN_ERR "ata%u: command timeout\n", ap->id);
drv_stat = ata_wait_idle(ap); 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; break;
default: default:
...@@ -410,7 +411,8 @@ static void pdc_eng_timeout(struct ata_port *ap) ...@@ -410,7 +411,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
ap->id, qc->tf.command, drv_stat); 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; break;
} }
...@@ -422,21 +424,21 @@ static void pdc_eng_timeout(struct ata_port *ap) ...@@ -422,21 +424,21 @@ static void pdc_eng_timeout(struct ata_port *ap)
static inline unsigned int pdc_host_intr( struct ata_port *ap, static inline unsigned int pdc_host_intr( struct ata_port *ap,
struct ata_queued_cmd *qc) struct ata_queued_cmd *qc)
{ {
unsigned int handled = 0, err_mask = 0; unsigned int handled = 0;
u32 tmp; u32 tmp;
void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL; void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
tmp = readl(mmio); tmp = readl(mmio);
if (tmp & PDC_ERR_MASK) { if (tmp & PDC_ERR_MASK) {
err_mask = AC_ERR_DEV; qc->err_mask |= AC_ERR_DEV;
pdc_reset_port(ap); pdc_reset_port(ap);
} }
switch (qc->tf.protocol) { switch (qc->tf.protocol) {
case ATA_PROT_DMA: case ATA_PROT_DMA:
case ATA_PROT_NODATA: case ATA_PROT_NODATA:
err_mask |= ac_err_mask(ata_wait_idle(ap)); qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
ata_qc_complete(qc, err_mask); ata_qc_complete(qc);
handled = 1; handled = 1;
break; break;
......
...@@ -409,8 +409,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set) ...@@ -409,8 +409,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set)
case 3: /* device error */ case 3: /* device error */
pp->state = qs_state_idle; pp->state = qs_state_idle;
qs_enter_reg_mode(qc->ap); qs_enter_reg_mode(qc->ap);
ata_qc_complete(qc, qc->err_mask |= ac_err_mask(sDST);
ac_err_mask(sDST)); ata_qc_complete(qc);
break; break;
default: default:
break; break;
...@@ -447,7 +447,8 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) ...@@ -447,7 +447,8 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
/* complete taskfile transaction */ /* complete taskfile transaction */
pp->state = qs_state_idle; 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; handled = 1;
} }
} }
......
...@@ -654,7 +654,8 @@ static void sil24_eng_timeout(struct ata_port *ap) ...@@ -654,7 +654,8 @@ static void sil24_eng_timeout(struct ata_port *ap)
*/ */
printk(KERN_ERR "ata%u: command timeout\n", ap->id); printk(KERN_ERR "ata%u: command timeout\n", ap->id);
qc->scsidone = scsi_finish_command; 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); sil24_reset_controller(ap);
} }
...@@ -711,8 +712,10 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) ...@@ -711,8 +712,10 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
sil24_reset_controller(ap); sil24_reset_controller(ap);
} }
if (qc) if (qc) {
ata_qc_complete(qc, err_mask); qc->err_mask |= err_mask;
ata_qc_complete(qc);
}
} }
static inline void sil24_host_intr(struct ata_port *ap) static inline void sil24_host_intr(struct ata_port *ap)
...@@ -734,8 +737,10 @@ 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); sil24_update_tf(ap);
if (qc) if (qc) {
ata_qc_complete(qc, ac_err_mask(pp->tf.command)); qc->err_mask |= ac_err_mask(pp->tf.command);
ata_qc_complete(qc);
}
} else } else
sil24_error_intr(ap, slot_stat); sil24_error_intr(ap, slot_stat);
} }
......
...@@ -718,7 +718,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, ...@@ -718,7 +718,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id, VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
/* get drive status; clear intr; complete txn */ /* 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); pdc20621_pop_hdma(qc);
} }
...@@ -756,7 +757,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, ...@@ -756,7 +757,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id, VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
/* get drive status; clear intr; complete txn */ /* 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); pdc20621_pop_hdma(qc);
} }
handled = 1; handled = 1;
...@@ -766,7 +768,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, ...@@ -766,7 +768,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); 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; handled = 1;
} else { } else {
...@@ -881,7 +884,8 @@ static void pdc_eng_timeout(struct ata_port *ap) ...@@ -881,7 +884,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
case ATA_PROT_DMA: case ATA_PROT_DMA:
case ATA_PROT_NODATA: case ATA_PROT_NODATA:
printk(KERN_ERR "ata%u: command timeout\n", ap->id); 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; break;
default: default:
...@@ -890,7 +894,8 @@ static void pdc_eng_timeout(struct ata_port *ap) ...@@ -890,7 +894,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
ap->id, qc->tf.command, drv_stat); 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; break;
} }
......
...@@ -194,7 +194,7 @@ struct ata_port; ...@@ -194,7 +194,7 @@ struct ata_port;
struct ata_queued_cmd; struct ata_queued_cmd;
/* typedefs */ /* 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 { struct ata_ioports {
unsigned long cmd_addr; unsigned long cmd_addr;
...@@ -279,6 +279,8 @@ struct ata_queued_cmd { ...@@ -279,6 +279,8 @@ struct ata_queued_cmd {
/* DO NOT iterate over __sg manually, use ata_for_each_sg() */ /* DO NOT iterate over __sg manually, use ata_for_each_sg() */
struct scatterlist *__sg; struct scatterlist *__sg;
unsigned int err_mask;
ata_qc_cb_t complete_fn; ata_qc_cb_t complete_fn;
struct completion *waiting; struct completion *waiting;
...@@ -475,7 +477,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc); ...@@ -475,7 +477,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc);
extern void ata_bmdma_stop(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 u8 ata_bmdma_status(struct ata_port *ap);
extern void ata_bmdma_irq_clear(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_eng_timeout(struct ata_port *ap);
extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd, extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *)); void (*done)(struct scsi_cmnd *));
...@@ -667,6 +669,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) ...@@ -667,6 +669,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
qc->cursect = qc->cursg = qc->cursg_ofs = 0; qc->cursect = qc->cursg = qc->cursg_ofs = 0;
qc->nsect = 0; qc->nsect = 0;
qc->nbytes = qc->curbytes = 0; qc->nbytes = qc->curbytes = 0;
qc->err_mask = 0;
ata_tf_init(qc->ap, &qc->tf, qc->dev->devno); ata_tf_init(qc->ap, &qc->tf, qc->dev->devno);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment