2 * Copyright (C) 2003-2008 Takahiro Hirofuchi
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 #include <linux/string.h>
21 #include <linux/module.h>
22 #include <linux/device.h>
24 #include "usbip_common.h"
27 #define DRIVER_AUTHOR "Takahiro Hirofuchi"
28 #define DRIVER_DESC "USB/IP Host Driver"
30 struct kmem_cache
*stub_priv_cache
;
32 * busid_tables defines matching busids that usbip can grab. A user can change
33 * dynamically what device is locally used and what device is exported to a
37 static struct bus_id_priv busid_table
[MAX_BUSID
];
38 static spinlock_t busid_table_lock
;
40 static void init_busid_table(void)
43 * This also sets the bus_table[i].status to
44 * STUB_BUSID_OTHER, which is 0.
46 memset(busid_table
, 0, sizeof(busid_table
));
48 spin_lock_init(&busid_table_lock
);
52 * Find the index of the busid by name.
53 * Must be called with busid_table_lock held.
55 static int get_busid_idx(const char *busid
)
60 for (i
= 0; i
< MAX_BUSID
; i
++)
61 if (busid_table
[i
].name
[0])
62 if (!strncmp(busid_table
[i
].name
, busid
, BUSID_SIZE
)) {
69 struct bus_id_priv
*get_busid_priv(const char *busid
)
72 struct bus_id_priv
*bid
= NULL
;
74 spin_lock(&busid_table_lock
);
75 idx
= get_busid_idx(busid
);
77 bid
= &(busid_table
[idx
]);
78 spin_unlock(&busid_table_lock
);
83 static int add_match_busid(char *busid
)
88 spin_lock(&busid_table_lock
);
89 /* already registered? */
90 if (get_busid_idx(busid
) >= 0) {
95 for (i
= 0; i
< MAX_BUSID
; i
++)
96 if (!busid_table
[i
].name
[0]) {
97 strlcpy(busid_table
[i
].name
, busid
, BUSID_SIZE
);
98 if ((busid_table
[i
].status
!= STUB_BUSID_ALLOC
) &&
99 (busid_table
[i
].status
!= STUB_BUSID_REMOV
))
100 busid_table
[i
].status
= STUB_BUSID_ADDED
;
106 spin_unlock(&busid_table_lock
);
111 int del_match_busid(char *busid
)
116 spin_lock(&busid_table_lock
);
117 idx
= get_busid_idx(busid
);
124 if (busid_table
[idx
].status
== STUB_BUSID_OTHER
)
125 memset(busid_table
[idx
].name
, 0, BUSID_SIZE
);
127 if ((busid_table
[idx
].status
!= STUB_BUSID_OTHER
) &&
128 (busid_table
[idx
].status
!= STUB_BUSID_ADDED
))
129 busid_table
[idx
].status
= STUB_BUSID_REMOV
;
132 spin_unlock(&busid_table_lock
);
137 static ssize_t
show_match_busid(struct device_driver
*drv
, char *buf
)
142 spin_lock(&busid_table_lock
);
143 for (i
= 0; i
< MAX_BUSID
; i
++)
144 if (busid_table
[i
].name
[0])
145 out
+= sprintf(out
, "%s ", busid_table
[i
].name
);
146 spin_unlock(&busid_table_lock
);
147 out
+= sprintf(out
, "\n");
152 static ssize_t
store_match_busid(struct device_driver
*dev
, const char *buf
,
156 char busid
[BUSID_SIZE
];
161 /* busid needs to include \0 termination */
162 len
= strlcpy(busid
, buf
+ 4, BUSID_SIZE
);
163 if (sizeof(busid
) <= len
)
166 if (!strncmp(buf
, "add ", 4)) {
167 if (add_match_busid(busid
) < 0)
170 pr_debug("add busid %s\n", busid
);
174 if (!strncmp(buf
, "del ", 4)) {
175 if (del_match_busid(busid
) < 0)
178 pr_debug("del busid %s\n", busid
);
184 static DRIVER_ATTR(match_busid
, S_IRUSR
| S_IWUSR
, show_match_busid
,
187 static ssize_t
rebind_store(struct device_driver
*dev
, const char *buf
,
192 struct bus_id_priv
*bid
;
194 /* buf length should be less that BUSID_SIZE */
195 len
= strnlen(buf
, BUSID_SIZE
);
197 if (!(len
< BUSID_SIZE
))
200 bid
= get_busid_priv(buf
);
204 ret
= device_attach(&bid
->udev
->dev
);
206 dev_err(&bid
->udev
->dev
, "rebind failed\n");
213 static DRIVER_ATTR_WO(rebind
);
215 static struct stub_priv
*stub_priv_pop_from_listhead(struct list_head
*listhead
)
217 struct stub_priv
*priv
, *tmp
;
219 list_for_each_entry_safe(priv
, tmp
, listhead
, list
) {
220 list_del(&priv
->list
);
227 static struct stub_priv
*stub_priv_pop(struct stub_device
*sdev
)
230 struct stub_priv
*priv
;
232 spin_lock_irqsave(&sdev
->priv_lock
, flags
);
234 priv
= stub_priv_pop_from_listhead(&sdev
->priv_init
);
238 priv
= stub_priv_pop_from_listhead(&sdev
->priv_tx
);
242 priv
= stub_priv_pop_from_listhead(&sdev
->priv_free
);
245 spin_unlock_irqrestore(&sdev
->priv_lock
, flags
);
250 void stub_device_cleanup_urbs(struct stub_device
*sdev
)
252 struct stub_priv
*priv
;
255 dev_dbg(&sdev
->udev
->dev
, "free sdev %p\n", sdev
);
257 while ((priv
= stub_priv_pop(sdev
))) {
259 dev_dbg(&sdev
->udev
->dev
, "free urb %p\n", urb
);
262 kmem_cache_free(stub_priv_cache
, priv
);
264 kfree(urb
->transfer_buffer
);
265 kfree(urb
->setup_packet
);
270 static int __init
usbip_host_init(void)
276 stub_priv_cache
= KMEM_CACHE(stub_priv
, SLAB_HWCACHE_ALIGN
);
277 if (!stub_priv_cache
) {
278 pr_err("kmem_cache_create failed\n");
282 ret
= usb_register_device_driver(&stub_driver
, THIS_MODULE
);
284 pr_err("usb_register failed %d\n", ret
);
285 goto err_usb_register
;
288 ret
= driver_create_file(&stub_driver
.drvwrap
.driver
,
289 &driver_attr_match_busid
);
291 pr_err("driver_create_file failed\n");
292 goto err_create_file
;
295 ret
= driver_create_file(&stub_driver
.drvwrap
.driver
,
296 &driver_attr_rebind
);
298 pr_err("driver_create_file failed\n");
299 goto err_create_file
;
302 pr_info(DRIVER_DESC
" v" USBIP_VERSION
"\n");
306 usb_deregister_device_driver(&stub_driver
);
308 kmem_cache_destroy(stub_priv_cache
);
312 static void __exit
usbip_host_exit(void)
314 driver_remove_file(&stub_driver
.drvwrap
.driver
,
315 &driver_attr_match_busid
);
317 driver_remove_file(&stub_driver
.drvwrap
.driver
,
318 &driver_attr_rebind
);
321 * deregister() calls stub_disconnect() for all devices. Device
322 * specific data is cleared in stub_disconnect().
324 usb_deregister_device_driver(&stub_driver
);
326 kmem_cache_destroy(stub_priv_cache
);
329 module_init(usbip_host_init
);
330 module_exit(usbip_host_exit
);
332 MODULE_AUTHOR(DRIVER_AUTHOR
);
333 MODULE_DESCRIPTION(DRIVER_DESC
);
334 MODULE_LICENSE("GPL");
335 MODULE_VERSION(USBIP_VERSION
);