Commit ea54763f authored by Tejun Heo's avatar Tejun Heo

[PATCH] libata: move BMDMA host status recording from EH to interrupt handler

For certain errors, interrupt handler alter BMDMA host status before
entering EH (clears active and intr).  Thus altered BMDMA host status
value is recorded by BMDMA EH and reported to user.  Move BMDMA host
status recording from EH to interrupt handler.
Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
parent f84e7e41
...@@ -4937,6 +4937,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) ...@@ -4937,6 +4937,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
inline unsigned int ata_host_intr (struct ata_port *ap, inline unsigned int ata_host_intr (struct ata_port *ap,
struct ata_queued_cmd *qc) struct ata_queued_cmd *qc)
{ {
struct ata_eh_info *ehi = &ap->eh_info;
u8 status, host_stat = 0; u8 status, host_stat = 0;
VPRINTK("ata%u: protocol %d task_state %d\n", VPRINTK("ata%u: protocol %d task_state %d\n",
...@@ -4997,6 +4998,11 @@ inline unsigned int ata_host_intr (struct ata_port *ap, ...@@ -4997,6 +4998,11 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
ap->ops->irq_clear(ap); ap->ops->irq_clear(ap);
ata_hsm_move(ap, qc, status, 0); ata_hsm_move(ap, qc, status, 0);
if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
qc->tf.protocol == ATA_PROT_ATAPI_DMA))
ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
return 1; /* irq handled */ return 1; /* irq handled */
idle_irq: idle_irq:
......
...@@ -743,7 +743,6 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ...@@ -743,7 +743,6 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
ata_postreset_fn_t postreset) ata_postreset_fn_t postreset)
{ {
struct ata_eh_context *ehc = &ap->eh_context;
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
unsigned long flags; unsigned long flags;
int thaw = 0; int thaw = 0;
...@@ -763,8 +762,6 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ...@@ -763,8 +762,6 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
host_stat = ap->ops->bmdma_status(ap); host_stat = ap->ops->bmdma_status(ap);
ata_ehi_push_desc(&ehc->i, "BMDMA stat 0x%x", host_stat);
/* BMDMA controllers indicate host bus error by /* BMDMA controllers indicate host bus error by
* setting DMA_ERR bit and timing out. As it wasn't * setting DMA_ERR bit and timing out. As it wasn't
* really a timeout event, adjust error mask and * really a timeout event, adjust error mask and
......
...@@ -356,6 +356,7 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) ...@@ -356,6 +356,7 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
static void sil_host_intr(struct ata_port *ap, u32 bmdma2) static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
{ {
struct ata_eh_info *ehi = &ap->eh_info;
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
u8 status; u8 status;
...@@ -428,6 +429,10 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) ...@@ -428,6 +429,10 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
/* kick HSM in the ass */ /* kick HSM in the ass */
ata_hsm_move(ap, qc, status, 0); ata_hsm_move(ap, qc, status, 0);
if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
qc->tf.protocol == ATA_PROT_ATAPI_DMA))
ata_ehi_push_desc(ehi, "BMDMA2 stat 0x%x", bmdma2);
return; return;
err_hsm: err_hsm:
......
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