Commit a21a84a3 authored by Jeff Garzik's avatar Jeff Garzik

[libata pdc_adma] minor fixes and cleanups

Changes mostly from Mark Lord.

- fix bugs in probe-time error handling
- only complete qc if not NULL
- check port-level polling flags
parent 96b88fb8
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "pdc_adma" #define DRV_NAME "pdc_adma"
#define DRV_VERSION "0.01" #define DRV_VERSION "0.03"
/* macro to calculate base address for ATA regs */ /* macro to calculate base address for ATA regs */
#define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40)) #define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40))
...@@ -79,7 +79,6 @@ enum { ...@@ -79,7 +79,6 @@ enum {
aNIEN = (1 << 8), /* irq mask: 1==masked */ aNIEN = (1 << 8), /* irq mask: 1==masked */
aGO = (1 << 7), /* packet trigger ("Go!") */ aGO = (1 << 7), /* packet trigger ("Go!") */
aRSTADM = (1 << 5), /* ADMA logic reset */ aRSTADM = (1 << 5), /* ADMA logic reset */
aRSTA = (1 << 2), /* ATA hard reset */
aPIOMD4 = 0x0003, /* PIO mode 4 */ aPIOMD4 = 0x0003, /* PIO mode 4 */
/* ADMA_STATUS register bits */ /* ADMA_STATUS register bits */
...@@ -452,24 +451,25 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) ...@@ -452,24 +451,25 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
struct adma_port_priv *pp; struct adma_port_priv *pp;
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
void __iomem *chan = ADMA_REGS(mmio_base, port_no); void __iomem *chan = ADMA_REGS(mmio_base, port_no);
u8 drv_stat, status = readb(chan + ADMA_STATUS); u8 drv_stat = 0, status = readb(chan + ADMA_STATUS);
if (status == 0) if (status == 0)
continue; continue;
handled = 1; handled = 1;
adma_enter_reg_mode(ap); adma_enter_reg_mode(ap);
if ((ap->flags & ATA_FLAG_PORT_DISABLED)) if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))
continue; continue;
pp = ap->private_data; pp = ap->private_data;
if (!pp || pp->state != adma_state_pkt) if (!pp || pp->state != adma_state_pkt)
continue; continue;
qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag);
drv_stat = 0; if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
if ((status & (aPERR | aPSD | aUIRQ))) if ((status & (aPERR | aPSD | aUIRQ)))
drv_stat = ATA_ERR; drv_stat = ATA_ERR;
else if (pp->pkt[0] != cDONE) else if (pp->pkt[0] != cDONE)
drv_stat = ATA_ERR; drv_stat = ATA_ERR;
ata_qc_complete(qc, drv_stat); ata_qc_complete(qc, drv_stat);
}
} }
return handled; return handled;
} }
...@@ -561,15 +561,15 @@ static int adma_port_start(struct ata_port *ap) ...@@ -561,15 +561,15 @@ static int adma_port_start(struct ata_port *ap)
if ((pp->pkt_dma & 7) != 0) { if ((pp->pkt_dma & 7) != 0) {
printk("bad alignment for pp->pkt_dma: %08x\n", printk("bad alignment for pp->pkt_dma: %08x\n",
(u32)pp->pkt_dma); (u32)pp->pkt_dma);
goto err_out_kfree2; dma_free_coherent(dev, ADMA_PKT_BYTES,
pp->pkt, pp->pkt_dma);
goto err_out_kfree;
} }
memset(pp->pkt, 0, ADMA_PKT_BYTES); memset(pp->pkt, 0, ADMA_PKT_BYTES);
ap->private_data = pp; ap->private_data = pp;
adma_reinit_engine(ap); adma_reinit_engine(ap);
return 0; return 0;
err_out_kfree2:
kfree(pp);
err_out_kfree: err_out_kfree:
kfree(pp); kfree(pp);
err_out: err_out:
......
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