0001
0002
0003
0004
0005
0006 #include <linux/string.h>
0007 #include <linux/module.h>
0008 #include <linux/device.h>
0009 #include <linux/scatterlist.h>
0010
0011 #include "usbip_common.h"
0012 #include "stub.h"
0013
0014 #define DRIVER_AUTHOR "Takahiro Hirofuchi"
0015 #define DRIVER_DESC "USB/IP Host Driver"
0016
0017 struct kmem_cache *stub_priv_cache;
0018
0019
0020
0021
0022
0023
0024 #define MAX_BUSID 16
0025 static struct bus_id_priv busid_table[MAX_BUSID];
0026 static DEFINE_SPINLOCK(busid_table_lock);
0027
0028 static void init_busid_table(void)
0029 {
0030 int i;
0031
0032
0033
0034
0035
0036 memset(busid_table, 0, sizeof(busid_table));
0037
0038 for (i = 0; i < MAX_BUSID; i++)
0039 spin_lock_init(&busid_table[i].busid_lock);
0040 }
0041
0042
0043
0044
0045
0046 static int get_busid_idx(const char *busid)
0047 {
0048 int i;
0049 int idx = -1;
0050
0051 for (i = 0; i < MAX_BUSID; i++) {
0052 spin_lock(&busid_table[i].busid_lock);
0053 if (busid_table[i].name[0])
0054 if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) {
0055 idx = i;
0056 spin_unlock(&busid_table[i].busid_lock);
0057 break;
0058 }
0059 spin_unlock(&busid_table[i].busid_lock);
0060 }
0061 return idx;
0062 }
0063
0064
0065 struct bus_id_priv *get_busid_priv(const char *busid)
0066 {
0067 int idx;
0068 struct bus_id_priv *bid = NULL;
0069
0070 spin_lock(&busid_table_lock);
0071 idx = get_busid_idx(busid);
0072 if (idx >= 0) {
0073 bid = &(busid_table[idx]);
0074
0075 spin_lock(&bid->busid_lock);
0076 }
0077 spin_unlock(&busid_table_lock);
0078
0079 return bid;
0080 }
0081
0082 void put_busid_priv(struct bus_id_priv *bid)
0083 {
0084 if (bid)
0085 spin_unlock(&bid->busid_lock);
0086 }
0087
0088 static int add_match_busid(char *busid)
0089 {
0090 int i;
0091 int ret = -1;
0092
0093 spin_lock(&busid_table_lock);
0094
0095 if (get_busid_idx(busid) >= 0) {
0096 ret = 0;
0097 goto out;
0098 }
0099
0100 for (i = 0; i < MAX_BUSID; i++) {
0101 spin_lock(&busid_table[i].busid_lock);
0102 if (!busid_table[i].name[0]) {
0103 strlcpy(busid_table[i].name, busid, BUSID_SIZE);
0104 if ((busid_table[i].status != STUB_BUSID_ALLOC) &&
0105 (busid_table[i].status != STUB_BUSID_REMOV))
0106 busid_table[i].status = STUB_BUSID_ADDED;
0107 ret = 0;
0108 spin_unlock(&busid_table[i].busid_lock);
0109 break;
0110 }
0111 spin_unlock(&busid_table[i].busid_lock);
0112 }
0113
0114 out:
0115 spin_unlock(&busid_table_lock);
0116
0117 return ret;
0118 }
0119
0120 int del_match_busid(char *busid)
0121 {
0122 int idx;
0123 int ret = -1;
0124
0125 spin_lock(&busid_table_lock);
0126 idx = get_busid_idx(busid);
0127 if (idx < 0)
0128 goto out;
0129
0130
0131 ret = 0;
0132
0133 spin_lock(&busid_table[idx].busid_lock);
0134
0135 if (busid_table[idx].status == STUB_BUSID_OTHER)
0136 memset(busid_table[idx].name, 0, BUSID_SIZE);
0137
0138 if ((busid_table[idx].status != STUB_BUSID_OTHER) &&
0139 (busid_table[idx].status != STUB_BUSID_ADDED))
0140 busid_table[idx].status = STUB_BUSID_REMOV;
0141
0142 spin_unlock(&busid_table[idx].busid_lock);
0143 out:
0144 spin_unlock(&busid_table_lock);
0145
0146 return ret;
0147 }
0148
0149 static ssize_t match_busid_show(struct device_driver *drv, char *buf)
0150 {
0151 int i;
0152 char *out = buf;
0153
0154 spin_lock(&busid_table_lock);
0155 for (i = 0; i < MAX_BUSID; i++) {
0156 spin_lock(&busid_table[i].busid_lock);
0157 if (busid_table[i].name[0])
0158 out += sprintf(out, "%s ", busid_table[i].name);
0159 spin_unlock(&busid_table[i].busid_lock);
0160 }
0161 spin_unlock(&busid_table_lock);
0162 out += sprintf(out, "\n");
0163
0164 return out - buf;
0165 }
0166
0167 static ssize_t match_busid_store(struct device_driver *dev, const char *buf,
0168 size_t count)
0169 {
0170 int len;
0171 char busid[BUSID_SIZE];
0172
0173 if (count < 5)
0174 return -EINVAL;
0175
0176
0177 len = strlcpy(busid, buf + 4, BUSID_SIZE);
0178 if (sizeof(busid) <= len)
0179 return -EINVAL;
0180
0181 if (!strncmp(buf, "add ", 4)) {
0182 if (add_match_busid(busid) < 0)
0183 return -ENOMEM;
0184
0185 pr_debug("add busid %s\n", busid);
0186 return count;
0187 }
0188
0189 if (!strncmp(buf, "del ", 4)) {
0190 if (del_match_busid(busid) < 0)
0191 return -ENODEV;
0192
0193 pr_debug("del busid %s\n", busid);
0194 return count;
0195 }
0196
0197 return -EINVAL;
0198 }
0199 static DRIVER_ATTR_RW(match_busid);
0200
0201 static int do_rebind(char *busid, struct bus_id_priv *busid_priv)
0202 {
0203 int ret = 0;
0204
0205
0206 if (busid_priv->udev->dev.parent)
0207 device_lock(busid_priv->udev->dev.parent);
0208 ret = device_attach(&busid_priv->udev->dev);
0209 if (busid_priv->udev->dev.parent)
0210 device_unlock(busid_priv->udev->dev.parent);
0211 if (ret < 0)
0212 dev_err(&busid_priv->udev->dev, "rebind failed\n");
0213 return ret;
0214 }
0215
0216 static void stub_device_rebind(void)
0217 {
0218 #if IS_MODULE(CONFIG_USBIP_HOST)
0219 struct bus_id_priv *busid_priv;
0220 int i;
0221
0222
0223 spin_lock(&busid_table_lock);
0224 for (i = 0; i < MAX_BUSID; i++) {
0225 if (busid_table[i].name[0] &&
0226 busid_table[i].shutdown_busid) {
0227 busid_priv = &(busid_table[i]);
0228 busid_priv->status = STUB_BUSID_OTHER;
0229 }
0230 }
0231 spin_unlock(&busid_table_lock);
0232
0233
0234 for (i = 0; i < MAX_BUSID; i++) {
0235 if (busid_table[i].name[0] &&
0236 busid_table[i].shutdown_busid) {
0237 busid_priv = &(busid_table[i]);
0238 do_rebind(busid_table[i].name, busid_priv);
0239 }
0240 }
0241 #endif
0242 }
0243
0244 static ssize_t rebind_store(struct device_driver *dev, const char *buf,
0245 size_t count)
0246 {
0247 int ret;
0248 int len;
0249 struct bus_id_priv *bid;
0250
0251
0252 len = strnlen(buf, BUSID_SIZE);
0253
0254 if (!(len < BUSID_SIZE))
0255 return -EINVAL;
0256
0257 bid = get_busid_priv(buf);
0258 if (!bid)
0259 return -ENODEV;
0260
0261
0262 bid->status = STUB_BUSID_OTHER;
0263
0264 put_busid_priv(bid);
0265
0266 ret = do_rebind((char *) buf, bid);
0267 if (ret < 0)
0268 return ret;
0269
0270
0271 del_match_busid((char *) buf);
0272
0273 return count;
0274 }
0275
0276 static DRIVER_ATTR_WO(rebind);
0277
0278 static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead)
0279 {
0280 struct stub_priv *priv, *tmp;
0281
0282 list_for_each_entry_safe(priv, tmp, listhead, list) {
0283 list_del_init(&priv->list);
0284 return priv;
0285 }
0286
0287 return NULL;
0288 }
0289
0290 void stub_free_priv_and_urb(struct stub_priv *priv)
0291 {
0292 struct urb *urb;
0293 int i;
0294
0295 for (i = 0; i < priv->num_urbs; i++) {
0296 urb = priv->urbs[i];
0297
0298 if (!urb)
0299 return;
0300
0301 kfree(urb->setup_packet);
0302 urb->setup_packet = NULL;
0303
0304
0305 if (urb->transfer_buffer && !priv->sgl) {
0306 kfree(urb->transfer_buffer);
0307 urb->transfer_buffer = NULL;
0308 }
0309
0310 if (urb->num_sgs) {
0311 sgl_free(urb->sg);
0312 urb->sg = NULL;
0313 urb->num_sgs = 0;
0314 }
0315
0316 usb_free_urb(urb);
0317 }
0318 if (!list_empty(&priv->list))
0319 list_del(&priv->list);
0320 if (priv->sgl)
0321 sgl_free(priv->sgl);
0322 kfree(priv->urbs);
0323 kmem_cache_free(stub_priv_cache, priv);
0324 }
0325
0326 static struct stub_priv *stub_priv_pop(struct stub_device *sdev)
0327 {
0328 unsigned long flags;
0329 struct stub_priv *priv;
0330
0331 spin_lock_irqsave(&sdev->priv_lock, flags);
0332
0333 priv = stub_priv_pop_from_listhead(&sdev->priv_init);
0334 if (priv)
0335 goto done;
0336
0337 priv = stub_priv_pop_from_listhead(&sdev->priv_tx);
0338 if (priv)
0339 goto done;
0340
0341 priv = stub_priv_pop_from_listhead(&sdev->priv_free);
0342
0343 done:
0344 spin_unlock_irqrestore(&sdev->priv_lock, flags);
0345
0346 return priv;
0347 }
0348
0349 void stub_device_cleanup_urbs(struct stub_device *sdev)
0350 {
0351 struct stub_priv *priv;
0352 int i;
0353
0354 dev_dbg(&sdev->udev->dev, "Stub device cleaning up urbs\n");
0355
0356 while ((priv = stub_priv_pop(sdev))) {
0357 for (i = 0; i < priv->num_urbs; i++)
0358 usb_kill_urb(priv->urbs[i]);
0359
0360 stub_free_priv_and_urb(priv);
0361 }
0362 }
0363
0364 static int __init usbip_host_init(void)
0365 {
0366 int ret;
0367
0368 init_busid_table();
0369
0370 stub_priv_cache = KMEM_CACHE(stub_priv, SLAB_HWCACHE_ALIGN);
0371 if (!stub_priv_cache) {
0372 pr_err("kmem_cache_create failed\n");
0373 return -ENOMEM;
0374 }
0375
0376 ret = usb_register_device_driver(&stub_driver, THIS_MODULE);
0377 if (ret) {
0378 pr_err("usb_register failed %d\n", ret);
0379 goto err_usb_register;
0380 }
0381
0382 ret = driver_create_file(&stub_driver.drvwrap.driver,
0383 &driver_attr_match_busid);
0384 if (ret) {
0385 pr_err("driver_create_file failed\n");
0386 goto err_create_file;
0387 }
0388
0389 ret = driver_create_file(&stub_driver.drvwrap.driver,
0390 &driver_attr_rebind);
0391 if (ret) {
0392 pr_err("driver_create_file failed\n");
0393 goto err_create_file;
0394 }
0395
0396 return ret;
0397
0398 err_create_file:
0399 usb_deregister_device_driver(&stub_driver);
0400 err_usb_register:
0401 kmem_cache_destroy(stub_priv_cache);
0402 return ret;
0403 }
0404
0405 static void __exit usbip_host_exit(void)
0406 {
0407 driver_remove_file(&stub_driver.drvwrap.driver,
0408 &driver_attr_match_busid);
0409
0410 driver_remove_file(&stub_driver.drvwrap.driver,
0411 &driver_attr_rebind);
0412
0413
0414
0415
0416
0417 usb_deregister_device_driver(&stub_driver);
0418
0419
0420 stub_device_rebind();
0421
0422 kmem_cache_destroy(stub_priv_cache);
0423 }
0424
0425 module_init(usbip_host_init);
0426 module_exit(usbip_host_exit);
0427
0428 MODULE_AUTHOR(DRIVER_AUTHOR);
0429 MODULE_DESCRIPTION(DRIVER_DESC);
0430 MODULE_LICENSE("GPL");