diff options
author | Arnd Bergmann <arnd@arndb.de> | 2011-07-28 15:25:46 +0000 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2011-07-28 15:25:46 +0000 |
commit | 6124a4e430b64d1577438c8648c59e996d02e73e (patch) | |
tree | 49cfafad785d1c9e403a5b0d755298b9af2c260f /drivers/staging/usbip/stub_main.c | |
parent | 8e267f3da5f117d2f1316cf6ddf740f93f1c73aa (diff) | |
parent | 580975d7f48d7d047e22bb0f42adf7557801d8d4 (diff) |
Merge branch 'imx/dt' into next/dt
Diffstat (limited to 'drivers/staging/usbip/stub_main.c')
-rw-r--r-- | drivers/staging/usbip/stub_main.c | 193 |
1 files changed, 87 insertions, 106 deletions
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c index e9085d66394..a34249a9cb6 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/staging/usbip/stub_main.c @@ -25,9 +25,7 @@ #define DRIVER_AUTHOR "Takahiro Hirofuchi" #define DRIVER_DESC "USB/IP Host Driver" -/* stub_priv is allocated from stub_priv_cache */ struct kmem_cache *stub_priv_cache; - /* * busid_tables defines matching busids that usbip can grab. A user can change * dynamically what device is locally used and what device is exported to a @@ -37,70 +35,60 @@ struct kmem_cache *stub_priv_cache; static struct bus_id_priv busid_table[MAX_BUSID]; static spinlock_t busid_table_lock; -int match_busid(const char *busid) +static void init_busid_table(void) { int i; - spin_lock(&busid_table_lock); - + memset(busid_table, 0, sizeof(busid_table)); for (i = 0; i < MAX_BUSID; i++) - if (busid_table[i].name[0]) - if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { - /* already registerd */ - spin_unlock(&busid_table_lock); - return 0; - } - - spin_unlock(&busid_table_lock); + busid_table[i].status = STUB_BUSID_OTHER; - return 1; + spin_lock_init(&busid_table_lock); } -struct bus_id_priv *get_busid_priv(const char *busid) +/* + * Find the index of the busid by name. + * Must be called with busid_table_lock held. + */ +static int get_busid_idx(const char *busid) { int i; - - spin_lock(&busid_table_lock); + int idx = -1; for (i = 0; i < MAX_BUSID; i++) if (busid_table[i].name[0]) if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { - /* already registerd */ - spin_unlock(&busid_table_lock); - return &(busid_table[i]); + idx = i; + break; } - - spin_unlock(&busid_table_lock); - - return NULL; + return idx; } -static ssize_t show_match_busid(struct device_driver *drv, char *buf) +struct bus_id_priv *get_busid_priv(const char *busid) { - int i; - char *out = buf; + int idx; + struct bus_id_priv *bid = NULL; spin_lock(&busid_table_lock); - - for (i = 0; i < MAX_BUSID; i++) - if (busid_table[i].name[0]) - out += sprintf(out, "%s ", busid_table[i].name); - + idx = get_busid_idx(busid); + if (idx >= 0) + bid = &(busid_table[idx]); spin_unlock(&busid_table_lock); - out += sprintf(out, "\n"); - - return out - buf; + return bid; } static int add_match_busid(char *busid) { int i; - - if (!match_busid(busid)) - return 0; + int ret = -1; spin_lock(&busid_table_lock); + /* already registered? */ + if (get_busid_idx(busid) >= 0) { + ret = 0; + goto out; + } for (i = 0; i < MAX_BUSID; i++) if (!busid_table[i].name[0]) { @@ -108,52 +96,55 @@ static int add_match_busid(char *busid) if ((busid_table[i].status != STUB_BUSID_ALLOC) && (busid_table[i].status != STUB_BUSID_REMOV)) busid_table[i].status = STUB_BUSID_ADDED; - spin_unlock(&busid_table_lock); - return 0; + ret = 0; + break; } +out: spin_unlock(&busid_table_lock); - return -1; + return ret; } int del_match_busid(char *busid) { - int i; + int idx; + int ret = -1; spin_lock(&busid_table_lock); + idx = get_busid_idx(busid); + if (idx < 0) + goto out; - for (i = 0; i < MAX_BUSID; i++) - if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { - /* found */ - if (busid_table[i].status == STUB_BUSID_OTHER) - memset(busid_table[i].name, 0, BUSID_SIZE); - if ((busid_table[i].status != STUB_BUSID_OTHER) && - (busid_table[i].status != STUB_BUSID_ADDED)) { - busid_table[i].status = STUB_BUSID_REMOV; - } - spin_unlock(&busid_table_lock); - return 0; - } + /* found */ + ret = 0; + + if (busid_table[idx].status == STUB_BUSID_OTHER) + memset(busid_table[idx].name, 0, BUSID_SIZE); + + if ((busid_table[idx].status != STUB_BUSID_OTHER) && + (busid_table[idx].status != STUB_BUSID_ADDED)) + busid_table[idx].status = STUB_BUSID_REMOV; +out: spin_unlock(&busid_table_lock); - return -1; + return ret; } -static void init_busid_table(void) +static ssize_t show_match_busid(struct device_driver *drv, char *buf) { int i; + char *out = buf; - for (i = 0; i < MAX_BUSID; i++) { - memset(busid_table[i].name, 0, BUSID_SIZE); - busid_table[i].status = STUB_BUSID_OTHER; - busid_table[i].interf_count = 0; - busid_table[i].sdev = NULL; - busid_table[i].shutdown_busid = 0; - } + spin_lock(&busid_table_lock); + for (i = 0; i < MAX_BUSID; i++) + if (busid_table[i].name[0]) + out += sprintf(out, "%s ", busid_table[i].name); + spin_unlock(&busid_table_lock); + out += sprintf(out, "\n"); - spin_lock_init(&busid_table_lock); + return out - buf; } static ssize_t store_match_busid(struct device_driver *dev, const char *buf, @@ -175,23 +166,24 @@ static ssize_t store_match_busid(struct device_driver *dev, const char *buf, strncpy(busid, buf + 4, BUSID_SIZE); if (!strncmp(buf, "add ", 4)) { - if (add_match_busid(busid) < 0) + if (add_match_busid(busid) < 0) { return -ENOMEM; - else { + } else { pr_debug("add busid %s\n", busid); return count; } } else if (!strncmp(buf, "del ", 4)) { - if (del_match_busid(busid) < 0) + if (del_match_busid(busid) < 0) { return -ENODEV; - else { + } else { pr_debug("del busid %s\n", busid); return count; } - } else + } else { return -EINVAL; + } } -static DRIVER_ATTR(match_busid, S_IRUSR|S_IWUSR, show_match_busid, +static DRIVER_ATTR(match_busid, S_IRUSR | S_IWUSR, show_match_busid, store_match_busid); static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead) @@ -214,36 +206,30 @@ static struct stub_priv *stub_priv_pop(struct stub_device *sdev) spin_lock_irqsave(&sdev->priv_lock, flags); priv = stub_priv_pop_from_listhead(&sdev->priv_init); - if (priv) { - spin_unlock_irqrestore(&sdev->priv_lock, flags); - return priv; - } + if (priv) + goto done; priv = stub_priv_pop_from_listhead(&sdev->priv_tx); - if (priv) { - spin_unlock_irqrestore(&sdev->priv_lock, flags); - return priv; - } + if (priv) + goto done; priv = stub_priv_pop_from_listhead(&sdev->priv_free); - if (priv) { - spin_unlock_irqrestore(&sdev->priv_lock, flags); - return priv; - } +done: spin_unlock_irqrestore(&sdev->priv_lock, flags); - return NULL; + + return priv; } void stub_device_cleanup_urbs(struct stub_device *sdev) { struct stub_priv *priv; + struct urb *urb; dev_dbg(&sdev->udev->dev, "free sdev %p\n", sdev); while ((priv = stub_priv_pop(sdev))) { - struct urb *urb = priv->urb; - + urb = priv->urb; dev_dbg(&sdev->udev->dev, "free urb %p\n", urb); usb_kill_urb(urb); @@ -251,51 +237,46 @@ void stub_device_cleanup_urbs(struct stub_device *sdev) kfree(urb->transfer_buffer); kfree(urb->setup_packet); - usb_free_urb(urb); } } -static int __init usb_stub_init(void) +static int __init usbip_host_init(void) { int ret; - stub_priv_cache = kmem_cache_create("stub_priv", - sizeof(struct stub_priv), 0, - SLAB_HWCACHE_ALIGN, NULL); + stub_priv_cache = KMEM_CACHE(stub_priv, SLAB_HWCACHE_ALIGN); if (!stub_priv_cache) { - pr_err("create stub_priv_cache error\n"); + pr_err("kmem_cache_create failed\n"); return -ENOMEM; } ret = usb_register(&stub_driver); - if (ret) { + if (ret < 0) { pr_err("usb_register failed %d\n", ret); - goto error_usb_register; + goto err_usb_register; } - pr_info(DRIVER_DESC " " USBIP_VERSION "\n"); - - init_busid_table(); - ret = driver_create_file(&stub_driver.drvwrap.driver, &driver_attr_match_busid); - - if (ret) { - pr_err("create driver sysfs\n"); - goto error_create_file; + if (ret < 0) { + pr_err("driver_create_file failed\n"); + goto err_create_file; } + init_busid_table(); + pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return ret; -error_create_file: + +err_create_file: usb_deregister(&stub_driver); -error_usb_register: +err_usb_register: kmem_cache_destroy(stub_priv_cache); return ret; } -static void __exit usb_stub_exit(void) +static void __exit usbip_host_exit(void) { driver_remove_file(&stub_driver.drvwrap.driver, &driver_attr_match_busid); @@ -309,8 +290,8 @@ static void __exit usb_stub_exit(void) kmem_cache_destroy(stub_priv_cache); } -module_init(usb_stub_init); -module_exit(usb_stub_exit); +module_init(usbip_host_init); +module_exit(usbip_host_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); |