Commit 3ba735a1 authored by Ben Collins's avatar Ben Collins

IEEE1394(r1161): Major cleanup and addition of a ud-class, to make things even cleaner.

parent 3c504d62
...@@ -120,7 +120,7 @@ struct host_info { ...@@ -120,7 +120,7 @@ struct host_info {
}; };
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
static int nodemgr_hotplug(struct device *dev, char **envp, int num_envp, static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size); char *buffer, int buffer_size);
static void nodemgr_resume_ne(struct node_entry *ne); static void nodemgr_resume_ne(struct node_entry *ne);
static void nodemgr_remove_ne(struct node_entry *ne); static void nodemgr_remove_ne(struct node_entry *ne);
...@@ -129,7 +129,6 @@ static struct node_entry *find_entry_by_guid(u64 guid); ...@@ -129,7 +129,6 @@ static struct node_entry *find_entry_by_guid(u64 guid);
struct bus_type ieee1394_bus_type = { struct bus_type ieee1394_bus_type = {
.name = "ieee1394", .name = "ieee1394",
.match = nodemgr_bus_match, .match = nodemgr_bus_match,
.hotplug = nodemgr_hotplug,
}; };
static void host_cls_release(struct class_device *class_dev) static void host_cls_release(struct class_device *class_dev)
...@@ -152,26 +151,21 @@ struct class nodemgr_ne_class = { ...@@ -152,26 +151,21 @@ struct class nodemgr_ne_class = {
.release = ne_cls_release, .release = ne_cls_release,
}; };
static struct hpsb_highlevel nodemgr_highlevel; static void ud_cls_release(struct class_device *class_dev)
static int nodemgr_platform_data_ud;
static int nodemgr_generic_probe(struct device *dev)
{ {
return -ENODEV; put_device(&container_of((class_dev), struct unit_directory, class_dev)->device);
} }
static struct device_driver nodemgr_driver_ne = { /* The name here is only so that unit directory hotplug works with old
.name = "ieee1394_node", * style hotplug, which only ever did unit directories anyway. */
.bus = &ieee1394_bus_type, struct class nodemgr_ud_class = {
.probe = nodemgr_generic_probe, .name = "ieee1394",
.release = ud_cls_release,
.hotplug = nodemgr_hotplug,
}; };
static struct device_driver nodemgr_driver_host = { static struct hpsb_highlevel nodemgr_highlevel;
.name = "ieee1394_host",
.bus = &ieee1394_bus_type,
.probe = nodemgr_generic_probe,
};
static void nodemgr_release_ud(struct device *dev) static void nodemgr_release_ud(struct device *dev)
{ {
...@@ -205,22 +199,22 @@ static void nodemgr_release_host(struct device *dev) ...@@ -205,22 +199,22 @@ static void nodemgr_release_host(struct device *dev)
kfree(host); kfree(host);
} }
static int nodemgr_ud_platform_data;
static struct device nodemgr_dev_template_ud = { static struct device nodemgr_dev_template_ud = {
.bus = &ieee1394_bus_type, .bus = &ieee1394_bus_type,
.release = nodemgr_release_ud, .release = nodemgr_release_ud,
.platform_data = &nodemgr_platform_data_ud, .platform_data = &nodemgr_ud_platform_data,
}; };
static struct device nodemgr_dev_template_ne = { static struct device nodemgr_dev_template_ne = {
.bus = &ieee1394_bus_type, .bus = &ieee1394_bus_type,
.release = nodemgr_release_ne, .release = nodemgr_release_ne,
.driver = &nodemgr_driver_ne,
}; };
struct device nodemgr_dev_template_host = { struct device nodemgr_dev_template_host = {
.bus = &ieee1394_bus_type, .bus = &ieee1394_bus_type,
.release = nodemgr_release_host, .release = nodemgr_release_host,
.driver = &nodemgr_driver_host,
}; };
...@@ -631,9 +625,8 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv) ...@@ -631,9 +625,8 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
struct unit_directory *ud; struct unit_directory *ud;
struct ieee1394_device_id *id; struct ieee1394_device_id *id;
/* We only match unit directories, and ignore our internal drivers */ /* We only match unit directories */
if (dev->platform_data != &nodemgr_platform_data_ud || if (dev->platform_data != &nodemgr_ud_platform_data)
drv->probe == nodemgr_generic_probe)
return 0; return 0;
ud = container_of(dev, struct unit_directory, device); ud = container_of(dev, struct unit_directory, device);
...@@ -666,41 +659,19 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv) ...@@ -666,41 +659,19 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
} }
static void nodemgr_remove_ud(struct unit_directory *ud) static void nodemgr_remove_uds(struct node_entry *ne)
{ {
struct device *dev = &ud->device; struct class_device *cdev, *next;
struct list_head *lh, *next;
int i;
list_for_each_safe(lh, next, &ud->device.children) {
struct unit_directory *ud; struct unit_directory *ud;
ud = container_of(list_to_dev(lh), struct unit_directory, device);
nodemgr_remove_ud(ud);
}
for (i = 0; i < ARRAY_SIZE(fw_ud_attrs); i++) list_for_each_entry_safe(cdev, next, &nodemgr_ud_class.children, node) {
device_remove_file(dev, fw_ud_attrs[i]); ud = container_of(cdev, struct unit_directory, class_dev);
device_remove_file(dev, &dev_attr_ud_specifier_id); if (ud->ne != ne)
device_remove_file(dev, &dev_attr_ud_version); continue;
device_remove_file(dev, &dev_attr_ud_vendor_id);
device_remove_file(dev, &dev_attr_ud_vendor_name_kv);
device_remove_file(dev, &dev_attr_ud_vendor_oui);
device_remove_file(dev, &dev_attr_ud_model_id);
device_remove_file(dev, &dev_attr_ud_model_name_kv);
device_unregister(dev);
}
static void nodemgr_remove_node_uds(struct node_entry *ne)
{
struct list_head *lh, *next;
list_for_each_safe(lh, next, &ne->device.children) { class_device_unregister(&ud->class_dev);
struct unit_directory *ud; device_unregister(&ud->device);
ud = container_of(list_to_dev(lh), struct unit_directory, device);
nodemgr_remove_ud(ud);
} }
} }
...@@ -708,39 +679,29 @@ static void nodemgr_remove_node_uds(struct node_entry *ne) ...@@ -708,39 +679,29 @@ static void nodemgr_remove_node_uds(struct node_entry *ne)
static void nodemgr_remove_ne(struct node_entry *ne) static void nodemgr_remove_ne(struct node_entry *ne)
{ {
struct device *dev = &ne->device; struct device *dev = &ne->device;
int i;
dev = get_device(&ne->device);
if (!dev)
return;
HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
nodemgr_remove_node_uds(ne); nodemgr_remove_uds(ne);
for (i = 0; i < ARRAY_SIZE(fw_ne_attrs); i++)
device_remove_file(dev, fw_ne_attrs[i]);
device_remove_file(dev, &dev_attr_ne_guid_vendor_oui);
device_remove_file(dev, &dev_attr_ne_vendor_name_kv);
device_remove_file(dev, &dev_attr_ne_vendor_oui);
device_remove_file(dev, &dev_attr_ne_in_limbo);
class_device_unregister(&ne->class_dev); class_device_unregister(&ne->class_dev);
device_unregister(dev); device_unregister(dev);
put_device(dev);
} }
static void nodemgr_remove_host_dev(struct device *dev) static void nodemgr_remove_host_dev(struct device *dev)
{ {
int i; struct device *ne_dev, *next;
struct list_head *lh, *next;
list_for_each_safe(lh, next, &dev->children) { list_for_each_entry_safe(ne_dev, next, &dev->children, node)
struct node_entry *ne; nodemgr_remove_ne(container_of(ne_dev, struct node_entry, device));
ne = container_of(list_to_dev(lh), struct node_entry, device);
nodemgr_remove_ne(ne);
}
for (i = 0; i < ARRAY_SIZE(fw_host_attrs); i++)
device_remove_file(dev, fw_host_attrs[i]);
sysfs_remove_link(&dev->kobj, "irm_id"); sysfs_remove_link(&dev->kobj, "irm_id");
sysfs_remove_link(&dev->kobj, "busmgr_id"); sysfs_remove_link(&dev->kobj, "busmgr_id");
...@@ -1005,7 +966,14 @@ static struct unit_directory *nodemgr_process_unit_directory ...@@ -1005,7 +966,14 @@ static struct unit_directory *nodemgr_process_unit_directory
snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u",
ne->device.bus_id, ud->id); ne->device.bus_id, ud->id);
ud->class_dev.dev = &ud->device;
ud->class_dev.class = &nodemgr_ud_class;
snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u",
ne->device.bus_id, ud->id);
device_register(&ud->device); device_register(&ud->device);
class_device_register(&ud->class_dev);
get_device(&ud->device);
if (ud->vendor_oui) if (ud->vendor_oui)
device_create_file(&ud->device, &dev_attr_ud_vendor_oui); device_create_file(&ud->device, &dev_attr_ud_vendor_oui);
...@@ -1071,36 +1039,30 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent ...@@ -1071,36 +1039,30 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
static int nodemgr_hotplug(struct device *dev, char **envp, int num_envp, static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size) char *buffer, int buffer_size)
{ {
struct unit_directory *ud; struct unit_directory *ud;
char *scratch;
int i = 0; int i = 0;
int length = 0; int length = 0;
if (!dev) if (!cdev)
return -ENODEV;
if (dev->platform_data != &nodemgr_platform_data_ud)
return -ENODEV; return -ENODEV;
ud = container_of(dev, struct unit_directory, device); ud = container_of(cdev, struct unit_directory, class_dev);
if (ud->ne->in_limbo || ud->ignore_driver) if (ud->ne->in_limbo || ud->ignore_driver)
return -ENODEV; return -ENODEV;
scratch = buffer;
#define PUT_ENVP(fmt,val) \ #define PUT_ENVP(fmt,val) \
do { \ do { \
envp[i++] = scratch; \ envp[i++] = buffer; \
length += snprintf(scratch, buffer_size - length, \ length += snprintf(buffer, buffer_size - length, \
fmt, val); \ fmt, val); \
if ((buffer_size - length <= 0) || (i >= num_envp)) \ if ((buffer_size - length <= 0) || (i >= num_envp)) \
return -ENOMEM; \ return -ENOMEM; \
++length; \ ++length; \
scratch = buffer + length; \ buffer += length; \
} while (0) } while (0)
PUT_ENVP("VENDOR_ID=%06x", ud->vendor_id); PUT_ENVP("VENDOR_ID=%06x", ud->vendor_id);
...@@ -1118,7 +1080,7 @@ do { \ ...@@ -1118,7 +1080,7 @@ do { \
#else #else
static int nodemgr_hotplug(struct device *dev, char **envp, int num_envp, static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size) char *buffer, int buffer_size)
{ {
return -ENODEV; return -ENODEV;
...@@ -1186,7 +1148,7 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, ...@@ -1186,7 +1148,7 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
/* If the node's configrom generation has changed, we /* If the node's configrom generation has changed, we
* unregister all the unit directories. */ * unregister all the unit directories. */
nodemgr_remove_node_uds(ne); nodemgr_remove_uds(ne);
nodemgr_update_bus_options(ne); nodemgr_update_bus_options(ne);
...@@ -1764,9 +1726,8 @@ static struct hpsb_highlevel nodemgr_highlevel = { ...@@ -1764,9 +1726,8 @@ static struct hpsb_highlevel nodemgr_highlevel = {
void init_ieee1394_nodemgr(void) void init_ieee1394_nodemgr(void)
{ {
driver_register(&nodemgr_driver_host);
driver_register(&nodemgr_driver_ne);
class_register(&nodemgr_ne_class); class_register(&nodemgr_ne_class);
class_register(&nodemgr_ud_class);
hpsb_register_highlevel(&nodemgr_highlevel); hpsb_register_highlevel(&nodemgr_highlevel);
} }
...@@ -1775,7 +1736,6 @@ void cleanup_ieee1394_nodemgr(void) ...@@ -1775,7 +1736,6 @@ void cleanup_ieee1394_nodemgr(void)
{ {
hpsb_unregister_highlevel(&nodemgr_highlevel); hpsb_unregister_highlevel(&nodemgr_highlevel);
class_unregister(&nodemgr_ud_class);
class_unregister(&nodemgr_ne_class); class_unregister(&nodemgr_ne_class);
driver_unregister(&nodemgr_driver_ne);
driver_unregister(&nodemgr_driver_host);
} }
...@@ -79,6 +79,8 @@ struct unit_directory { ...@@ -79,6 +79,8 @@ struct unit_directory {
struct device device; struct device device;
struct class_device class_dev;
struct csr1212_keyval *ud_kv; struct csr1212_keyval *ud_kv;
}; };
......
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