libata-pmp-prep: implement sata_async_notification()
AN serves multiple purposes. For ATAPI, it's used for media change notification. For PMP, for downstream PHY status change notification. Implement sata_async_notification() which demultiplexes AN. To avoid unnecessary port events, ATAPI AN is not enabled if PMP is attached but SNTF is not available. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Kriten Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
@@ -1356,27 +1356,17 @@ static void ahci_port_intr(struct ata_port *ap)
|
||||
}
|
||||
|
||||
if (status & PORT_IRQ_SDB_FIS) {
|
||||
/*
|
||||
* if this is an ATAPI device with AN turned on,
|
||||
* then we should interrogate the device to
|
||||
* determine the cause of the interrupt
|
||||
*
|
||||
* for AN - this we should check the SDB FIS
|
||||
* and find the I and N bits set
|
||||
/* If the 'N' bit in word 0 of the FIS is set, we just
|
||||
* received asynchronous notification. Tell libata
|
||||
* about it. Note that as the SDB FIS itself is
|
||||
* accessible, SNotification can be emulated by the
|
||||
* driver but don't bother for the time being.
|
||||
*/
|
||||
const __le32 *f = pp->rx_fis + RX_FIS_SDB;
|
||||
u32 f0 = le32_to_cpu(f[0]);
|
||||
|
||||
/* check the 'N' bit in word 0 of the FIS */
|
||||
if (f0 & (1 << 15)) {
|
||||
int port_addr = ((f0 & 0x00000f00) >> 8);
|
||||
struct ata_device *adev;
|
||||
if (port_addr < ATA_MAX_DEVICES) {
|
||||
adev = &ap->link.device[port_addr];
|
||||
if (adev->flags & ATA_DFLAG_AN)
|
||||
ata_scsi_media_change_notify(adev);
|
||||
}
|
||||
}
|
||||
if (f0 & (1 << 15))
|
||||
sata_async_notification(ap);
|
||||
}
|
||||
|
||||
if (ap->link.sactive)
|
||||
|
Reference in New Issue
Block a user