ata: libata-sff: refactor ata_sff_altstatus()
The driver's calls to ata_sff_altstatus() are mostly surrounded by some clumsy checks. Refactor ata_sff_altstatus() to include the repetitive checks and return a 'bool' result indicating if the alternate status register exists or not. While at it, further update the 'kernel-doc' comment -- the alternate status register has never been a part of the taskfile, despite what Jeff and co. think! :-) In ata_sff_lost_interrupt(), wrap the ata_sff_altstatus() call in a WARN_ON_ONCE() check to issue a warning if the device control register does not exist. And while at it, fix the strange argument indentation in the ata_port_warn() call following the call to ata_sff_altstatus(). Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
This commit is contained in:
parent
4fc5f0aa97
commit
03c0e84f9c
@ -70,22 +70,35 @@ EXPORT_SYMBOL_GPL(ata_sff_check_status);
|
|||||||
/**
|
/**
|
||||||
* ata_sff_altstatus - Read device alternate status reg
|
* ata_sff_altstatus - Read device alternate status reg
|
||||||
* @ap: port where the device is
|
* @ap: port where the device is
|
||||||
|
* @status: pointer to a status value
|
||||||
*
|
*
|
||||||
* Reads ATA taskfile alternate status register for
|
* Reads ATA alternate status register for currently-selected device
|
||||||
* currently-selected device and return its value.
|
* and return its value.
|
||||||
*
|
*
|
||||||
* Note: may NOT be used as the check_altstatus() entry in
|
* RETURN:
|
||||||
* ata_port_operations.
|
* true if the register exists, false if not.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* Inherited from caller.
|
* Inherited from caller.
|
||||||
*/
|
*/
|
||||||
static u8 ata_sff_altstatus(struct ata_port *ap)
|
static bool ata_sff_altstatus(struct ata_port *ap, u8 *status)
|
||||||
{
|
{
|
||||||
if (ap->ops->sff_check_altstatus)
|
u8 tmp;
|
||||||
return ap->ops->sff_check_altstatus(ap);
|
|
||||||
|
|
||||||
return ioread8(ap->ioaddr.altstatus_addr);
|
if (ap->ops->sff_check_altstatus) {
|
||||||
|
tmp = ap->ops->sff_check_altstatus(ap);
|
||||||
|
goto read;
|
||||||
|
}
|
||||||
|
if (ap->ioaddr.altstatus_addr) {
|
||||||
|
tmp = ioread8(ap->ioaddr.altstatus_addr);
|
||||||
|
goto read;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
read:
|
||||||
|
if (status)
|
||||||
|
*status = tmp;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,12 +117,9 @@ static u8 ata_sff_irq_status(struct ata_port *ap)
|
|||||||
{
|
{
|
||||||
u8 status;
|
u8 status;
|
||||||
|
|
||||||
if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) {
|
/* Not us: We are busy */
|
||||||
status = ata_sff_altstatus(ap);
|
if (ata_sff_altstatus(ap, &status) && (status & ATA_BUSY))
|
||||||
/* Not us: We are busy */
|
return status;
|
||||||
if (status & ATA_BUSY)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
/* Clear INTRQ latch */
|
/* Clear INTRQ latch */
|
||||||
status = ap->ops->sff_check_status(ap);
|
status = ap->ops->sff_check_status(ap);
|
||||||
return status;
|
return status;
|
||||||
@ -129,10 +139,7 @@ static u8 ata_sff_irq_status(struct ata_port *ap)
|
|||||||
|
|
||||||
static void ata_sff_sync(struct ata_port *ap)
|
static void ata_sff_sync(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
if (ap->ops->sff_check_altstatus)
|
ata_sff_altstatus(ap, NULL);
|
||||||
ap->ops->sff_check_altstatus(ap);
|
|
||||||
else if (ap->ioaddr.altstatus_addr)
|
|
||||||
ioread8(ap->ioaddr.altstatus_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,12 +171,12 @@ EXPORT_SYMBOL_GPL(ata_sff_pause);
|
|||||||
|
|
||||||
void ata_sff_dma_pause(struct ata_port *ap)
|
void ata_sff_dma_pause(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) {
|
/*
|
||||||
/* An altstatus read will cause the needed delay without
|
* An altstatus read will cause the needed delay without
|
||||||
messing up the IRQ status */
|
* messing up the IRQ status
|
||||||
ata_sff_altstatus(ap);
|
*/
|
||||||
|
if (ata_sff_altstatus(ap, NULL))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
/* There are no DMA controllers without ctl. BUG here to ensure
|
/* There are no DMA controllers without ctl. BUG here to ensure
|
||||||
we never violate the HDMA1:0 transition timing and risk
|
we never violate the HDMA1:0 transition timing and risk
|
||||||
corruption. */
|
corruption. */
|
||||||
@ -1637,14 +1644,14 @@ void ata_sff_lost_interrupt(struct ata_port *ap)
|
|||||||
return;
|
return;
|
||||||
/* See if the controller thinks it is still busy - if so the command
|
/* See if the controller thinks it is still busy - if so the command
|
||||||
isn't a lost IRQ but is still in progress */
|
isn't a lost IRQ but is still in progress */
|
||||||
status = ata_sff_altstatus(ap);
|
if (WARN_ON_ONCE(!ata_sff_altstatus(ap, &status)))
|
||||||
|
return;
|
||||||
if (status & ATA_BUSY)
|
if (status & ATA_BUSY)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* There was a command running, we are no longer busy and we have
|
/* There was a command running, we are no longer busy and we have
|
||||||
no interrupt. */
|
no interrupt. */
|
||||||
ata_port_warn(ap, "lost interrupt (Status 0x%x)\n",
|
ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
|
||||||
status);
|
|
||||||
/* Run the host interrupt logic as if the interrupt had not been
|
/* Run the host interrupt logic as if the interrupt had not been
|
||||||
lost */
|
lost */
|
||||||
ata_sff_port_intr(ap, qc);
|
ata_sff_port_intr(ap, qc);
|
||||||
|
Loading…
Reference in New Issue
Block a user