Commit 154173a0 authored by Mike Anderson's avatar Mike Anderson Committed by James Bottomley

[PATCH] scsi host sysfs support again [4/4]

-andmike
--
Michael Anderson
andmike@us.ibm.com


DESC
Change scsi sysfs to support scsi host class device and call release
functions when ref count goes to zero.
EDESC


 drivers/scsi/scsi_sysfs.c |  111 +++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 96 insertions(+), 15 deletions(-)
parent 19e4ff96
...@@ -22,9 +22,9 @@ ...@@ -22,9 +22,9 @@
*/ */
#define shost_show_function(field, format_string) \ #define shost_show_function(field, format_string) \
static ssize_t \ static ssize_t \
show_##field (struct device *dev, char *buf) \ show_##field (struct class_device *class_dev, char *buf) \
{ \ { \
struct Scsi_Host *shost = to_scsi_host(dev); \ struct Scsi_Host *shost = class_to_shost(class_dev); \
return snprintf (buf, 20, format_string, shost->field); \ return snprintf (buf, 20, format_string, shost->field); \
} }
...@@ -33,8 +33,8 @@ show_##field (struct device *dev, char *buf) \ ...@@ -33,8 +33,8 @@ show_##field (struct device *dev, char *buf) \
* read only field. * read only field.
*/ */
#define shost_rd_attr(field, format_string) \ #define shost_rd_attr(field, format_string) \
shost_show_function(field, format_string) \ shost_show_function(field, format_string) \
static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)
/* /*
* Create the actual show/store functions and data structures. * Create the actual show/store functions and data structures.
...@@ -45,16 +45,16 @@ shost_rd_attr(cmd_per_lun, "%hd\n"); ...@@ -45,16 +45,16 @@ shost_rd_attr(cmd_per_lun, "%hd\n");
shost_rd_attr(sg_tablesize, "%hu\n"); shost_rd_attr(sg_tablesize, "%hu\n");
shost_rd_attr(unchecked_isa_dma, "%d\n"); shost_rd_attr(unchecked_isa_dma, "%d\n");
static struct device_attribute *const shost_attrs[] = { static struct class_device_attribute *const shost_attrs[] = {
&dev_attr_unique_id, &class_device_attr_unique_id,
&dev_attr_host_busy, &class_device_attr_host_busy,
&dev_attr_cmd_per_lun, &class_device_attr_cmd_per_lun,
&dev_attr_sg_tablesize, &class_device_attr_sg_tablesize,
&dev_attr_unchecked_isa_dma, &class_device_attr_unchecked_isa_dma,
}; };
struct class shost_class = { struct class shost_class = {
.name = "scsi-host", .name = "scsi_host",
}; };
/** /**
...@@ -91,10 +91,16 @@ static struct bus_type scsi_bus_type = { ...@@ -91,10 +91,16 @@ static struct bus_type scsi_bus_type = {
int scsi_sysfs_register(void) int scsi_sysfs_register(void)
{ {
bus_register(&scsi_bus_type); int error;
class_register(&shost_class);
return 0; error = bus_register(&scsi_bus_type);
if (error)
return error;
error = class_register(&shost_class);
if (error)
return error;
return error;
} }
void scsi_sysfs_unregister(void) void scsi_sysfs_unregister(void)
...@@ -250,6 +256,16 @@ static struct device_attribute * const sdev_attrs[] = { ...@@ -250,6 +256,16 @@ static struct device_attribute * const sdev_attrs[] = {
&dev_attr_rescan, &dev_attr_rescan,
}; };
static void scsi_device_release(struct device *dev)
{
struct scsi_device *sdev;
sdev = to_scsi_device(dev);
if (!sdev)
return;
scsi_free_sdev(sdev);
}
/** /**
* scsi_device_register - register a scsi device with the scsi bus * scsi_device_register - register a scsi device with the scsi bus
* @sdev: scsi_device to register * @sdev: scsi_device to register
...@@ -263,8 +279,9 @@ int scsi_device_register(struct scsi_device *sdev) ...@@ -263,8 +279,9 @@ int scsi_device_register(struct scsi_device *sdev)
sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d", sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
sdev->sdev_driverfs_dev.parent = sdev->host->host_gendev; sdev->sdev_driverfs_dev.parent = &sdev->host->host_gendev;
sdev->sdev_driverfs_dev.bus = &scsi_bus_type; sdev->sdev_driverfs_dev.bus = &scsi_bus_type;
sdev->sdev_driverfs_dev.release = scsi_device_release;
error = device_register(&sdev->sdev_driverfs_dev); error = device_register(&sdev->sdev_driverfs_dev);
if (error) if (error)
...@@ -292,3 +309,67 @@ void scsi_device_unregister(struct scsi_device *sdev) ...@@ -292,3 +309,67 @@ void scsi_device_unregister(struct scsi_device *sdev)
device_remove_file(&sdev->sdev_driverfs_dev, sdev_attrs[i]); device_remove_file(&sdev->sdev_driverfs_dev, sdev_attrs[i]);
device_unregister(&sdev->sdev_driverfs_dev); device_unregister(&sdev->sdev_driverfs_dev);
} }
static void scsi_host_release(struct device *dev)
{
struct Scsi_Host *shost;
shost = dev_to_shost(dev);
if (!shost)
return;
shost->hostt->release(shost);
}
/**
* scsi_sysfs_add_host - add scsi host to subsystem
* @shost: scsi host struct to add to subsystem
* @dev: parent struct device pointer
**/
int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev)
{
int i, error;
sprintf(shost->host_gendev.bus_id,"host%d",
shost->host_no);
if (!shost->host_gendev.parent)
shost->host_gendev.parent = (dev) ? dev : &legacy_bus;
shost->host_gendev.release = scsi_host_release;
error = device_register(&shost->host_gendev);
if (error)
return error;
shost->class_dev.dev = &shost->host_gendev;
shost->class_dev.class = &shost_class;
snprintf(shost->class_dev.class_id, BUS_ID_SIZE, "host%d",
shost->host_no);
error = class_device_register(&shost->class_dev);
if (error)
goto clean_device;
for (i = 0; !error && i < ARRAY_SIZE(shost_attrs); i++)
error = class_device_create_file(&shost->class_dev,
shost_attrs[i]);
if (error)
goto clean_class;
return error;
clean_class:
class_device_unregister(&shost->class_dev);
clean_device:
device_unregister(&shost->host_gendev);
return error;
}
/**
* scsi_sysfs_remove_host - remove scsi host from subsystem
* @shost: scsi host to remove from subsystem
**/
void scsi_sysfs_remove_host(struct Scsi_Host *shost)
{
class_device_unregister(&shost->class_dev);
device_unregister(&shost->host_gendev);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment