* [patch 2/3] libata: expose AN support to user space via sysfs
[not found] <20070321004740.939006166@intel.com>
@ 2007-03-21 0:52 ` Kristen Carlson Accardi
0 siblings, 0 replies; 13+ messages in thread
From: Kristen Carlson Accardi @ 2007-03-21 0:52 UTC (permalink / raw)
To: linux-ide; +Cc: jgarzik, Kristen Carlson Accardi
[-- Attachment #1: Type: text/plain, Size: 3662 bytes --]
Allow user space to determine if an ATAPI device supports
async notification (AN) of media changes. This is done by
adding a new sysfs file "async_notification" to genhd.
If the file reads 1, then the device supports async
notification. If the file reads 0, it does not.
A flag is set in the generic disk to indicate whether
or not AN is supported. This flag is set by the SCSI
subsystem when it registers with add_disk. The SCSI
system gets information from libata on whether the
device supports AN during dev_configure.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/block/genhd.c
===================================================================
--- 2.6-git.orig/block/genhd.c 2007-03-21 01:22:04.000000000 -0700
+++ 2.6-git/block/genhd.c 2007-03-21 01:23:46.000000000 -0700
@@ -369,6 +369,11 @@
{
return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
}
+static ssize_t disk_an_read(struct gendisk * disk, char *page)
+{
+ return sprintf(page, "%d\n",
+ (disk->flags & GENHD_FL_ASYNC_NOTIFICATION ? 1 : 0));
+}
static ssize_t disk_stats_read(struct gendisk * disk, char *page)
{
@@ -416,6 +421,10 @@
.attr = {.name = "stat", .mode = S_IRUGO },
.show = disk_stats_read
};
+static struct disk_attribute disk_attr_an = {
+ .attr = {.name = "async_notification", .mode = S_IRUGO },
+ .show = disk_an_read
+};
#ifdef CONFIG_FAIL_MAKE_REQUEST
@@ -452,6 +461,7 @@
&disk_attr_removable.attr,
&disk_attr_size.attr,
&disk_attr_stat.attr,
+ &disk_attr_an.attr,
#ifdef CONFIG_FAIL_MAKE_REQUEST
&disk_attr_fail.attr,
#endif
Index: 2.6-git/include/linux/genhd.h
===================================================================
--- 2.6-git.orig/include/linux/genhd.h 2007-03-21 01:22:04.000000000 -0700
+++ 2.6-git/include/linux/genhd.h 2007-03-21 01:23:46.000000000 -0700
@@ -90,6 +90,7 @@
#define GENHD_FL_REMOVABLE 1
#define GENHD_FL_DRIVERFS 2
+#define GENHD_FL_ASYNC_NOTIFICATION 4
#define GENHD_FL_CD 8
#define GENHD_FL_UP 16
#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
Index: 2.6-git/include/scsi/scsi_device.h
===================================================================
--- 2.6-git.orig/include/scsi/scsi_device.h 2007-03-21 01:22:04.000000000 -0700
+++ 2.6-git/include/scsi/scsi_device.h 2007-03-21 01:23:46.000000000 -0700
@@ -123,7 +123,7 @@
unsigned select_no_atn:1;
unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */
unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */
-
+ unsigned async_notification:1; /* device supports async notification */
unsigned int device_blocked; /* Device returned QUEUE_FULL. */
unsigned int max_device_blocked; /* what device_blocked counts down from */
Index: 2.6-git/drivers/ata/libata-scsi.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-scsi.c 2007-03-21 01:22:04.000000000 -0700
+++ 2.6-git/drivers/ata/libata-scsi.c 2007-03-21 01:23:46.000000000 -0700
@@ -855,6 +855,9 @@
blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
}
+ if (dev->flags & ATA_DFLAG_AN)
+ sdev->async_notification = 1;
+
if (dev->flags & ATA_DFLAG_NCQ) {
int depth;
Index: 2.6-git/drivers/scsi/sr.c
===================================================================
--- 2.6-git.orig/drivers/scsi/sr.c 2007-03-21 01:22:04.000000000 -0700
+++ 2.6-git/drivers/scsi/sr.c 2007-03-21 01:23:46.000000000 -0700
@@ -602,6 +602,8 @@
dev_set_drvdata(dev, cd);
disk->flags |= GENHD_FL_REMOVABLE;
+ if (sdev->async_notification)
+ disk->flags |= GENHD_FL_ASYNC_NOTIFICATION;
add_disk(disk);
sdev_printk(KERN_DEBUG, sdev,
--
[-- Attachment #2: libata-expose-an-to-users --]
[-- Type: text/plain, Size: 3662 bytes --]
Allow user space to determine if an ATAPI device supports
async notification (AN) of media changes. This is done by
adding a new sysfs file "async_notification" to genhd.
If the file reads 1, then the device supports async
notification. If the file reads 0, it does not.
A flag is set in the generic disk to indicate whether
or not AN is supported. This flag is set by the SCSI
subsystem when it registers with add_disk. The SCSI
system gets information from libata on whether the
device supports AN during dev_configure.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/block/genhd.c
===================================================================
--- 2.6-git.orig/block/genhd.c 2007-03-21 01:22:04.000000000 -0700
+++ 2.6-git/block/genhd.c 2007-03-21 01:23:46.000000000 -0700
@@ -369,6 +369,11 @@
{
return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
}
+static ssize_t disk_an_read(struct gendisk * disk, char *page)
+{
+ return sprintf(page, "%d\n",
+ (disk->flags & GENHD_FL_ASYNC_NOTIFICATION ? 1 : 0));
+}
static ssize_t disk_stats_read(struct gendisk * disk, char *page)
{
@@ -416,6 +421,10 @@
.attr = {.name = "stat", .mode = S_IRUGO },
.show = disk_stats_read
};
+static struct disk_attribute disk_attr_an = {
+ .attr = {.name = "async_notification", .mode = S_IRUGO },
+ .show = disk_an_read
+};
#ifdef CONFIG_FAIL_MAKE_REQUEST
@@ -452,6 +461,7 @@
&disk_attr_removable.attr,
&disk_attr_size.attr,
&disk_attr_stat.attr,
+ &disk_attr_an.attr,
#ifdef CONFIG_FAIL_MAKE_REQUEST
&disk_attr_fail.attr,
#endif
Index: 2.6-git/include/linux/genhd.h
===================================================================
--- 2.6-git.orig/include/linux/genhd.h 2007-03-21 01:22:04.000000000 -0700
+++ 2.6-git/include/linux/genhd.h 2007-03-21 01:23:46.000000000 -0700
@@ -90,6 +90,7 @@
#define GENHD_FL_REMOVABLE 1
#define GENHD_FL_DRIVERFS 2
+#define GENHD_FL_ASYNC_NOTIFICATION 4
#define GENHD_FL_CD 8
#define GENHD_FL_UP 16
#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
Index: 2.6-git/include/scsi/scsi_device.h
===================================================================
--- 2.6-git.orig/include/scsi/scsi_device.h 2007-03-21 01:22:04.000000000 -0700
+++ 2.6-git/include/scsi/scsi_device.h 2007-03-21 01:23:46.000000000 -0700
@@ -123,7 +123,7 @@
unsigned select_no_atn:1;
unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */
unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */
-
+ unsigned async_notification:1; /* device supports async notification */
unsigned int device_blocked; /* Device returned QUEUE_FULL. */
unsigned int max_device_blocked; /* what device_blocked counts down from */
Index: 2.6-git/drivers/ata/libata-scsi.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-scsi.c 2007-03-21 01:22:04.000000000 -0700
+++ 2.6-git/drivers/ata/libata-scsi.c 2007-03-21 01:23:46.000000000 -0700
@@ -855,6 +855,9 @@
blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
}
+ if (dev->flags & ATA_DFLAG_AN)
+ sdev->async_notification = 1;
+
if (dev->flags & ATA_DFLAG_NCQ) {
int depth;
Index: 2.6-git/drivers/scsi/sr.c
===================================================================
--- 2.6-git.orig/drivers/scsi/sr.c 2007-03-21 01:22:04.000000000 -0700
+++ 2.6-git/drivers/scsi/sr.c 2007-03-21 01:23:46.000000000 -0700
@@ -602,6 +602,8 @@
dev_set_drvdata(dev, cd);
disk->flags |= GENHD_FL_REMOVABLE;
+ if (sdev->async_notification)
+ disk->flags |= GENHD_FL_ASYNC_NOTIFICATION;
add_disk(disk);
sdev_printk(KERN_DEBUG, sdev,
--
^ permalink raw reply [flat|nested] 13+ messages in thread
* [patch 1/3] libata: check for AN support
[not found] <20070328230108.597741522@intel.com>
@ 2007-03-28 23:44 ` Kristen Carlson Accardi
2007-03-29 1:53 ` Tejun Heo
2007-03-28 23:44 ` [patch 2/3] libata: expose AN support to user space via sysfs Kristen Carlson Accardi
2007-03-28 23:44 ` [patch 3/3] libata: handle AN interrupt Kristen Carlson Accardi
2 siblings, 1 reply; 13+ messages in thread
From: Kristen Carlson Accardi @ 2007-03-28 23:44 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, linux-ide, jgarzik, Kristen Carlson Accardi
Check to see if an ATAPI device supports Asynchronous Notification.
If so, enable it.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-mm/drivers/ata/libata-core.c
===================================================================
--- 2.6-mm.orig/drivers/ata/libata-core.c
+++ 2.6-mm/drivers/ata/libata-core.c
@@ -71,6 +71,7 @@ const unsigned long sata_deb_timing_long
static unsigned int ata_dev_init_params(struct ata_device *dev,
u16 heads, u16 sectors);
static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
+static unsigned int ata_dev_set_AN(struct ata_device *dev);
static void ata_dev_xfermask(struct ata_device *dev);
static unsigned int ata_print_id = 1;
@@ -1745,6 +1746,23 @@ int ata_dev_configure(struct ata_device
}
dev->cdb_len = (unsigned int) rc;
+ /*
+ * check to see if this ATAPI device supports
+ * Asynchronous Notification
+ */
+ if (ata_id_has_AN(id))
+ {
+ /* issue SET feature command to turn this on */
+ rc = ata_dev_set_AN(dev);
+ if (rc) {
+ ata_dev_printk(dev, KERN_ERR,
+ "unable to set AN\n");
+ rc = -EINVAL;
+ goto err_out_nosup;
+ }
+ dev->flags |= ATA_DFLAG_AN;
+ }
+
if (ata_id_cdb_intr(dev->id)) {
dev->flags |= ATA_DFLAG_CDB_INTR;
cdb_intr_string = ", CDB intr";
@@ -3642,6 +3660,42 @@ static unsigned int ata_dev_set_xfermode
}
/**
+ * ata_dev_set_AN - Issue SET FEATURES - SATA FEATURES
+ * with sector count set to indicate
+ * Asynchronous Notification feature
+ * @dev: Device to which command will be sent
+ *
+ * Issue SET FEATURES - SATA FEATURES command to device @dev
+ * on port @ap.
+ *
+ * LOCKING:
+ * PCI/etc. bus probe sem.
+ *
+ * RETURNS:
+ * 0 on success, AC_ERR_* mask otherwise.
+ */
+static unsigned int ata_dev_set_AN(struct ata_device *dev)
+{
+ struct ata_taskfile tf;
+ unsigned int err_mask;
+
+ /* set up set-features taskfile */
+ DPRINTK("set features - SATA features\n");
+
+ ata_tf_init(dev, &tf);
+ tf.command = ATA_CMD_SET_FEATURES;
+ tf.feature = SETFEATURES_SATA_ENABLE;
+ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ tf.protocol = ATA_PROT_NODATA;
+ tf.nsect = SATA_AN;
+
+ err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+
+ DPRINTK("EXIT, err_mask=%x\n", err_mask);
+ return err_mask;
+}
+
+/**
* ata_dev_init_params - Issue INIT DEV PARAMS command
* @dev: Device to which command will be sent
* @heads: Number of heads (taskfile parameter)
Index: 2.6-mm/include/linux/ata.h
===================================================================
--- 2.6-mm.orig/include/linux/ata.h
+++ 2.6-mm/include/linux/ata.h
@@ -193,6 +193,12 @@ enum {
SETFEATURES_WC_ON = 0x02, /* Enable write cache */
SETFEATURES_WC_OFF = 0x82, /* Disable write cache */
+ SETFEATURES_SATA_ENABLE = 0x10, /* Enable use of SATA feature */
+ SETFEATURES_SATA_DISABLE = 0x90, /* Disable use of SATA feature */
+
+ /* SETFEATURE Sector counts for SATA features */
+ SATA_AN = 0x05, /* Asynchronous Notification */
+
/* ATAPI stuff */
ATAPI_PKT_DMA = (1 << 0),
ATAPI_DMADIR = (1 << 2), /* ATAPI data dir:
@@ -298,6 +304,8 @@ struct ata_taskfile {
#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1)
#define ata_id_removeable(id) ((id)[0] & (1 << 7))
#define ata_id_has_dword_io(id) ((id)[50] & (1 << 0))
+#define ata_id_has_AN(id) \
+ ((id[76] && (~id[76])) & ((id)[78] & (1 << 5)))
#define ata_id_iordy_disable(id) ((id)[49] & (1 << 10))
#define ata_id_has_iordy(id) ((id)[49] & (1 << 9))
#define ata_id_u32(id,n) \
Index: 2.6-mm/include/linux/libata.h
===================================================================
--- 2.6-mm.orig/include/linux/libata.h
+++ 2.6-mm/include/linux/libata.h
@@ -136,6 +136,7 @@ enum {
ATA_DFLAG_CDB_INTR = (1 << 2), /* device asserts INTRQ when ready for CDB */
ATA_DFLAG_NCQ = (1 << 3), /* device supports NCQ */
ATA_DFLAG_FLUSH_EXT = (1 << 4), /* do FLUSH_EXT instead of FLUSH */
+ ATA_DFLAG_AN = (1 << 5), /* device supports Async notification */
ATA_DFLAG_CFG_MASK = (1 << 8) - 1,
ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
--
^ permalink raw reply [flat|nested] 13+ messages in thread
* [patch 2/3] libata: expose AN support to user space via sysfs
[not found] <20070328230108.597741522@intel.com>
2007-03-28 23:44 ` [patch 1/3] libata: check for AN support Kristen Carlson Accardi
@ 2007-03-28 23:44 ` Kristen Carlson Accardi
2007-03-29 0:15 ` Jeff Garzik
2007-03-29 2:04 ` Tejun Heo
2007-03-28 23:44 ` [patch 3/3] libata: handle AN interrupt Kristen Carlson Accardi
2 siblings, 2 replies; 13+ messages in thread
From: Kristen Carlson Accardi @ 2007-03-28 23:44 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, linux-ide, jgarzik, Kristen Carlson Accardi
Allow user space to determine if an ATAPI device supports
async notification (AN) of media changes. This is done by
adding a new sysfs file "async_notification" to genhd.
If the file reads 1, then the device supports async
notification. If the file reads 0, it does not.
A flag is set in the generic disk to indicate whether
or not AN is supported. This flag is set by the SCSI
subsystem when it registers with add_disk. The SCSI
system gets information from libata on whether the
device supports AN during dev_configure.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-mm/block/genhd.c
===================================================================
--- 2.6-mm.orig/block/genhd.c
+++ 2.6-mm/block/genhd.c
@@ -372,6 +372,11 @@ static ssize_t disk_size_read(struct gen
{
return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
}
+static ssize_t disk_AN_read(struct gendisk * disk, char *page)
+{
+ return sprintf(page, "%d\n",
+ (disk->flags & GENHD_FL_ASYNC_NOTIFICATION ? 1 : 0));
+}
static ssize_t disk_stats_read(struct gendisk * disk, char *page)
{
@@ -419,6 +424,10 @@ static struct disk_attribute disk_attr_s
.attr = {.name = "stat", .mode = S_IRUGO },
.show = disk_stats_read
};
+static struct disk_attribute disk_attr_AN = {
+ .attr = {.name = "media_change_events", .mode = S_IRUGO },
+ .show = disk_AN_read
+};
#ifdef CONFIG_FAIL_MAKE_REQUEST
@@ -455,6 +464,7 @@ static struct attribute * default_attrs[
&disk_attr_removable.attr,
&disk_attr_size.attr,
&disk_attr_stat.attr,
+ &disk_attr_AN.attr,
#ifdef CONFIG_FAIL_MAKE_REQUEST
&disk_attr_fail.attr,
#endif
Index: 2.6-mm/include/linux/genhd.h
===================================================================
--- 2.6-mm.orig/include/linux/genhd.h
+++ 2.6-mm/include/linux/genhd.h
@@ -94,6 +94,7 @@ struct hd_struct {
#define GENHD_FL_REMOVABLE 1
#define GENHD_FL_DRIVERFS 2
+#define GENHD_FL_ASYNC_NOTIFICATION 4
#define GENHD_FL_CD 8
#define GENHD_FL_UP 16
#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
Index: 2.6-mm/include/scsi/scsi_device.h
===================================================================
--- 2.6-mm.orig/include/scsi/scsi_device.h
+++ 2.6-mm/include/scsi/scsi_device.h
@@ -126,7 +126,7 @@ struct scsi_device {
unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */
unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */
unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */
-
+ unsigned async_notification:1; /* device supports async notification */
unsigned int device_blocked; /* Device returned QUEUE_FULL. */
unsigned int max_device_blocked; /* what device_blocked counts down from */
Index: 2.6-mm/drivers/ata/libata-scsi.c
===================================================================
--- 2.6-mm.orig/drivers/ata/libata-scsi.c
+++ 2.6-mm/drivers/ata/libata-scsi.c
@@ -899,6 +899,9 @@ static void ata_scsi_dev_config(struct s
blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
}
+ if (dev->flags & ATA_DFLAG_AN)
+ sdev->async_notification = 1;
+
if (dev->flags & ATA_DFLAG_NCQ) {
int depth;
Index: 2.6-mm/drivers/scsi/sr.c
===================================================================
--- 2.6-mm.orig/drivers/scsi/sr.c
+++ 2.6-mm/drivers/scsi/sr.c
@@ -603,6 +603,8 @@ static int sr_probe(struct device *dev)
dev_set_drvdata(dev, cd);
disk->flags |= GENHD_FL_REMOVABLE;
+ if (sdev->async_notification)
+ disk->flags |= GENHD_FL_ASYNC_NOTIFICATION;
add_disk(disk);
sdev_printk(KERN_DEBUG, sdev,
--
^ permalink raw reply [flat|nested] 13+ messages in thread
* [patch 3/3] libata: handle AN interrupt
[not found] <20070328230108.597741522@intel.com>
2007-03-28 23:44 ` [patch 1/3] libata: check for AN support Kristen Carlson Accardi
2007-03-28 23:44 ` [patch 2/3] libata: expose AN support to user space via sysfs Kristen Carlson Accardi
@ 2007-03-28 23:44 ` Kristen Carlson Accardi
2007-03-29 2:13 ` Tejun Heo
2 siblings, 1 reply; 13+ messages in thread
From: Kristen Carlson Accardi @ 2007-03-28 23:44 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, linux-ide, jgarzik, Kristen Carlson Accardi
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. The ahci host controller will send the
event via KOBJ_CHANGE uevent.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-mm/drivers/ata/ahci.c
===================================================================
--- 2.6-mm.orig/drivers/ata/ahci.c
+++ 2.6-mm/drivers/ata/ahci.c
@@ -1164,6 +1164,26 @@ static void ahci_host_intr(struct ata_po
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 u32 *f = pp->rx_fis + RX_FIS_SDB;
+
+ /* check the 'N' bit in word 0 of the FIS */
+ if (f[0] & (1 << 15)) {
+ int port_addr = ((f[0] & 0x00000f00) >> 8);
+ struct ata_device *adev = &ap->device[port_addr];
+ ata_port_printk(ap, KERN_INFO, "N bit set on SDB FIS!\n");
+ if (adev->flags & ATA_DFLAG_AN)
+ ata_async_notify(adev);
+ }
+ }
if (ap->sactive)
qc_active = readl(port_mmio + PORT_SCR_ACT);
else
Index: 2.6-mm/include/linux/libata.h
===================================================================
--- 2.6-mm.orig/include/linux/libata.h
+++ 2.6-mm/include/linux/libata.h
@@ -492,6 +492,7 @@ struct ata_device {
/* ACPI objects info */
acpi_handle obj_handle;
#endif
+ struct work_struct async_notify;
};
/* Offset into struct ata_device. Fields above it are maintained
@@ -826,6 +827,7 @@ extern void ata_scsi_slave_destroy(struc
extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
int queue_depth);
extern struct ata_device *ata_dev_pair(struct ata_device *adev);
+extern void ata_async_notify(struct ata_device *atadev);
extern int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
extern u8 ata_irq_on(struct ata_port *ap);
extern u8 ata_dummy_irq_on(struct ata_port *ap);
Index: 2.6-mm/drivers/ata/libata-core.c
===================================================================
--- 2.6-mm.orig/drivers/ata/libata-core.c
+++ 2.6-mm/drivers/ata/libata-core.c
@@ -1576,6 +1576,26 @@ static void ata_dev_config_ncq(struct at
snprintf(desc, desc_sz, "NCQ (depth %d/%d)", hdepth, ddepth);
}
+static void async_notify_thread(struct work_struct *work)
+{
+ struct ata_device *atadev =
+ container_of(work, struct ata_device, async_notify);
+
+ /*
+ * TBD - who should send this event? I couldn't find an
+ * easy way to map an ata_device to a genhd device, so
+ * decided maybe the ata host should send the event and
+ * allow user space to figure out what happened?
+ */
+ kobject_uevent(&atadev->ap->host->dev->kobj, KOBJ_CHANGE);
+}
+
+void ata_async_notify(struct ata_device *atadev)
+{
+ schedule_work(&atadev->async_notify);
+}
+
+
/**
* ata_dev_configure - Configure the specified ATA/ATAPI device
* @dev: Target device to configure
@@ -1761,6 +1781,7 @@ int ata_dev_configure(struct ata_device
goto err_out_nosup;
}
dev->flags |= ATA_DFLAG_AN;
+ INIT_WORK(&dev->async_notify, async_notify_thread);
}
if (ata_id_cdb_intr(dev->id)) {
@@ -6650,6 +6671,7 @@ EXPORT_SYMBOL_GPL(ata_dummy_irq_on);
EXPORT_SYMBOL_GPL(ata_irq_ack);
EXPORT_SYMBOL_GPL(ata_dummy_irq_ack);
EXPORT_SYMBOL_GPL(ata_dev_try_classify);
+EXPORT_SYMBOL_GPL(ata_async_notify);
EXPORT_SYMBOL_GPL(ata_cable_40wire);
EXPORT_SYMBOL_GPL(ata_cable_80wire);
--
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [patch 2/3] libata: expose AN support to user space via sysfs
2007-03-28 23:44 ` [patch 2/3] libata: expose AN support to user space via sysfs Kristen Carlson Accardi
@ 2007-03-29 0:15 ` Jeff Garzik
2007-03-29 2:07 ` Tejun Heo
2007-03-29 2:04 ` Tejun Heo
1 sibling, 1 reply; 13+ messages in thread
From: Jeff Garzik @ 2007-03-29 0:15 UTC (permalink / raw)
To: Kristen Carlson Accardi; +Cc: linux-kernel, akpm, linux-ide, linux-scsi
Kristen Carlson Accardi wrote:
> Allow user space to determine if an ATAPI device supports
> async notification (AN) of media changes. This is done by
> adding a new sysfs file "async_notification" to genhd.
> If the file reads 1, then the device supports async
> notification. If the file reads 0, it does not.
>
> A flag is set in the generic disk to indicate whether
> or not AN is supported. This flag is set by the SCSI
> subsystem when it registers with add_disk. The SCSI
> system gets information from libata on whether the
> device supports AN during dev_configure.
>
> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
>
> Index: 2.6-mm/block/genhd.c
> ===================================================================
> --- 2.6-mm.orig/block/genhd.c
> +++ 2.6-mm/block/genhd.c
> @@ -372,6 +372,11 @@ static ssize_t disk_size_read(struct gen
> {
> return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
> }
> +static ssize_t disk_AN_read(struct gendisk * disk, char *page)
> +{
> + return sprintf(page, "%d\n",
> + (disk->flags & GENHD_FL_ASYNC_NOTIFICATION ? 1 : 0));
> +}
>
> static ssize_t disk_stats_read(struct gendisk * disk, char *page)
> {
> @@ -419,6 +424,10 @@ static struct disk_attribute disk_attr_s
> .attr = {.name = "stat", .mode = S_IRUGO },
> .show = disk_stats_read
> };
> +static struct disk_attribute disk_attr_AN = {
> + .attr = {.name = "media_change_events", .mode = S_IRUGO },
> + .show = disk_AN_read
> +};
>
> #ifdef CONFIG_FAIL_MAKE_REQUEST
>
> @@ -455,6 +464,7 @@ static struct attribute * default_attrs[
> &disk_attr_removable.attr,
> &disk_attr_size.attr,
> &disk_attr_stat.attr,
> + &disk_attr_AN.attr,
> #ifdef CONFIG_FAIL_MAKE_REQUEST
> &disk_attr_fail.attr,
> #endif
> Index: 2.6-mm/include/linux/genhd.h
> ===================================================================
> --- 2.6-mm.orig/include/linux/genhd.h
> +++ 2.6-mm/include/linux/genhd.h
> @@ -94,6 +94,7 @@ struct hd_struct {
>
> #define GENHD_FL_REMOVABLE 1
> #define GENHD_FL_DRIVERFS 2
> +#define GENHD_FL_ASYNC_NOTIFICATION 4
> #define GENHD_FL_CD 8
> #define GENHD_FL_UP 16
> #define GENHD_FL_SUPPRESS_PARTITION_INFO 32
> Index: 2.6-mm/include/scsi/scsi_device.h
> ===================================================================
> --- 2.6-mm.orig/include/scsi/scsi_device.h
> +++ 2.6-mm/include/scsi/scsi_device.h
> @@ -126,7 +126,7 @@ struct scsi_device {
> unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */
> unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */
> unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */
> -
> + unsigned async_notification:1; /* device supports async notification */
> unsigned int device_blocked; /* Device returned QUEUE_FULL. */
>
> unsigned int max_device_blocked; /* what device_blocked counts down from */
> Index: 2.6-mm/drivers/ata/libata-scsi.c
> ===================================================================
> --- 2.6-mm.orig/drivers/ata/libata-scsi.c
> +++ 2.6-mm/drivers/ata/libata-scsi.c
> @@ -899,6 +899,9 @@ static void ata_scsi_dev_config(struct s
> blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
> }
>
> + if (dev->flags & ATA_DFLAG_AN)
> + sdev->async_notification = 1;
> +
> if (dev->flags & ATA_DFLAG_NCQ) {
> int depth;
>
> Index: 2.6-mm/drivers/scsi/sr.c
> ===================================================================
> --- 2.6-mm.orig/drivers/scsi/sr.c
> +++ 2.6-mm/drivers/scsi/sr.c
> @@ -603,6 +603,8 @@ static int sr_probe(struct device *dev)
>
> dev_set_drvdata(dev, cd);
> disk->flags |= GENHD_FL_REMOVABLE;
> + if (sdev->async_notification)
> + disk->flags |= GENHD_FL_ASYNC_NOTIFICATION;
> add_disk(disk);
(added linux-scsi to CC)
Comments:
1) From a procedural standpoint, you'll want to separate this patch into
three patches: generic block layer stuff, SCSI stuff, and libata stuff.
2) I don't claim to be a sysfs expert, but this seems like a reasonable
approach for reporting async-notification capabilities
3) I would make the contents of 'media_change_events' be a list of
flags, rather than a boolean. Thus, when AN is present,
media_change_events would return "AN\n". It would return "\n" (no
flags) when AN is absent. This permits future expansion of this
capabilities reporting variable.
4) Figure out some place to document 'media_change_events', in
Documentation/*
5) I think the method of delivery probably needs discussing, and some
work. Presumably the normal hotplug paths should be traversed for this
sort of thing.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [patch 1/3] libata: check for AN support
2007-03-28 23:44 ` [patch 1/3] libata: check for AN support Kristen Carlson Accardi
@ 2007-03-29 1:53 ` Tejun Heo
2007-03-29 2:02 ` Jeff Garzik
0 siblings, 1 reply; 13+ messages in thread
From: Tejun Heo @ 2007-03-29 1:53 UTC (permalink / raw)
To: Kristen Carlson Accardi; +Cc: linux-kernel, akpm, linux-ide, jgarzik
Kristen Carlson Accardi wrote:
> Check to see if an ATAPI device supports Asynchronous Notification.
> If so, enable it.
As supporting AN needs host interrupt handler change. I think we need
host-supports-AN flag; otherwise, we might end up with screaming
interrupts in the worst case.
--
tejun
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [patch 1/3] libata: check for AN support
2007-03-29 1:53 ` Tejun Heo
@ 2007-03-29 2:02 ` Jeff Garzik
0 siblings, 0 replies; 13+ messages in thread
From: Jeff Garzik @ 2007-03-29 2:02 UTC (permalink / raw)
To: Tejun Heo; +Cc: Kristen Carlson Accardi, linux-kernel, akpm, linux-ide
Tejun Heo wrote:
> Kristen Carlson Accardi wrote:
>> Check to see if an ATAPI device supports Asynchronous Notification.
>> If so, enable it.
>
> As supporting AN needs host interrupt handler change. I think we need
> host-supports-AN flag; otherwise, we might end up with screaming
> interrupts in the worst case.
Quite so. Lacking a host flag, we need to know how each and every
controller behaves when AN is activated (and supported by the device).
I'm willing to bet some of the first-gen SATA controllers' ASIC state
machines croak when AN is activated.
Jeff
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [patch 2/3] libata: expose AN support to user space via sysfs
2007-03-28 23:44 ` [patch 2/3] libata: expose AN support to user space via sysfs Kristen Carlson Accardi
2007-03-29 0:15 ` Jeff Garzik
@ 2007-03-29 2:04 ` Tejun Heo
1 sibling, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2007-03-29 2:04 UTC (permalink / raw)
To: Kristen Carlson Accardi; +Cc: linux-kernel, akpm, linux-ide, jgarzik
Kristen Carlson Accardi wrote:
> Allow user space to determine if an ATAPI device supports
> async notification (AN) of media changes. This is done by
> adding a new sysfs file "async_notification" to genhd.
> If the file reads 1, then the device supports async
> notification. If the file reads 0, it does not.
>
> A flag is set in the generic disk to indicate whether
> or not AN is supported. This flag is set by the SCSI
> subsystem when it registers with add_disk. The SCSI
> system gets information from libata on whether the
> device supports AN during dev_configure.
I'm not sure whether this should be in generic block layer or in libata
proper. libata sysfs hierarchy isn't there yet but is scheduled to be
added soon. Async notification of media change is generic event for any
block device with removable media, so I guess it can belong to generic
layer. BTW, I think you also need to forward the flag in sd - disk
device can be removable too. And please cc linux-scsi@vger.kernel.org
to get SCSI part reviewed.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [patch 2/3] libata: expose AN support to user space via sysfs
2007-03-29 0:15 ` Jeff Garzik
@ 2007-03-29 2:07 ` Tejun Heo
2007-03-29 2:19 ` Jeff Garzik
0 siblings, 1 reply; 13+ messages in thread
From: Tejun Heo @ 2007-03-29 2:07 UTC (permalink / raw)
To: Jeff Garzik
Cc: Kristen Carlson Accardi, linux-kernel, akpm, linux-ide,
linux-scsi
Jeff Garzik wrote:
> Kristen Carlson Accardi wrote:
>> Allow user space to determine if an ATAPI device supports
>> async notification (AN) of media changes. This is done by
>> adding a new sysfs file "async_notification" to genhd.
>> If the file reads 1, then the device supports async notification. If
>> the file reads 0, it does not.
>> A flag is set in the generic disk to indicate whether
>> or not AN is supported. This flag is set by the SCSI
>> subsystem when it registers with add_disk. The SCSI
>> system gets information from libata on whether the
>> device supports AN during dev_configure.
>> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
>>
>
> 3) I would make the contents of 'media_change_events' be a list of
> flags, rather than a boolean. Thus, when AN is present,
> media_change_events would return "AN\n". It would return "\n" (no
> flags) when AN is absent. This permits future expansion of this
> capabilities reporting variable.
I'm not sure about this. AN is kind of specific term for ATA while
media change event is generic. So, I think the original approach is
okay. No matter how the actual thing is implemented, it's the same
media change event and as long as event delivery interface is the same,
upper layer shouldn't care about how it's done.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [patch 3/3] libata: handle AN interrupt
2007-03-28 23:44 ` [patch 3/3] libata: handle AN interrupt Kristen Carlson Accardi
@ 2007-03-29 2:13 ` Tejun Heo
0 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2007-03-29 2:13 UTC (permalink / raw)
To: Kristen Carlson Accardi; +Cc: linux-kernel, akpm, linux-ide, jgarzik
Kristen Carlson Accardi wrote:
> 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. The ahci host controller will send the
> event via KOBJ_CHANGE uevent.
>
> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
>
> +static void async_notify_thread(struct work_struct *work)
> +{
> + struct ata_device *atadev =
> + container_of(work, struct ata_device, async_notify);
> +
> + /*
> + * TBD - who should send this event? I couldn't find an
> + * easy way to map an ata_device to a genhd device, so
> + * decided maybe the ata host should send the event and
> + * allow user space to figure out what happened?
> + */
> + kobject_uevent(&atadev->ap->host->dev->kobj, KOBJ_CHANGE);
> +}
I don't think this is right. If you're gonna make media_change_event
capability generic, you gotta make event delivery generic too. You can
make it a genhd event and make genhd supply the interface function, say,
genhd_notify_media_change() which is then forwarded by SCSI layer.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [patch 2/3] libata: expose AN support to user space via sysfs
2007-03-29 2:07 ` Tejun Heo
@ 2007-03-29 2:19 ` Jeff Garzik
2007-03-29 2:38 ` Tejun Heo
0 siblings, 1 reply; 13+ messages in thread
From: Jeff Garzik @ 2007-03-29 2:19 UTC (permalink / raw)
To: Tejun Heo
Cc: Kristen Carlson Accardi, linux-kernel, akpm, linux-ide,
linux-scsi
Tejun Heo wrote:
> Jeff Garzik wrote:
>> Kristen Carlson Accardi wrote:
>>> Allow user space to determine if an ATAPI device supports
>>> async notification (AN) of media changes. This is done by
>>> adding a new sysfs file "async_notification" to genhd.
>>> If the file reads 1, then the device supports async notification. If
>>> the file reads 0, it does not. A flag is set in the generic disk to
>>> indicate whether
>>> or not AN is supported. This flag is set by the SCSI
>>> subsystem when it registers with add_disk. The SCSI
>>> system gets information from libata on whether the
>>> device supports AN during dev_configure.
>>> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
>>>
>>
>> 3) I would make the contents of 'media_change_events' be a list of
>> flags, rather than a boolean. Thus, when AN is present,
>> media_change_events would return "AN\n". It would return "\n" (no
>> flags) when AN is absent. This permits future expansion of this
>> capabilities reporting variable.
>
> I'm not sure about this. AN is kind of specific term for ATA while
> media change event is generic. So, I think the original approach is
> okay. No matter how the actual thing is implemented, it's the same
> media change event and as long as event delivery interface is the same,
> upper layer shouldn't care about how it's done.
AN is a generic concept that I feel will propagate elsewhere.
Though perhaps it should be in a 'capability_flags' file rather than a
'media_change_event' file.
Jeff
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [patch 2/3] libata: expose AN support to user space via sysfs
2007-03-29 2:19 ` Jeff Garzik
@ 2007-03-29 2:38 ` Tejun Heo
2007-04-05 8:03 ` Jeff Garzik
0 siblings, 1 reply; 13+ messages in thread
From: Tejun Heo @ 2007-03-29 2:38 UTC (permalink / raw)
To: Jeff Garzik
Cc: Kristen Carlson Accardi, linux-kernel, akpm, linux-ide,
linux-scsi
Jeff Garzik wrote:
> AN is a generic concept that I feel will propagate elsewhere.
I think SCSI already has it or am I imagining things again? :-)
> Though perhaps it should be in a 'capability_flags' file rather than a
> 'media_change_event' file.
IMHO, if it's genhd.capability_flags then the flag should be
MEDIA_CHANGE_NOTIFY not ASYNC_NOTIFICATION because AN itself doesn't
imply any specific event. It's just a notification mechanism, for ATAPI
devices, it means media change, for PMP it has a different meaning, so I
think we need to export the processed meaning not the specific mechanism
to userland.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [patch 2/3] libata: expose AN support to user space via sysfs
2007-03-29 2:38 ` Tejun Heo
@ 2007-04-05 8:03 ` Jeff Garzik
0 siblings, 0 replies; 13+ messages in thread
From: Jeff Garzik @ 2007-04-05 8:03 UTC (permalink / raw)
To: Tejun Heo
Cc: Kristen Carlson Accardi, linux-kernel, akpm, linux-ide,
linux-scsi
Tejun Heo wrote:
> Jeff Garzik wrote:
>> AN is a generic concept that I feel will propagate elsewhere.
>
> I think SCSI already has it or am I imagining things again? :-)
>
>> Though perhaps it should be in a 'capability_flags' file rather than a
>> 'media_change_event' file.
>
> IMHO, if it's genhd.capability_flags then the flag should be
> MEDIA_CHANGE_NOTIFY not ASYNC_NOTIFICATION because AN itself doesn't
> imply any specific event. It's just a notification mechanism, for ATAPI
> devices, it means media change, for PMP it has a different meaning, so I
> think we need to export the processed meaning not the specific mechanism
> to userland.
Agreed, sounds good.
Jeff
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2007-04-05 8:03 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20070328230108.597741522@intel.com>
2007-03-28 23:44 ` [patch 1/3] libata: check for AN support Kristen Carlson Accardi
2007-03-29 1:53 ` Tejun Heo
2007-03-29 2:02 ` Jeff Garzik
2007-03-28 23:44 ` [patch 2/3] libata: expose AN support to user space via sysfs Kristen Carlson Accardi
2007-03-29 0:15 ` Jeff Garzik
2007-03-29 2:07 ` Tejun Heo
2007-03-29 2:19 ` Jeff Garzik
2007-03-29 2:38 ` Tejun Heo
2007-04-05 8:03 ` Jeff Garzik
2007-03-29 2:04 ` Tejun Heo
2007-03-28 23:44 ` [patch 3/3] libata: handle AN interrupt Kristen Carlson Accardi
2007-03-29 2:13 ` Tejun Heo
[not found] <20070321004740.939006166@intel.com>
2007-03-21 0:52 ` [patch 2/3] libata: expose AN support to user space via sysfs Kristen Carlson Accardi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).