linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs
@ 2009-04-07 18:04 Mike Miller (OS Dev)
  2009-04-08  6:19 ` Jens Axboe
  2009-04-10  4:52 ` Andrew Morton
  0 siblings, 2 replies; 13+ messages in thread
From: Mike Miller (OS Dev) @ 2009-04-07 18:04 UTC (permalink / raw)
  To: Andrew Morton, Jens Axboe
  Cc: LKML, LKML-SCSI, andrew.patterson, mikem, mike.miller

Patch 1 of 1 resubmit

cciss: add cciss driver sysfs entries

This patch adds sysfs entries to the cciss driver needed for the
dm/multipath tools. A file for vendor, model, rev, and unique_id are
added for each logical drive under directory
/sys/bus/pci/devices/<dev>/ccissX/cXdY. Where X = the controller (or
host) number and Y is the logical drive number. A link from
/sys/bus/pci/devices/<dev>/ccissX/cXdY/block:cciss!cXdY to
/sys/block/cciss!cXdY/device is also created.

From: Andrew Patterson <andrew.patterson@hp.com>

Signed-off-by: Mike Miller <Mike.Miller@hp.com>
Signed-off-by: Andrew Patterson <andrew.patterson@hp.com>
---

Changelog:
Added some documentation
Added From: field

diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
new file mode 100644
index 0000000..0a92a7c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
@@ -0,0 +1,33 @@
+Where:		/sys/bus/pci/devices/<dev>/ccissX/cXdY/model
+Date:		March 2009
+Kernel Version: 2.6.30
+Contact:	iss_storagedev@hp.com
+Description:	Displays the SCSI INQUIRY page 0 model for logical drive
+		Y of controller X.
+
+Where:		/sys/bus/pci/devices/<dev>/ccissX/cXdY/rev
+Date:		March 2009
+Kernel Version: 2.6.30
+Contact:	iss_storagedev@hp.com
+Description:	Displays the SCSI INQUIRY page 0 revision for logical
+		drive Y of controller X.
+
+Where:		/sys/bus/pci/devices/<dev>/ccissX/cXdY/unique_id
+Date:		March 2009
+Kernel Version: 2.6.30
+Contact:	iss_storagedev@hp.com
+Description:	Displays the SCSI INQUIRY page 83 serial number for logical
+		drive Y of controller X.
+
+Where:		/sys/bus/pci/devices/<dev>/ccissX/cXdY/vendor
+Date:		March 2009
+Kernel Version: 2.6.30
+Contact:	iss_storagedev@hp.com
+Description:	Displays the SCSI INQUIRY page 0 vendor for logical drive
+		Y of controller X.
+
+Where:		/sys/bus/pci/devices/<dev>/ccissX/cXdY/block:cciss!cXdY
+Date:		March 2009
+Kernel Version: 2.6.30
+Contact:	iss_storagedev@hp.com
+Description:	A symbolic link to /sys/block/cciss!cXdY
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 5d0e135..de6e991 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -434,6 +434,187 @@ static void __devinit cciss_procinit(int i)
 }
 #endif				/* CONFIG_PROC_FS */
 
+#define MAX_PRODUCT_NAME_LEN 19
+
+#define to_hba(n) container_of(n, struct ctlr_info, dev)
+#define to_drv(n) container_of(n, drive_info_struct, dev)
+
+static struct device_type cciss_host_type = {
+	.name		= "cciss_host",
+};
+
+static ssize_t dev_show_unique_id(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	drive_info_struct *drv = to_drv(dev);
+	struct ctlr_info *h = to_hba(drv->dev.parent);
+	__u8 sn[16];
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+	if (h->busy_configuring)
+		ret = -EBUSY;
+	else
+		memcpy(sn, drv->serial_no, sizeof(sn));
+	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+
+	if (ret)
+		return ret;
+	else
+		return snprintf(buf, 16 * 2 + 2,
+				"%02X%02X%02X%02X%02X%02X%02X%02X"
+				"%02X%02X%02X%02X%02X%02X%02X%02X\n",
+				sn[0], sn[1], sn[2], sn[3],
+				sn[4], sn[5], sn[6], sn[7],
+				sn[8], sn[9], sn[10], sn[11],
+				sn[12], sn[13], sn[14], sn[15]);
+}
+DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL);
+
+static ssize_t dev_show_vendor(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	drive_info_struct *drv = to_drv(dev);
+	struct ctlr_info *h = to_hba(drv->dev.parent);
+	char vendor[VENDOR_LEN + 1];
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+	if (h->busy_configuring)
+		ret = -EBUSY;
+	else
+		memcpy(vendor, drv->vendor, VENDOR_LEN + 1);
+	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+
+	if (ret)
+		return ret;
+	else
+		return snprintf(buf, VENDOR_LEN + 2, "%s\n", drv->vendor);
+}
+DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL);
+
+static ssize_t dev_show_model(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	drive_info_struct *drv = to_drv(dev);
+	struct ctlr_info *h = to_hba(drv->dev.parent);
+	char model[MODEL_LEN + 1];
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+	if (h->busy_configuring)
+		ret = -EBUSY;
+	else
+		memcpy(model, drv->model, MODEL_LEN + 1);
+	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+
+	if (ret)
+		return ret;
+	else
+		return snprintf(buf, MODEL_LEN + 2, "%s\n", drv->model);
+}
+DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL);
+
+static ssize_t dev_show_rev(struct device *dev,
+			    struct device_attribute *attr,
+			    char *buf)
+{
+	drive_info_struct *drv = to_drv(dev);
+	struct ctlr_info *h = to_hba(drv->dev.parent);
+	char rev[REV_LEN + 1];
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+	if (h->busy_configuring)
+		ret = -EBUSY;
+	else
+		memcpy(rev, drv->rev, REV_LEN + 1);
+	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+
+	if (ret)
+		return ret;
+	else
+		return snprintf(buf, REV_LEN + 2, "%s\n", drv->rev);
+}
+DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
+
+static struct attribute *cciss_dev_attrs[] = {
+	&dev_attr_unique_id.attr,
+	&dev_attr_model.attr,
+	&dev_attr_vendor.attr,
+	&dev_attr_rev.attr,
+	NULL
+};
+
+static struct attribute_group cciss_dev_attr_group = {
+	.attrs = cciss_dev_attrs,
+};
+
+static struct attribute_group *cciss_dev_attr_groups[] = {
+	&cciss_dev_attr_group,
+	NULL
+};
+
+static struct device_type cciss_dev_type = {
+	.name		= "cciss_device",
+	.groups		= cciss_dev_attr_groups,
+};
+
+/*
+ * Initialize sysfs entry for each controller.  This sets up and registers
+ * the 'cciss#' directory for each individual controller under
+ * /sys/bus/pci/devices/<dev>/.
+ */
+static int cciss_create_hba_sysfs_entry(struct ctlr_info *h)
+{
+	device_initialize(&h->dev);
+	h->dev.type = &cciss_host_type;
+	dev_set_name(&h->dev, "%s", h->devname);
+	h->dev.parent = &h->pdev->dev;
+
+	return device_add(&h->dev);
+}
+
+/*
+ * Remove sysfs entries for an hba.
+ */
+static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h)
+{
+	device_del(&h->dev);
+}
+
+/*
+ * Initialize sysfs for each logical drive.  This sets up and registers
+ * the 'c#d#' directory for each individual logical drive under
+ * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from
+ * /sys/block/cciss!c#d# to this entry.
+ */
+static int cciss_create_ld_sysfs_entry(struct ctlr_info *h,
+				       drive_info_struct *drv,
+				       int drv_index)
+{
+	device_initialize(&drv->dev);
+	drv->dev.type = &cciss_dev_type;
+	dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index);
+	drv->dev.parent = &h->dev;
+	return device_add(&drv->dev);
+}
+
+/*
+ * Remove sysfs entries for a logical drive.
+ */
+static void cciss_destroy_ld_sysfs_entry(drive_info_struct *drv)
+{
+	device_del(&drv->dev);
+}
+
 /*
  * For operations that cannot sleep, a command block is allocated at init,
  * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track
@@ -1317,6 +1498,45 @@ static void cciss_softirq_done(struct request *rq)
 	spin_unlock_irqrestore(&h->lock, flags);
 }
 
+/* This function gets the SCSI vendor, model, and revision of a logical drive
+ * via the inquiry page 0.  Model, vendor, and rev are set to empty strings if
+ * they cannot be read.
+ */
+static void cciss_get_device_descr(int ctlr, int logvol, int withirq,
+				   char *vendor, char *model, char *rev)
+{
+	int rc;
+	InquiryData_struct *inq_buf;
+
+	*vendor = '\0';
+	*model = '\0';
+	*rev = '\0';
+
+	inq_buf = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL);
+	if (!inq_buf)
+		return;
+
+	if (withirq)
+		rc = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buf,
+				     sizeof(InquiryData_struct), 1, logvol,
+				     0, TYPE_CMD);
+	else
+		rc = sendcmd(CISS_INQUIRY, ctlr, inq_buf,
+			     sizeof(InquiryData_struct), 1, logvol, 0, NULL,
+			     TYPE_CMD);
+	if (rc == IO_OK) {
+		memcpy(vendor, &inq_buf->data_byte[8], VENDOR_LEN);
+		vendor[VENDOR_LEN] = '\0';
+		memcpy(model, &inq_buf->data_byte[16], MODEL_LEN);
+		model[MODEL_LEN] = '\0';
+		memcpy(rev, &inq_buf->data_byte[32], REV_LEN);
+		rev[REV_LEN] = '\0';
+	}
+
+	kfree(inq_buf);
+	return;
+}
+
 /* This function gets the serial number of a logical drive via
  * inquiry page 0x83.  Serial no. is 16 bytes.  If the serial
  * number cannot be had, for whatever reason, 16 bytes of 0xff
@@ -1357,7 +1577,7 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
 	disk->first_minor = drv_index << NWD_SHIFT;
 	disk->fops = &cciss_fops;
 	disk->private_data = &h->drv[drv_index];
-	disk->driverfs_dev = &h->pdev->dev;
+	disk->driverfs_dev = &h->drv[drv_index].dev;
 
 	/* Set up queue information */
 	blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
@@ -1448,6 +1668,8 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
 	drvinfo->block_size = block_size;
 	drvinfo->nr_blocks = total_size + 1;
 
+	cciss_get_device_descr(ctlr, drv_index, 1, drvinfo->vendor,
+				drvinfo->model, drvinfo->rev);
 	cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no,
 			sizeof(drvinfo->serial_no));
 
@@ -1497,6 +1719,9 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
 	h->drv[drv_index].cylinders = drvinfo->cylinders;
 	h->drv[drv_index].raid_level = drvinfo->raid_level;
 	memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16);
+	memcpy(h->drv[drv_index].vendor, drvinfo->vendor, VENDOR_LEN + 1);
+	memcpy(h->drv[drv_index].model, drvinfo->model, MODEL_LEN + 1);
+	memcpy(h->drv[drv_index].rev, drvinfo->rev, REV_LEN + 1);
 
 	++h->num_luns;
 	disk = h->gendisk[drv_index];
@@ -1571,6 +1796,8 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
 		}
 	}
 	h->drv[drv_index].LunID = lunid;
+	if (cciss_create_ld_sysfs_entry(h, &h->drv[drv_index], drv_index))
+		goto err_free_disk;
 
 	/* Don't need to mark this busy because nobody */
 	/* else knows about this disk yet to contend */
@@ -1578,6 +1805,11 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
 	h->drv[drv_index].busy_configuring = 0;
 	wmb();
 	return drv_index;
+
+err_free_disk:
+	put_disk(h->gendisk[drv_index]);
+	h->gendisk[drv_index] = NULL;
+	return -1;
 }
 
 /* This is for the special case of a controller which
@@ -1698,6 +1930,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
 			h->drv[i].busy_configuring = 1;
 			spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
 			return_code = deregister_disk(h, i, 1);
+			cciss_destroy_ld_sysfs_entry(&h->drv[i]);
 			h->drv[i].busy_configuring = 0;
 		}
 	}
@@ -3630,12 +3863,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 	INIT_HLIST_HEAD(&hba[i]->reqQ);
 
 	if (cciss_pci_init(hba[i], pdev) != 0)
-		goto clean1;
+		goto clean0;
 
 	sprintf(hba[i]->devname, "cciss%d", i);
 	hba[i]->ctlr = i;
 	hba[i]->pdev = pdev;
 
+	if (cciss_create_hba_sysfs_entry(hba[i]))
+		goto clean0;
+
 	/* configure PCI DMA stuff */
 	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK))
 		dac = 1;
@@ -3774,6 +4010,8 @@ clean4:
 clean2:
 	unregister_blkdev(hba[i]->major, hba[i]->devname);
 clean1:
+	cciss_destroy_hba_sysfs_entry(hba[i]);
+clean0:
 	hba[i]->busy_initializing = 0;
 	/* cleanup any queues that may have been initialized */
 	for (j=0; j <= hba[i]->highest_lun; j++){
@@ -3881,6 +4119,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
 	 */
 	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
+	cciss_destroy_hba_sysfs_entry(hba[i]);
 	free_hba(i);
 }
 
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 15e2b84..552ecca 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -12,6 +12,11 @@
 #define IO_OK		0
 #define IO_ERROR	1
 
+#define VENDOR_LEN	8
+#define MODEL_LEN	16
+#define REV_LEN		4
+
+
 struct ctlr_info;
 typedef struct ctlr_info ctlr_info_t;
 
@@ -34,13 +39,18 @@ typedef struct _drive_info_struct
 	int 	cylinders;
 	int	raid_level; /* set to -1 to indicate that
 			     * the drive is not in use/configured
-			    */
-	int	busy_configuring; /*This is set when the drive is being removed
-				   *to prevent it from being opened or it's queue
-				   *from being started.
-				  */
-	__u8 serial_no[16]; /* from inquiry page 0x83, */
-			    /* not necc. null terminated. */
+			     */
+	int	busy_configuring; /* This is set when a drive is being removed
+				   * to prevent it from being opened or it's
+				   * queue from being started.
+				   */
+	struct	device dev;
+	__u8 serial_no[16]; /* from inquiry page 0x83,
+			     * not necc. null terminated.
+			     */
+	char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */
+	char model[MODEL_LEN + 1];   /* SCSI model string */
+	char rev[REV_LEN + 1];       /* SCSI revision string */
 } drive_info_struct;
 
 #ifdef CONFIG_CISS_SCSI_TAPE
@@ -121,6 +131,7 @@ struct ctlr_info
 	struct sendcmd_reject_list scsi_rejects;
 #endif
 	unsigned char alive;
+	struct device dev;
 };
 
 /*  Defining the diffent access_menthods */

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs
  2009-04-07 18:04 [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs Mike Miller (OS Dev)
@ 2009-04-08  6:19 ` Jens Axboe
  2009-04-08  8:13   ` Jens Axboe
  2009-04-08 12:26   ` Kay Sievers
  2009-04-10  4:52 ` Andrew Morton
  1 sibling, 2 replies; 13+ messages in thread
From: Jens Axboe @ 2009-04-08  6:19 UTC (permalink / raw)
  To: Mike Miller (OS Dev)
  Cc: Andrew Morton, LKML, LKML-SCSI, andrew.patterson, mike.miller,
	kay.sievers

On Tue, Apr 07 2009, Mike Miller (OS Dev) wrote:
> Patch 1 of 1 resubmit
> 
> cciss: add cciss driver sysfs entries
> 
> This patch adds sysfs entries to the cciss driver needed for the
> dm/multipath tools. A file for vendor, model, rev, and unique_id are
> added for each logical drive under directory
> /sys/bus/pci/devices/<dev>/ccissX/cXdY. Where X = the controller (or
> host) number and Y is the logical drive number. A link from
> /sys/bus/pci/devices/<dev>/ccissX/cXdY/block:cciss!cXdY to
> /sys/block/cciss!cXdY/device is also created.
> 
> From: Andrew Patterson <andrew.patterson@hp.com>

You want to put that at the top of the email, so you have
{from,description,signed-offs} in that order.

The patch looks fine to me, but my sysfs foo is very weak though. CC'ing
Kay, perhaps he can help take a quick look at this.

> 
> Signed-off-by: Mike Miller <Mike.Miller@hp.com>
> Signed-off-by: Andrew Patterson <andrew.patterson@hp.com>
> ---
> 
> Changelog:
> Added some documentation
> Added From: field
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
> new file mode 100644
> index 0000000..0a92a7c
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
> @@ -0,0 +1,33 @@
> +Where:		/sys/bus/pci/devices/<dev>/ccissX/cXdY/model
> +Date:		March 2009
> +Kernel Version: 2.6.30
> +Contact:	iss_storagedev@hp.com
> +Description:	Displays the SCSI INQUIRY page 0 model for logical drive
> +		Y of controller X.
> +
> +Where:		/sys/bus/pci/devices/<dev>/ccissX/cXdY/rev
> +Date:		March 2009
> +Kernel Version: 2.6.30
> +Contact:	iss_storagedev@hp.com
> +Description:	Displays the SCSI INQUIRY page 0 revision for logical
> +		drive Y of controller X.
> +
> +Where:		/sys/bus/pci/devices/<dev>/ccissX/cXdY/unique_id
> +Date:		March 2009
> +Kernel Version: 2.6.30
> +Contact:	iss_storagedev@hp.com
> +Description:	Displays the SCSI INQUIRY page 83 serial number for logical
> +		drive Y of controller X.
> +
> +Where:		/sys/bus/pci/devices/<dev>/ccissX/cXdY/vendor
> +Date:		March 2009
> +Kernel Version: 2.6.30
> +Contact:	iss_storagedev@hp.com
> +Description:	Displays the SCSI INQUIRY page 0 vendor for logical drive
> +		Y of controller X.
> +
> +Where:		/sys/bus/pci/devices/<dev>/ccissX/cXdY/block:cciss!cXdY
> +Date:		March 2009
> +Kernel Version: 2.6.30
> +Contact:	iss_storagedev@hp.com
> +Description:	A symbolic link to /sys/block/cciss!cXdY
> diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
> index 5d0e135..de6e991 100644
> --- a/drivers/block/cciss.c
> +++ b/drivers/block/cciss.c
> @@ -434,6 +434,187 @@ static void __devinit cciss_procinit(int i)
>  }
>  #endif				/* CONFIG_PROC_FS */
>  
> +#define MAX_PRODUCT_NAME_LEN 19
> +
> +#define to_hba(n) container_of(n, struct ctlr_info, dev)
> +#define to_drv(n) container_of(n, drive_info_struct, dev)
> +
> +static struct device_type cciss_host_type = {
> +	.name		= "cciss_host",
> +};
> +
> +static ssize_t dev_show_unique_id(struct device *dev,
> +				 struct device_attribute *attr,
> +				 char *buf)
> +{
> +	drive_info_struct *drv = to_drv(dev);
> +	struct ctlr_info *h = to_hba(drv->dev.parent);
> +	__u8 sn[16];
> +	unsigned long flags;
> +	int ret = 0;
> +
> +	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
> +	if (h->busy_configuring)
> +		ret = -EBUSY;
> +	else
> +		memcpy(sn, drv->serial_no, sizeof(sn));
> +	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
> +
> +	if (ret)
> +		return ret;
> +	else
> +		return snprintf(buf, 16 * 2 + 2,
> +				"%02X%02X%02X%02X%02X%02X%02X%02X"
> +				"%02X%02X%02X%02X%02X%02X%02X%02X\n",
> +				sn[0], sn[1], sn[2], sn[3],
> +				sn[4], sn[5], sn[6], sn[7],
> +				sn[8], sn[9], sn[10], sn[11],
> +				sn[12], sn[13], sn[14], sn[15]);
> +}
> +DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL);
> +
> +static ssize_t dev_show_vendor(struct device *dev,
> +			       struct device_attribute *attr,
> +			       char *buf)
> +{
> +	drive_info_struct *drv = to_drv(dev);
> +	struct ctlr_info *h = to_hba(drv->dev.parent);
> +	char vendor[VENDOR_LEN + 1];
> +	unsigned long flags;
> +	int ret = 0;
> +
> +	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
> +	if (h->busy_configuring)
> +		ret = -EBUSY;
> +	else
> +		memcpy(vendor, drv->vendor, VENDOR_LEN + 1);
> +	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
> +
> +	if (ret)
> +		return ret;
> +	else
> +		return snprintf(buf, VENDOR_LEN + 2, "%s\n", drv->vendor);
> +}
> +DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL);
> +
> +static ssize_t dev_show_model(struct device *dev,
> +			      struct device_attribute *attr,
> +			      char *buf)
> +{
> +	drive_info_struct *drv = to_drv(dev);
> +	struct ctlr_info *h = to_hba(drv->dev.parent);
> +	char model[MODEL_LEN + 1];
> +	unsigned long flags;
> +	int ret = 0;
> +
> +	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
> +	if (h->busy_configuring)
> +		ret = -EBUSY;
> +	else
> +		memcpy(model, drv->model, MODEL_LEN + 1);
> +	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
> +
> +	if (ret)
> +		return ret;
> +	else
> +		return snprintf(buf, MODEL_LEN + 2, "%s\n", drv->model);
> +}
> +DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL);
> +
> +static ssize_t dev_show_rev(struct device *dev,
> +			    struct device_attribute *attr,
> +			    char *buf)
> +{
> +	drive_info_struct *drv = to_drv(dev);
> +	struct ctlr_info *h = to_hba(drv->dev.parent);
> +	char rev[REV_LEN + 1];
> +	unsigned long flags;
> +	int ret = 0;
> +
> +	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
> +	if (h->busy_configuring)
> +		ret = -EBUSY;
> +	else
> +		memcpy(rev, drv->rev, REV_LEN + 1);
> +	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
> +
> +	if (ret)
> +		return ret;
> +	else
> +		return snprintf(buf, REV_LEN + 2, "%s\n", drv->rev);
> +}
> +DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
> +
> +static struct attribute *cciss_dev_attrs[] = {
> +	&dev_attr_unique_id.attr,
> +	&dev_attr_model.attr,
> +	&dev_attr_vendor.attr,
> +	&dev_attr_rev.attr,
> +	NULL
> +};
> +
> +static struct attribute_group cciss_dev_attr_group = {
> +	.attrs = cciss_dev_attrs,
> +};
> +
> +static struct attribute_group *cciss_dev_attr_groups[] = {
> +	&cciss_dev_attr_group,
> +	NULL
> +};
> +
> +static struct device_type cciss_dev_type = {
> +	.name		= "cciss_device",
> +	.groups		= cciss_dev_attr_groups,
> +};
> +
> +/*
> + * Initialize sysfs entry for each controller.  This sets up and registers
> + * the 'cciss#' directory for each individual controller under
> + * /sys/bus/pci/devices/<dev>/.
> + */
> +static int cciss_create_hba_sysfs_entry(struct ctlr_info *h)
> +{
> +	device_initialize(&h->dev);
> +	h->dev.type = &cciss_host_type;
> +	dev_set_name(&h->dev, "%s", h->devname);
> +	h->dev.parent = &h->pdev->dev;
> +
> +	return device_add(&h->dev);
> +}
> +
> +/*
> + * Remove sysfs entries for an hba.
> + */
> +static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h)
> +{
> +	device_del(&h->dev);
> +}
> +
> +/*
> + * Initialize sysfs for each logical drive.  This sets up and registers
> + * the 'c#d#' directory for each individual logical drive under
> + * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from
> + * /sys/block/cciss!c#d# to this entry.
> + */
> +static int cciss_create_ld_sysfs_entry(struct ctlr_info *h,
> +				       drive_info_struct *drv,
> +				       int drv_index)
> +{
> +	device_initialize(&drv->dev);
> +	drv->dev.type = &cciss_dev_type;
> +	dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index);
> +	drv->dev.parent = &h->dev;
> +	return device_add(&drv->dev);
> +}
> +
> +/*
> + * Remove sysfs entries for a logical drive.
> + */
> +static void cciss_destroy_ld_sysfs_entry(drive_info_struct *drv)
> +{
> +	device_del(&drv->dev);
> +}
> +
>  /*
>   * For operations that cannot sleep, a command block is allocated at init,
>   * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track
> @@ -1317,6 +1498,45 @@ static void cciss_softirq_done(struct request *rq)
>  	spin_unlock_irqrestore(&h->lock, flags);
>  }
>  
> +/* This function gets the SCSI vendor, model, and revision of a logical drive
> + * via the inquiry page 0.  Model, vendor, and rev are set to empty strings if
> + * they cannot be read.
> + */
> +static void cciss_get_device_descr(int ctlr, int logvol, int withirq,
> +				   char *vendor, char *model, char *rev)
> +{
> +	int rc;
> +	InquiryData_struct *inq_buf;
> +
> +	*vendor = '\0';
> +	*model = '\0';
> +	*rev = '\0';
> +
> +	inq_buf = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL);
> +	if (!inq_buf)
> +		return;
> +
> +	if (withirq)
> +		rc = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buf,
> +				     sizeof(InquiryData_struct), 1, logvol,
> +				     0, TYPE_CMD);
> +	else
> +		rc = sendcmd(CISS_INQUIRY, ctlr, inq_buf,
> +			     sizeof(InquiryData_struct), 1, logvol, 0, NULL,
> +			     TYPE_CMD);
> +	if (rc == IO_OK) {
> +		memcpy(vendor, &inq_buf->data_byte[8], VENDOR_LEN);
> +		vendor[VENDOR_LEN] = '\0';
> +		memcpy(model, &inq_buf->data_byte[16], MODEL_LEN);
> +		model[MODEL_LEN] = '\0';
> +		memcpy(rev, &inq_buf->data_byte[32], REV_LEN);
> +		rev[REV_LEN] = '\0';
> +	}
> +
> +	kfree(inq_buf);
> +	return;
> +}
> +
>  /* This function gets the serial number of a logical drive via
>   * inquiry page 0x83.  Serial no. is 16 bytes.  If the serial
>   * number cannot be had, for whatever reason, 16 bytes of 0xff
> @@ -1357,7 +1577,7 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
>  	disk->first_minor = drv_index << NWD_SHIFT;
>  	disk->fops = &cciss_fops;
>  	disk->private_data = &h->drv[drv_index];
> -	disk->driverfs_dev = &h->pdev->dev;
> +	disk->driverfs_dev = &h->drv[drv_index].dev;
>  
>  	/* Set up queue information */
>  	blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
> @@ -1448,6 +1668,8 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
>  	drvinfo->block_size = block_size;
>  	drvinfo->nr_blocks = total_size + 1;
>  
> +	cciss_get_device_descr(ctlr, drv_index, 1, drvinfo->vendor,
> +				drvinfo->model, drvinfo->rev);
>  	cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no,
>  			sizeof(drvinfo->serial_no));
>  
> @@ -1497,6 +1719,9 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
>  	h->drv[drv_index].cylinders = drvinfo->cylinders;
>  	h->drv[drv_index].raid_level = drvinfo->raid_level;
>  	memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16);
> +	memcpy(h->drv[drv_index].vendor, drvinfo->vendor, VENDOR_LEN + 1);
> +	memcpy(h->drv[drv_index].model, drvinfo->model, MODEL_LEN + 1);
> +	memcpy(h->drv[drv_index].rev, drvinfo->rev, REV_LEN + 1);
>  
>  	++h->num_luns;
>  	disk = h->gendisk[drv_index];
> @@ -1571,6 +1796,8 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
>  		}
>  	}
>  	h->drv[drv_index].LunID = lunid;
> +	if (cciss_create_ld_sysfs_entry(h, &h->drv[drv_index], drv_index))
> +		goto err_free_disk;
>  
>  	/* Don't need to mark this busy because nobody */
>  	/* else knows about this disk yet to contend */
> @@ -1578,6 +1805,11 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
>  	h->drv[drv_index].busy_configuring = 0;
>  	wmb();
>  	return drv_index;
> +
> +err_free_disk:
> +	put_disk(h->gendisk[drv_index]);
> +	h->gendisk[drv_index] = NULL;
> +	return -1;
>  }
>  
>  /* This is for the special case of a controller which
> @@ -1698,6 +1930,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
>  			h->drv[i].busy_configuring = 1;
>  			spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
>  			return_code = deregister_disk(h, i, 1);
> +			cciss_destroy_ld_sysfs_entry(&h->drv[i]);
>  			h->drv[i].busy_configuring = 0;
>  		}
>  	}
> @@ -3630,12 +3863,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
>  	INIT_HLIST_HEAD(&hba[i]->reqQ);
>  
>  	if (cciss_pci_init(hba[i], pdev) != 0)
> -		goto clean1;
> +		goto clean0;
>  
>  	sprintf(hba[i]->devname, "cciss%d", i);
>  	hba[i]->ctlr = i;
>  	hba[i]->pdev = pdev;
>  
> +	if (cciss_create_hba_sysfs_entry(hba[i]))
> +		goto clean0;
> +
>  	/* configure PCI DMA stuff */
>  	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK))
>  		dac = 1;
> @@ -3774,6 +4010,8 @@ clean4:
>  clean2:
>  	unregister_blkdev(hba[i]->major, hba[i]->devname);
>  clean1:
> +	cciss_destroy_hba_sysfs_entry(hba[i]);
> +clean0:
>  	hba[i]->busy_initializing = 0;
>  	/* cleanup any queues that may have been initialized */
>  	for (j=0; j <= hba[i]->highest_lun; j++){
> @@ -3881,6 +4119,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
>  	 */
>  	pci_release_regions(pdev);
>  	pci_set_drvdata(pdev, NULL);
> +	cciss_destroy_hba_sysfs_entry(hba[i]);
>  	free_hba(i);
>  }
>  
> diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
> index 15e2b84..552ecca 100644
> --- a/drivers/block/cciss.h
> +++ b/drivers/block/cciss.h
> @@ -12,6 +12,11 @@
>  #define IO_OK		0
>  #define IO_ERROR	1
>  
> +#define VENDOR_LEN	8
> +#define MODEL_LEN	16
> +#define REV_LEN		4
> +
> +
>  struct ctlr_info;
>  typedef struct ctlr_info ctlr_info_t;
>  
> @@ -34,13 +39,18 @@ typedef struct _drive_info_struct
>  	int 	cylinders;
>  	int	raid_level; /* set to -1 to indicate that
>  			     * the drive is not in use/configured
> -			    */
> -	int	busy_configuring; /*This is set when the drive is being removed
> -				   *to prevent it from being opened or it's queue
> -				   *from being started.
> -				  */
> -	__u8 serial_no[16]; /* from inquiry page 0x83, */
> -			    /* not necc. null terminated. */
> +			     */
> +	int	busy_configuring; /* This is set when a drive is being removed
> +				   * to prevent it from being opened or it's
> +				   * queue from being started.
> +				   */
> +	struct	device dev;
> +	__u8 serial_no[16]; /* from inquiry page 0x83,
> +			     * not necc. null terminated.
> +			     */
> +	char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */
> +	char model[MODEL_LEN + 1];   /* SCSI model string */
> +	char rev[REV_LEN + 1];       /* SCSI revision string */
>  } drive_info_struct;
>  
>  #ifdef CONFIG_CISS_SCSI_TAPE
> @@ -121,6 +131,7 @@ struct ctlr_info
>  	struct sendcmd_reject_list scsi_rejects;
>  #endif
>  	unsigned char alive;
> +	struct device dev;
>  };
>  
>  /*  Defining the diffent access_menthods */

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs
  2009-04-08  6:19 ` Jens Axboe
@ 2009-04-08  8:13   ` Jens Axboe
  2009-04-08 14:53     ` Mike Miller (OS Dev)
  2009-04-08 12:26   ` Kay Sievers
  1 sibling, 1 reply; 13+ messages in thread
From: Jens Axboe @ 2009-04-08  8:13 UTC (permalink / raw)
  To: Mike Miller (OS Dev)
  Cc: Andrew Morton, LKML, LKML-SCSI, andrew.patterson, mike.miller,
	kay.sievers

On Wed, Apr 08 2009, Jens Axboe wrote:
> On Tue, Apr 07 2009, Mike Miller (OS Dev) wrote:
> > Patch 1 of 1 resubmit
> > 
> > cciss: add cciss driver sysfs entries
> > 
> > This patch adds sysfs entries to the cciss driver needed for the
> > dm/multipath tools. A file for vendor, model, rev, and unique_id are
> > added for each logical drive under directory
> > /sys/bus/pci/devices/<dev>/ccissX/cXdY. Where X = the controller (or
> > host) number and Y is the logical drive number. A link from
> > /sys/bus/pci/devices/<dev>/ccissX/cXdY/block:cciss!cXdY to
> > /sys/block/cciss!cXdY/device is also created.
> > 
> > From: Andrew Patterson <andrew.patterson@hp.com>
> 
> You want to put that at the top of the email, so you have
> {from,description,signed-offs} in that order.
> 
> The patch looks fine to me, but my sysfs foo is very weak though. CC'ing
> Kay, perhaps he can help take a quick look at this.

It doesn't apply to 2.6.30-rc1:

patching file Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
patching file drivers/block/cciss.c
Hunk #1 succeeded at 437 (offset 3 lines).
Hunk #2 succeeded at 1518 (offset 20 lines).
Hunk #3 succeeded at 1597 (offset 20 lines).
Hunk #4 succeeded at 1688 (offset 20 lines).
Hunk #5 succeeded at 1739 (offset 20 lines).
Hunk #6 succeeded at 1816 (offset 20 lines).
Hunk #7 succeeded at 1825 (offset 20 lines).
Hunk #8 succeeded at 1950 (offset 20 lines).
Hunk #9 succeeded at 3956 with fuzz 2 (offset 93 lines).
Hunk #10 succeeded at 4108 (offset 98 lines).
Hunk #11 succeeded at 4220 (offset 101 lines).
patching file drivers/block/cciss.h
Hunk #3 FAILED at 131.
1 out of 3 hunks FAILED -- saving rejects to file
drivers/block/cciss.h.rej

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to  sysfs
  2009-04-08  6:19 ` Jens Axboe
  2009-04-08  8:13   ` Jens Axboe
@ 2009-04-08 12:26   ` Kay Sievers
  2009-04-08 16:24     ` Andrew Patterson
       [not found]     ` <1239258160.19984.217.camel@grinch>
  1 sibling, 2 replies; 13+ messages in thread
From: Kay Sievers @ 2009-04-08 12:26 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Mike Miller (OS Dev),
	Andrew Morton, LKML, LKML-SCSI, andrew.patterson, mike.miller

On Tue, Apr 7, 2009 at 23:19, Jens Axboe <jens.axboe@oracle.com> wrote:
> On Tue, Apr 07 2009, Mike Miller (OS Dev) wrote:

> The patch looks fine to me, but my sysfs foo is very weak though. CC'ing
> Kay, perhaps he can help take a quick look at this.

>> + * Initialize sysfs for each logical drive.  This sets up and registers
>> + * the 'c#d#' directory for each individual logical drive under
>> + * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from
>> + * /sys/block/cciss!c#d# to this entry.
>> + */
>> +static int cciss_create_ld_sysfs_entry(struct ctlr_info *h,
>> +                                    drive_info_struct *drv,
>> +                                    int drv_index)
>> +{
>> +     device_initialize(&drv->dev);
>> +     drv->dev.type = &cciss_dev_type;
>> +     dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index);
>> +     drv->dev.parent = &h->dev;
>> +     return device_add(&drv->dev);
>> +}

If I read that correctly, you are creating a hierarchy of devices
where the devices do not belong to any subsystem? This is what we need
to avoid in almost all cases, we need a "subsystem" link in sysfs.

I wold expect the cciss devices not to be a magic, silently created,
subdirectory of a pci device, but to have their own "cciss" bus in
sysfs, so the created devices get proper events at creation time. All
the cciss devices would show up in its own directory
/sys/bus/cciss/devices/*.

I think, you should name all "cciss bus devices" uniquely, and assign
them to a "cciss bus_type". We really do not want unclassified devices
in the chain of parent devices of a block device.

Or do I missing something here?

Kay

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs
  2009-04-08  8:13   ` Jens Axboe
@ 2009-04-08 14:53     ` Mike Miller (OS Dev)
  0 siblings, 0 replies; 13+ messages in thread
From: Mike Miller (OS Dev) @ 2009-04-08 14:53 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Andrew Morton, LKML, LKML-SCSI, andrew.patterson, mike.miller,
	kay.sievers

On Wed, Apr 08, 2009 at 10:13:37AM +0200, Jens Axboe wrote:
> On Wed, Apr 08 2009, Jens Axboe wrote:
> > On Tue, Apr 07 2009, Mike Miller (OS Dev) wrote:
> > > Patch 1 of 1 resubmit
> > > 
> > > cciss: add cciss driver sysfs entries
> > > 
> > > This patch adds sysfs entries to the cciss driver needed for the
> > > dm/multipath tools. A file for vendor, model, rev, and unique_id are
> > > added for each logical drive under directory
> > > /sys/bus/pci/devices/<dev>/ccissX/cXdY. Where X = the controller (or
> > > host) number and Y is the logical drive number. A link from
> > > /sys/bus/pci/devices/<dev>/ccissX/cXdY/block:cciss!cXdY to
> > > /sys/block/cciss!cXdY/device is also created.
> > > 
> > > From: Andrew Patterson <andrew.patterson@hp.com>
> > 
> > You want to put that at the top of the email, so you have
> > {from,description,signed-offs} in that order.
> > 
> > The patch looks fine to me, but my sysfs foo is very weak though. CC'ing
> > Kay, perhaps he can help take a quick look at this.
> 
> It doesn't apply to 2.6.30-rc1:
> 
> patching file Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
> patching file drivers/block/cciss.c
> Hunk #1 succeeded at 437 (offset 3 lines).
> Hunk #2 succeeded at 1518 (offset 20 lines).
> Hunk #3 succeeded at 1597 (offset 20 lines).
> Hunk #4 succeeded at 1688 (offset 20 lines).
> Hunk #5 succeeded at 1739 (offset 20 lines).
> Hunk #6 succeeded at 1816 (offset 20 lines).
> Hunk #7 succeeded at 1825 (offset 20 lines).
> Hunk #8 succeeded at 1950 (offset 20 lines).
> Hunk #9 succeeded at 3956 with fuzz 2 (offset 93 lines).
> Hunk #10 succeeded at 4108 (offset 98 lines).
> Hunk #11 succeeded at 4220 (offset 101 lines).
> patching file drivers/block/cciss.h
> Hunk #3 FAILED at 131.
> 1 out of 3 hunks FAILED -- saving rejects to file
> drivers/block/cciss.h.rej
> 
My apologies, I built this against 2.6.29 not thinking that my other
changes had been merged.

But it looks like Kay has issues with the patch. Andrew P.?

-- mikem

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to  sysfs
  2009-04-08 12:26   ` Kay Sievers
@ 2009-04-08 16:24     ` Andrew Patterson
  2009-04-08 16:34       ` Kay Sievers
       [not found]     ` <1239258160.19984.217.camel@grinch>
  1 sibling, 1 reply; 13+ messages in thread
From: Andrew Patterson @ 2009-04-08 16:24 UTC (permalink / raw)
  To: Kay Sievers
  Cc: Jens Axboe, Mike Miller (OS Dev),
	Andrew Morton, LKML, LKML-SCSI, mike.miller

On Wed, 2009-04-08 at 05:26 -0700, Kay Sievers wrote:
> On Tue, Apr 7, 2009 at 23:19, Jens Axboe <jens.axboe@oracle.com> wrote:
> > On Tue, Apr 07 2009, Mike Miller (OS Dev) wrote:
> 
> > The patch looks fine to me, but my sysfs foo is very weak though. CC'ing
> > Kay, perhaps he can help take a quick look at this.
> 
> >> + * Initialize sysfs for each logical drive.  This sets up and registers
> >> + * the 'c#d#' directory for each individual logical drive under
> >> + * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from
> >> + * /sys/block/cciss!c#d# to this entry.
> >> + */
> >> +static int cciss_create_ld_sysfs_entry(struct ctlr_info *h,
> >> +                                    drive_info_struct *drv,
> >> +                                    int drv_index)
> >> +{
> >> +     device_initialize(&drv->dev);
> >> +     drv->dev.type = &cciss_dev_type;
> >> +     dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index);
> >> +     drv->dev.parent = &h->dev;
> >> +     return device_add(&drv->dev);
> >> +}
> 
> If I read that correctly, you are creating a hierarchy of devices
> where the devices do not belong to any subsystem? This is what we need
> to avoid in almost all cases, we need a "subsystem" link in sysfs.
> 

Yes, but apparently mistakenly.

> I wold expect the cciss devices not to be a magic, silently created,
> subdirectory of a pci device, but to have their own "cciss" bus in
> sysfs, so the created devices get proper events at creation time. All
> the cciss devices would show up in its own directory
> /sys/bus/cciss/devices/*.
> 
> I think, you should name all "cciss bus devices" uniquely, and assign
> them to a "cciss bus_type". We really do not want unclassified devices
> in the chain of parent devices of a block device.
> 

I'll try this.  Although I am wondering whether to put hosts or logical
drives in /sys/bus/cciss/devices (or both). Can I do what I am doing
now, just moving it to /sys/bus/cciss/devices? That
is, /sys/bus/cciss/devices/ccissX/cYdZ.

Andrew

> Or do I missing something here?
> 
> Kay



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to  sysfs
  2009-04-08 16:24     ` Andrew Patterson
@ 2009-04-08 16:34       ` Kay Sievers
  0 siblings, 0 replies; 13+ messages in thread
From: Kay Sievers @ 2009-04-08 16:34 UTC (permalink / raw)
  To: Andrew Patterson
  Cc: Jens Axboe, Mike Miller (OS Dev),
	Andrew Morton, LKML, LKML-SCSI, mike.miller

On Wed, Apr 8, 2009 at 09:24, Andrew Patterson <andrew.patterson@hp.com> wrote:
> On Wed, 2009-04-08 at 05:26 -0700, Kay Sievers wrote:
>> On Tue, Apr 7, 2009 at 23:19, Jens Axboe <jens.axboe@oracle.com> wrote:
>> > On Tue, Apr 07 2009, Mike Miller (OS Dev) wrote:
>>
>> > The patch looks fine to me, but my sysfs foo is very weak though. CC'ing
>> > Kay, perhaps he can help take a quick look at this.
>>
>> >> + * Initialize sysfs for each logical drive.  This sets up and registers
>> >> + * the 'c#d#' directory for each individual logical drive under
>> >> + * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from
>> >> + * /sys/block/cciss!c#d# to this entry.
>> >> + */
>> >> +static int cciss_create_ld_sysfs_entry(struct ctlr_info *h,
>> >> +                                    drive_info_struct *drv,
>> >> +                                    int drv_index)
>> >> +{
>> >> +     device_initialize(&drv->dev);
>> >> +     drv->dev.type = &cciss_dev_type;
>> >> +     dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index);
>> >> +     drv->dev.parent = &h->dev;
>> >> +     return device_add(&drv->dev);
>> >> +}
>>
>> If I read that correctly, you are creating a hierarchy of devices
>> where the devices do not belong to any subsystem? This is what we need
>> to avoid in almost all cases, we need a "subsystem" link in sysfs.
>>
>
> Yes, but apparently mistakenly.
>
>> I wold expect the cciss devices not to be a magic, silently created,
>> subdirectory of a pci device, but to have their own "cciss" bus in
>> sysfs, so the created devices get proper events at creation time. All
>> the cciss devices would show up in its own directory
>> /sys/bus/cciss/devices/*.
>>
>> I think, you should name all "cciss bus devices" uniquely, and assign
>> them to a "cciss bus_type". We really do not want unclassified devices
>> in the chain of parent devices of a block device.
>>
>
> I'll try this.  Although I am wondering whether to put hosts or logical
> drives in /sys/bus/cciss/devices (or both). Can I do what I am doing
> now, just moving it to /sys/bus/cciss/devices? That
> is, /sys/bus/cciss/devices/ccissX/cYdZ.

Do what you have today, just make sure all your devices are uniquely
named, and assigned to the cciss bus_type. There can be no hierarchies
in /sys/bus/*/devices, there are only symlinks. The hierarchy is only
in /sys/devices/, and if I correctly look at what you have, you have
that already.

Kay

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to  sysfs
       [not found]           ` <ac3eb2510904091005q13e5b5a1j3907de22ad3df70c@mail.gmail.com>
@ 2009-04-09 18:07             ` Andrew Patterson
  2009-04-09 18:12               ` Kay Sievers
  0 siblings, 1 reply; 13+ messages in thread
From: Andrew Patterson @ 2009-04-09 18:07 UTC (permalink / raw)
  To: Kay Sievers
  Cc: ens Axboe, Mike Miller (OS Dev), Andrew Morton, LKML, LKML-SCSI

On Thu, 2009-04-09 at 10:05 -0700, Kay Sievers wrote:
> On Thu, Apr 9, 2009 at 09:57, Andrew Patterson <andrew.patterson@hp.com> wrote:
> > On Thu, 2009-04-09 at 07:19 -0700, Kay Sievers wrote:
> 
> >> I would need to see the output of:
> >>   /sbin/udevadm info --attribute-walk --path=/block/<disk-name>
> 
> >  looking at device '/block/cciss!c0d0':
> >    KERNEL=="cciss!c0d0"
> >    SUBSYSTEM=="block"
> >    DRIVER==""
> >    ATTR{range}=="16"
> >    ATTR{ext_range}=="16"
> >    ATTR{removable}=="0"
> >    ATTR{ro}=="0"
> >    ATTR{size}=="286611840"
> >    ATTR{capability}=="10"
> 
> The block device needs a parent, please assign the cciss bus device.
> It's the driverfs_dev in the genhd struct.
> 

This is already done in cciss_add_disk():

	disk->fops = &cciss_fops;
	disk->private_data = &h->drv[drv_index];
	disk->driverfs_dev = &h->drv[drv_index].dev;

I think my problem is I was assigning cciss_bus_type to the controller,
not the block device. I have fixed that.

> Please provide the output again, it will get much larger then.
> 
> Also, please disable CONFIG_SYSFS_DEPRECATED* in your kernel config.
> 

Done.

# /sbin/udevadm info --attribute-walk "--path=/block/cciss!c0d0"

Udevinfo starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

'/devices/pci0000:4f/0000:4f:00.0/0000:50:00.0/0000:51:04.0/0000:8b:00.0/cciss0/c0d0/block/cciss!c0d0':
    KERNEL=="cciss!c0d0"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{range}=="16"
    ATTR{ext_range}=="16"
    ATTR{removable}=="0"
    ATTR{ro}=="0"
    ATTR{size}=="286611840"
    ATTR{capability}=="10"
    ATTR{stat}=="      29       37     2112       52        0        0
0        0        0       52       52"

  looking at parent device
'/devices/pci0000:4f/0000:4f:00.0/0000:50:00.0/0000:51:04.0/0000:8b:00.0/cciss0/c0d0':
    KERNELS=="c0d0"
    SUBSYSTEMS=="cciss"
    DRIVERS==""
    ATTRS{unique_id}=="600508B1001044424654324558350012"
    ATTRS{model}=="LOGICAL VOLUME  "
    ATTRS{vendor}=="HP      "
    ATTRS{rev}=="5.20"

  looking at parent device
'/devices/pci0000:4f/0000:4f:00.0/0000:50:00.0/0000:51:04.0/0000:8b:00.0/cciss0':
    KERNELS=="cciss0"
    SUBSYSTEMS==""
    DRIVERS==""

  looking at parent device
'/devices/pci0000:4f/0000:4f:00.0/0000:50:00.0/0000:51:04.0/0000:8b:00.0':
    KERNELS=="0000:8b:00.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="cciss"
    ATTRS{vendor}=="0x103c"
    ATTRS{device}=="0x3230"
    ATTRS{subsystem_vendor}=="0x103c"
    ATTRS{subsystem_device}=="0x3223"
    ATTRS{class}=="0x010400"
    ATTRS{irq}=="67"

ATTRS{local_cpus}=="ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff"
    ATTRS{local_cpulist}=="0-511"

ATTRS{modalias}=="pci:v0000103Cd00003230sv0000103Csd00003223bc01sc04i00"
    ATTRS{numa_node}=="-1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}==""

  looking at parent device
'/devices/pci0000:4f/0000:4f:00.0/0000:50:00.0/0000:51:04.0':
    KERNELS=="0000:51:04.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="pcieport-driver"
    ATTRS{vendor}=="0x111d"
    ATTRS{device}=="0x801c"
    ATTRS{subsystem_vendor}=="0x0000"
    ATTRS{subsystem_device}=="0x0000"
    ATTRS{class}=="0x060400"
    ATTRS{irq}=="53"

ATTRS{local_cpus}=="ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff"
    ATTRS{local_cpulist}=="0-511"

ATTRS{modalias}=="pci:v0000111Dd0000801Csv00000000sd00000000bc06sc04i00"
    ATTRS{numa_node}=="-1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}=="1"

  looking at parent device
'/devices/pci0000:4f/0000:4f:00.0/0000:50:00.0':
    KERNELS=="0000:50:00.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="pcieport-driver"
    ATTRS{vendor}=="0x111d"
    ATTRS{device}=="0x801c"
    ATTRS{subsystem_vendor}=="0x0000"
    ATTRS{subsystem_device}=="0x0000"
    ATTRS{class}=="0x060400"
    ATTRS{irq}=="0"

ATTRS{local_cpus}=="ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff"
    ATTRS{local_cpulist}=="0-511"

ATTRS{modalias}=="pci:v0000111Dd0000801Csv00000000sd00000000bc06sc04i00"
    ATTRS{numa_node}=="-1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}=="1"

  looking at parent device '/devices/pci0000:4f/0000:4f:00.0':
    KERNELS=="0000:4f:00.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="pcieport-driver"
    ATTRS{vendor}=="0x103c"
    ATTRS{device}=="0x403b"
    ATTRS{subsystem_vendor}=="0x0000"
    ATTRS{subsystem_device}=="0x0000"
    ATTRS{class}=="0x060400"
    ATTRS{irq}=="51"

ATTRS{local_cpus}=="ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff"
    ATTRS{local_cpulist}=="0-511"

ATTRS{modalias}=="pci:v0000103Cd0000403Bsv00000000sd00000000bc06sc04i00"
    ATTRS{numa_node}=="-1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}=="1"

  looking at parent device '/devices/pci0000:4f':
    KERNELS=="pci0000:4f"
    SUBSYSTEMS==""
    DRIVERS==""

> Thanks,
> Kay

Thanks for looking at this.

Andrew


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to  sysfs
  2009-04-09 18:07             ` Andrew Patterson
@ 2009-04-09 18:12               ` Kay Sievers
  0 siblings, 0 replies; 13+ messages in thread
From: Kay Sievers @ 2009-04-09 18:12 UTC (permalink / raw)
  To: Andrew Patterson
  Cc: ens Axboe, Mike Miller (OS Dev), Andrew Morton, LKML, LKML-SCSI

On Thu, Apr 9, 2009 at 11:07, Andrew Patterson <andrew.patterson@hp.com> wrote:
> On Thu, 2009-04-09 at 10:05 -0700, Kay Sievers wrote:

>> The block device needs a parent, please assign the cciss bus device.
>> It's the driverfs_dev in the genhd struct.
>>
>
> This is already done in cciss_add_disk():
>
>        disk->fops = &cciss_fops;
>        disk->private_data = &h->drv[drv_index];
>        disk->driverfs_dev = &h->drv[drv_index].dev;
>
> I think my problem is I was assigning cciss_bus_type to the controller,
> not the block device. I have fixed that.

> # /sbin/udevadm info --attribute-walk "--path=/block/cciss!c0d0"

>  looking at parent device
> '/devices/pci0000:4f/0000:4f:00.0/0000:50:00.0/0000:51:04.0/0000:8b:00.0/cciss0':
>    KERNELS=="cciss0"
>    SUBSYSTEMS==""

This device also needs the cciss bus_type assigned, so the subsystem
becomes cciss, and it also shows up in /sys/bus/cciss/devices/.

Other than that, the sysfs hierarchy looks fine.

Thanks,
Kay

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs
  2009-04-07 18:04 [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs Mike Miller (OS Dev)
  2009-04-08  6:19 ` Jens Axboe
@ 2009-04-10  4:52 ` Andrew Morton
  2009-04-10  5:08   ` Andrew Patterson
  1 sibling, 1 reply; 13+ messages in thread
From: Andrew Morton @ 2009-04-10  4:52 UTC (permalink / raw)
  To: Mike Miller (OS Dev)
  Cc: Jens Axboe, LKML, LKML-SCSI, andrew.patterson, mike.miller

On Tue, 7 Apr 2009 13:04:11 -0500 "Mike Miller (OS Dev)" <mikem@beardog.cca.cpqcorp.net> wrote:

> Patch 1 of 1 resubmit
> 
> cciss: add cciss driver sysfs entries
> 
> This patch adds sysfs entries to the cciss driver needed for the
> dm/multipath tools. A file for vendor, model, rev, and unique_id are
> added for each logical drive under directory
> /sys/bus/pci/devices/<dev>/ccissX/cXdY. Where X = the controller (or
> host) number and Y is the logical drive number. A link from
> /sys/bus/pci/devices/<dev>/ccissX/cXdY/block:cciss!cXdY to
> /sys/block/cciss!cXdY/device is also created.
> 
> ...
>
> +static ssize_t dev_show_model(struct device *dev,
> +			      struct device_attribute *attr,
> +			      char *buf)
> +{
> +	drive_info_struct *drv = to_drv(dev);
> +	struct ctlr_info *h = to_hba(drv->dev.parent);
> +	char model[MODEL_LEN + 1];
> +	unsigned long flags;
> +	int ret = 0;
> +
> +	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
> +	if (h->busy_configuring)
> +		ret = -EBUSY;
> +	else
> +		memcpy(model, drv->model, MODEL_LEN + 1);
> +	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
> +
> +	if (ret)
> +		return ret;
> +	else
> +		return snprintf(buf, MODEL_LEN + 2, "%s\n", drv->model);

Isn't the buffer sizing wrong here?  Should be MODEL_LEN+1.

> +}
> +DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL);
> +
> +static ssize_t dev_show_rev(struct device *dev,
> +			    struct device_attribute *attr,
> +			    char *buf)
> +{
> +	drive_info_struct *drv = to_drv(dev);
> +	struct ctlr_info *h = to_hba(drv->dev.parent);
> +	char rev[REV_LEN + 1];
> +	unsigned long flags;
> +	int ret = 0;
> +
> +	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
> +	if (h->busy_configuring)
> +		ret = -EBUSY;
> +	else
> +		memcpy(rev, drv->rev, REV_LEN + 1);
> +	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
> +
> +	if (ret)
> +		return ret;
> +	else
> +		return snprintf(buf, REV_LEN + 2, "%s\n", drv->rev);

Repeated in various places.

> +}


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs
  2009-04-10  4:52 ` Andrew Morton
@ 2009-04-10  5:08   ` Andrew Patterson
  2009-04-10  5:17     ` Andrew Morton
  0 siblings, 1 reply; 13+ messages in thread
From: Andrew Patterson @ 2009-04-10  5:08 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Mike Miller (OS Dev), Jens Axboe, LKML, LKML-SCSI, mike.miller

On Thu, 2009-04-09 at 21:52 -0700, Andrew Morton wrote:
> On Tue, 7 Apr 2009 13:04:11 -0500 "Mike Miller (OS Dev)" <mikem@beardog.cca.cpqcorp.net> wrote:
> 
> > Patch 1 of 1 resubmit
> > 
> > cciss: add cciss driver sysfs entries
> > 
> > This patch adds sysfs entries to the cciss driver needed for the
> > dm/multipath tools. A file for vendor, model, rev, and unique_id are
> > added for each logical drive under directory
> > /sys/bus/pci/devices/<dev>/ccissX/cXdY. Where X = the controller (or
> > host) number and Y is the logical drive number. A link from
> > /sys/bus/pci/devices/<dev>/ccissX/cXdY/block:cciss!cXdY to
> > /sys/block/cciss!cXdY/device is also created.
> > 
> > ...
> >
> > +static ssize_t dev_show_model(struct device *dev,
> > +			      struct device_attribute *attr,
> > +			      char *buf)
> > +{
> > +	drive_info_struct *drv = to_drv(dev);
> > +	struct ctlr_info *h = to_hba(drv->dev.parent);
> > +	char model[MODEL_LEN + 1];
> > +	unsigned long flags;
> > +	int ret = 0;
> > +
> > +	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
> > +	if (h->busy_configuring)
> > +		ret = -EBUSY;
> > +	else
> > +		memcpy(model, drv->model, MODEL_LEN + 1);
> > +	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
> > +
> > +	if (ret)
> > +		return ret;
> > +	else
> > +		return snprintf(buf, MODEL_LEN + 2, "%s\n", drv->model);
> 
> Isn't the buffer sizing wrong here?  Should be MODEL_LEN+1.
> 

Don't we need space for the '\0' and the '\n'?

> > +}
> > +DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL);
> > +
> > +static ssize_t dev_show_rev(struct device *dev,
> > +			    struct device_attribute *attr,
> > +			    char *buf)
> > +{
> > +	drive_info_struct *drv = to_drv(dev);
> > +	struct ctlr_info *h = to_hba(drv->dev.parent);
> > +	char rev[REV_LEN + 1];
> > +	unsigned long flags;
> > +	int ret = 0;
> > +
> > +	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
> > +	if (h->busy_configuring)
> > +		ret = -EBUSY;
> > +	else
> > +		memcpy(rev, drv->rev, REV_LEN + 1);
> > +	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
> > +
> > +	if (ret)
> > +		return ret;
> > +	else
> > +		return snprintf(buf, REV_LEN + 2, "%s\n", drv->rev);
> 
> Repeated in various places.
> 
> > +}



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs
  2009-04-10  5:08   ` Andrew Patterson
@ 2009-04-10  5:17     ` Andrew Morton
  2009-04-10 17:19       ` Andrew Patterson
  0 siblings, 1 reply; 13+ messages in thread
From: Andrew Morton @ 2009-04-10  5:17 UTC (permalink / raw)
  To: Andrew Patterson
  Cc: Mike Miller (OS Dev), Jens Axboe, LKML, LKML-SCSI, mike.miller

On Fri, 10 Apr 2009 05:08:54 +0000 Andrew Patterson <andrew.patterson@hp.com> wrote:

> > > +	char model[MODEL_LEN + 1];
> > > ...
> > > +		return snprintf(buf, MODEL_LEN + 2, "%s\n", drv->model);
> > 
> > Isn't the buffer sizing wrong here?  Should be MODEL_LEN+1.
> > 
> 
> Don't we need space for the '\0' and the '\n'?

The second arg to snprintf() tells snprintf() how large the buffer is. 
That buffer should be sized to allow room for the trailing \0.

So if MODEL_LEN represents the maximum number of characters in a string
then you want:

	char model[MODEL_LEN + 2];	/* Room for the \n and the \0 */
	...
	return snprintf(buf, sizeof(model), "%s\n", drv->model);

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs
  2009-04-10  5:17     ` Andrew Morton
@ 2009-04-10 17:19       ` Andrew Patterson
  0 siblings, 0 replies; 13+ messages in thread
From: Andrew Patterson @ 2009-04-10 17:19 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Mike Miller (OS Dev), Jens Axboe, LKML, LKML-SCSI, mike.miller

On Thu, 2009-04-09 at 22:17 -0700, Andrew Morton wrote: 
> On Fri, 10 Apr 2009 05:08:54 +0000 Andrew Patterson <andrew.patterson@hp.com> wrote:
> 
> > > > +	char model[MODEL_LEN + 1];
> > > > ...
> > > > +		return snprintf(buf, MODEL_LEN + 2, "%s\n", drv->model);
> > > 
> > > Isn't the buffer sizing wrong here?  Should be MODEL_LEN+1.
> > > 
> > 
> > Don't we need space for the '\0' and the '\n'?
> 
> The second arg to snprintf() tells snprintf() how large the buffer is. 
> That buffer should be sized to allow room for the trailing \0.
> 
> So if MODEL_LEN represents the maximum number of characters in a string
> then you want:
> 
> 	char model[MODEL_LEN + 2];	/* Room for the \n and the \0 */
> 	...
> 	return snprintf(buf, sizeof(model), "%s\n", drv->model);

Note that I don't want the '\n" in the source string.  I just want it
output to the dest string (buf).  I could do:

  return snprintf(buf, sizeof(model) + 1, "%s\n", drv->model);

if that is preferable.  Perhaps what is confusing is using:

#define MODEL_LEN	16
char model[MODEL_LEN + 1];   /* SCSI model string */

So MODEL_LEN is not accounting for the '\0'.

I am not sure what the convention is here.  It have seen SCSI code that
uses the above, e.g., include/scsi/scsi_transport_sas.h.  But I am happy
to have *_LEN account for the '\0' if that makes it less confusing.

Andrew


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2009-04-10 17:20 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-07 18:04 [PATCH 1/1] cciss: resubmit export uid, model, vendor, rev to sysfs Mike Miller (OS Dev)
2009-04-08  6:19 ` Jens Axboe
2009-04-08  8:13   ` Jens Axboe
2009-04-08 14:53     ` Mike Miller (OS Dev)
2009-04-08 12:26   ` Kay Sievers
2009-04-08 16:24     ` Andrew Patterson
2009-04-08 16:34       ` Kay Sievers
     [not found]     ` <1239258160.19984.217.camel@grinch>
     [not found]       ` <ac3eb2510904090719n730dededp54b25390a9087a79@mail.gmail.com>
     [not found]         ` <1239296221.19984.218.camel@grinch>
     [not found]           ` <ac3eb2510904091005q13e5b5a1j3907de22ad3df70c@mail.gmail.com>
2009-04-09 18:07             ` Andrew Patterson
2009-04-09 18:12               ` Kay Sievers
2009-04-10  4:52 ` Andrew Morton
2009-04-10  5:08   ` Andrew Patterson
2009-04-10  5:17     ` Andrew Morton
2009-04-10 17:19       ` Andrew Patterson

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).