forked from Minki/linux
sata_sil24: separate out sil24_exec_polled_cmd()
Separate out sil24_exec_polled_cmd() from sil24_softreset(). This will be used to implement sil24_pmp_read/write(). Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
e59f0dad33
commit
37b99cba8c
@ -531,16 +531,60 @@ static int sil24_init_port(struct ata_port *ap)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sil24_softreset(struct ata_port *ap, unsigned int *class,
|
static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp,
|
||||||
unsigned long deadline)
|
const struct ata_taskfile *tf,
|
||||||
|
int is_cmd, u32 ctrl,
|
||||||
|
unsigned long timeout_msec)
|
||||||
{
|
{
|
||||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||||
struct sil24_port_priv *pp = ap->private_data;
|
struct sil24_port_priv *pp = ap->private_data;
|
||||||
struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
|
struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
|
||||||
dma_addr_t paddr = pp->cmd_block_dma;
|
dma_addr_t paddr = pp->cmd_block_dma;
|
||||||
|
u32 irq_enabled, irq_mask, irq_stat;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
prb->ctrl = cpu_to_le16(ctrl);
|
||||||
|
ata_tf_to_fis(tf, pmp, is_cmd, prb->fis);
|
||||||
|
|
||||||
|
/* temporarily plug completion and error interrupts */
|
||||||
|
irq_enabled = readl(port + PORT_IRQ_ENABLE_SET);
|
||||||
|
writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR);
|
||||||
|
|
||||||
|
writel((u32)paddr, port + PORT_CMD_ACTIVATE);
|
||||||
|
writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
|
||||||
|
|
||||||
|
irq_mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
|
||||||
|
irq_stat = ata_wait_register(port + PORT_IRQ_STAT, irq_mask, 0x0,
|
||||||
|
10, timeout_msec);
|
||||||
|
|
||||||
|
writel(irq_mask, port + PORT_IRQ_STAT); /* clear IRQs */
|
||||||
|
irq_stat >>= PORT_IRQ_RAW_SHIFT;
|
||||||
|
|
||||||
|
if (irq_stat & PORT_IRQ_COMPLETE)
|
||||||
|
rc = 0;
|
||||||
|
else {
|
||||||
|
/* force port into known state */
|
||||||
|
sil24_init_port(ap);
|
||||||
|
|
||||||
|
if (irq_stat & PORT_IRQ_ERROR)
|
||||||
|
rc = -EIO;
|
||||||
|
else
|
||||||
|
rc = -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore IRQ enabled */
|
||||||
|
writel(irq_enabled, port + PORT_IRQ_ENABLE_SET);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sil24_softreset(struct ata_port *ap, unsigned int *class,
|
||||||
|
unsigned long deadline)
|
||||||
|
{
|
||||||
|
unsigned long timeout_msec = 0;
|
||||||
struct ata_taskfile tf;
|
struct ata_taskfile tf;
|
||||||
u32 mask, irq_stat;
|
|
||||||
const char *reason;
|
const char *reason;
|
||||||
|
int rc;
|
||||||
|
|
||||||
DPRINTK("ENTER\n");
|
DPRINTK("ENTER\n");
|
||||||
|
|
||||||
@ -557,24 +601,16 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* do SRST */
|
/* do SRST */
|
||||||
prb->ctrl = cpu_to_le16(PRB_CTRL_SRST);
|
if (time_after(deadline, jiffies))
|
||||||
prb->fis[1] = 0; /* no PMP yet */
|
timeout_msec = jiffies_to_msecs(deadline - jiffies);
|
||||||
|
|
||||||
writel((u32)paddr, port + PORT_CMD_ACTIVATE);
|
ata_tf_init(ap->device, &tf); /* doesn't really matter */
|
||||||
writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
|
rc = sil24_exec_polled_cmd(ap, 0, &tf, 0, PRB_CTRL_SRST, timeout_msec);
|
||||||
|
if (rc == -EBUSY) {
|
||||||
mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
|
reason = "timeout";
|
||||||
irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0,
|
goto err;
|
||||||
100, jiffies_to_msecs(deadline - jiffies));
|
} else if (rc) {
|
||||||
|
reason = "SRST command error";
|
||||||
writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */
|
|
||||||
irq_stat >>= PORT_IRQ_RAW_SHIFT;
|
|
||||||
|
|
||||||
if (!(irq_stat & PORT_IRQ_COMPLETE)) {
|
|
||||||
if (irq_stat & PORT_IRQ_ERROR)
|
|
||||||
reason = "SRST command error";
|
|
||||||
else
|
|
||||||
reason = "timeout";
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user