From 748e1230cb921369738104415ed9352e81ccc413 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Fri, 3 Oct 2014 14:14:22 -0500 Subject: [PATCH] greybus: fix some hasty bugs Fix some omissions found in the code. - initialize and use the host device connections list - rename the interface connections list (was "functions") - use the interface connections list - define a spinlock protecting the connections lists - declare gb_operation_submit() in "operation.h" And the cport id map lock is per-host device, it's shared across all host devices. There's no need for one in struct greybus_host_device. Signed-off-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/connection.c | 12 ++++++++++++ drivers/staging/greybus/core.c | 5 +++-- drivers/staging/greybus/greybus.h | 1 - drivers/staging/greybus/interface.c | 2 +- drivers/staging/greybus/interface.h | 2 +- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index d63048c4f7de..806eb8cd73e0 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -11,6 +11,8 @@ #include "kernel_ver.h" #include "greybus.h" +static DEFINE_SPINLOCK(gb_connections_lock); + /* * Set up a Greybus connection, representing the bidirectional link * between a CPort on a (local) Greybus host device and a CPort on @@ -43,6 +45,11 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface, connection->interface_cport_id = cport_id; connection->protocol = protocol; + spin_lock_irq(&gb_connections_lock); + list_add_tail(&connection->hd_links, &hd->connections); + list_add_tail(&connection->interface_links, &interface->connections); + spin_unlock_irq(&gb_connections_lock); + INIT_LIST_HEAD(&connection->operations); atomic_set(&connection->op_cycle, 0); @@ -60,6 +67,11 @@ void gb_connection_destroy(struct gb_connection *connection) /* XXX Need to wait for any outstanding requests to complete */ WARN_ON(!list_empty(&connection->operations)); + spin_lock_irq(&gb_connections_lock); + list_del(&connection->hd_links); + list_del(&connection->interface_links); + spin_unlock_irq(&gb_connections_lock); + greybus_hd_cport_id_free(connection->hd, connection->hd_cport_id); /* kref_put(connection->interface); */ /* kref_put(connection->hd); */ diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c index 8811f35f9eaa..16100e720105 100644 --- a/drivers/staging/greybus/core.c +++ b/drivers/staging/greybus/core.c @@ -298,9 +298,9 @@ u16 greybus_hd_cport_id_alloc(struct greybus_host_device *hd) return CPORT_ID_BAD; spin_lock_irq(&cport_id_map_lock); - cport_id = find_next_zero_bit(hd->cport_id_map, hd->cport_id_count, + cport_id = find_next_zero_bit(hd->cport_id_map, HOST_DEV_CPORT_ID_MAX, hd->cport_id_next_free); - if (cport_id < hd->cport_id_count) { + if (cport_id < HOST_DEV_CPORT_ID_MAX) { hd->cport_id_next_free = cport_id + 1; /* Success */ hd->cport_id_count++; } else { @@ -367,6 +367,7 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver hd->parent = parent; hd->driver = driver; INIT_LIST_HEAD(&hd->modules); + INIT_LIST_HEAD(&hd->connections); /* Pre-allocate CPort 0 for control stuff. XXX */ if (greybus_hd_cport_id_alloc(hd) != 0) { diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h index 0813201260b1..460ace535322 100644 --- a/drivers/staging/greybus/greybus.h +++ b/drivers/staging/greybus/greybus.h @@ -194,7 +194,6 @@ struct greybus_host_device { struct list_head modules; struct list_head connections; - spinlock_t cport_id_map_lock; DECLARE_BITMAP(cport_id_map, HOST_DEV_CPORT_ID_MAX); u16 cport_id_count; /* How many have been allocated */ u16 cport_id_next_free; /* Where to start checking anyway */ diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c index a2c2f05f1fd9..b9dd93093cc6 100644 --- a/drivers/staging/greybus/interface.c +++ b/drivers/staging/greybus/interface.c @@ -33,7 +33,7 @@ gb_interface_create(struct gb_module *gmod, u8 interface_id) interface->gmod = gmod; /* XXX refcount? */ interface->id = interface_id; - INIT_LIST_HEAD(&interface->functions); + INIT_LIST_HEAD(&interface->connections); spin_lock_irq(&gb_interfaces_lock); list_add_tail(&interface->links, &gmod->interfaces); diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h index 7a4b3704b6a0..9c9ffe7715a5 100644 --- a/drivers/staging/greybus/interface.h +++ b/drivers/staging/greybus/interface.h @@ -14,7 +14,7 @@ struct gb_interface { struct gb_module *gmod; u8 id; - struct list_head functions; + struct list_head connections; struct list_head links; /* module->interfaces */ };