mirror of https://gitee.com/openkylin/linux.git
[libata] ahci: send event when AN received
When we get an SDB FIS with the 'N' bit set, we should send an event to user space to indicate that there has been a media change. This will be done via the scsi device. Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
9f45cbd3f0
commit
2f2949680a
|
@ -1368,6 +1368,30 @@ static void ahci_port_intr(struct ata_port *ap)
|
|||
return;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
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 (ap->link.sactive)
|
||||
qc_active = readl(port_mmio + PORT_SCR_ACT);
|
||||
else
|
||||
|
|
|
@ -3159,6 +3159,24 @@ static void ata_scsi_handle_link_detach(struct ata_link *link)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_media_change_notify - send media change event
|
||||
* @atadev: Pointer to the disk device with media change event
|
||||
*
|
||||
* Tell the block layer to send a media change notification
|
||||
* event.
|
||||
*
|
||||
* LOCKING:
|
||||
* interrupt context, may not sleep.
|
||||
*/
|
||||
void ata_scsi_media_change_notify(struct ata_device *atadev)
|
||||
{
|
||||
#ifdef OTHER_AN_PATCHES_HAVE_BEEN_APPLIED
|
||||
scsi_device_event_notify(atadev->sdev, SDEV_MEDIA_CHANGE);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_scsi_media_change_notify);
|
||||
|
||||
/**
|
||||
* ata_scsi_hotplug - SCSI part of hotplug
|
||||
* @work: Pointer to ATA port to perform SCSI hotplug on
|
||||
|
|
|
@ -755,6 +755,7 @@ extern void ata_host_init(struct ata_host *, struct device *,
|
|||
extern int ata_scsi_detect(struct scsi_host_template *sht);
|
||||
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
|
||||
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
|
||||
extern void ata_scsi_media_change_notify(struct ata_device *atadev);
|
||||
extern void ata_sas_port_destroy(struct ata_port *);
|
||||
extern struct ata_port *ata_sas_port_alloc(struct ata_host *,
|
||||
struct ata_port_info *, struct Scsi_Host *);
|
||||
|
|
Loading…
Reference in New Issue