blob: 7dcc2070ee96a5a60539650626ae21f35f69c589 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * Gadget Driver for Android ADB
3 *
4 * Copyright (C) 2008 Google, Inc.
5 * Author: Mike Lockwood <lockwood@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/poll.h>
21#include <linux/delay.h>
22#include <linux/wait.h>
23#include <linux/err.h>
24#include <linux/interrupt.h>
25#include <linux/sched.h>
26#include <linux/types.h>
27#include <linux/device.h>
28#include <linux/miscdevice.h>
29#include <linux/proc_fs.h>
30#include <linux/seq_file.h>
31
32#define ADB_BULK_BUFFER_SIZE 4096
33
34/* number of tx requests to allocate */
35#define TX_REQ_MAX 4
36
37#define ADB_ADD_STATISTICS_INTERFACE
38
39static const char adb_shortname[] = "android_adb";
40
41#if defined(CONFIG_CPU_ASR18XX) && defined(CONFIG_USB_MVC2)
42static int adb_inited;
43#endif
44
45#if defined(CONFIG_FIXED_USB_IFACE)
46int nr_adb_dummy_interface = 0;
47#define ADB_INTERFACE_NUMBER 6
48#endif
49
50struct adb_dev {
51 struct usb_function function;
52 struct usb_composite_dev *cdev;
53 spinlock_t lock;
54
55 struct usb_ep *ep_in;
56 struct usb_ep *ep_out;
57
58 int online;
59 int error;
60
61 atomic_t read_excl;
62 atomic_t write_excl;
63 atomic_t open_excl;
64
65 struct list_head tx_idle;
66
67 wait_queue_head_t read_wq;
68 wait_queue_head_t write_wq;
69 struct usb_request *rx_req;
70 int rx_done;
71#if defined(ADB_ADD_STATISTICS_INTERFACE) && defined(CONFIG_PROC_FS)
72 u32 adb_nr_rx;
73 u32 adb_nr_rx_bytes;
74 u32 adb_nr_tx;
75 u32 adb_nr_tx_bytes;
76 struct proc_dir_entry *pde;
77#endif
78};
79
80static struct usb_interface_descriptor adb_interface_desc = {
81 .bLength = USB_DT_INTERFACE_SIZE,
82 .bDescriptorType = USB_DT_INTERFACE,
83 .bInterfaceNumber = 0,
84 .bNumEndpoints = 2,
85 .bInterfaceClass = 0xFF,
86 .bInterfaceSubClass = 0x42,
87 .bInterfaceProtocol = 1,
88};
89
90static struct usb_endpoint_descriptor adb_superspeed_in_desc = {
91 .bLength = USB_DT_ENDPOINT_SIZE,
92 .bDescriptorType = USB_DT_ENDPOINT,
93 .bEndpointAddress = USB_DIR_IN,
94 .bmAttributes = USB_ENDPOINT_XFER_BULK,
95 .wMaxPacketSize = __constant_cpu_to_le16(1024),
96};
97
98static struct usb_endpoint_descriptor adb_superspeed_out_desc = {
99 .bLength = USB_DT_ENDPOINT_SIZE,
100 .bDescriptorType = USB_DT_ENDPOINT,
101 .bEndpointAddress = USB_DIR_OUT,
102 .bmAttributes = USB_ENDPOINT_XFER_BULK,
103 .wMaxPacketSize = __constant_cpu_to_le16(1024),
104};
105
106static struct usb_ss_ep_comp_descriptor adb_ss_bulk_comp_desc = {
107 .bLength = sizeof adb_ss_bulk_comp_desc,
108 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
109};
110
111static struct usb_endpoint_descriptor adb_highspeed_in_desc = {
112 .bLength = USB_DT_ENDPOINT_SIZE,
113 .bDescriptorType = USB_DT_ENDPOINT,
114 .bEndpointAddress = USB_DIR_IN,
115 .bmAttributes = USB_ENDPOINT_XFER_BULK,
116 .wMaxPacketSize = __constant_cpu_to_le16(512),
117};
118
119static struct usb_endpoint_descriptor adb_highspeed_out_desc = {
120 .bLength = USB_DT_ENDPOINT_SIZE,
121 .bDescriptorType = USB_DT_ENDPOINT,
122 .bEndpointAddress = USB_DIR_OUT,
123 .bmAttributes = USB_ENDPOINT_XFER_BULK,
124 .wMaxPacketSize = __constant_cpu_to_le16(512),
125};
126
127static struct usb_endpoint_descriptor adb_fullspeed_in_desc = {
128 .bLength = USB_DT_ENDPOINT_SIZE,
129 .bDescriptorType = USB_DT_ENDPOINT,
130 .bEndpointAddress = USB_DIR_IN,
131 .bmAttributes = USB_ENDPOINT_XFER_BULK,
132};
133
134static struct usb_endpoint_descriptor adb_fullspeed_out_desc = {
135 .bLength = USB_DT_ENDPOINT_SIZE,
136 .bDescriptorType = USB_DT_ENDPOINT,
137 .bEndpointAddress = USB_DIR_OUT,
138 .bmAttributes = USB_ENDPOINT_XFER_BULK,
139};
140
141static struct usb_descriptor_header *fs_adb_descs[] = {
142 (struct usb_descriptor_header *) &adb_interface_desc,
143 (struct usb_descriptor_header *) &adb_fullspeed_in_desc,
144 (struct usb_descriptor_header *) &adb_fullspeed_out_desc,
145 NULL,
146};
147
148static struct usb_descriptor_header *hs_adb_descs[] = {
149 (struct usb_descriptor_header *) &adb_interface_desc,
150 (struct usb_descriptor_header *) &adb_highspeed_in_desc,
151 (struct usb_descriptor_header *) &adb_highspeed_out_desc,
152 NULL,
153};
154
155static struct usb_descriptor_header *ss_adb_descs[] = {
156 (struct usb_descriptor_header *) &adb_interface_desc,
157 (struct usb_descriptor_header *) &adb_superspeed_in_desc,
158 (struct usb_descriptor_header *) &adb_ss_bulk_comp_desc,
159 (struct usb_descriptor_header *) &adb_superspeed_out_desc,
160 (struct usb_descriptor_header *) &adb_ss_bulk_comp_desc,
161 NULL,
162};
163
164static void adb_ready_callback(void);
165static void adb_closed_callback(void);
166
167/* temporary variable used between adb_open() and adb_gadget_bind() */
168static struct adb_dev *_adb_dev;
169
170static inline struct adb_dev *func_to_adb(struct usb_function *f)
171{
172 return container_of(f, struct adb_dev, function);
173}
174
175
176static struct usb_request *adb_request_new(struct usb_ep *ep, int buffer_size)
177{
178 struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL);
179 if (!req)
180 return NULL;
181
182 /* now allocate buffers for the requests */
183#ifdef CONFIG_PXA910_1G_DDR_WORKAROUND
184 req->buf = kmalloc(buffer_size, GFP_KERNEL | GFP_DMA);
185#else
186 req->buf = kmalloc(buffer_size, GFP_KERNEL);
187#endif
188 if (!req->buf) {
189 usb_ep_free_request(ep, req);
190 return NULL;
191 }
192
193 return req;
194}
195
196static void adb_request_free(struct usb_request *req, struct usb_ep *ep)
197{
198 if (req) {
199 kfree(req->buf);
200 usb_ep_free_request(ep, req);
201 }
202}
203
204static inline int adb_lock(atomic_t *excl)
205{
206 if (atomic_inc_return(excl) == 1) {
207 return 0;
208 } else {
209 atomic_dec(excl);
210 return -1;
211 }
212}
213
214static inline void adb_unlock(atomic_t *excl)
215{
216 atomic_dec(excl);
217}
218
219/* add a request to the tail of a list */
220void adb_req_put(struct adb_dev *dev, struct list_head *head,
221 struct usb_request *req)
222{
223 unsigned long flags;
224
225 spin_lock_irqsave(&dev->lock, flags);
226 list_add_tail(&req->list, head);
227 spin_unlock_irqrestore(&dev->lock, flags);
228}
229
230/* remove a request from the head of a list */
231struct usb_request *adb_req_get(struct adb_dev *dev, struct list_head *head)
232{
233 unsigned long flags;
234 struct usb_request *req;
235
236 spin_lock_irqsave(&dev->lock, flags);
237 if (list_empty(head)) {
238 req = 0;
239 } else {
240 req = list_first_entry(head, struct usb_request, list);
241 list_del(&req->list);
242 }
243 spin_unlock_irqrestore(&dev->lock, flags);
244 return req;
245}
246
247static void adb_complete_in(struct usb_ep *ep, struct usb_request *req)
248{
249 struct adb_dev *dev = _adb_dev;
250
251 if (req->status != 0)
252 dev->error = 1;
253
254 adb_req_put(dev, &dev->tx_idle, req);
255
256 wake_up(&dev->write_wq);
257}
258
259static void adb_complete_out(struct usb_ep *ep, struct usb_request *req)
260{
261 struct adb_dev *dev = _adb_dev;
262
263 dev->rx_done = 1;
264 if (req->status != 0 && req->status != -ECONNRESET)
265 dev->error = 1;
266
267 wake_up(&dev->read_wq);
268}
269
270static int adb_create_bulk_endpoints(struct adb_dev *dev,
271 struct usb_endpoint_descriptor *in_desc,
272 struct usb_endpoint_descriptor *out_desc)
273{
274 struct usb_composite_dev *cdev = dev->cdev;
275 struct usb_request *req;
276 struct usb_ep *ep;
277 int i;
278
279 DBG(cdev, "create_bulk_endpoints dev: %p\n", dev);
280
281 ep = usb_ep_autoconfig(cdev->gadget, in_desc);
282 if (!ep) {
283 DBG(cdev, "usb_ep_autoconfig for ep_in failed\n");
284 return -ENODEV;
285 }
286 DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name);
287 ep->driver_data = dev; /* claim the endpoint */
288 dev->ep_in = ep;
289
290 ep = usb_ep_autoconfig(cdev->gadget, out_desc);
291 if (!ep) {
292 DBG(cdev, "usb_ep_autoconfig for ep_out failed\n");
293 return -ENODEV;
294 }
295 DBG(cdev, "usb_ep_autoconfig for adb ep_out got %s\n", ep->name);
296 ep->driver_data = dev; /* claim the endpoint */
297 dev->ep_out = ep;
298
299 /* now allocate requests for our endpoints */
300 req = adb_request_new(dev->ep_out, ADB_BULK_BUFFER_SIZE);
301 if (!req)
302 goto fail;
303 req->complete = adb_complete_out;
304 dev->rx_req = req;
305
306 for (i = 0; i < TX_REQ_MAX; i++) {
307 req = adb_request_new(dev->ep_in, ADB_BULK_BUFFER_SIZE);
308 if (!req)
309 goto fail;
310 req->complete = adb_complete_in;
311 adb_req_put(dev, &dev->tx_idle, req);
312 }
313
314 return 0;
315
316fail:
317 printk(KERN_ERR "adb_bind() could not allocate requests\n");
318 return -1;
319}
320
321static ssize_t adb_read(struct file *fp, char __user *buf,
322 size_t count, loff_t *pos)
323{
324 struct adb_dev *dev = fp->private_data;
325 struct usb_request *req;
326 int r = count, xfer;
327 int ret;
328
329 pr_debug("adb_read(%zu)\n", count);
330 if (!_adb_dev)
331 return -ENODEV;
332
333 if (count > ADB_BULK_BUFFER_SIZE)
334 return -EINVAL;
335
336 if (adb_lock(&dev->read_excl))
337 return -EBUSY;
338
339 /* we will block until we're online */
340 while (!(dev->online || dev->error)) {
341 pr_debug("adb_read: waiting for online state\n");
342 ret = wait_event_interruptible(dev->read_wq,
343 (dev->online || dev->error));
344 if (ret < 0) {
345 adb_unlock(&dev->read_excl);
346 return ret;
347 }
348 }
349 if (dev->error) {
350 r = -EIO;
351 goto done;
352 }
353
354requeue_req:
355 /* queue a request */
356 req = dev->rx_req;
357#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_DWC2)
358 req->length = ADB_BULK_BUFFER_SIZE;
359#else
360 req->length = count;
361#endif
362 dev->rx_done = 0;
363 ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC);
364 if (ret < 0) {
365 pr_debug("adb_read: failed to queue req %p (%d)\n", req, ret);
366 r = -EIO;
367 dev->error = 1;
368 if (((-ESHUTDOWN) == ret) || ((-EAGAIN) == ret)) {
369 usleep_range(5000, 5000);
370 }
371 goto done;
372 } else {
373 pr_debug("rx %p queue\n", req);
374 }
375
376 /* wait for a request to complete */
377 ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
378 if (ret < 0) {
379 if (ret != -ERESTARTSYS)
380 dev->error = 1;
381 r = ret;
382 usb_ep_dequeue(dev->ep_out, req);
383 goto done;
384 }
385 if (!dev->error) {
386 /* If we got a 0-len packet, throw it back and try again. */
387 if (req->actual == 0)
388 goto requeue_req;
389
390 pr_debug("rx %p %d\n", req, req->actual);
391 xfer = (req->actual < count) ? req->actual : count;
392 if (copy_to_user(buf, req->buf, xfer))
393 r = -EFAULT;
394
395#if defined(ADB_ADD_STATISTICS_INTERFACE) && defined(CONFIG_PROC_FS)
396 dev->adb_nr_rx++;
397 dev->adb_nr_rx_bytes += xfer;
398#endif
399 } else
400 r = -EIO;
401
402done:
403 adb_unlock(&dev->read_excl);
404 pr_debug("adb_read returning %d\n", r);
405 return r;
406}
407
408static ssize_t adb_write(struct file *fp, const char __user *buf,
409 size_t count, loff_t *pos)
410{
411 struct adb_dev *dev = fp->private_data;
412 struct usb_request *req = 0;
413 int r = count, xfer;
414 int ret;
415
416 if (!_adb_dev)
417 return -ENODEV;
418 pr_debug("adb_write(%zu)\n", count);
419
420 if (adb_lock(&dev->write_excl))
421 return -EBUSY;
422
423 while (count > 0) {
424 if (dev->error) {
425 pr_debug("adb_write dev->error\n");
426 r = -EIO;
427 break;
428 }
429
430 /* get an idle tx request to use */
431 req = 0;
432 ret = wait_event_interruptible(dev->write_wq,
433 (req = adb_req_get(dev, &dev->tx_idle)) || dev->error);
434
435 if (ret < 0) {
436 r = ret;
437 break;
438 }
439
440 if (req != 0) {
441 if (count > ADB_BULK_BUFFER_SIZE)
442 xfer = ADB_BULK_BUFFER_SIZE;
443 else
444 xfer = count;
445 if (copy_from_user(req->buf, buf, xfer)) {
446 r = -EFAULT;
447 break;
448 }
449
450#if defined(ADB_ADD_STATISTICS_INTERFACE) && defined(CONFIG_PROC_FS)
451 dev->adb_nr_tx++;
452 dev->adb_nr_tx_bytes += xfer;
453#endif
454 req->length = xfer;
455 ret = usb_ep_queue(dev->ep_in, req, GFP_ATOMIC);
456 if (ret < 0) {
457 pr_debug("adb_write: xfer error %d\n", ret);
458 dev->error = 1;
459 r = -EIO;
460 break;
461 }
462
463 buf += xfer;
464 count -= xfer;
465
466 /* zero this so we don't try to free it on error exit */
467 req = 0;
468 }
469 }
470
471 if (req)
472 adb_req_put(dev, &dev->tx_idle, req);
473
474 adb_unlock(&dev->write_excl);
475 pr_debug("adb_write returning %d\n", r);
476 return r;
477}
478
479static int adb_open(struct inode *ip, struct file *fp)
480{
481 pr_info_ratelimited("adb_open\n");
482 if (!_adb_dev)
483 return -ENODEV;
484
485 if (adb_lock(&_adb_dev->open_excl))
486 return -EBUSY;
487
488 fp->private_data = _adb_dev;
489
490 /* clear the error latch */
491 _adb_dev->error = 0;
492
493 if (system_state == SYSTEM_BOOTING || system_state == SYSTEM_RUNNING)
494 adb_ready_callback();
495
496 return 0;
497}
498
499static int adb_release(struct inode *ip, struct file *fp)
500{
501 pr_info_ratelimited("adb_release\n");
502
503 adb_closed_callback();
504
505 adb_unlock(&_adb_dev->open_excl);
506 return 0;
507}
508
509/* file operations for ADB device /dev/android_adb */
510static const struct file_operations adb_fops = {
511 .owner = THIS_MODULE,
512 .read = adb_read,
513 .write = adb_write,
514 .open = adb_open,
515 .release = adb_release,
516};
517
518static struct miscdevice adb_device = {
519 .minor = MISC_DYNAMIC_MINOR,
520 .name = adb_shortname,
521 .fops = &adb_fops,
522};
523
524
525static int
526adb_function_bind(struct usb_configuration *c, struct usb_function *f)
527{
528 struct usb_composite_dev *cdev = c->cdev;
529 struct adb_dev *dev = func_to_adb(f);
530 int id;
531 int ret;
532#if defined(CONFIG_FIXED_USB_IFACE)
533 int num = 0, i;
534#endif
535 dev->cdev = cdev;
536 DBG(cdev, "adb_function_bind dev: %p\n", dev);
537
538#if defined(CONFIG_FIXED_USB_IFACE)
539 id = get_usb_interface_id(c);
540 if (id < 0) {
541 return id;
542 } else if(id < ADB_INTERFACE_NUMBER) {
543 num = ADB_INTERFACE_NUMBER - id;
544 nr_adb_dummy_interface = num;
545 } else
546 num = 0;
547
548 if (num > 0) {
549 for(i = 0; i < num; i++) {
550 id = usb_interface_id(c, NULL);
551 if (id < 0)
552 return id;
553 else
554 pr_info("%s: dummy interface: %d\n",
555 __func__, id);
556 }
557 }
558#endif
559
560 /* allocate interface ID(s) */
561 id = usb_interface_id(c, f);
562 if (id < 0)
563 return id;
564 adb_interface_desc.bInterfaceNumber = id;
565
566 /* allocate endpoints */
567 ret = adb_create_bulk_endpoints(dev, &adb_fullspeed_in_desc,
568 &adb_fullspeed_out_desc);
569 if (ret)
570 return ret;
571
572 /* support high speed hardware */
573 if (gadget_is_dualspeed(c->cdev->gadget)) {
574 adb_highspeed_in_desc.bEndpointAddress =
575 adb_fullspeed_in_desc.bEndpointAddress;
576 adb_highspeed_out_desc.bEndpointAddress =
577 adb_fullspeed_out_desc.bEndpointAddress;
578 }
579
580 /* support super speed hardware */
581 if (gadget_is_superspeed(c->cdev->gadget)) {
582 adb_superspeed_in_desc.bEndpointAddress =
583 adb_fullspeed_in_desc.bEndpointAddress;
584 adb_superspeed_out_desc.bEndpointAddress =
585 adb_fullspeed_out_desc.bEndpointAddress;
586 }
587
588 DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
589 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
590 f->name, dev->ep_in->name, dev->ep_out->name);
591 return 0;
592}
593
594static void
595adb_function_unbind(struct usb_configuration *c, struct usb_function *f)
596{
597 struct adb_dev *dev = func_to_adb(f);
598 struct usb_request *req;
599
600
601 dev->online = 0;
602 dev->error = 1;
603
604 wake_up(&dev->read_wq);
605
606 adb_request_free(dev->rx_req, dev->ep_out);
607 while ((req = adb_req_get(dev, &dev->tx_idle)))
608 adb_request_free(req, dev->ep_in);
609
610#if defined(CONFIG_FIXED_USB_IFACE)
611 nr_adb_dummy_interface = 0;
612#endif
613}
614
615static int adb_function_set_alt(struct usb_function *f,
616 unsigned intf, unsigned alt)
617{
618 struct adb_dev *dev = func_to_adb(f);
619 struct usb_composite_dev *cdev = f->config->cdev;
620 int ret;
621
622 DBG(cdev, "adb_function_set_alt intf: %d alt: %d\n", intf, alt);
623
624 ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in);
625 if (ret)
626 return ret;
627
628 ret = usb_ep_enable(dev->ep_in);
629 if (ret)
630 return ret;
631
632 ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out);
633 if (ret)
634 return ret;
635
636 ret = usb_ep_enable(dev->ep_out);
637 if (ret) {
638 usb_ep_disable(dev->ep_in);
639 return ret;
640 }
641 dev->online = 1;
642
643 /* readers may be blocked waiting for us to go online */
644 wake_up(&dev->read_wq);
645 return 0;
646}
647
648static void adb_function_disable(struct usb_function *f)
649{
650 struct adb_dev *dev = func_to_adb(f);
651 struct usb_composite_dev *cdev = dev->cdev;
652
653 DBG(cdev, "adb_function_disable cdev %p\n", cdev);
654 dev->online = 0;
655 dev->error = 1;
656 usb_ep_disable(dev->ep_in);
657 usb_ep_disable(dev->ep_out);
658
659 /* readers may be blocked waiting for us to go online */
660 wake_up(&dev->read_wq);
661
662 VDBG(cdev, "%s disabled\n", dev->function.name);
663}
664
665static int adb_bind_config(struct usb_configuration *c)
666{
667 struct adb_dev *dev = _adb_dev;
668
669 printk(KERN_INFO "adb_bind_config\n");
670
671 dev->cdev = c->cdev;
672 dev->function.name = "adb";
673 dev->function.fs_descriptors = fs_adb_descs;
674 dev->function.hs_descriptors = hs_adb_descs;
675 dev->function.ss_descriptors = ss_adb_descs;
676 dev->function.ssp_descriptors = ss_adb_descs;
677
678 dev->function.bind = adb_function_bind;
679 dev->function.unbind = adb_function_unbind;
680 dev->function.set_alt = adb_function_set_alt;
681 dev->function.disable = adb_function_disable;
682
683 return usb_add_function(c, &dev->function);
684}
685
686#if defined(ADB_ADD_STATISTICS_INTERFACE) && defined(CONFIG_PROC_FS)
687/*
688 * Info exported via "/proc/driver/adb".
689 */
690static int adb_proc_show(struct seq_file *seq, void *v)
691{
692 seq_printf(seq, "rx-tx: %10d:%10d:%10d:%10d\n",
693 _adb_dev->adb_nr_rx,
694 _adb_dev->adb_nr_rx_bytes,
695 _adb_dev->adb_nr_tx,
696 _adb_dev->adb_nr_tx_bytes);
697 return 0;
698}
699
700static int adb_proc_open(struct inode *inode, struct file *file)
701{
702 return single_open(file, adb_proc_show, NULL);
703}
704
705static const struct file_operations adb_proc_fops = {
706 .owner = THIS_MODULE,
707 .open = adb_proc_open,
708 .read = seq_read,
709 .llseek = seq_lseek,
710 .release = single_release,
711};
712#endif
713
714static int adb_setup(void)
715{
716 struct adb_dev *dev;
717 int ret;
718
719#if defined(CONFIG_CPU_ASR18XX) && defined(CONFIG_USB_MVC2)
720 if (adb_inited)
721 return 0;
722 else
723 adb_inited = 1;
724#endif
725 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
726 if (!dev)
727 return -ENOMEM;
728
729 spin_lock_init(&dev->lock);
730
731 init_waitqueue_head(&dev->read_wq);
732 init_waitqueue_head(&dev->write_wq);
733
734 atomic_set(&dev->open_excl, 0);
735 atomic_set(&dev->read_excl, 0);
736 atomic_set(&dev->write_excl, 0);
737
738 INIT_LIST_HEAD(&dev->tx_idle);
739
740 _adb_dev = dev;
741 ret = misc_register(&adb_device);
742 if (ret)
743 goto err;
744
745#if defined(ADB_ADD_STATISTICS_INTERFACE) && defined(CONFIG_PROC_FS)
746 _adb_dev->pde = proc_create("driver/adb", S_IRUSR, NULL, &adb_proc_fops);
747 if (!_adb_dev->pde)
748 printk(KERN_WARNING "adb: Failed to register procfs.\n");
749#endif
750
751 return 0;
752
753err:
754 kfree(dev);
755 printk(KERN_ERR "adb gadget driver failed to initialize\n");
756 return ret;
757}
758
759static void adb_cleanup(void)
760{
761#if !defined(CONFIG_CPU_ASR18XX) || !defined(CONFIG_USB_MVC2)
762
763#if defined(ADB_ADD_STATISTICS_INTERFACE) && defined(CONFIG_PROC_FS)
764 if (_adb_dev->pde)
765 proc_remove(_adb_dev->pde);
766#endif
767 misc_deregister(&adb_device);
768 adb_device.minor = MISC_DYNAMIC_MINOR;
769 kfree(_adb_dev);
770 _adb_dev = NULL;
771#endif
772}