[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
This commit is contained in:
parent
96b88fb850
commit
a21a84a375
@ -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 {
|
|||||||
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,25 +451,26 @@ 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)
|
|||||||
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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user