Skip to content

Commit

Permalink
[libata] ahci: send event when AN received
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Kristen Carlson Accardi authored and Jeff Garzik committed Oct 12, 2007
1 parent 9f45cbd commit 2f29496
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
24 changes: 24 additions & 0 deletions drivers/ata/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down

0 comments on commit 2f29496

Please sign in to comment.