Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sergey Shtylyov and committed by
Damien Le Moal
03c0e84f 4fc5f0aa

+33 -26
+33 -26
drivers/ata/libata-sff.c
··· 70 70 /** 71 71 * ata_sff_altstatus - Read device alternate status reg 72 72 * @ap: port where the device is 73 + * @status: pointer to a status value 73 74 * 74 - * Reads ATA taskfile alternate status register for 75 - * currently-selected device and return its value. 75 + * Reads ATA alternate status register for currently-selected device 76 + * and return its value. 76 77 * 77 - * Note: may NOT be used as the check_altstatus() entry in 78 - * ata_port_operations. 78 + * RETURN: 79 + * true if the register exists, false if not. 79 80 * 80 81 * LOCKING: 81 82 * Inherited from caller. 82 83 */ 83 - static u8 ata_sff_altstatus(struct ata_port *ap) 84 + static bool ata_sff_altstatus(struct ata_port *ap, u8 *status) 84 85 { 85 - if (ap->ops->sff_check_altstatus) 86 - return ap->ops->sff_check_altstatus(ap); 86 + u8 tmp; 87 87 88 - return ioread8(ap->ioaddr.altstatus_addr); 88 + if (ap->ops->sff_check_altstatus) { 89 + tmp = ap->ops->sff_check_altstatus(ap); 90 + goto read; 91 + } 92 + if (ap->ioaddr.altstatus_addr) { 93 + tmp = ioread8(ap->ioaddr.altstatus_addr); 94 + goto read; 95 + } 96 + return false; 97 + 98 + read: 99 + if (status) 100 + *status = tmp; 101 + return true; 89 102 } 90 103 91 104 /** ··· 117 104 { 118 105 u8 status; 119 106 120 - if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) { 121 - status = ata_sff_altstatus(ap); 122 - /* Not us: We are busy */ 123 - if (status & ATA_BUSY) 124 - return status; 125 - } 107 + /* Not us: We are busy */ 108 + if (ata_sff_altstatus(ap, &status) && (status & ATA_BUSY)) 109 + return status; 126 110 /* Clear INTRQ latch */ 127 111 status = ap->ops->sff_check_status(ap); 128 112 return status; ··· 139 129 140 130 static void ata_sff_sync(struct ata_port *ap) 141 131 { 142 - if (ap->ops->sff_check_altstatus) 143 - ap->ops->sff_check_altstatus(ap); 144 - else if (ap->ioaddr.altstatus_addr) 145 - ioread8(ap->ioaddr.altstatus_addr); 132 + ata_sff_altstatus(ap, NULL); 146 133 } 147 134 148 135 /** ··· 171 164 172 165 void ata_sff_dma_pause(struct ata_port *ap) 173 166 { 174 - if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) { 175 - /* An altstatus read will cause the needed delay without 176 - messing up the IRQ status */ 177 - ata_sff_altstatus(ap); 167 + /* 168 + * An altstatus read will cause the needed delay without 169 + * messing up the IRQ status 170 + */ 171 + if (ata_sff_altstatus(ap, NULL)) 178 172 return; 179 - } 180 173 /* There are no DMA controllers without ctl. BUG here to ensure 181 174 we never violate the HDMA1:0 transition timing and risk 182 175 corruption. */ ··· 1644 1637 return; 1645 1638 /* See if the controller thinks it is still busy - if so the command 1646 1639 isn't a lost IRQ but is still in progress */ 1647 - status = ata_sff_altstatus(ap); 1640 + if (WARN_ON_ONCE(!ata_sff_altstatus(ap, &status))) 1641 + return; 1648 1642 if (status & ATA_BUSY) 1649 1643 return; 1650 1644 1651 1645 /* There was a command running, we are no longer busy and we have 1652 1646 no interrupt. */ 1653 - ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", 1654 - status); 1647 + ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status); 1655 1648 /* Run the host interrupt logic as if the interrupt had not been 1656 1649 lost */ 1657 1650 ata_sff_port_intr(ap, qc);