LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [patch 1/7] libata: check for AN support
[not found] <20070424074856.005152262@intel.com>
@ 2007-04-23 23:59 ` Kristen Carlson Accardi
2007-04-24 8:03 ` Tejun Heo
2007-04-24 8:07 ` Alan Cox
2007-04-23 23:59 ` [patch 2/7] genhd: expose AN to user space Kristen Carlson Accardi
` (8 subsequent siblings)
9 siblings, 2 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-23 23:59 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, htejun, 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-git/drivers/ata/libata-core.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-core.c
+++ 2.6-git/drivers/ata/libata-core.c
@@ -70,6 +70,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;
@@ -1744,6 +1745,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 ((ap->flags & ATA_FLAG_AN) && 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";
@@ -3525,6 +3543,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-git/include/linux/ata.h
===================================================================
--- 2.6-git.orig/include/linux/ata.h
+++ 2.6-git/include/linux/ata.h
@@ -194,6 +194,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:
@@ -299,6 +305,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-git/include/linux/libata.h
===================================================================
--- 2.6-git.orig/include/linux/libata.h
+++ 2.6-git/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 */
@@ -174,6 +175,7 @@ enum {
ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
+ ATA_FLAG_AN = (1 << 17), /* controller supports AN */
/* The following flag belongs to ap->pflags but is kept in
* ap->flags because it's referenced in many LLDs and will be
--
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 2/7] genhd: expose AN to user space
[not found] <20070424074856.005152262@intel.com>
2007-04-23 23:59 ` [patch 1/7] libata: check for AN support Kristen Carlson Accardi
@ 2007-04-23 23:59 ` Kristen Carlson Accardi
2007-04-24 8:05 ` Tejun Heo
2007-04-23 23:59 ` [patch 3/7] scsi: expose AN to user space Kristen Carlson Accardi
` (7 subsequent siblings)
9 siblings, 1 reply; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-23 23:59 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, htejun, Kristen Carlson Accardi
Allow user space to determine if a disk supports Asynchronous Notification
of media changes. This is done by adding a new sysfs file "capability_flags",
which is documented in (insert file name). This sysfs file will export all
disk capabilities flags to user space. We also define a new flag to define
the media change notification capability.
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
+++ 2.6-git/block/genhd.c
@@ -370,7 +370,10 @@ static ssize_t disk_size_read(struct gen
{
return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
}
-
+static ssize_t disk_capability_read(struct gendisk *disk, char *page)
+{
+ return sprintf(page, "%x\n", disk->flags);
+}
static ssize_t disk_stats_read(struct gendisk * disk, char *page)
{
preempt_disable();
@@ -413,6 +416,10 @@ static struct disk_attribute disk_attr_s
.attr = {.name = "size", .mode = S_IRUGO },
.show = disk_size_read
};
+static struct disk_attribute disk_attr_capability = {
+ .attr = {.name = "capability_flags", .mode = S_IRUGO },
+ .show = disk_capability_read
+};
static struct disk_attribute disk_attr_stat = {
.attr = {.name = "stat", .mode = S_IRUGO },
.show = disk_stats_read
@@ -453,6 +460,7 @@ static struct attribute * default_attrs[
&disk_attr_removable.attr,
&disk_attr_size.attr,
&disk_attr_stat.attr,
+ &disk_attr_capability.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
+++ 2.6-git/include/linux/genhd.h
@@ -94,6 +94,7 @@ struct hd_struct {
#define GENHD_FL_REMOVABLE 1
#define GENHD_FL_DRIVERFS 2
+#define GENHD_FL_MEDIA_CHANGE_NOTIFY 4
#define GENHD_FL_CD 8
#define GENHD_FL_UP 16
#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
Index: 2.6-git/Documentation/block/capability_flags.txt
===================================================================
--- /dev/null
+++ 2.6-git/Documentation/block/capability_flags.txt
@@ -0,0 +1,15 @@
+Generic Block Device Capability Flags
+===============================================================================
+This file documents the sysfs file block/<disk>/capability_flags
+
+capability_flags is a hex word indicating which capabilities a specific
+disk supports. For more information on bits not listed here, see
+include/linux/genhd.h
+
+Capability Value
+-------------------------------------------------------------------------------
+GENHD_FL_MEDIA_CHANGE_NOTIFY 4
+ When this bit is set, the disk supports Asynchronous Notification
+ of media change events. These events will be broadcast to user
+ space via kernel uevent.
+
--
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 3/7] scsi: expose AN to user space
[not found] <20070424074856.005152262@intel.com>
2007-04-23 23:59 ` [patch 1/7] libata: check for AN support Kristen Carlson Accardi
2007-04-23 23:59 ` [patch 2/7] genhd: expose AN to user space Kristen Carlson Accardi
@ 2007-04-23 23:59 ` Kristen Carlson Accardi
2007-04-24 0:00 ` [patch 4/7] libata: " Kristen Carlson Accardi
` (6 subsequent siblings)
9 siblings, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-23 23:59 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, htejun, Kristen Carlson Accardi
Get media change notification capability from disk and pass this information
to genhd by setting appropriate flag.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/scsi/sr.c
===================================================================
--- 2.6-git.orig/drivers/scsi/sr.c
+++ 2.6-git/drivers/scsi/sr.c
@@ -601,6 +601,8 @@ static int sr_probe(struct device *dev)
dev_set_drvdata(dev, cd);
disk->flags |= GENHD_FL_REMOVABLE;
+ if (sdev->media_change_notify)
+ disk->flags |= GENHD_FL_MEDIA_CHANGE_NOTIFY;
add_disk(disk);
sdev_printk(KERN_DEBUG, sdev,
Index: 2.6-git/include/scsi/scsi_device.h
===================================================================
--- 2.6-git.orig/include/scsi/scsi_device.h
+++ 2.6-git/include/scsi/scsi_device.h
@@ -124,7 +124,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 media_change_notify:1; /* dev supports async media notify */
unsigned int device_blocked; /* Device returned QUEUE_FULL. */
unsigned int max_device_blocked; /* what device_blocked counts down from */
Index: 2.6-git/drivers/scsi/sd.c
===================================================================
--- 2.6-git.orig/drivers/scsi/sd.c
+++ 2.6-git/drivers/scsi/sd.c
@@ -1706,6 +1706,9 @@ static int sd_probe(struct device *dev)
if (sdp->removable)
gd->flags |= GENHD_FL_REMOVABLE;
+ if (sdp->media_change_notify)
+ gd->flags |= GENHD_FL_MEDIA_CHANGE_NOTIFY;
+
dev_set_drvdata(dev, sdkp);
add_disk(gd);
--
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 4/7] libata: expose AN to user space
[not found] <20070424074856.005152262@intel.com>
` (2 preceding siblings ...)
2007-04-23 23:59 ` [patch 3/7] scsi: expose AN to user space Kristen Carlson Accardi
@ 2007-04-24 0:00 ` Kristen Carlson Accardi
2007-04-24 0:00 ` [patch 5/7] genhd: send async notification on media change Kristen Carlson Accardi
` (5 subsequent siblings)
9 siblings, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 0:00 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, htejun, Kristen Carlson Accardi
If Asynchronous Notification of media change events is supported,
pass that information up to the SCSI layer.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/ata/libata-scsi.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-scsi.c
+++ 2.6-git/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->media_change_notify = 1;
+
if (dev->flags & ATA_DFLAG_NCQ) {
int depth;
--
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 5/7] genhd: send async notification on media change
[not found] <20070424074856.005152262@intel.com>
` (3 preceding siblings ...)
2007-04-24 0:00 ` [patch 4/7] libata: " Kristen Carlson Accardi
@ 2007-04-24 0:00 ` Kristen Carlson Accardi
2007-04-24 8:20 ` Tejun Heo
2007-04-24 0:00 ` [patch 6/7] SCSI: save disk in scsi_device Kristen Carlson Accardi
` (4 subsequent siblings)
9 siblings, 1 reply; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 0:00 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, htejun, Kristen Carlson Accardi
Send an uevent to user space to indicate that a media change event has occurred.
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
+++ 2.6-git/block/genhd.c
@@ -643,6 +643,25 @@ struct seq_operations diskstats_op = {
.show = diskstats_show
};
+static void media_change_notify_thread(struct work_struct *work)
+{
+ struct gendisk *gd = container_of(work, struct gendisk, async_notify);
+ char event[] = "MEDIA_CHANGE=1";
+ char *envp[] = { event, NULL };
+
+ /*
+ * set enviroment vars to indicate which event this is for
+ * so that user space will know to go check the media status.
+ */
+ kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp);
+}
+
+void genhd_media_change_notify(struct gendisk *disk)
+{
+ schedule_work(&disk->async_notify);
+}
+EXPORT_SYMBOL_GPL(genhd_media_change_notify);
+
struct gendisk *alloc_disk(int minors)
{
return alloc_disk_node(minors, -1);
@@ -672,6 +691,8 @@ struct gendisk *alloc_disk_node(int mino
kobj_set_kset_s(disk,block_subsys);
kobject_init(&disk->kobj);
rand_initialize_disk(disk);
+ INIT_WORK(&disk->async_notify,
+ media_change_notify_thread);
}
return disk;
}
Index: 2.6-git/include/linux/genhd.h
===================================================================
--- 2.6-git.orig/include/linux/genhd.h
+++ 2.6-git/include/linux/genhd.h
@@ -66,6 +66,7 @@ struct partition {
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/fs.h>
+#include <linux/workqueue.h>
struct partition {
unsigned char boot_ind; /* 0x80 - active */
@@ -139,6 +140,7 @@ struct gendisk {
#else
struct disk_stats dkstats;
#endif
+ struct work_struct async_notify;
};
/* Structure for sysfs attributes on block devices */
@@ -419,7 +421,7 @@ extern struct gendisk *alloc_disk_node(i
extern struct gendisk *alloc_disk(int minors);
extern struct kobject *get_disk(struct gendisk *disk);
extern void put_disk(struct gendisk *disk);
-
+extern void genhd_media_change_notify(struct gendisk *disk);
extern void blk_register_region(dev_t dev, unsigned long range,
struct module *module,
struct kobject *(*probe)(dev_t, int *, void *),
--
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 6/7] SCSI: save disk in scsi_device
[not found] <20070424074856.005152262@intel.com>
` (4 preceding siblings ...)
2007-04-24 0:00 ` [patch 5/7] genhd: send async notification on media change Kristen Carlson Accardi
@ 2007-04-24 0:00 ` Kristen Carlson Accardi
2007-04-24 0:00 ` [patch 7/7] libata: send event when AN received Kristen Carlson Accardi
` (3 subsequent siblings)
9 siblings, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 0:00 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, htejun, Kristen Carlson Accardi
Give anyone who has access to scsi_device access to the genhd struct as well.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/scsi/sd.c
===================================================================
--- 2.6-git.orig/drivers/scsi/sd.c
+++ 2.6-git/drivers/scsi/sd.c
@@ -1711,6 +1711,7 @@ static int sd_probe(struct device *dev)
dev_set_drvdata(dev, sdkp);
add_disk(gd);
+ sdp->disk = gd;
sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n",
sdp->removable ? "removable " : "", gd->disk_name);
Index: 2.6-git/drivers/scsi/sr.c
===================================================================
--- 2.6-git.orig/drivers/scsi/sr.c
+++ 2.6-git/drivers/scsi/sr.c
@@ -604,6 +604,7 @@ static int sr_probe(struct device *dev)
if (sdev->media_change_notify)
disk->flags |= GENHD_FL_MEDIA_CHANGE_NOTIFY;
add_disk(disk);
+ sdev->disk = disk;
sdev_printk(KERN_DEBUG, sdev,
"Attached scsi CD-ROM %s\n", cd->cdi.name);
Index: 2.6-git/include/scsi/scsi_device.h
===================================================================
--- 2.6-git.orig/include/scsi/scsi_device.h
+++ 2.6-git/include/scsi/scsi_device.h
@@ -138,7 +138,7 @@ struct scsi_device {
struct device sdev_gendev;
struct class_device sdev_classdev;
-
+ struct gendisk *disk;
struct execute_work ew; /* used to get process context on put */
enum scsi_device_state sdev_state;
--
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 7/7] libata: send event when AN received
[not found] <20070424074856.005152262@intel.com>
` (5 preceding siblings ...)
2007-04-24 0:00 ` [patch 6/7] SCSI: save disk in scsi_device Kristen Carlson Accardi
@ 2007-04-24 0:00 ` Kristen Carlson Accardi
2007-04-24 8:09 ` Alan Cox
2007-05-04 18:16 ` [patch 3/7] scsi: expose AN to user space " Kristen Carlson Accardi
` (2 subsequent siblings)
9 siblings, 1 reply; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 0:00 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, htejun, 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. This will be done via the block device.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/ata/ahci.c
===================================================================
--- 2.6-git.orig/drivers/ata/ahci.c
+++ 2.6-git/drivers/ata/ahci.c
@@ -1147,6 +1147,25 @@ 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];
+ if (adev->flags & ATA_DFLAG_AN)
+ ata_scsi_media_change_notify(adev);
+ }
+ }
if (ap->sactive)
qc_active = readl(port_mmio + PORT_SCR_ACT);
else
Index: 2.6-git/include/linux/libata.h
===================================================================
--- 2.6-git.orig/include/linux/libata.h
+++ 2.6-git/include/linux/libata.h
@@ -737,6 +737,7 @@ extern void ata_host_init(struct ata_hos
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 *);
Index: 2.6-git/drivers/ata/libata-scsi.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-scsi.c
+++ 2.6-git/drivers/ata/libata-scsi.c
@@ -3057,6 +3057,22 @@ static void ata_scsi_remove_dev(struct a
}
/**
+ * 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)
+{
+ genhd_media_change_notify(atadev->sdev->disk);
+}
+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
*
--
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-23 23:59 ` [patch 1/7] libata: check for AN support Kristen Carlson Accardi
@ 2007-04-24 8:03 ` Tejun Heo
2007-04-24 15:54 ` Kristen Carlson Accardi
2007-04-24 8:07 ` Alan Cox
1 sibling, 1 reply; 39+ messages in thread
From: Tejun Heo @ 2007-04-24 8:03 UTC (permalink / raw)
To: Kristen Carlson Accardi; +Cc: jeff, linux-kernel, linux-scsi, linux-ide
Hello,
Kristen Carlson Accardi wrote:
> static unsigned int ata_print_id = 1;
> @@ -1744,6 +1745,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 ((ap->flags & ATA_FLAG_AN) && ata_id_has_AN(id))
> + {
> + /* issue SET feature command to turn this on */
> + rc = ata_dev_set_AN(dev);
Please don't store err_mask into int rc. Please store it to a separate
err_mask variable and report it when printing error message.
> + if (rc) {
> + ata_dev_printk(dev, KERN_ERR,
> + "unable to set AN\n");
> + rc = -EINVAL;
Wouldn't -EIO be more appropriate?
> + goto err_out_nosup;
> + }
> + dev->flags |= ATA_DFLAG_AN;
> + }
> +
Not NACKing. Just notes for future improvements. We need to be more
careful here. ATA/ATAPI world is filled with braindamaged devices and I
bet there are devices which advertises it can do AN but chokes when AN
is enabled.
This should be handled similarly to ACPI failure. Currently ACPI does
the following.
1. try once, if fail, record that ACPI failed. return error to trigger
retry.
2. try again, if fail again, ignore error if possible (!FROZEN) and turn
off ACPI.
This fallback mechanism for optional features can probably be
generalized and used for both ACPI and AN.
--
tejun
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 2/7] genhd: expose AN to user space
2007-04-23 23:59 ` [patch 2/7] genhd: expose AN to user space Kristen Carlson Accardi
@ 2007-04-24 8:05 ` Tejun Heo
2007-04-24 21:30 ` Kristen Carlson Accardi
2007-05-04 18:15 ` [patch 2/7] genhd: expose AN to user space - resend Kristen Carlson Accardi
0 siblings, 2 replies; 39+ messages in thread
From: Tejun Heo @ 2007-04-24 8:05 UTC (permalink / raw)
To: Kristen Carlson Accardi; +Cc: jeff, linux-kernel, linux-scsi, linux-ide
Kristen Carlson Accardi wrote:
> +static struct disk_attribute disk_attr_capability = {
> + .attr = {.name = "capability_flags", .mode = S_IRUGO },
> + .show = disk_capability_read
> +};
How about just "capability"? I think that would be more consistent with
other attributes.
--
tejun
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-23 23:59 ` [patch 1/7] libata: check for AN support Kristen Carlson Accardi
2007-04-24 8:03 ` Tejun Heo
@ 2007-04-24 8:07 ` Alan Cox
2007-04-24 10:23 ` Olivier Galibert
1 sibling, 1 reply; 39+ messages in thread
From: Alan Cox @ 2007-04-24 8:07 UTC (permalink / raw)
To: Kristen Carlson Accardi
Cc: jeff, linux-kernel, linux-scsi, linux-ide, htejun,
Kristen Carlson Accardi
> + /*
> + * check to see if this ATAPI device supports
> + * Asynchronous Notification
> + */
> + if ((ap->flags & ATA_FLAG_AN) && ata_id_has_AN(id))
> + {
Bracketing police ^^^
> + /* 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;
How fatal is this - do we need to ignore the device at this point or
should we just pretend (possibly correctly) that the device itself does
not support notification.
> @@ -299,6 +305,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)))
Might be nice to check ATA version as well to be paranoid but this all
looks ok as its a reserved field since way back when.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 7/7] libata: send event when AN received
2007-04-24 0:00 ` [patch 7/7] libata: send event when AN received Kristen Carlson Accardi
@ 2007-04-24 8:09 ` Alan Cox
2007-04-24 21:38 ` Kristen Carlson Accardi
2007-05-04 18:18 ` [patch 7/7] libata: send event when AN received - resend Kristen Carlson Accardi
0 siblings, 2 replies; 39+ messages in thread
From: Alan Cox @ 2007-04-24 8:09 UTC (permalink / raw)
To: Kristen Carlson Accardi
Cc: jeff, linux-kernel, linux-scsi, linux-ide, htejun,
Kristen Carlson Accardi
> + /* 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];
You can't be sure that the port_addr returned will be in range if a
device is malfunctioning...
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 5/7] genhd: send async notification on media change
2007-04-24 0:00 ` [patch 5/7] genhd: send async notification on media change Kristen Carlson Accardi
@ 2007-04-24 8:20 ` Tejun Heo
2007-04-24 21:36 ` Kristen Carlson Accardi
2007-05-04 18:17 ` Kristen Carlson Accardi
0 siblings, 2 replies; 39+ messages in thread
From: Tejun Heo @ 2007-04-24 8:20 UTC (permalink / raw)
To: Kristen Carlson Accardi; +Cc: jeff, linux-kernel, linux-scsi, linux-ide
Kristen Carlson Accardi wrote:
> Send an uevent to user space to indicate that a media change event has occurred.
>
> 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
> +++ 2.6-git/block/genhd.c
> @@ -643,6 +643,25 @@ struct seq_operations diskstats_op = {
> .show = diskstats_show
> };
>
> +static void media_change_notify_thread(struct work_struct *work)
> +{
> + struct gendisk *gd = container_of(work, struct gendisk, async_notify);
> + char event[] = "MEDIA_CHANGE=1";
> + char *envp[] = { event, NULL };
> +
> + /*
> + * set enviroment vars to indicate which event this is for
> + * so that user space will know to go check the media status.
> + */
> + kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp);
> +}
> +
> +void genhd_media_change_notify(struct gendisk *disk)
> +{
> + schedule_work(&disk->async_notify);
> +}
> +EXPORT_SYMBOL_GPL(genhd_media_change_notify);
genhd might go away while async_notify work is in-flight. You'll need
to either grab a reference or wait for the work to finish in release
routine.
--
tejun
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-24 8:07 ` Alan Cox
@ 2007-04-24 10:23 ` Olivier Galibert
2007-04-24 15:49 ` Kristen Carlson Accardi
0 siblings, 1 reply; 39+ messages in thread
From: Olivier Galibert @ 2007-04-24 10:23 UTC (permalink / raw)
To: Kristen Carlson Accardi
Cc: Alan Cox, jeff, linux-kernel, linux-scsi, linux-ide, htejun
Sorry for replying to Alan's reply, I missed the original mail.
> > +#define ata_id_has_AN(id) \
> > + ((id[76] && (~id[76])) & ((id)[78] & (1 << 5)))
(a && ~a) & (b & 32)
I don't think that does what you think it does, because at that point
it's a funny way to write 0 ((0 or 1) binary-and (0 or 32)).
I'm not even sure what it is you want. If for the first part you
wanted (id[76] != 0x00 && id[76] != 0xff), please write just that,
thanks :-)
OG.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-24 10:23 ` Olivier Galibert
@ 2007-04-24 15:49 ` Kristen Carlson Accardi
2007-04-24 18:05 ` Olivier Galibert
0 siblings, 1 reply; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 15:49 UTC (permalink / raw)
To: Olivier Galibert
Cc: Alan Cox, jeff, linux-kernel, linux-scsi, linux-ide, htejun
On Tue, 24 Apr 2007 12:23:04 +0200
Olivier Galibert <galibert@pobox.com> wrote:
> Sorry for replying to Alan's reply, I missed the original mail.
>
> > > +#define ata_id_has_AN(id) \
> > > + ((id[76] && (~id[76])) & ((id)[78] & (1 << 5)))
>
> (a && ~a) & (b & 32)
>
> I don't think that does what you think it does, because at that point
> it's a funny way to write 0 ((0 or 1) binary-and (0 or 32)).
>
> I'm not even sure what it is you want. If for the first part you
> wanted (id[76] != 0x00 && id[76] != 0xff), please write just that,
> thanks :-)
>
> OG.
>
>From the serial ata spec, we have:
13.2.1.18 Word 78: Serial ATA features supported
If Word 76 is not 0000h or FFFFh, Word 78 reports the optional features
supported by the device. Support for this word is optional and if not
supported the word shall be zero indicating the device has no support for new
Serial ATA capabilities.
so, basically yes, I'm really testing to make sure that word 76 isn't 0 or all
one then using that value & with value of bit in work 78 to determine AN
support - if you think this is really obfuscated, I've got no problem changing
it - there's obviously many ways to mess around with bits.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-24 8:03 ` Tejun Heo
@ 2007-04-24 15:54 ` Kristen Carlson Accardi
0 siblings, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 15:54 UTC (permalink / raw)
To: Tejun Heo; +Cc: jeff, linux-kernel, linux-scsi, linux-ide
On Tue, 24 Apr 2007 17:03:29 +0900
Tejun Heo <htejun@gmail.com> wrote:
> Hello,
>
> Kristen Carlson Accardi wrote:
> > static unsigned int ata_print_id = 1;
> > @@ -1744,6 +1745,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 ((ap->flags & ATA_FLAG_AN) && ata_id_has_AN(id))
> > + {
> > + /* issue SET feature command to turn this on */
> > + rc = ata_dev_set_AN(dev);
>
> Please don't store err_mask into int rc. Please store it to a separate
> err_mask variable and report it when printing error message.
>
> > + if (rc) {
> > + ata_dev_printk(dev, KERN_ERR,
> > + "unable to set AN\n");
> > + rc = -EINVAL;
>
> Wouldn't -EIO be more appropriate?
I think Alan is right - and being unable to turn on AN should not be fatal.
I'll just change all this code to just print the err and keep going.
>
> > + goto err_out_nosup;
> > + }
> > + dev->flags |= ATA_DFLAG_AN;
> > + }
> > +
>
> Not NACKing. Just notes for future improvements. We need to be more
> careful here. ATA/ATAPI world is filled with braindamaged devices and I
> bet there are devices which advertises it can do AN but chokes when AN
> is enabled.
>
> This should be handled similarly to ACPI failure. Currently ACPI does
> the following.
>
> 1. try once, if fail, record that ACPI failed. return error to trigger
> retry.
> 2. try again, if fail again, ignore error if possible (!FROZEN) and turn
> off ACPI.
>
> This fallback mechanism for optional features can probably be
> generalized and used for both ACPI and AN.
Ok - meanwhile I think it's appropriate here to just do try-once-fail-give-up.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-24 15:49 ` Kristen Carlson Accardi
@ 2007-04-24 18:05 ` Olivier Galibert
2007-04-24 18:29 ` Kristen Carlson Accardi
2007-04-24 20:53 ` Kristen Carlson Accardi
0 siblings, 2 replies; 39+ messages in thread
From: Olivier Galibert @ 2007-04-24 18:05 UTC (permalink / raw)
To: Kristen Carlson Accardi
Cc: Alan Cox, jeff, linux-kernel, linux-scsi, linux-ide, htejun
On Tue, Apr 24, 2007 at 08:49:04AM -0700, Kristen Carlson Accardi wrote:
> On Tue, 24 Apr 2007 12:23:04 +0200
> Olivier Galibert <galibert@pobox.com> wrote:
>
> > Sorry for replying to Alan's reply, I missed the original mail.
> >
> > > > +#define ata_id_has_AN(id) \
> > > > + ((id[76] && (~id[76])) & ((id)[78] & (1 << 5)))
> >
> > (a && ~a) & (b & 32)
> >
> > I don't think that does what you think it does, because at that point
> > it's a funny way to write 0 ((0 or 1) binary-and (0 or 32)).
> >
> > I'm not even sure what it is you want. If for the first part you
> > wanted (id[76] != 0x00 && id[76] != 0xff), please write just that,
> > thanks :-)
> >
> > OG.
> >
>
> >From the serial ata spec, we have:
>
> 13.2.1.18 Word 78: Serial ATA features supported
> If Word 76 is not 0000h or FFFFh, Word 78 reports the optional features
> supported by the device. Support for this word is optional and if not
> supported the word shall be zero indicating the device has no support for new
> Serial ATA capabilities.
>
> so, basically yes, I'm really testing to make sure that word 76 isn't 0 or all
> one then using that value & with value of bit in work 78 to determine AN
> support - if you think this is really obfuscated, I've got no problem changing
> it - there's obviously many ways to mess around with bits.
& is not &&, so right now it's really incorrect. 1 & 32 is 0.
((id)[76] != 0x0000 && (id)[76] != 0xffff && ((id)[78] & (1 << 5)))
The implicit typing of id looks dangerous to me, but you're not the
one who has started it.
OG.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-24 18:05 ` Olivier Galibert
@ 2007-04-24 18:29 ` Kristen Carlson Accardi
2007-04-24 20:53 ` Kristen Carlson Accardi
1 sibling, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 18:29 UTC (permalink / raw)
To: Olivier Galibert
Cc: Alan Cox, jeff, linux-kernel, linux-scsi, linux-ide, htejun
On Tue, 24 Apr 2007 20:05:52 +0200
Olivier Galibert <galibert@pobox.com> wrote:
> On Tue, Apr 24, 2007 at 08:49:04AM -0700, Kristen Carlson Accardi wrote:
> > On Tue, 24 Apr 2007 12:23:04 +0200
> > Olivier Galibert <galibert@pobox.com> wrote:
> >
> > > Sorry for replying to Alan's reply, I missed the original mail.
> > >
> > > > > +#define ata_id_has_AN(id) \
> > > > > + ((id[76] && (~id[76])) & ((id)[78] & (1 << 5)))
> > >
> > > (a && ~a) & (b & 32)
> > >
> > > I don't think that does what you think it does, because at that point
> > > it's a funny way to write 0 ((0 or 1) binary-and (0 or 32)).
> > >
> > > I'm not even sure what it is you want. If for the first part you
> > > wanted (id[76] != 0x00 && id[76] != 0xff), please write just that,
> > > thanks :-)
> > >
> > > OG.
> > >
> >
> > >From the serial ata spec, we have:
> >
> > 13.2.1.18 Word 78: Serial ATA features supported
> > If Word 76 is not 0000h or FFFFh, Word 78 reports the optional features
> > supported by the device. Support for this word is optional and if not
> > supported the word shall be zero indicating the device has no support for new
> > Serial ATA capabilities.
> >
> > so, basically yes, I'm really testing to make sure that word 76 isn't 0 or all
> > one then using that value & with value of bit in work 78 to determine AN
> > support - if you think this is really obfuscated, I've got no problem changing
> > it - there's obviously many ways to mess around with bits.
>
> & is not &&, so right now it's really incorrect. 1 & 32 is 0.
ah - ok, gotcha, thanks.
>
> ((id)[76] != 0x0000 && (id)[76] != 0xffff && ((id)[78] & (1 << 5)))
>
> The implicit typing of id looks dangerous to me, but you're not the
> one who has started it.
>
> OG.
>
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-24 18:05 ` Olivier Galibert
2007-04-24 18:29 ` Kristen Carlson Accardi
@ 2007-04-24 20:53 ` Kristen Carlson Accardi
2007-04-25 0:49 ` Olivier Galibert
1 sibling, 1 reply; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 20:53 UTC (permalink / raw)
To: Olivier Galibert
Cc: Alan Cox, jeff, linux-kernel, linux-scsi, linux-ide, htejun
Check to see if an ATAPI device supports Asynchronous Notification.
If so, enable it.
changes from last version:
* fix typo in ata_id_has_AN and make word 76 test more clear
* If we fail to set the AN feature, just print a warning and continue
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/ata/libata-core.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-core.c
+++ 2.6-git/drivers/ata/libata-core.c
@@ -70,6 +70,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;
@@ -1744,6 +1745,22 @@ int ata_dev_configure(struct ata_device
}
dev->cdb_len = (unsigned int) rc;
+ /*
+ * check to see if this ATAPI device supports
+ * Asynchronous Notification
+ */
+ if ((ap->flags & ATA_FLAG_AN) && ata_id_has_AN(id)) {
+ int err;
+ /* issue SET feature command to turn this on */
+ err = ata_dev_set_AN(dev);
+ if (err)
+ ata_dev_printk(dev, KERN_ERR,
+ "unable to set AN, err %x\n",
+ err);
+ else
+ dev->flags |= ATA_DFLAG_AN;
+ }
+
if (ata_id_cdb_intr(dev->id)) {
dev->flags |= ATA_DFLAG_CDB_INTR;
cdb_intr_string = ", CDB intr";
@@ -3525,6 +3542,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-git/include/linux/ata.h
===================================================================
--- 2.6-git.orig/include/linux/ata.h
+++ 2.6-git/include/linux/ata.h
@@ -194,6 +194,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:
@@ -299,6 +305,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] != 0x0000) && (id[76] != 0xffff)) && ((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-git/include/linux/libata.h
===================================================================
--- 2.6-git.orig/include/linux/libata.h
+++ 2.6-git/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 */
@@ -174,6 +175,7 @@ enum {
ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
+ ATA_FLAG_AN = (1 << 17), /* controller supports AN */
/* The following flag belongs to ap->pflags but is kept in
* ap->flags because it's referenced in many LLDs and will be
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 2/7] genhd: expose AN to user space
2007-04-24 8:05 ` Tejun Heo
@ 2007-04-24 21:30 ` Kristen Carlson Accardi
2007-05-04 18:15 ` [patch 2/7] genhd: expose AN to user space - resend Kristen Carlson Accardi
1 sibling, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 21:30 UTC (permalink / raw)
To: Tejun Heo; +Cc: jeff, linux-kernel, linux-scsi, linux-ide
Allow user space to determine if a disk supports Asynchronous Notification
of media changes. This is done by adding a new sysfs file "capability_flags",
which is documented in (insert file name). This sysfs file will export all
disk capabilities flags to user space. We also define a new flag to define
the media change notification capability.
Changed from last version:
* changed sysfs filename to "capability" from "capability_flags"
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
+++ 2.6-git/block/genhd.c
@@ -370,7 +370,10 @@ static ssize_t disk_size_read(struct gen
{
return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
}
-
+static ssize_t disk_capability_read(struct gendisk *disk, char *page)
+{
+ return sprintf(page, "%x\n", disk->flags);
+}
static ssize_t disk_stats_read(struct gendisk * disk, char *page)
{
preempt_disable();
@@ -413,6 +416,10 @@ static struct disk_attribute disk_attr_s
.attr = {.name = "size", .mode = S_IRUGO },
.show = disk_size_read
};
+static struct disk_attribute disk_attr_capability = {
+ .attr = {.name = "capability", .mode = S_IRUGO },
+ .show = disk_capability_read
+};
static struct disk_attribute disk_attr_stat = {
.attr = {.name = "stat", .mode = S_IRUGO },
.show = disk_stats_read
@@ -453,6 +460,7 @@ static struct attribute * default_attrs[
&disk_attr_removable.attr,
&disk_attr_size.attr,
&disk_attr_stat.attr,
+ &disk_attr_capability.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
+++ 2.6-git/include/linux/genhd.h
@@ -94,6 +94,7 @@ struct hd_struct {
#define GENHD_FL_REMOVABLE 1
#define GENHD_FL_DRIVERFS 2
+#define GENHD_FL_MEDIA_CHANGE_NOTIFY 4
#define GENHD_FL_CD 8
#define GENHD_FL_UP 16
#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
Index: 2.6-git/Documentation/block/capability.txt
===================================================================
--- /dev/null
+++ 2.6-git/Documentation/block/capability.txt
@@ -0,0 +1,15 @@
+Generic Block Device Capability
+===============================================================================
+This file documents the sysfs file block/<disk>/capability
+
+capability is a hex word indicating which capabilities a specific disk
+supports. For more information on bits not listed here, see
+include/linux/genhd.h
+
+Capability Value
+-------------------------------------------------------------------------------
+GENHD_FL_MEDIA_CHANGE_NOTIFY 4
+ When this bit is set, the disk supports Asynchronous Notification
+ of media change events. These events will be broadcast to user
+ space via kernel uevent.
+
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 5/7] genhd: send async notification on media change
2007-04-24 8:20 ` Tejun Heo
@ 2007-04-24 21:36 ` Kristen Carlson Accardi
2007-05-04 18:17 ` Kristen Carlson Accardi
1 sibling, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 21:36 UTC (permalink / raw)
To: Tejun Heo; +Cc: jeff, linux-kernel, linux-scsi, linux-ide
Send an uevent to user space to indicate that a media change event has occurred.
Changes from last version:
* use get/put_device to increment reference count on the device struct
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
+++ 2.6-git/block/genhd.c
@@ -643,6 +643,27 @@ struct seq_operations diskstats_op = {
.show = diskstats_show
};
+static void media_change_notify_thread(struct work_struct *work)
+{
+ struct gendisk *gd = container_of(work, struct gendisk, async_notify);
+ char event[] = "MEDIA_CHANGE=1";
+ char *envp[] = { event, NULL };
+
+ /*
+ * set enviroment vars to indicate which event this is for
+ * so that user space will know to go check the media status.
+ */
+ kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp);
+ put_device(gd->driverfs_dev);
+}
+
+void genhd_media_change_notify(struct gendisk *disk)
+{
+ get_device(disk->driverfs_dev);
+ schedule_work(&disk->async_notify);
+}
+EXPORT_SYMBOL_GPL(genhd_media_change_notify);
+
struct gendisk *alloc_disk(int minors)
{
return alloc_disk_node(minors, -1);
@@ -672,6 +693,8 @@ struct gendisk *alloc_disk_node(int mino
kobj_set_kset_s(disk,block_subsys);
kobject_init(&disk->kobj);
rand_initialize_disk(disk);
+ INIT_WORK(&disk->async_notify,
+ media_change_notify_thread);
}
return disk;
}
Index: 2.6-git/include/linux/genhd.h
===================================================================
--- 2.6-git.orig/include/linux/genhd.h
+++ 2.6-git/include/linux/genhd.h
@@ -66,6 +66,7 @@ struct partition {
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/fs.h>
+#include <linux/workqueue.h>
struct partition {
unsigned char boot_ind; /* 0x80 - active */
@@ -139,6 +140,7 @@ struct gendisk {
#else
struct disk_stats dkstats;
#endif
+ struct work_struct async_notify;
};
/* Structure for sysfs attributes on block devices */
@@ -419,7 +421,7 @@ extern struct gendisk *alloc_disk_node(i
extern struct gendisk *alloc_disk(int minors);
extern struct kobject *get_disk(struct gendisk *disk);
extern void put_disk(struct gendisk *disk);
-
+extern void genhd_media_change_notify(struct gendisk *disk);
extern void blk_register_region(dev_t dev, unsigned long range,
struct module *module,
struct kobject *(*probe)(dev_t, int *, void *),
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 7/7] libata: send event when AN received
2007-04-24 8:09 ` Alan Cox
@ 2007-04-24 21:38 ` Kristen Carlson Accardi
2007-05-04 18:18 ` [patch 7/7] libata: send event when AN received - resend Kristen Carlson Accardi
1 sibling, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-24 21:38 UTC (permalink / raw)
To: Alan Cox; +Cc: jeff, linux-kernel, linux-scsi, linux-ide, htejun
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 block device.
changed from last version:
* Make sure that port_addr is within ATA_MAX_DEVICES
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/ata/ahci.c
===================================================================
--- 2.6-git.orig/drivers/ata/ahci.c
+++ 2.6-git/drivers/ata/ahci.c
@@ -1147,6 +1147,28 @@ 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;
+ if (port_addr < ATA_MAX_DEVICES) {
+ adev = &ap->device[port_addr];
+ if (adev->flags & ATA_DFLAG_AN)
+ ata_scsi_media_change_notify(adev);
+ }
+ }
+ }
if (ap->sactive)
qc_active = readl(port_mmio + PORT_SCR_ACT);
else
Index: 2.6-git/include/linux/libata.h
===================================================================
--- 2.6-git.orig/include/linux/libata.h
+++ 2.6-git/include/linux/libata.h
@@ -737,6 +737,7 @@ extern void ata_host_init(struct ata_hos
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 *);
Index: 2.6-git/drivers/ata/libata-scsi.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-scsi.c
+++ 2.6-git/drivers/ata/libata-scsi.c
@@ -3057,6 +3057,22 @@ static void ata_scsi_remove_dev(struct a
}
/**
+ * 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)
+{
+ genhd_media_change_notify(atadev->sdev->disk);
+}
+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
*
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-24 20:53 ` Kristen Carlson Accardi
@ 2007-04-25 0:49 ` Olivier Galibert
2007-04-25 17:55 ` Kristen Carlson Accardi
` (2 more replies)
0 siblings, 3 replies; 39+ messages in thread
From: Olivier Galibert @ 2007-04-25 0:49 UTC (permalink / raw)
To: Kristen Carlson Accardi
Cc: Alan Cox, jeff, linux-kernel, linux-scsi, linux-ide, htejun
On Tue, Apr 24, 2007 at 01:53:27PM -0700, Kristen Carlson Accardi wrote:
> Check to see if an ATAPI device supports Asynchronous Notification.
> If so, enable it.
>
> changes from last version:
> * fix typo in ata_id_has_AN and make word 76 test more clear
> * If we fail to set the AN feature, just print a warning and continue
>
> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
>
> @@ -299,6 +305,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] != 0x0000) && (id[76] != 0xffff)) && ((id)[78] & (1 << 5)))
(id)[76] I guess ? Sorry for being a pain :/
OG.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-25 0:49 ` Olivier Galibert
@ 2007-04-25 17:55 ` Kristen Carlson Accardi
2007-04-25 18:40 ` Kristen Carlson Accardi
2007-05-04 18:14 ` [patch 1/7] libata: check for AN support - resend Kristen Carlson Accardi
2 siblings, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-25 17:55 UTC (permalink / raw)
To: Olivier Galibert
Cc: Alan Cox, jeff, linux-kernel, linux-scsi, linux-ide, htejun
On Wed, 25 Apr 2007 02:49:46 +0200
Olivier Galibert <galibert@pobox.com> wrote:
> On Tue, Apr 24, 2007 at 01:53:27PM -0700, Kristen Carlson Accardi wrote:
> > Check to see if an ATAPI device supports Asynchronous Notification.
> > If so, enable it.
> >
> > changes from last version:
> > * fix typo in ata_id_has_AN and make word 76 test more clear
> > * If we fail to set the AN feature, just print a warning and continue
> >
> > Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
> >
> > @@ -299,6 +305,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] != 0x0000) && (id[76] != 0xffff)) && ((id)[78] & (1 << 5)))
>
> (id)[76] I guess ? Sorry for being a pain :/
>
> OG.
>
Ok - I'll fix that. Thank you for being a pain :), I really appreciate
the time you are taking to review my patches.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-25 0:49 ` Olivier Galibert
2007-04-25 17:55 ` Kristen Carlson Accardi
@ 2007-04-25 18:40 ` Kristen Carlson Accardi
2007-04-25 19:16 ` Matt Sealey
2007-05-04 18:14 ` [patch 1/7] libata: check for AN support - resend Kristen Carlson Accardi
2 siblings, 1 reply; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-25 18:40 UTC (permalink / raw)
To: Olivier Galibert
Cc: Alan Cox, jeff, linux-kernel, linux-scsi, linux-ide, htejun
Check to see if an ATAPI device supports Asynchronous Notification.
If so, enable it.
Changes from last version:
* use parens around id in ata.h
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/ata/libata-core.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-core.c
+++ 2.6-git/drivers/ata/libata-core.c
@@ -70,6 +70,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;
@@ -1744,6 +1745,22 @@ int ata_dev_configure(struct ata_device
}
dev->cdb_len = (unsigned int) rc;
+ /*
+ * check to see if this ATAPI device supports
+ * Asynchronous Notification
+ */
+ if ((ap->flags & ATA_FLAG_AN) && ata_id_has_AN(id)) {
+ int err;
+ /* issue SET feature command to turn this on */
+ err = ata_dev_set_AN(dev);
+ if (err)
+ ata_dev_printk(dev, KERN_ERR,
+ "unable to set AN, err %x\n",
+ err);
+ else
+ dev->flags |= ATA_DFLAG_AN;
+ }
+
if (ata_id_cdb_intr(dev->id)) {
dev->flags |= ATA_DFLAG_CDB_INTR;
cdb_intr_string = ", CDB intr";
@@ -3525,6 +3542,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-git/include/linux/ata.h
===================================================================
--- 2.6-git.orig/include/linux/ata.h
+++ 2.6-git/include/linux/ata.h
@@ -194,6 +194,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:
@@ -299,6 +305,9 @@ 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] != 0x0000) && ((id)[76] != 0xffff)) && \
+ ((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-git/include/linux/libata.h
===================================================================
--- 2.6-git.orig/include/linux/libata.h
+++ 2.6-git/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 */
@@ -174,6 +175,7 @@ enum {
ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
+ ATA_FLAG_AN = (1 << 17), /* controller supports AN */
/* The following flag belongs to ap->pflags but is kept in
* ap->flags because it's referenced in many LLDs and will be
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-25 18:40 ` Kristen Carlson Accardi
@ 2007-04-25 19:16 ` Matt Sealey
2007-04-25 20:34 ` Kristen Carlson Accardi
2007-04-25 20:40 ` Olivier Galibert
0 siblings, 2 replies; 39+ messages in thread
From: Matt Sealey @ 2007-04-25 19:16 UTC (permalink / raw)
To: Kristen Carlson Accardi
Cc: Olivier Galibert, Alan Cox, jeff, linux-kernel, linux-scsi,
linux-ide, htejun
Kristen Carlson Accardi wrote:
> Check to see if an ATAPI device supports Asynchronous Notification.
> If so, enable it.
>
> Changes from last version:
> * use parens around id in ata.h
>
> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
>
> Index: 2.6-git/drivers/ata/libata-core.c
> ===================================================================
> --- 2.6-git.orig/drivers/ata/libata-core.c
> +++ 2.6-git/drivers/ata/libata-core.c
> @@ -70,6 +70,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;
> @@ -1744,6 +1745,22 @@ int ata_dev_configure(struct ata_device
> }
> dev->cdb_len = (unsigned int) rc;
>
> + /*
> + * check to see if this ATAPI device supports
> + * Asynchronous Notification
> + */
> + if ((ap->flags & ATA_FLAG_AN) && ata_id_has_AN(id)) {
> + int err;
> + /* issue SET feature command to turn this on */
> + err = ata_dev_set_AN(dev);
> + if (err)
> + ata_dev_printk(dev, KERN_ERR,
> + "unable to set AN, err %x\n",
> + err);
> + else
> + dev->flags |= ATA_DFLAG_AN;
> + }
> +
> if (ata_id_cdb_intr(dev->id)) {
> dev->flags |= ATA_DFLAG_CDB_INTR;
> cdb_intr_string = ", CDB intr";
> @@ -3525,6 +3542,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-git/include/linux/ata.h
> ===================================================================
> --- 2.6-git.orig/include/linux/ata.h
> +++ 2.6-git/include/linux/ata.h
> @@ -194,6 +194,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:
> @@ -299,6 +305,9 @@ 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] != 0x0000) && ((id)[76] != 0xffff)) && \
> + ((id)[78] & (1 << 5)) )
??
> --- 2.6-git.orig/include/linux/libata.h
> +++ 2.6-git/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,
Why don't the macros use the enums? It makes the code hard to read without
painful cross-reference doesn't it? Surely (id)[76] & (ATA_DFLAG_AN) is a
lot more readable than 1 << 5 - even if the flag is obviously that, a lot
of values and registers can have 1 << 5 as a flag and mean a lot of different
things.
--
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-25 19:16 ` Matt Sealey
@ 2007-04-25 20:34 ` Kristen Carlson Accardi
2007-04-25 20:59 ` Matt Sealey
2007-04-25 20:40 ` Olivier Galibert
1 sibling, 1 reply; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-04-25 20:34 UTC (permalink / raw)
To: Matt Sealey
Cc: Olivier Galibert, Alan Cox, jeff, linux-kernel, linux-scsi,
linux-ide, htejun
On Wed, 25 Apr 2007 20:16:51 +0100
Matt Sealey <matt@genesi-usa.com> wrote:
> > +#define ata_id_has_AN(id) \
> > + ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
> > + ((id)[78] & (1 << 5)) )
>
> ??
>
> > --- 2.6-git.orig/include/linux/libata.h
> > +++ 2.6-git/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,
>
> Why don't the macros use the enums? It makes the code hard to read without
> painful cross-reference doesn't it? Surely (id)[76] & (ATA_DFLAG_AN) is a
> lot more readable than 1 << 5 - even if the flag is obviously that, a lot
> of values and registers can have 1 << 5 as a flag and mean a lot of different
> things.
It's really just a coincidence that the ATA_DFLAG_AN bit is the same as the bit
in the identify device word, so this would not be appropriate.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-25 19:16 ` Matt Sealey
2007-04-25 20:34 ` Kristen Carlson Accardi
@ 2007-04-25 20:40 ` Olivier Galibert
1 sibling, 0 replies; 39+ messages in thread
From: Olivier Galibert @ 2007-04-25 20:40 UTC (permalink / raw)
To: Matt Sealey
Cc: Kristen Carlson Accardi, Alan Cox, jeff, linux-kernel,
linux-scsi, linux-ide, htejun
On Wed, Apr 25, 2007 at 08:16:51PM +0100, Matt Sealey wrote:
> > +#define ata_id_has_AN(id) \
> > + ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
> > + ((id)[78] & (1 << 5)) )
>
> ??
>
> > --- 2.6-git.orig/include/linux/libata.h
> > +++ 2.6-git/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,
>
> Why don't the macros use the enums? It makes the code hard to read without
> painful cross-reference doesn't it? Surely (id)[76] & (ATA_DFLAG_AN) is a
> lot more readable than 1 << 5 - even if the flag is obviously that, a lot
> of values and registers can have 1 << 5 as a flag and mean a lot of different
> things.
The two being 32 is just a coincidence. One is a hardware register
bit, the other the signification of the bits of ata_device->flags.
OG.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 1/7] libata: check for AN support
2007-04-25 20:34 ` Kristen Carlson Accardi
@ 2007-04-25 20:59 ` Matt Sealey
0 siblings, 0 replies; 39+ messages in thread
From: Matt Sealey @ 2007-04-25 20:59 UTC (permalink / raw)
To: Kristen Carlson Accardi
Cc: Olivier Galibert, Alan Cox, jeff, linux-kernel, linux-scsi,
linux-ide, htejun
Kristen Carlson Accardi wrote:
> On Wed, 25 Apr 2007 20:16:51 +0100
> Matt Sealey <matt@genesi-usa.com> wrote:
>
>>> +#define ata_id_has_AN(id) \
>>> + ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
>>> + ((id)[78] & (1 << 5)) )
>> ??
>>
>>> --- 2.6-git.orig/include/linux/libata.h
>>> +++ 2.6-git/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,
>> Why don't the macros use the enums? It makes the code hard to read without
>> painful cross-reference doesn't it? Surely (id)[76] & (ATA_DFLAG_AN) is a
>> lot more readable than 1 << 5 - even if the flag is obviously that, a lot
>> of values and registers can have 1 << 5 as a flag and mean a lot of different
>> things.
>
> It's really just a coincidence that the ATA_DFLAG_AN bit is the same as the bit
> in the identify device word, so this would not be appropriate.
Okay, that makes sense.. I just had a bad day cross-referencing some terrible
code in another project, was in the mood to nit :D
--
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 1/7] libata: check for AN support - resend
2007-04-25 0:49 ` Olivier Galibert
2007-04-25 17:55 ` Kristen Carlson Accardi
2007-04-25 18:40 ` Kristen Carlson Accardi
@ 2007-05-04 18:14 ` Kristen Carlson Accardi
2 siblings, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-05-04 18:14 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, htejun, akpm
Check to see if an ATAPI device supports Asynchronous Notification.
If so, enable it.
Changes from last version:
* use parens around id in ata.h
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/ata/libata-core.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-core.c
+++ 2.6-git/drivers/ata/libata-core.c
@@ -70,6 +70,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;
@@ -1744,6 +1745,22 @@ int ata_dev_configure(struct ata_device
}
dev->cdb_len = (unsigned int) rc;
+ /*
+ * check to see if this ATAPI device supports
+ * Asynchronous Notification
+ */
+ if ((ap->flags & ATA_FLAG_AN) && ata_id_has_AN(id)) {
+ int err;
+ /* issue SET feature command to turn this on */
+ err = ata_dev_set_AN(dev);
+ if (err)
+ ata_dev_printk(dev, KERN_ERR,
+ "unable to set AN, err %x\n",
+ err);
+ else
+ dev->flags |= ATA_DFLAG_AN;
+ }
+
if (ata_id_cdb_intr(dev->id)) {
dev->flags |= ATA_DFLAG_CDB_INTR;
cdb_intr_string = ", CDB intr";
@@ -3525,6 +3542,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-git/include/linux/ata.h
===================================================================
--- 2.6-git.orig/include/linux/ata.h
+++ 2.6-git/include/linux/ata.h
@@ -194,6 +194,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:
@@ -299,6 +305,9 @@ 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] != 0x0000) && ((id)[76] != 0xffff)) && \
+ ((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-git/include/linux/libata.h
===================================================================
--- 2.6-git.orig/include/linux/libata.h
+++ 2.6-git/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 */
@@ -174,6 +175,7 @@ enum {
ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
+ ATA_FLAG_AN = (1 << 17), /* controller supports AN */
/* The following flag belongs to ap->pflags but is kept in
* ap->flags because it's referenced in many LLDs and will be
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 2/7] genhd: expose AN to user space - resend
2007-04-24 8:05 ` Tejun Heo
2007-04-24 21:30 ` Kristen Carlson Accardi
@ 2007-05-04 18:15 ` Kristen Carlson Accardi
1 sibling, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-05-04 18:15 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, Tejun Heo, akpm
Allow user space to determine if a disk supports Asynchronous Notification
of media changes. This is done by adding a new sysfs file "capability_flags",
which is documented in (insert file name). This sysfs file will export all
disk capabilities flags to user space. We also define a new flag to define
the media change notification capability.
Changed from last version:
* changed sysfs filename to "capability" from "capability_flags"
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
+++ 2.6-git/block/genhd.c
@@ -370,7 +370,10 @@ static ssize_t disk_size_read(struct gen
{
return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
}
-
+static ssize_t disk_capability_read(struct gendisk *disk, char *page)
+{
+ return sprintf(page, "%x\n", disk->flags);
+}
static ssize_t disk_stats_read(struct gendisk * disk, char *page)
{
preempt_disable();
@@ -413,6 +416,10 @@ static struct disk_attribute disk_attr_s
.attr = {.name = "size", .mode = S_IRUGO },
.show = disk_size_read
};
+static struct disk_attribute disk_attr_capability = {
+ .attr = {.name = "capability", .mode = S_IRUGO },
+ .show = disk_capability_read
+};
static struct disk_attribute disk_attr_stat = {
.attr = {.name = "stat", .mode = S_IRUGO },
.show = disk_stats_read
@@ -453,6 +460,7 @@ static struct attribute * default_attrs[
&disk_attr_removable.attr,
&disk_attr_size.attr,
&disk_attr_stat.attr,
+ &disk_attr_capability.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
+++ 2.6-git/include/linux/genhd.h
@@ -94,6 +94,7 @@ struct hd_struct {
#define GENHD_FL_REMOVABLE 1
#define GENHD_FL_DRIVERFS 2
+#define GENHD_FL_MEDIA_CHANGE_NOTIFY 4
#define GENHD_FL_CD 8
#define GENHD_FL_UP 16
#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
Index: 2.6-git/Documentation/block/capability.txt
===================================================================
--- /dev/null
+++ 2.6-git/Documentation/block/capability.txt
@@ -0,0 +1,15 @@
+Generic Block Device Capability
+===============================================================================
+This file documents the sysfs file block/<disk>/capability
+
+capability is a hex word indicating which capabilities a specific disk
+supports. For more information on bits not listed here, see
+include/linux/genhd.h
+
+Capability Value
+-------------------------------------------------------------------------------
+GENHD_FL_MEDIA_CHANGE_NOTIFY 4
+ When this bit is set, the disk supports Asynchronous Notification
+ of media change events. These events will be broadcast to user
+ space via kernel uevent.
+
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 3/7] scsi: expose AN to user space - resend
[not found] <20070424074856.005152262@intel.com>
` (6 preceding siblings ...)
2007-04-24 0:00 ` [patch 7/7] libata: send event when AN received Kristen Carlson Accardi
@ 2007-05-04 18:16 ` Kristen Carlson Accardi
2007-05-04 18:16 ` [patch 4/7] libata: " Kristen Carlson Accardi
2007-05-04 18:17 ` [patch 6/7] SCSI: save disk in scsi_device " Kristen Carlson Accardi
9 siblings, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-05-04 18:16 UTC (permalink / raw)
To: jeff
Cc: linux-kernel, linux-scsi, linux-ide, htejun,
Kristen Carlson Accardi, akpm
Get media change notification capability from disk and pass this information
to genhd by setting appropriate flag.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/scsi/sr.c
===================================================================
--- 2.6-git.orig/drivers/scsi/sr.c
+++ 2.6-git/drivers/scsi/sr.c
@@ -601,6 +601,8 @@ static int sr_probe(struct device *dev)
dev_set_drvdata(dev, cd);
disk->flags |= GENHD_FL_REMOVABLE;
+ if (sdev->media_change_notify)
+ disk->flags |= GENHD_FL_MEDIA_CHANGE_NOTIFY;
add_disk(disk);
sdev_printk(KERN_DEBUG, sdev,
Index: 2.6-git/include/scsi/scsi_device.h
===================================================================
--- 2.6-git.orig/include/scsi/scsi_device.h
+++ 2.6-git/include/scsi/scsi_device.h
@@ -124,7 +124,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 media_change_notify:1; /* dev supports async media notify */
unsigned int device_blocked; /* Device returned QUEUE_FULL. */
unsigned int max_device_blocked; /* what device_blocked counts down from */
Index: 2.6-git/drivers/scsi/sd.c
===================================================================
--- 2.6-git.orig/drivers/scsi/sd.c
+++ 2.6-git/drivers/scsi/sd.c
@@ -1706,6 +1706,9 @@ static int sd_probe(struct device *dev)
if (sdp->removable)
gd->flags |= GENHD_FL_REMOVABLE;
+ if (sdp->media_change_notify)
+ gd->flags |= GENHD_FL_MEDIA_CHANGE_NOTIFY;
+
dev_set_drvdata(dev, sdkp);
add_disk(gd);
--
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 4/7] libata: expose AN to user space - resend
[not found] <20070424074856.005152262@intel.com>
` (7 preceding siblings ...)
2007-05-04 18:16 ` [patch 3/7] scsi: expose AN to user space " Kristen Carlson Accardi
@ 2007-05-04 18:16 ` Kristen Carlson Accardi
2007-05-04 18:17 ` [patch 6/7] SCSI: save disk in scsi_device " Kristen Carlson Accardi
9 siblings, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-05-04 18:16 UTC (permalink / raw)
To: jeff
Cc: linux-kernel, linux-scsi, linux-ide, htejun,
Kristen Carlson Accardi, akpm
If Asynchronous Notification of media change events is supported,
pass that information up to the SCSI layer.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/ata/libata-scsi.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-scsi.c
+++ 2.6-git/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->media_change_notify = 1;
+
if (dev->flags & ATA_DFLAG_NCQ) {
int depth;
--
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 5/7] genhd: send async notification on media change
2007-04-24 8:20 ` Tejun Heo
2007-04-24 21:36 ` Kristen Carlson Accardi
@ 2007-05-04 18:17 ` Kristen Carlson Accardi
1 sibling, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-05-04 18:17 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, Tejun Heo, akpm
Send an uevent to user space to indicate that a media change event has occurred.
Changes from last version:
* use get/put_device to increment reference count on the device struct
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
+++ 2.6-git/block/genhd.c
@@ -643,6 +643,27 @@ struct seq_operations diskstats_op = {
.show = diskstats_show
};
+static void media_change_notify_thread(struct work_struct *work)
+{
+ struct gendisk *gd = container_of(work, struct gendisk, async_notify);
+ char event[] = "MEDIA_CHANGE=1";
+ char *envp[] = { event, NULL };
+
+ /*
+ * set enviroment vars to indicate which event this is for
+ * so that user space will know to go check the media status.
+ */
+ kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp);
+ put_device(gd->driverfs_dev);
+}
+
+void genhd_media_change_notify(struct gendisk *disk)
+{
+ get_device(disk->driverfs_dev);
+ schedule_work(&disk->async_notify);
+}
+EXPORT_SYMBOL_GPL(genhd_media_change_notify);
+
struct gendisk *alloc_disk(int minors)
{
return alloc_disk_node(minors, -1);
@@ -672,6 +693,8 @@ struct gendisk *alloc_disk_node(int mino
kobj_set_kset_s(disk,block_subsys);
kobject_init(&disk->kobj);
rand_initialize_disk(disk);
+ INIT_WORK(&disk->async_notify,
+ media_change_notify_thread);
}
return disk;
}
Index: 2.6-git/include/linux/genhd.h
===================================================================
--- 2.6-git.orig/include/linux/genhd.h
+++ 2.6-git/include/linux/genhd.h
@@ -66,6 +66,7 @@ struct partition {
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/fs.h>
+#include <linux/workqueue.h>
struct partition {
unsigned char boot_ind; /* 0x80 - active */
@@ -139,6 +140,7 @@ struct gendisk {
#else
struct disk_stats dkstats;
#endif
+ struct work_struct async_notify;
};
/* Structure for sysfs attributes on block devices */
@@ -419,7 +421,7 @@ extern struct gendisk *alloc_disk_node(i
extern struct gendisk *alloc_disk(int minors);
extern struct kobject *get_disk(struct gendisk *disk);
extern void put_disk(struct gendisk *disk);
-
+extern void genhd_media_change_notify(struct gendisk *disk);
extern void blk_register_region(dev_t dev, unsigned long range,
struct module *module,
struct kobject *(*probe)(dev_t, int *, void *),
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 6/7] SCSI: save disk in scsi_device - resend
[not found] <20070424074856.005152262@intel.com>
` (8 preceding siblings ...)
2007-05-04 18:16 ` [patch 4/7] libata: " Kristen Carlson Accardi
@ 2007-05-04 18:17 ` Kristen Carlson Accardi
2007-05-04 20:30 ` James Bottomley
9 siblings, 1 reply; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-05-04 18:17 UTC (permalink / raw)
To: jeff
Cc: linux-kernel, linux-scsi, linux-ide, htejun,
Kristen Carlson Accardi, akpm
Give anyone who has access to scsi_device access to the genhd struct as well.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/scsi/sd.c
===================================================================
--- 2.6-git.orig/drivers/scsi/sd.c
+++ 2.6-git/drivers/scsi/sd.c
@@ -1711,6 +1711,7 @@ static int sd_probe(struct device *dev)
dev_set_drvdata(dev, sdkp);
add_disk(gd);
+ sdp->disk = gd;
sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n",
sdp->removable ? "removable " : "", gd->disk_name);
Index: 2.6-git/drivers/scsi/sr.c
===================================================================
--- 2.6-git.orig/drivers/scsi/sr.c
+++ 2.6-git/drivers/scsi/sr.c
@@ -604,6 +604,7 @@ static int sr_probe(struct device *dev)
if (sdev->media_change_notify)
disk->flags |= GENHD_FL_MEDIA_CHANGE_NOTIFY;
add_disk(disk);
+ sdev->disk = disk;
sdev_printk(KERN_DEBUG, sdev,
"Attached scsi CD-ROM %s\n", cd->cdi.name);
Index: 2.6-git/include/scsi/scsi_device.h
===================================================================
--- 2.6-git.orig/include/scsi/scsi_device.h
+++ 2.6-git/include/scsi/scsi_device.h
@@ -138,7 +138,7 @@ struct scsi_device {
struct device sdev_gendev;
struct class_device sdev_classdev;
-
+ struct gendisk *disk;
struct execute_work ew; /* used to get process context on put */
enum scsi_device_state sdev_state;
--
^ permalink raw reply [flat|nested] 39+ messages in thread
* [patch 7/7] libata: send event when AN received - resend
2007-04-24 8:09 ` Alan Cox
2007-04-24 21:38 ` Kristen Carlson Accardi
@ 2007-05-04 18:18 ` Kristen Carlson Accardi
1 sibling, 0 replies; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-05-04 18:18 UTC (permalink / raw)
To: jeff; +Cc: linux-kernel, linux-scsi, linux-ide, htejun, akpm
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 block device.
changed from last version:
* Make sure that port_addr is within ATA_MAX_DEVICES
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Index: 2.6-git/drivers/ata/ahci.c
===================================================================
--- 2.6-git.orig/drivers/ata/ahci.c
+++ 2.6-git/drivers/ata/ahci.c
@@ -1147,6 +1147,28 @@ 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;
+ if (port_addr < ATA_MAX_DEVICES) {
+ adev = &ap->device[port_addr];
+ if (adev->flags & ATA_DFLAG_AN)
+ ata_scsi_media_change_notify(adev);
+ }
+ }
+ }
if (ap->sactive)
qc_active = readl(port_mmio + PORT_SCR_ACT);
else
Index: 2.6-git/include/linux/libata.h
===================================================================
--- 2.6-git.orig/include/linux/libata.h
+++ 2.6-git/include/linux/libata.h
@@ -737,6 +737,7 @@ extern void ata_host_init(struct ata_hos
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 *);
Index: 2.6-git/drivers/ata/libata-scsi.c
===================================================================
--- 2.6-git.orig/drivers/ata/libata-scsi.c
+++ 2.6-git/drivers/ata/libata-scsi.c
@@ -3057,6 +3057,22 @@ static void ata_scsi_remove_dev(struct a
}
/**
+ * 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)
+{
+ genhd_media_change_notify(atadev->sdev->disk);
+}
+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
*
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 6/7] SCSI: save disk in scsi_device - resend
2007-05-04 18:17 ` [patch 6/7] SCSI: save disk in scsi_device " Kristen Carlson Accardi
@ 2007-05-04 20:30 ` James Bottomley
2007-05-07 15:29 ` Kristen Carlson Accardi
0 siblings, 1 reply; 39+ messages in thread
From: James Bottomley @ 2007-05-04 20:30 UTC (permalink / raw)
To: Kristen Carlson Accardi
Cc: jeff, linux-kernel, linux-scsi, linux-ide, htejun, akpm
On Fri, 2007-05-04 at 11:17 -0700, Kristen Carlson Accardi wrote:
> Give anyone who has access to scsi_device access to the genhd struct as well.
>
> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
> Index: 2.6-git/drivers/scsi/sd.c
> ===================================================================
> --- 2.6-git.orig/drivers/scsi/sd.c
> +++ 2.6-git/drivers/scsi/sd.c
> @@ -1711,6 +1711,7 @@ static int sd_probe(struct device *dev)
>
> dev_set_drvdata(dev, sdkp);
> add_disk(gd);
> + sdp->disk = gd;
>
> sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n",
> sdp->removable ? "removable " : "", gd->disk_name);
> Index: 2.6-git/drivers/scsi/sr.c
> ===================================================================
> --- 2.6-git.orig/drivers/scsi/sr.c
> +++ 2.6-git/drivers/scsi/sr.c
> @@ -604,6 +604,7 @@ static int sr_probe(struct device *dev)
> if (sdev->media_change_notify)
> disk->flags |= GENHD_FL_MEDIA_CHANGE_NOTIFY;
> add_disk(disk);
> + sdev->disk = disk;
>
> sdev_printk(KERN_DEBUG, sdev,
> "Attached scsi CD-ROM %s\n", cd->cdi.name);
> Index: 2.6-git/include/scsi/scsi_device.h
> ===================================================================
> --- 2.6-git.orig/include/scsi/scsi_device.h
> +++ 2.6-git/include/scsi/scsi_device.h
> @@ -138,7 +138,7 @@ struct scsi_device {
>
> struct device sdev_gendev;
> struct class_device sdev_classdev;
> -
> + struct gendisk *disk;
> struct execute_work ew; /* used to get process context on put */
>
> enum scsi_device_state sdev_state;
If you're going to do this, you need to take on board removing the
struct gendisk from all the ULD structures (since it's now become
generic).
James
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 6/7] SCSI: save disk in scsi_device - resend
2007-05-04 20:30 ` James Bottomley
@ 2007-05-07 15:29 ` Kristen Carlson Accardi
2007-05-09 22:50 ` Kristen Carlson Accardi
0 siblings, 1 reply; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-05-07 15:29 UTC (permalink / raw)
To: James Bottomley; +Cc: jeff, linux-kernel, linux-scsi, linux-ide, htejun, akpm
On Fri, 04 May 2007 15:30:48 -0500
James Bottomley <James.Bottomley@SteelEye.com> wrote:
> On Fri, 2007-05-04 at 11:17 -0700, Kristen Carlson Accardi wrote:
> > Give anyone who has access to scsi_device access to the genhd struct as well.
> >
> > Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
> > Index: 2.6-git/drivers/scsi/sd.c
> > ===================================================================
> > --- 2.6-git.orig/drivers/scsi/sd.c
> > +++ 2.6-git/drivers/scsi/sd.c
> > @@ -1711,6 +1711,7 @@ static int sd_probe(struct device *dev)
> >
> > dev_set_drvdata(dev, sdkp);
> > add_disk(gd);
> > + sdp->disk = gd;
> >
> > sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n",
> > sdp->removable ? "removable " : "", gd->disk_name);
> > Index: 2.6-git/drivers/scsi/sr.c
> > ===================================================================
> > --- 2.6-git.orig/drivers/scsi/sr.c
> > +++ 2.6-git/drivers/scsi/sr.c
> > @@ -604,6 +604,7 @@ static int sr_probe(struct device *dev)
> > if (sdev->media_change_notify)
> > disk->flags |= GENHD_FL_MEDIA_CHANGE_NOTIFY;
> > add_disk(disk);
> > + sdev->disk = disk;
> >
> > sdev_printk(KERN_DEBUG, sdev,
> > "Attached scsi CD-ROM %s\n", cd->cdi.name);
> > Index: 2.6-git/include/scsi/scsi_device.h
> > ===================================================================
> > --- 2.6-git.orig/include/scsi/scsi_device.h
> > +++ 2.6-git/include/scsi/scsi_device.h
> > @@ -138,7 +138,7 @@ struct scsi_device {
> >
> > struct device sdev_gendev;
> > struct class_device sdev_classdev;
> > -
> > + struct gendisk *disk;
> > struct execute_work ew; /* used to get process context on put */
> >
> > enum scsi_device_state sdev_state;
>
> If you're going to do this, you need to take on board removing the
> struct gendisk from all the ULD structures (since it's now become
> generic).
>
> James
>
Ok - I can send that as a separate patch series, or I can include it
in this one. Which is preferred?
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 6/7] SCSI: save disk in scsi_device - resend
2007-05-07 15:29 ` Kristen Carlson Accardi
@ 2007-05-09 22:50 ` Kristen Carlson Accardi
2007-05-09 23:04 ` James Bottomley
0 siblings, 1 reply; 39+ messages in thread
From: Kristen Carlson Accardi @ 2007-05-09 22:50 UTC (permalink / raw)
To: James Bottomley, jeff; +Cc: linux-kernel, linux-scsi, linux-ide, htejun, akpm
On Mon, 7 May 2007 08:29:28 -0700
Kristen Carlson Accardi <kristen.c.accardi@intel.com> wrote:
> On Fri, 04 May 2007 15:30:48 -0500
> James Bottomley <James.Bottomley@SteelEye.com> wrote:
>
> > On Fri, 2007-05-04 at 11:17 -0700, Kristen Carlson Accardi wrote:
> > > Give anyone who has access to scsi_device access to the genhd struct as well.
> > >
> > > Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
> > > Index: 2.6-git/drivers/scsi/sd.c
> > > ===================================================================
> > > --- 2.6-git.orig/drivers/scsi/sd.c
> > > +++ 2.6-git/drivers/scsi/sd.c
> > > @@ -1711,6 +1711,7 @@ static int sd_probe(struct device *dev)
> > >
> > > dev_set_drvdata(dev, sdkp);
> > > add_disk(gd);
> > > + sdp->disk = gd;
> > >
> > > sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n",
> > > sdp->removable ? "removable " : "", gd->disk_name);
> > > Index: 2.6-git/drivers/scsi/sr.c
> > > ===================================================================
> > > --- 2.6-git.orig/drivers/scsi/sr.c
> > > +++ 2.6-git/drivers/scsi/sr.c
> > > @@ -604,6 +604,7 @@ static int sr_probe(struct device *dev)
> > > if (sdev->media_change_notify)
> > > disk->flags |= GENHD_FL_MEDIA_CHANGE_NOTIFY;
> > > add_disk(disk);
> > > + sdev->disk = disk;
> > >
> > > sdev_printk(KERN_DEBUG, sdev,
> > > "Attached scsi CD-ROM %s\n", cd->cdi.name);
> > > Index: 2.6-git/include/scsi/scsi_device.h
> > > ===================================================================
> > > --- 2.6-git.orig/include/scsi/scsi_device.h
> > > +++ 2.6-git/include/scsi/scsi_device.h
> > > @@ -138,7 +138,7 @@ struct scsi_device {
> > >
> > > struct device sdev_gendev;
> > > struct class_device sdev_classdev;
> > > -
> > > + struct gendisk *disk;
> > > struct execute_work ew; /* used to get process context on put */
> > >
> > > enum scsi_device_state sdev_state;
> >
> > If you're going to do this, you need to take on board removing the
> > struct gendisk from all the ULD structures (since it's now become
> > generic).
> >
> > James
> >
>
> Ok - I can send that as a separate patch series, or I can include it
> in this one. Which is preferred?
>
I interpret the lack of response to this question to mean that I can just
decide for myself - in which case I prefer to send this as a separate
patchset after this one is integrated.
Thanks!
Kristen
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [patch 6/7] SCSI: save disk in scsi_device - resend
2007-05-09 22:50 ` Kristen Carlson Accardi
@ 2007-05-09 23:04 ` James Bottomley
0 siblings, 0 replies; 39+ messages in thread
From: James Bottomley @ 2007-05-09 23:04 UTC (permalink / raw)
To: Kristen Carlson Accardi
Cc: jeff, linux-kernel, linux-scsi, linux-ide, htejun, akpm
On Wed, 2007-05-09 at 15:50 -0700, Kristen Carlson Accardi wrote:
> interpret the lack of response to this question to mean that I can
> just
> decide for myself - in which case I prefer to send this as a separate
> patchset after this one is integrated.
Sorry ... was sidetracked getting tree into shape.
Yes, separate patch is preferred.
James
^ permalink raw reply [flat|nested] 39+ messages in thread
end of thread, other threads:[~2007-05-09 23:04 UTC | newest]
Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20070424074856.005152262@intel.com>
2007-04-23 23:59 ` [patch 1/7] libata: check for AN support Kristen Carlson Accardi
2007-04-24 8:03 ` Tejun Heo
2007-04-24 15:54 ` Kristen Carlson Accardi
2007-04-24 8:07 ` Alan Cox
2007-04-24 10:23 ` Olivier Galibert
2007-04-24 15:49 ` Kristen Carlson Accardi
2007-04-24 18:05 ` Olivier Galibert
2007-04-24 18:29 ` Kristen Carlson Accardi
2007-04-24 20:53 ` Kristen Carlson Accardi
2007-04-25 0:49 ` Olivier Galibert
2007-04-25 17:55 ` Kristen Carlson Accardi
2007-04-25 18:40 ` Kristen Carlson Accardi
2007-04-25 19:16 ` Matt Sealey
2007-04-25 20:34 ` Kristen Carlson Accardi
2007-04-25 20:59 ` Matt Sealey
2007-04-25 20:40 ` Olivier Galibert
2007-05-04 18:14 ` [patch 1/7] libata: check for AN support - resend Kristen Carlson Accardi
2007-04-23 23:59 ` [patch 2/7] genhd: expose AN to user space Kristen Carlson Accardi
2007-04-24 8:05 ` Tejun Heo
2007-04-24 21:30 ` Kristen Carlson Accardi
2007-05-04 18:15 ` [patch 2/7] genhd: expose AN to user space - resend Kristen Carlson Accardi
2007-04-23 23:59 ` [patch 3/7] scsi: expose AN to user space Kristen Carlson Accardi
2007-04-24 0:00 ` [patch 4/7] libata: " Kristen Carlson Accardi
2007-04-24 0:00 ` [patch 5/7] genhd: send async notification on media change Kristen Carlson Accardi
2007-04-24 8:20 ` Tejun Heo
2007-04-24 21:36 ` Kristen Carlson Accardi
2007-05-04 18:17 ` Kristen Carlson Accardi
2007-04-24 0:00 ` [patch 6/7] SCSI: save disk in scsi_device Kristen Carlson Accardi
2007-04-24 0:00 ` [patch 7/7] libata: send event when AN received Kristen Carlson Accardi
2007-04-24 8:09 ` Alan Cox
2007-04-24 21:38 ` Kristen Carlson Accardi
2007-05-04 18:18 ` [patch 7/7] libata: send event when AN received - resend Kristen Carlson Accardi
2007-05-04 18:16 ` [patch 3/7] scsi: expose AN to user space " Kristen Carlson Accardi
2007-05-04 18:16 ` [patch 4/7] libata: " Kristen Carlson Accardi
2007-05-04 18:17 ` [patch 6/7] SCSI: save disk in scsi_device " Kristen Carlson Accardi
2007-05-04 20:30 ` James Bottomley
2007-05-07 15:29 ` Kristen Carlson Accardi
2007-05-09 22:50 ` Kristen Carlson Accardi
2007-05-09 23:04 ` James Bottomley
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).