]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/usb/usb_dev.c
Merge r256782 from head:
[FreeBSD/stable/10.git] / sys / dev / usb / usb_dev.c
1 /* $FreeBSD$ */
2 /*-
3  * Copyright (c) 2006-2008 Hans Petter Selasky. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *
27  * usb_dev.c - An abstraction layer for creating devices under /dev/...
28  */
29
30 #ifdef USB_GLOBAL_INCLUDE_FILE
31 #include USB_GLOBAL_INCLUDE_FILE
32 #else
33 #include <sys/stdint.h>
34 #include <sys/stddef.h>
35 #include <sys/param.h>
36 #include <sys/queue.h>
37 #include <sys/types.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/bus.h>
41 #include <sys/module.h>
42 #include <sys/lock.h>
43 #include <sys/mutex.h>
44 #include <sys/condvar.h>
45 #include <sys/sysctl.h>
46 #include <sys/sx.h>
47 #include <sys/unistd.h>
48 #include <sys/callout.h>
49 #include <sys/malloc.h>
50 #include <sys/priv.h>
51 #include <sys/vnode.h>
52 #include <sys/conf.h>
53 #include <sys/fcntl.h>
54
55 #include <dev/usb/usb.h>
56 #include <dev/usb/usb_ioctl.h>
57 #include <dev/usb/usbdi.h>
58 #include <dev/usb/usbdi_util.h>
59
60 #define USB_DEBUG_VAR usb_fifo_debug
61
62 #include <dev/usb/usb_core.h>
63 #include <dev/usb/usb_dev.h>
64 #include <dev/usb/usb_mbuf.h>
65 #include <dev/usb/usb_process.h>
66 #include <dev/usb/usb_device.h>
67 #include <dev/usb/usb_debug.h>
68 #include <dev/usb/usb_busdma.h>
69 #include <dev/usb/usb_generic.h>
70 #include <dev/usb/usb_dynamic.h>
71 #include <dev/usb/usb_util.h>
72
73 #include <dev/usb/usb_controller.h>
74 #include <dev/usb/usb_bus.h>
75
76 #include <sys/filio.h>
77 #include <sys/ttycom.h>
78 #include <sys/syscallsubr.h>
79
80 #include <machine/stdarg.h>
81 #endif                  /* USB_GLOBAL_INCLUDE_FILE */
82
83 #if USB_HAVE_UGEN
84
85 #ifdef USB_DEBUG
86 static int usb_fifo_debug = 0;
87
88 static SYSCTL_NODE(_hw_usb, OID_AUTO, dev, CTLFLAG_RW, 0, "USB device");
89 SYSCTL_INT(_hw_usb_dev, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN,
90     &usb_fifo_debug, 0, "Debug Level");
91 TUNABLE_INT("hw.usb.dev.debug", &usb_fifo_debug);
92 #endif
93
94 #if ((__FreeBSD_version >= 700001) || (__FreeBSD_version == 0) || \
95      ((__FreeBSD_version >= 600034) && (__FreeBSD_version < 700000)))
96 #define USB_UCRED struct ucred *ucred,
97 #else
98 #define USB_UCRED
99 #endif
100
101 /* prototypes */
102
103 static int      usb_fifo_open(struct usb_cdev_privdata *, 
104                     struct usb_fifo *, int);
105 static void     usb_fifo_close(struct usb_fifo *, int);
106 static void     usb_dev_init(void *);
107 static void     usb_dev_init_post(void *);
108 static void     usb_dev_uninit(void *);
109 static int      usb_fifo_uiomove(struct usb_fifo *, void *, int,
110                     struct uio *);
111 static void     usb_fifo_check_methods(struct usb_fifo_methods *);
112 static struct   usb_fifo *usb_fifo_alloc(struct mtx *);
113 static struct   usb_endpoint *usb_dev_get_ep(struct usb_device *, uint8_t,
114                     uint8_t);
115 static void     usb_loc_fill(struct usb_fs_privdata *,
116                     struct usb_cdev_privdata *);
117 static void     usb_close(void *);
118 static usb_error_t usb_ref_device(struct usb_cdev_privdata *, struct usb_cdev_refdata *, int);
119 static usb_error_t usb_usb_ref_device(struct usb_cdev_privdata *, struct usb_cdev_refdata *);
120 static void     usb_unref_device(struct usb_cdev_privdata *, struct usb_cdev_refdata *);
121
122 static d_open_t usb_open;
123 static d_ioctl_t usb_ioctl;
124 static d_read_t usb_read;
125 static d_write_t usb_write;
126 static d_poll_t usb_poll;
127 static d_kqfilter_t usb_kqfilter;
128
129 static d_ioctl_t usb_static_ioctl;
130
131 static usb_fifo_open_t usb_fifo_dummy_open;
132 static usb_fifo_close_t usb_fifo_dummy_close;
133 static usb_fifo_ioctl_t usb_fifo_dummy_ioctl;
134 static usb_fifo_cmd_t usb_fifo_dummy_cmd;
135
136 /* character device structure used for devices (/dev/ugenX.Y and /dev/uXXX) */
137 struct cdevsw usb_devsw = {
138         .d_version = D_VERSION,
139         .d_open = usb_open,
140         .d_ioctl = usb_ioctl,
141         .d_name = "usbdev",
142         .d_flags = D_TRACKCLOSE,
143         .d_read = usb_read,
144         .d_write = usb_write,
145         .d_poll = usb_poll,
146         .d_kqfilter = usb_kqfilter,
147 };
148
149 static struct cdev* usb_dev = NULL;
150
151 /* character device structure used for /dev/usb */
152 static struct cdevsw usb_static_devsw = {
153         .d_version = D_VERSION,
154         .d_ioctl = usb_static_ioctl,
155         .d_name = "usb"
156 };
157
158 static TAILQ_HEAD(, usb_symlink) usb_sym_head;
159 static struct sx usb_sym_lock;
160
161 struct mtx usb_ref_lock;
162
163 /*------------------------------------------------------------------------*
164  *      usb_loc_fill
165  *
166  * This is used to fill out a usb_cdev_privdata structure based on the
167  * device's address as contained in usb_fs_privdata.
168  *------------------------------------------------------------------------*/
169 static void
170 usb_loc_fill(struct usb_fs_privdata* pd, struct usb_cdev_privdata *cpd)
171 {
172         cpd->bus_index = pd->bus_index;
173         cpd->dev_index = pd->dev_index;
174         cpd->ep_addr = pd->ep_addr;
175         cpd->fifo_index = pd->fifo_index;
176 }
177
178 /*------------------------------------------------------------------------*
179  *      usb_ref_device
180  *
181  * This function is used to atomically refer an USB device by its
182  * device location. If this function returns success the USB device
183  * will not dissappear until the USB device is unreferenced.
184  *
185  * Return values:
186  *  0: Success, refcount incremented on the given USB device.
187  *  Else: Failure.
188  *------------------------------------------------------------------------*/
189 static usb_error_t
190 usb_ref_device(struct usb_cdev_privdata *cpd, 
191     struct usb_cdev_refdata *crd, int need_uref)
192 {
193         struct usb_fifo **ppf;
194         struct usb_fifo *f;
195
196         DPRINTFN(2, "cpd=%p need uref=%d\n", cpd, need_uref);
197
198         /* clear all refs */
199         memset(crd, 0, sizeof(*crd));
200
201         mtx_lock(&usb_ref_lock);
202         cpd->bus = devclass_get_softc(usb_devclass_ptr, cpd->bus_index);
203         if (cpd->bus == NULL) {
204                 DPRINTFN(2, "no bus at %u\n", cpd->bus_index);
205                 goto error;
206         }
207         cpd->udev = cpd->bus->devices[cpd->dev_index];
208         if (cpd->udev == NULL) {
209                 DPRINTFN(2, "no device at %u\n", cpd->dev_index);
210                 goto error;
211         }
212         if (cpd->udev->state == USB_STATE_DETACHED &&
213             (need_uref != 2)) {
214                 DPRINTFN(2, "device is detached\n");
215                 goto error;
216         }
217         if (need_uref) {
218                 DPRINTFN(2, "ref udev - needed\n");
219
220                 if (cpd->udev->refcount == USB_DEV_REF_MAX) {
221                         DPRINTFN(2, "no dev ref\n");
222                         goto error;
223                 }
224                 cpd->udev->refcount++;
225
226                 mtx_unlock(&usb_ref_lock);
227
228                 /*
229                  * We need to grab the enumeration SX-lock before
230                  * grabbing the FIFO refs to avoid deadlock at detach!
231                  */
232                 crd->do_unlock = usbd_enum_lock(cpd->udev);
233
234                 mtx_lock(&usb_ref_lock);
235
236                 /* 
237                  * Set "is_uref" after grabbing the default SX lock
238                  */
239                 crd->is_uref = 1;
240         }
241
242         /* check if we are doing an open */
243         if (cpd->fflags == 0) {
244                 /* use zero defaults */
245         } else {
246                 /* check for write */
247                 if (cpd->fflags & FWRITE) {
248                         ppf = cpd->udev->fifo;
249                         f = ppf[cpd->fifo_index + USB_FIFO_TX];
250                         crd->txfifo = f;
251                         crd->is_write = 1;      /* ref */
252                         if (f == NULL || f->refcount == USB_FIFO_REF_MAX)
253                                 goto error;
254                         if (f->curr_cpd != cpd)
255                                 goto error;
256                         /* check if USB-FS is active */
257                         if (f->fs_ep_max != 0) {
258                                 crd->is_usbfs = 1;
259                         }
260                 }
261
262                 /* check for read */
263                 if (cpd->fflags & FREAD) {
264                         ppf = cpd->udev->fifo;
265                         f = ppf[cpd->fifo_index + USB_FIFO_RX];
266                         crd->rxfifo = f;
267                         crd->is_read = 1;       /* ref */
268                         if (f == NULL || f->refcount == USB_FIFO_REF_MAX)
269                                 goto error;
270                         if (f->curr_cpd != cpd)
271                                 goto error;
272                         /* check if USB-FS is active */
273                         if (f->fs_ep_max != 0) {
274                                 crd->is_usbfs = 1;
275                         }
276                 }
277         }
278
279         /* when everything is OK we increment the refcounts */
280         if (crd->is_write) {
281                 DPRINTFN(2, "ref write\n");
282                 crd->txfifo->refcount++;
283         }
284         if (crd->is_read) {
285                 DPRINTFN(2, "ref read\n");
286                 crd->rxfifo->refcount++;
287         }
288         mtx_unlock(&usb_ref_lock);
289
290         return (0);
291
292 error:
293         if (crd->do_unlock)
294                 usbd_enum_unlock(cpd->udev);
295
296         if (crd->is_uref) {
297                 cpd->udev->refcount--;
298                 cv_broadcast(&cpd->udev->ref_cv);
299         }
300         mtx_unlock(&usb_ref_lock);
301         DPRINTFN(2, "fail\n");
302         return (USB_ERR_INVAL);
303 }
304
305 /*------------------------------------------------------------------------*
306  *      usb_usb_ref_device
307  *
308  * This function is used to upgrade an USB reference to include the
309  * USB device reference on a USB location.
310  *
311  * Return values:
312  *  0: Success, refcount incremented on the given USB device.
313  *  Else: Failure.
314  *------------------------------------------------------------------------*/
315 static usb_error_t
316 usb_usb_ref_device(struct usb_cdev_privdata *cpd,
317     struct usb_cdev_refdata *crd)
318 {
319         /*
320          * Check if we already got an USB reference on this location:
321          */
322         if (crd->is_uref)
323                 return (0);             /* success */
324
325         /*
326          * To avoid deadlock at detach we need to drop the FIFO ref
327          * and re-acquire a new ref!
328          */
329         usb_unref_device(cpd, crd);
330
331         return (usb_ref_device(cpd, crd, 1 /* need uref */));
332 }
333
334 /*------------------------------------------------------------------------*
335  *      usb_unref_device
336  *
337  * This function will release the reference count by one unit for the
338  * given USB device.
339  *------------------------------------------------------------------------*/
340 static void
341 usb_unref_device(struct usb_cdev_privdata *cpd,
342     struct usb_cdev_refdata *crd)
343 {
344
345         DPRINTFN(2, "cpd=%p is_uref=%d\n", cpd, crd->is_uref);
346
347         if (crd->do_unlock)
348                 usbd_enum_unlock(cpd->udev);
349
350         mtx_lock(&usb_ref_lock);
351         if (crd->is_read) {
352                 if (--(crd->rxfifo->refcount) == 0) {
353                         cv_signal(&crd->rxfifo->cv_drain);
354                 }
355                 crd->is_read = 0;
356         }
357         if (crd->is_write) {
358                 if (--(crd->txfifo->refcount) == 0) {
359                         cv_signal(&crd->txfifo->cv_drain);
360                 }
361                 crd->is_write = 0;
362         }
363         if (crd->is_uref) {
364                 crd->is_uref = 0;
365                 cpd->udev->refcount--;
366                 cv_broadcast(&cpd->udev->ref_cv);
367         }
368         mtx_unlock(&usb_ref_lock);
369 }
370
371 static struct usb_fifo *
372 usb_fifo_alloc(struct mtx *mtx)
373 {
374         struct usb_fifo *f;
375
376         f = malloc(sizeof(*f), M_USBDEV, M_WAITOK | M_ZERO);
377         if (f != NULL) {
378                 cv_init(&f->cv_io, "FIFO-IO");
379                 cv_init(&f->cv_drain, "FIFO-DRAIN");
380                 f->priv_mtx = mtx;
381                 f->refcount = 1;
382                 knlist_init_mtx(&f->selinfo.si_note, mtx);
383         }
384         return (f);
385 }
386
387 /*------------------------------------------------------------------------*
388  *      usb_fifo_create
389  *------------------------------------------------------------------------*/
390 static int
391 usb_fifo_create(struct usb_cdev_privdata *cpd,
392     struct usb_cdev_refdata *crd)
393 {
394         struct usb_device *udev = cpd->udev;
395         struct usb_fifo *f;
396         struct usb_endpoint *ep;
397         uint8_t n;
398         uint8_t is_tx;
399         uint8_t is_rx;
400         uint8_t no_null;
401         uint8_t is_busy;
402         int e = cpd->ep_addr;
403
404         is_tx = (cpd->fflags & FWRITE) ? 1 : 0;
405         is_rx = (cpd->fflags & FREAD) ? 1 : 0;
406         no_null = 1;
407         is_busy = 0;
408
409         /* Preallocated FIFO */
410         if (e < 0) {
411                 DPRINTFN(5, "Preallocated FIFO\n");
412                 if (is_tx) {
413                         f = udev->fifo[cpd->fifo_index + USB_FIFO_TX];
414                         if (f == NULL)
415                                 return (EINVAL);
416                         crd->txfifo = f;
417                 }
418                 if (is_rx) {
419                         f = udev->fifo[cpd->fifo_index + USB_FIFO_RX];
420                         if (f == NULL)
421                                 return (EINVAL);
422                         crd->rxfifo = f;
423                 }
424                 return (0);
425         }
426
427         KASSERT(e >= 0 && e <= 15, ("endpoint %d out of range", e));
428
429         /* search for a free FIFO slot */
430         DPRINTFN(5, "Endpoint device, searching for 0x%02x\n", e);
431         for (n = 0;; n += 2) {
432
433                 if (n == USB_FIFO_MAX) {
434                         if (no_null) {
435                                 no_null = 0;
436                                 n = 0;
437                         } else {
438                                 /* end of FIFOs reached */
439                                 DPRINTFN(5, "out of FIFOs\n");
440                                 return (ENOMEM);
441                         }
442                 }
443                 /* Check for TX FIFO */
444                 if (is_tx) {
445                         f = udev->fifo[n + USB_FIFO_TX];
446                         if (f != NULL) {
447                                 if (f->dev_ep_index != e) {
448                                         /* wrong endpoint index */
449                                         continue;
450                                 }
451                                 if (f->curr_cpd != NULL) {
452                                         /* FIFO is opened */
453                                         is_busy = 1;
454                                         continue;
455                                 }
456                         } else if (no_null) {
457                                 continue;
458                         }
459                 }
460                 /* Check for RX FIFO */
461                 if (is_rx) {
462                         f = udev->fifo[n + USB_FIFO_RX];
463                         if (f != NULL) {
464                                 if (f->dev_ep_index != e) {
465                                         /* wrong endpoint index */
466                                         continue;
467                                 }
468                                 if (f->curr_cpd != NULL) {
469                                         /* FIFO is opened */
470                                         is_busy = 1;
471                                         continue;
472                                 }
473                         } else if (no_null) {
474                                 continue;
475                         }
476                 }
477                 break;
478         }
479
480         if (no_null == 0) {
481                 if (e >= (USB_EP_MAX / 2)) {
482                         /* we don't create any endpoints in this range */
483                         DPRINTFN(5, "ep out of range\n");
484                         return (is_busy ? EBUSY : EINVAL);
485                 }
486         }
487
488         if ((e != 0) && is_busy) {
489                 /*
490                  * Only the default control endpoint is allowed to be
491                  * opened multiple times!
492                  */
493                 DPRINTFN(5, "busy\n");
494                 return (EBUSY);
495         }
496
497         /* Check TX FIFO */
498         if (is_tx &&
499             (udev->fifo[n + USB_FIFO_TX] == NULL)) {
500                 ep = usb_dev_get_ep(udev, e, USB_FIFO_TX);
501                 DPRINTFN(5, "dev_get_endpoint(%d, 0x%x)\n", e, USB_FIFO_TX);
502                 if (ep == NULL) {
503                         DPRINTFN(5, "dev_get_endpoint returned NULL\n");
504                         return (EINVAL);
505                 }
506                 f = usb_fifo_alloc(&udev->device_mtx);
507                 if (f == NULL) {
508                         DPRINTFN(5, "could not alloc tx fifo\n");
509                         return (ENOMEM);
510                 }
511                 /* update some fields */
512                 f->fifo_index = n + USB_FIFO_TX;
513                 f->dev_ep_index = e;
514                 f->priv_sc0 = ep;
515                 f->methods = &usb_ugen_methods;
516                 f->iface_index = ep->iface_index;
517                 f->udev = udev;
518                 mtx_lock(&usb_ref_lock);
519                 udev->fifo[n + USB_FIFO_TX] = f;
520                 mtx_unlock(&usb_ref_lock);
521         }
522         /* Check RX FIFO */
523         if (is_rx &&
524             (udev->fifo[n + USB_FIFO_RX] == NULL)) {
525
526                 ep = usb_dev_get_ep(udev, e, USB_FIFO_RX);
527                 DPRINTFN(5, "dev_get_endpoint(%d, 0x%x)\n", e, USB_FIFO_RX);
528                 if (ep == NULL) {
529                         DPRINTFN(5, "dev_get_endpoint returned NULL\n");
530                         return (EINVAL);
531                 }
532                 f = usb_fifo_alloc(&udev->device_mtx);
533                 if (f == NULL) {
534                         DPRINTFN(5, "could not alloc rx fifo\n");
535                         return (ENOMEM);
536                 }
537                 /* update some fields */
538                 f->fifo_index = n + USB_FIFO_RX;
539                 f->dev_ep_index = e;
540                 f->priv_sc0 = ep;
541                 f->methods = &usb_ugen_methods;
542                 f->iface_index = ep->iface_index;
543                 f->udev = udev;
544                 mtx_lock(&usb_ref_lock);
545                 udev->fifo[n + USB_FIFO_RX] = f;
546                 mtx_unlock(&usb_ref_lock);
547         }
548         if (is_tx) {
549                 crd->txfifo = udev->fifo[n + USB_FIFO_TX];
550         }
551         if (is_rx) {
552                 crd->rxfifo = udev->fifo[n + USB_FIFO_RX];
553         }
554         /* fill out fifo index */
555         DPRINTFN(5, "fifo index = %d\n", n);
556         cpd->fifo_index = n;
557
558         /* complete */
559
560         return (0);
561 }
562
563 void
564 usb_fifo_free(struct usb_fifo *f)
565 {
566         uint8_t n;
567
568         if (f == NULL) {
569                 /* be NULL safe */
570                 return;
571         }
572         /* destroy symlink devices, if any */
573         for (n = 0; n != 2; n++) {
574                 if (f->symlink[n]) {
575                         usb_free_symlink(f->symlink[n]);
576                         f->symlink[n] = NULL;
577                 }
578         }
579         mtx_lock(&usb_ref_lock);
580
581         /* delink ourselves to stop calls from userland */
582         if ((f->fifo_index < USB_FIFO_MAX) &&
583             (f->udev != NULL) &&
584             (f->udev->fifo[f->fifo_index] == f)) {
585                 f->udev->fifo[f->fifo_index] = NULL;
586         } else {
587                 DPRINTFN(0, "USB FIFO %p has not been linked\n", f);
588         }
589
590         /* decrease refcount */
591         f->refcount--;
592         /* prevent any write flush */
593         f->flag_iserror = 1;
594         /* need to wait until all callers have exited */
595         while (f->refcount != 0) {
596                 mtx_unlock(&usb_ref_lock);      /* avoid LOR */
597                 mtx_lock(f->priv_mtx);
598                 /* get I/O thread out of any sleep state */
599                 if (f->flag_sleeping) {
600                         f->flag_sleeping = 0;
601                         cv_broadcast(&f->cv_io);
602                 }
603                 mtx_unlock(f->priv_mtx);
604                 mtx_lock(&usb_ref_lock);
605
606                 /*
607                  * Check if the "f->refcount" variable reached zero
608                  * during the unlocked time before entering wait:
609                  */
610                 if (f->refcount == 0)
611                         break;
612
613                 /* wait for sync */
614                 cv_wait(&f->cv_drain, &usb_ref_lock);
615         }
616         mtx_unlock(&usb_ref_lock);
617
618         /* take care of closing the device here, if any */
619         usb_fifo_close(f, 0);
620
621         cv_destroy(&f->cv_io);
622         cv_destroy(&f->cv_drain);
623
624         knlist_clear(&f->selinfo.si_note, 0);
625         seldrain(&f->selinfo);
626         knlist_destroy(&f->selinfo.si_note);
627
628         free(f, M_USBDEV);
629 }
630
631 static struct usb_endpoint *
632 usb_dev_get_ep(struct usb_device *udev, uint8_t ep_index, uint8_t dir)
633 {
634         struct usb_endpoint *ep;
635         uint8_t ep_dir;
636
637         if (ep_index == 0) {
638                 ep = &udev->ctrl_ep;
639         } else {
640                 if (dir == USB_FIFO_RX) {
641                         if (udev->flags.usb_mode == USB_MODE_HOST) {
642                                 ep_dir = UE_DIR_IN;
643                         } else {
644                                 ep_dir = UE_DIR_OUT;
645                         }
646                 } else {
647                         if (udev->flags.usb_mode == USB_MODE_HOST) {
648                                 ep_dir = UE_DIR_OUT;
649                         } else {
650                                 ep_dir = UE_DIR_IN;
651                         }
652                 }
653                 ep = usbd_get_ep_by_addr(udev, ep_index | ep_dir);
654         }
655
656         if (ep == NULL) {
657                 /* if the endpoint does not exist then return */
658                 return (NULL);
659         }
660         if (ep->edesc == NULL) {
661                 /* invalid endpoint */
662                 return (NULL);
663         }
664         return (ep);                    /* success */
665 }
666
667 /*------------------------------------------------------------------------*
668  *      usb_fifo_open
669  *
670  * Returns:
671  * 0: Success
672  * Else: Failure
673  *------------------------------------------------------------------------*/
674 static int
675 usb_fifo_open(struct usb_cdev_privdata *cpd, 
676     struct usb_fifo *f, int fflags)
677 {
678         int err;
679
680         if (f == NULL) {
681                 /* no FIFO there */
682                 DPRINTFN(2, "no FIFO\n");
683                 return (ENXIO);
684         }
685         /* remove FWRITE and FREAD flags */
686         fflags &= ~(FWRITE | FREAD);
687
688         /* set correct file flags */
689         if ((f->fifo_index & 1) == USB_FIFO_TX) {
690                 fflags |= FWRITE;
691         } else {
692                 fflags |= FREAD;
693         }
694
695         /* check if we are already opened */
696         /* we don't need any locks when checking this variable */
697         if (f->curr_cpd != NULL) {
698                 err = EBUSY;
699                 goto done;
700         }
701
702         /* reset short flag before open */
703         f->flag_short = 0;
704
705         /* call open method */
706         err = (f->methods->f_open) (f, fflags);
707         if (err) {
708                 goto done;
709         }
710         mtx_lock(f->priv_mtx);
711
712         /* reset sleep flag */
713         f->flag_sleeping = 0;
714
715         /* reset error flag */
716         f->flag_iserror = 0;
717
718         /* reset complete flag */
719         f->flag_iscomplete = 0;
720
721         /* reset select flag */
722         f->flag_isselect = 0;
723
724         /* reset flushing flag */
725         f->flag_flushing = 0;
726
727         /* reset ASYNC proc flag */
728         f->async_p = NULL;
729
730         mtx_lock(&usb_ref_lock);
731         /* flag the fifo as opened to prevent others */
732         f->curr_cpd = cpd;
733         mtx_unlock(&usb_ref_lock);
734
735         /* reset queue */
736         usb_fifo_reset(f);
737
738         mtx_unlock(f->priv_mtx);
739 done:
740         return (err);
741 }
742
743 /*------------------------------------------------------------------------*
744  *      usb_fifo_reset
745  *------------------------------------------------------------------------*/
746 void
747 usb_fifo_reset(struct usb_fifo *f)
748 {
749         struct usb_mbuf *m;
750
751         if (f == NULL) {
752                 return;
753         }
754         while (1) {
755                 USB_IF_DEQUEUE(&f->used_q, m);
756                 if (m) {
757                         USB_IF_ENQUEUE(&f->free_q, m);
758                 } else {
759                         break;
760                 }
761         }
762         /* reset have fragment flag */
763         f->flag_have_fragment = 0;
764 }
765
766 /*------------------------------------------------------------------------*
767  *      usb_fifo_close
768  *------------------------------------------------------------------------*/
769 static void
770 usb_fifo_close(struct usb_fifo *f, int fflags)
771 {
772         int err;
773
774         /* check if we are not opened */
775         if (f->curr_cpd == NULL) {
776                 /* nothing to do - already closed */
777                 return;
778         }
779         mtx_lock(f->priv_mtx);
780
781         /* clear current cdev private data pointer */
782         mtx_lock(&usb_ref_lock);
783         f->curr_cpd = NULL;
784         mtx_unlock(&usb_ref_lock);
785
786         /* check if we are watched by kevent */
787         KNOTE_LOCKED(&f->selinfo.si_note, 0);
788
789         /* check if we are selected */
790         if (f->flag_isselect) {
791                 selwakeup(&f->selinfo);
792                 f->flag_isselect = 0;
793         }
794         /* check if a thread wants SIGIO */
795         if (f->async_p != NULL) {
796                 PROC_LOCK(f->async_p);
797                 kern_psignal(f->async_p, SIGIO);
798                 PROC_UNLOCK(f->async_p);
799                 f->async_p = NULL;
800         }
801         /* remove FWRITE and FREAD flags */
802         fflags &= ~(FWRITE | FREAD);
803
804         /* flush written data, if any */
805         if ((f->fifo_index & 1) == USB_FIFO_TX) {
806
807                 if (!f->flag_iserror) {
808
809                         /* set flushing flag */
810                         f->flag_flushing = 1;
811
812                         /* get the last packet in */
813                         if (f->flag_have_fragment) {
814                                 struct usb_mbuf *m;
815                                 f->flag_have_fragment = 0;
816                                 USB_IF_DEQUEUE(&f->free_q, m);
817                                 if (m) {
818                                         USB_IF_ENQUEUE(&f->used_q, m);
819                                 }
820                         }
821
822                         /* start write transfer, if not already started */
823                         (f->methods->f_start_write) (f);
824
825                         /* check if flushed already */
826                         while (f->flag_flushing &&
827                             (!f->flag_iserror)) {
828                                 /* wait until all data has been written */
829                                 f->flag_sleeping = 1;
830                                 err = cv_wait_sig(&f->cv_io, f->priv_mtx);
831                                 if (err) {
832                                         DPRINTF("signal received\n");
833                                         break;
834                                 }
835                         }
836                 }
837                 fflags |= FWRITE;
838
839                 /* stop write transfer, if not already stopped */
840                 (f->methods->f_stop_write) (f);
841         } else {
842                 fflags |= FREAD;
843
844                 /* stop write transfer, if not already stopped */
845                 (f->methods->f_stop_read) (f);
846         }
847
848         /* check if we are sleeping */
849         if (f->flag_sleeping) {
850                 DPRINTFN(2, "Sleeping at close!\n");
851         }
852         mtx_unlock(f->priv_mtx);
853
854         /* call close method */
855         (f->methods->f_close) (f, fflags);
856
857         DPRINTF("closed\n");
858 }
859
860 /*------------------------------------------------------------------------*
861  *      usb_open - cdev callback
862  *------------------------------------------------------------------------*/
863 static int
864 usb_open(struct cdev *dev, int fflags, int devtype, struct thread *td)
865 {
866         struct usb_fs_privdata* pd = (struct usb_fs_privdata*)dev->si_drv1;
867         struct usb_cdev_refdata refs;
868         struct usb_cdev_privdata *cpd;
869         int err, ep;
870
871         DPRINTFN(2, "%s fflags=0x%08x\n", devtoname(dev), fflags);
872
873         KASSERT(fflags & (FREAD|FWRITE), ("invalid open flags"));
874         if (((fflags & FREAD) && !(pd->mode & FREAD)) ||
875             ((fflags & FWRITE) && !(pd->mode & FWRITE))) {
876                 DPRINTFN(2, "access mode not supported\n");
877                 return (EPERM);
878         }
879
880         cpd = malloc(sizeof(*cpd), M_USBDEV, M_WAITOK | M_ZERO);
881         ep = cpd->ep_addr = pd->ep_addr;
882
883         usb_loc_fill(pd, cpd);
884         err = usb_ref_device(cpd, &refs, 1);
885         if (err) {
886                 DPRINTFN(2, "cannot ref device\n");
887                 free(cpd, M_USBDEV);
888                 return (ENXIO);
889         }
890         cpd->fflags = fflags;   /* access mode for open lifetime */
891
892         /* create FIFOs, if any */
893         err = usb_fifo_create(cpd, &refs);
894         /* check for error */
895         if (err) {
896                 DPRINTFN(2, "cannot create fifo\n");
897                 usb_unref_device(cpd, &refs);
898                 free(cpd, M_USBDEV);
899                 return (err);
900         }
901         if (fflags & FREAD) {
902                 err = usb_fifo_open(cpd, refs.rxfifo, fflags);
903                 if (err) {
904                         DPRINTFN(2, "read open failed\n");
905                         usb_unref_device(cpd, &refs);
906                         free(cpd, M_USBDEV);
907                         return (err);
908                 }
909         }
910         if (fflags & FWRITE) {
911                 err = usb_fifo_open(cpd, refs.txfifo, fflags);
912                 if (err) {
913                         DPRINTFN(2, "write open failed\n");
914                         if (fflags & FREAD) {
915                                 usb_fifo_close(refs.rxfifo, fflags);
916                         }
917                         usb_unref_device(cpd, &refs);
918                         free(cpd, M_USBDEV);
919                         return (err);
920                 }
921         }
922         usb_unref_device(cpd, &refs);
923         devfs_set_cdevpriv(cpd, usb_close);
924
925         return (0);
926 }
927
928 /*------------------------------------------------------------------------*
929  *      usb_close - cdev callback
930  *------------------------------------------------------------------------*/
931 static void
932 usb_close(void *arg)
933 {
934         struct usb_cdev_refdata refs;
935         struct usb_cdev_privdata *cpd = arg;
936         int err;
937
938         DPRINTFN(2, "cpd=%p\n", cpd);
939
940         err = usb_ref_device(cpd, &refs,
941             2 /* uref and allow detached state */);
942         if (err) {
943                 DPRINTFN(2, "Cannot grab USB reference when "
944                     "closing USB file handle\n");
945                 goto done;
946         }
947         if (cpd->fflags & FREAD) {
948                 usb_fifo_close(refs.rxfifo, cpd->fflags);
949         }
950         if (cpd->fflags & FWRITE) {
951                 usb_fifo_close(refs.txfifo, cpd->fflags);
952         }
953         usb_unref_device(cpd, &refs);
954 done:
955         free(cpd, M_USBDEV);
956 }
957
958 static void
959 usb_dev_init(void *arg)
960 {
961         mtx_init(&usb_ref_lock, "USB ref mutex", NULL, MTX_DEF);
962         sx_init(&usb_sym_lock, "USB sym mutex");
963         TAILQ_INIT(&usb_sym_head);
964
965         /* check the UGEN methods */
966         usb_fifo_check_methods(&usb_ugen_methods);
967 }
968
969 SYSINIT(usb_dev_init, SI_SUB_KLD, SI_ORDER_FIRST, usb_dev_init, NULL);
970
971 static void
972 usb_dev_init_post(void *arg)
973 {
974         /*
975          * Create /dev/usb - this is needed for usbconfig(8), which
976          * needs a well-known device name to access.
977          */
978         usb_dev = make_dev(&usb_static_devsw, 0, UID_ROOT, GID_OPERATOR,
979             0644, USB_DEVICE_NAME);
980         if (usb_dev == NULL) {
981                 DPRINTFN(0, "Could not create usb bus device\n");
982         }
983 }
984
985 SYSINIT(usb_dev_init_post, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, usb_dev_init_post, NULL);
986
987 static void
988 usb_dev_uninit(void *arg)
989 {
990         if (usb_dev != NULL) {
991                 destroy_dev(usb_dev);
992                 usb_dev = NULL;
993         }
994         mtx_destroy(&usb_ref_lock);
995         sx_destroy(&usb_sym_lock);
996 }
997
998 SYSUNINIT(usb_dev_uninit, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb_dev_uninit, NULL);
999
1000 static int
1001 usb_ioctl_f_sub(struct usb_fifo *f, u_long cmd, void *addr,
1002     struct thread *td)
1003 {
1004         int error = 0;
1005
1006         switch (cmd) {
1007         case FIODTYPE:
1008                 *(int *)addr = 0;       /* character device */
1009                 break;
1010
1011         case FIONBIO:
1012                 /* handled by upper FS layer */
1013                 break;
1014
1015         case FIOASYNC:
1016                 if (*(int *)addr) {
1017                         if (f->async_p != NULL) {
1018                                 error = EBUSY;
1019                                 break;
1020                         }
1021                         f->async_p = USB_TD_GET_PROC(td);
1022                 } else {
1023                         f->async_p = NULL;
1024                 }
1025                 break;
1026
1027                 /* XXX this is not the most general solution */
1028         case TIOCSPGRP:
1029                 if (f->async_p == NULL) {
1030                         error = EINVAL;
1031                         break;
1032                 }
1033                 if (*(int *)addr != USB_PROC_GET_GID(f->async_p)) {
1034                         error = EPERM;
1035                         break;
1036                 }
1037                 break;
1038         default:
1039                 return (ENOIOCTL);
1040         }
1041         DPRINTFN(3, "cmd 0x%lx = %d\n", cmd, error);
1042         return (error);
1043 }
1044
1045 /*------------------------------------------------------------------------*
1046  *      usb_ioctl - cdev callback
1047  *------------------------------------------------------------------------*/
1048 static int
1049 usb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread* td)
1050 {
1051         struct usb_cdev_refdata refs;
1052         struct usb_cdev_privdata* cpd;
1053         struct usb_fifo *f;
1054         int fflags;
1055         int err;
1056
1057         DPRINTFN(2, "cmd=0x%lx\n", cmd);
1058
1059         err = devfs_get_cdevpriv((void **)&cpd);
1060         if (err != 0)
1061                 return (err);
1062
1063         /* 
1064          * Performance optimisation: We try to check for IOCTL's that
1065          * don't need the USB reference first. Then we grab the USB
1066          * reference if we need it!
1067          */
1068         err = usb_ref_device(cpd, &refs, 0 /* no uref */ );
1069         if (err)
1070                 return (ENXIO);
1071
1072         fflags = cpd->fflags;
1073
1074         f = NULL;                       /* set default value */
1075         err = ENOIOCTL;                 /* set default value */
1076
1077         if (fflags & FWRITE) {
1078                 f = refs.txfifo;
1079                 err = usb_ioctl_f_sub(f, cmd, addr, td);
1080         }
1081         if (fflags & FREAD) {
1082                 f = refs.rxfifo;
1083                 err = usb_ioctl_f_sub(f, cmd, addr, td);
1084         }
1085         KASSERT(f != NULL, ("fifo not found"));
1086         if (err != ENOIOCTL)
1087                 goto done;
1088
1089         err = (f->methods->f_ioctl) (f, cmd, addr, fflags);
1090
1091         DPRINTFN(2, "f_ioctl cmd 0x%lx = %d\n", cmd, err);
1092
1093         if (err != ENOIOCTL)
1094                 goto done;
1095
1096         if (usb_usb_ref_device(cpd, &refs)) {
1097                 err = ENXIO;
1098                 goto done;
1099         }
1100
1101         err = (f->methods->f_ioctl_post) (f, cmd, addr, fflags);
1102
1103         DPRINTFN(2, "f_ioctl_post cmd 0x%lx = %d\n", cmd, err);
1104
1105         if (err == ENOIOCTL)
1106                 err = ENOTTY;
1107
1108         if (err)
1109                 goto done;
1110
1111         /* Wait for re-enumeration, if any */
1112
1113         while (f->udev->re_enumerate_wait != USB_RE_ENUM_DONE) {
1114
1115                 usb_unref_device(cpd, &refs);
1116
1117                 usb_pause_mtx(NULL, hz / 128);
1118
1119                 if (usb_ref_device(cpd, &refs, 1 /* need uref */)) {
1120                         err = ENXIO;
1121                         goto done;
1122                 }
1123         }
1124
1125 done:
1126         usb_unref_device(cpd, &refs);
1127         return (err);
1128 }
1129
1130 static void
1131 usb_filter_detach(struct knote *kn)
1132 {
1133         struct usb_fifo *f = kn->kn_hook;
1134         knlist_remove(&f->selinfo.si_note, kn, 0);
1135 }
1136
1137 static int
1138 usb_filter_write(struct knote *kn, long hint)
1139 {
1140         struct usb_cdev_privdata* cpd;
1141         struct usb_fifo *f;
1142         struct usb_mbuf *m;
1143
1144         DPRINTFN(2, "\n");
1145
1146         f = kn->kn_hook;
1147
1148         mtx_assert(f->priv_mtx, MA_OWNED);
1149
1150         cpd = f->curr_cpd;
1151         if (cpd == NULL) {
1152                 m = (void *)1;
1153         } else if (f->fs_ep_max == 0) {
1154                 if (f->flag_iserror) {
1155                         /* we got an error */
1156                         m = (void *)1;
1157                 } else {
1158                         if (f->queue_data == NULL) {
1159                                 /*
1160                                  * start write transfer, if not
1161                                  * already started
1162                                  */
1163                                 (f->methods->f_start_write) (f);
1164                         }
1165                         /* check if any packets are available */
1166                         USB_IF_POLL(&f->free_q, m);
1167                 }
1168         } else {
1169                 if (f->flag_iscomplete) {
1170                         m = (void *)1;
1171                 } else {
1172                         m = NULL;
1173                 }
1174         }
1175         return (m ? 1 : 0);
1176 }
1177
1178 static int
1179 usb_filter_read(struct knote *kn, long hint)
1180 {
1181         struct usb_cdev_privdata* cpd;
1182         struct usb_fifo *f;
1183         struct usb_mbuf *m;
1184
1185         DPRINTFN(2, "\n");
1186
1187         f = kn->kn_hook;
1188
1189         mtx_assert(f->priv_mtx, MA_OWNED);
1190
1191         cpd = f->curr_cpd;
1192         if (cpd == NULL) {
1193                 m = (void *)1;
1194         } else if (f->fs_ep_max == 0) {
1195                 if (f->flag_iserror) {
1196                         /* we have an error */
1197                         m = (void *)1;
1198                 } else {
1199                         if (f->queue_data == NULL) {
1200                                 /*
1201                                  * start read transfer, if not
1202                                  * already started
1203                                  */
1204                                 (f->methods->f_start_read) (f);
1205                         }
1206                         /* check if any packets are available */
1207                         USB_IF_POLL(&f->used_q, m);
1208
1209                         /* start reading data, if any */
1210                         if (m == NULL)
1211                                 (f->methods->f_start_read) (f);
1212                 }
1213         } else {
1214                 if (f->flag_iscomplete) {
1215                         m = (void *)1;
1216                 } else {
1217                         m = NULL;
1218                 }
1219         }
1220         return (m ? 1 : 0);
1221 }
1222
1223 static struct filterops usb_filtops_write = {
1224         .f_isfd = 1,
1225         .f_detach = usb_filter_detach,
1226         .f_event = usb_filter_write,
1227 };
1228
1229 static struct filterops usb_filtops_read = {
1230         .f_isfd = 1,
1231         .f_detach = usb_filter_detach,
1232         .f_event = usb_filter_read,
1233 };
1234
1235
1236 /* ARGSUSED */
1237 static int
1238 usb_kqfilter(struct cdev* dev, struct knote *kn)
1239 {
1240         struct usb_cdev_refdata refs;
1241         struct usb_cdev_privdata* cpd;
1242         struct usb_fifo *f;
1243         int fflags;
1244         int err = EINVAL;
1245
1246         DPRINTFN(2, "\n");
1247
1248         if (devfs_get_cdevpriv((void **)&cpd) != 0 ||
1249             usb_ref_device(cpd, &refs, 0) != 0)
1250                 return (ENXIO);
1251
1252         fflags = cpd->fflags;
1253
1254         /* Figure out who needs service */
1255         switch (kn->kn_filter) {
1256         case EVFILT_WRITE:
1257                 if (fflags & FWRITE) {
1258                         f = refs.txfifo;
1259                         kn->kn_fop = &usb_filtops_write;
1260                         err = 0;
1261                 }
1262                 break;
1263         case EVFILT_READ:
1264                 if (fflags & FREAD) {
1265                         f = refs.rxfifo;
1266                         kn->kn_fop = &usb_filtops_read;
1267                         err = 0;
1268                 }
1269                 break;
1270         default:
1271                 err = EOPNOTSUPP;
1272                 break;
1273         }
1274
1275         if (err == 0) {
1276                 kn->kn_hook = f;
1277                 mtx_lock(f->priv_mtx);
1278                 knlist_add(&f->selinfo.si_note, kn, 1);
1279                 mtx_unlock(f->priv_mtx);
1280         }
1281
1282         usb_unref_device(cpd, &refs);
1283         return (err);
1284 }
1285
1286 /* ARGSUSED */
1287 static int
1288 usb_poll(struct cdev* dev, int events, struct thread* td)
1289 {
1290         struct usb_cdev_refdata refs;
1291         struct usb_cdev_privdata* cpd;
1292         struct usb_fifo *f;
1293         struct usb_mbuf *m;
1294         int fflags, revents;
1295
1296         if (devfs_get_cdevpriv((void **)&cpd) != 0 ||
1297             usb_ref_device(cpd, &refs, 0) != 0)
1298                 return (events &
1299                     (POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM));
1300
1301         fflags = cpd->fflags;
1302
1303         /* Figure out who needs service */
1304         revents = 0;
1305         if ((events & (POLLOUT | POLLWRNORM)) &&
1306             (fflags & FWRITE)) {
1307
1308                 f = refs.txfifo;
1309
1310                 mtx_lock(f->priv_mtx);
1311
1312                 if (!refs.is_usbfs) {
1313                         if (f->flag_iserror) {
1314                                 /* we got an error */
1315                                 m = (void *)1;
1316                         } else {
1317                                 if (f->queue_data == NULL) {
1318                                         /*
1319                                          * start write transfer, if not
1320                                          * already started
1321                                          */
1322                                         (f->methods->f_start_write) (f);
1323                                 }
1324                                 /* check if any packets are available */
1325                                 USB_IF_POLL(&f->free_q, m);
1326                         }
1327                 } else {
1328                         if (f->flag_iscomplete) {
1329                                 m = (void *)1;
1330                         } else {
1331                                 m = NULL;
1332                         }
1333                 }
1334
1335                 if (m) {
1336                         revents |= events & (POLLOUT | POLLWRNORM);
1337                 } else {
1338                         f->flag_isselect = 1;
1339                         selrecord(td, &f->selinfo);
1340                 }
1341
1342                 mtx_unlock(f->priv_mtx);
1343         }
1344         if ((events & (POLLIN | POLLRDNORM)) &&
1345             (fflags & FREAD)) {
1346
1347                 f = refs.rxfifo;
1348
1349                 mtx_lock(f->priv_mtx);
1350
1351                 if (!refs.is_usbfs) {
1352                         if (f->flag_iserror) {
1353                                 /* we have an error */
1354                                 m = (void *)1;
1355                         } else {
1356                                 if (f->queue_data == NULL) {
1357                                         /*
1358                                          * start read transfer, if not
1359                                          * already started
1360                                          */
1361                                         (f->methods->f_start_read) (f);
1362                                 }
1363                                 /* check if any packets are available */
1364                                 USB_IF_POLL(&f->used_q, m);
1365                         }
1366                 } else {
1367                         if (f->flag_iscomplete) {
1368                                 m = (void *)1;
1369                         } else {
1370                                 m = NULL;
1371                         }
1372                 }
1373
1374                 if (m) {
1375                         revents |= events & (POLLIN | POLLRDNORM);
1376                 } else {
1377                         f->flag_isselect = 1;
1378                         selrecord(td, &f->selinfo);
1379
1380                         if (!refs.is_usbfs) {
1381                                 /* start reading data */
1382                                 (f->methods->f_start_read) (f);
1383                         }
1384                 }
1385
1386                 mtx_unlock(f->priv_mtx);
1387         }
1388         usb_unref_device(cpd, &refs);
1389         return (revents);
1390 }
1391
1392 static int
1393 usb_read(struct cdev *dev, struct uio *uio, int ioflag)
1394 {
1395         struct usb_cdev_refdata refs;
1396         struct usb_cdev_privdata* cpd;
1397         struct usb_fifo *f;
1398         struct usb_mbuf *m;
1399         int fflags;
1400         int resid;
1401         int io_len;
1402         int err;
1403         uint8_t tr_data = 0;
1404
1405         err = devfs_get_cdevpriv((void **)&cpd);
1406         if (err != 0)
1407                 return (err);
1408
1409         err = usb_ref_device(cpd, &refs, 0 /* no uref */ );
1410         if (err) {
1411                 return (ENXIO);
1412         }
1413         fflags = cpd->fflags;
1414
1415         f = refs.rxfifo;
1416         if (f == NULL) {
1417                 /* should not happen */
1418                 usb_unref_device(cpd, &refs);
1419                 return (EPERM);
1420         }
1421
1422         resid = uio->uio_resid;
1423
1424         mtx_lock(f->priv_mtx);
1425
1426         /* check for permanent read error */
1427         if (f->flag_iserror) {
1428                 err = EIO;
1429                 goto done;
1430         }
1431         /* check if USB-FS interface is active */
1432         if (refs.is_usbfs) {
1433                 /*
1434                  * The queue is used for events that should be
1435                  * retrieved using the "USB_FS_COMPLETE" ioctl.
1436                  */
1437                 err = EINVAL;
1438                 goto done;
1439         }
1440         while (uio->uio_resid > 0) {
1441
1442                 USB_IF_DEQUEUE(&f->used_q, m);
1443
1444                 if (m == NULL) {
1445
1446                         /* start read transfer, if not already started */
1447
1448                         (f->methods->f_start_read) (f);
1449
1450                         if (ioflag & IO_NDELAY) {
1451                                 if (tr_data) {
1452                                         /* return length before error */
1453                                         break;
1454                                 }
1455                                 err = EWOULDBLOCK;
1456                                 break;
1457                         }
1458                         DPRINTF("sleeping\n");
1459
1460                         err = usb_fifo_wait(f);
1461                         if (err) {
1462                                 break;
1463                         }
1464                         continue;
1465                 }
1466                 if (f->methods->f_filter_read) {
1467                         /*
1468                          * Sometimes it is convenient to process data at the
1469                          * expense of a userland process instead of a kernel
1470                          * process.
1471                          */
1472                         (f->methods->f_filter_read) (f, m);
1473                 }
1474                 tr_data = 1;
1475
1476                 io_len = MIN(m->cur_data_len, uio->uio_resid);
1477
1478                 DPRINTFN(2, "transfer %d bytes from %p\n",
1479                     io_len, m->cur_data_ptr);
1480
1481                 err = usb_fifo_uiomove(f,
1482                     m->cur_data_ptr, io_len, uio);
1483
1484                 m->cur_data_len -= io_len;
1485                 m->cur_data_ptr += io_len;
1486
1487                 if (m->cur_data_len == 0) {
1488
1489                         uint8_t last_packet;
1490
1491                         last_packet = m->last_packet;
1492
1493                         USB_IF_ENQUEUE(&f->free_q, m);
1494
1495                         if (last_packet) {
1496                                 /* keep framing */
1497                                 break;
1498                         }
1499                 } else {
1500                         USB_IF_PREPEND(&f->used_q, m);
1501                 }
1502
1503                 if (err) {
1504                         break;
1505                 }
1506         }
1507 done:
1508         mtx_unlock(f->priv_mtx);
1509
1510         usb_unref_device(cpd, &refs);
1511
1512         return (err);
1513 }
1514
1515 static int
1516 usb_write(struct cdev *dev, struct uio *uio, int ioflag)
1517 {
1518         struct usb_cdev_refdata refs;
1519         struct usb_cdev_privdata* cpd;
1520         struct usb_fifo *f;
1521         struct usb_mbuf *m;
1522         uint8_t *pdata;
1523         int fflags;
1524         int resid;
1525         int io_len;
1526         int err;
1527         uint8_t tr_data = 0;
1528
1529         DPRINTFN(2, "\n");
1530
1531         err = devfs_get_cdevpriv((void **)&cpd);
1532         if (err != 0)
1533                 return (err);
1534
1535         err = usb_ref_device(cpd, &refs, 0 /* no uref */ );
1536         if (err) {
1537                 return (ENXIO);
1538         }
1539         fflags = cpd->fflags;
1540
1541         f = refs.txfifo;
1542         if (f == NULL) {
1543                 /* should not happen */
1544                 usb_unref_device(cpd, &refs);
1545                 return (EPERM);
1546         }
1547         resid = uio->uio_resid;
1548
1549         mtx_lock(f->priv_mtx);
1550
1551         /* check for permanent write error */
1552         if (f->flag_iserror) {
1553                 err = EIO;
1554                 goto done;
1555         }
1556         /* check if USB-FS interface is active */
1557         if (refs.is_usbfs) {
1558                 /*
1559                  * The queue is used for events that should be
1560                  * retrieved using the "USB_FS_COMPLETE" ioctl.
1561                  */
1562                 err = EINVAL;
1563                 goto done;
1564         }
1565         if (f->queue_data == NULL) {
1566                 /* start write transfer, if not already started */
1567                 (f->methods->f_start_write) (f);
1568         }
1569         /* we allow writing zero length data */
1570         do {
1571                 USB_IF_DEQUEUE(&f->free_q, m);
1572
1573                 if (m == NULL) {
1574
1575                         if (ioflag & IO_NDELAY) {
1576                                 if (tr_data) {
1577                                         /* return length before error */
1578                                         break;
1579                                 }
1580                                 err = EWOULDBLOCK;
1581                                 break;
1582                         }
1583                         DPRINTF("sleeping\n");
1584
1585                         err = usb_fifo_wait(f);
1586                         if (err) {
1587                                 break;
1588                         }
1589                         continue;
1590                 }
1591                 tr_data = 1;
1592
1593                 if (f->flag_have_fragment == 0) {
1594                         USB_MBUF_RESET(m);
1595                         io_len = m->cur_data_len;
1596                         pdata = m->cur_data_ptr;
1597                         if (io_len > uio->uio_resid)
1598                                 io_len = uio->uio_resid;
1599                         m->cur_data_len = io_len;
1600                 } else {
1601                         io_len = m->max_data_len - m->cur_data_len;
1602                         pdata = m->cur_data_ptr + m->cur_data_len;
1603                         if (io_len > uio->uio_resid)
1604                                 io_len = uio->uio_resid;
1605                         m->cur_data_len += io_len;
1606                 }
1607
1608                 DPRINTFN(2, "transfer %d bytes to %p\n",
1609                     io_len, pdata);
1610
1611                 err = usb_fifo_uiomove(f, pdata, io_len, uio);
1612
1613                 if (err) {
1614                         f->flag_have_fragment = 0;
1615                         USB_IF_ENQUEUE(&f->free_q, m);
1616                         break;
1617                 }
1618
1619                 /* check if the buffer is ready to be transmitted */
1620
1621                 if ((f->flag_write_defrag == 0) ||
1622                     (m->cur_data_len == m->max_data_len)) {
1623                         f->flag_have_fragment = 0;
1624
1625                         /*
1626                          * Check for write filter:
1627                          *
1628                          * Sometimes it is convenient to process data
1629                          * at the expense of a userland process
1630                          * instead of a kernel process.
1631                          */
1632                         if (f->methods->f_filter_write) {
1633                                 (f->methods->f_filter_write) (f, m);
1634                         }
1635
1636                         /* Put USB mbuf in the used queue */
1637                         USB_IF_ENQUEUE(&f->used_q, m);
1638
1639                         /* Start writing data, if not already started */
1640                         (f->methods->f_start_write) (f);
1641                 } else {
1642                         /* Wait for more data or close */
1643                         f->flag_have_fragment = 1;
1644                         USB_IF_PREPEND(&f->free_q, m);
1645                 }
1646
1647         } while (uio->uio_resid > 0);
1648 done:
1649         mtx_unlock(f->priv_mtx);
1650
1651         usb_unref_device(cpd, &refs);
1652
1653         return (err);
1654 }
1655
1656 int
1657 usb_static_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
1658     struct thread *td)
1659 {
1660         union {
1661                 struct usb_read_dir *urd;
1662                 void* data;
1663         } u;
1664         int err;
1665
1666         u.data = data;
1667         switch (cmd) {
1668                 case USB_READ_DIR:
1669                         err = usb_read_symlink(u.urd->urd_data,
1670                             u.urd->urd_startentry, u.urd->urd_maxlen);
1671                         break;
1672                 case USB_DEV_QUIRK_GET:
1673                 case USB_QUIRK_NAME_GET:
1674                 case USB_DEV_QUIRK_ADD:
1675                 case USB_DEV_QUIRK_REMOVE:
1676                         err = usb_quirk_ioctl_p(cmd, data, fflag, td);
1677                         break;
1678                 case USB_GET_TEMPLATE:
1679                         *(int *)data = usb_template;
1680                         err = 0;
1681                         break;
1682                 case USB_SET_TEMPLATE:
1683                         err = priv_check(curthread, PRIV_DRIVER);
1684                         if (err)
1685                                 break;
1686                         usb_template = *(int *)data;
1687                         break;
1688                 default:
1689                         err = ENOTTY;
1690                         break;
1691         }
1692         return (err);
1693 }
1694
1695 static int
1696 usb_fifo_uiomove(struct usb_fifo *f, void *cp,
1697     int n, struct uio *uio)
1698 {
1699         int error;
1700
1701         mtx_unlock(f->priv_mtx);
1702
1703         /*
1704          * "uiomove()" can sleep so one needs to make a wrapper,
1705          * exiting the mutex and checking things:
1706          */
1707         error = uiomove(cp, n, uio);
1708
1709         mtx_lock(f->priv_mtx);
1710
1711         return (error);
1712 }
1713
1714 int
1715 usb_fifo_wait(struct usb_fifo *f)
1716 {
1717         int err;
1718
1719         mtx_assert(f->priv_mtx, MA_OWNED);
1720
1721         if (f->flag_iserror) {
1722                 /* we are gone */
1723                 return (EIO);
1724         }
1725         f->flag_sleeping = 1;
1726
1727         err = cv_wait_sig(&f->cv_io, f->priv_mtx);
1728
1729         if (f->flag_iserror) {
1730                 /* we are gone */
1731                 err = EIO;
1732         }
1733         return (err);
1734 }
1735
1736 void
1737 usb_fifo_signal(struct usb_fifo *f)
1738 {
1739         if (f->flag_sleeping) {
1740                 f->flag_sleeping = 0;
1741                 cv_broadcast(&f->cv_io);
1742         }
1743 }
1744
1745 void
1746 usb_fifo_wakeup(struct usb_fifo *f)
1747 {
1748         usb_fifo_signal(f);
1749
1750         KNOTE_LOCKED(&f->selinfo.si_note, 0);
1751
1752         if (f->flag_isselect) {
1753                 selwakeup(&f->selinfo);
1754                 f->flag_isselect = 0;
1755         }
1756         if (f->async_p != NULL) {
1757                 PROC_LOCK(f->async_p);
1758                 kern_psignal(f->async_p, SIGIO);
1759                 PROC_UNLOCK(f->async_p);
1760         }
1761 }
1762
1763 static int
1764 usb_fifo_dummy_open(struct usb_fifo *fifo, int fflags)
1765 {
1766         return (0);
1767 }
1768
1769 static void
1770 usb_fifo_dummy_close(struct usb_fifo *fifo, int fflags)
1771 {
1772         return;
1773 }
1774
1775 static int
1776 usb_fifo_dummy_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags)
1777 {
1778         return (ENOIOCTL);
1779 }
1780
1781 static void
1782 usb_fifo_dummy_cmd(struct usb_fifo *fifo)
1783 {
1784         fifo->flag_flushing = 0;        /* not flushing */
1785 }
1786
1787 static void
1788 usb_fifo_check_methods(struct usb_fifo_methods *pm)
1789 {
1790         /* check that all callback functions are OK */
1791
1792         if (pm->f_open == NULL)
1793                 pm->f_open = &usb_fifo_dummy_open;
1794
1795         if (pm->f_close == NULL)
1796                 pm->f_close = &usb_fifo_dummy_close;
1797
1798         if (pm->f_ioctl == NULL)
1799                 pm->f_ioctl = &usb_fifo_dummy_ioctl;
1800
1801         if (pm->f_ioctl_post == NULL)
1802                 pm->f_ioctl_post = &usb_fifo_dummy_ioctl;
1803
1804         if (pm->f_start_read == NULL)
1805                 pm->f_start_read = &usb_fifo_dummy_cmd;
1806
1807         if (pm->f_stop_read == NULL)
1808                 pm->f_stop_read = &usb_fifo_dummy_cmd;
1809
1810         if (pm->f_start_write == NULL)
1811                 pm->f_start_write = &usb_fifo_dummy_cmd;
1812
1813         if (pm->f_stop_write == NULL)
1814                 pm->f_stop_write = &usb_fifo_dummy_cmd;
1815 }
1816
1817 /*------------------------------------------------------------------------*
1818  *      usb_fifo_attach
1819  *
1820  * The following function will create a duplex FIFO.
1821  *
1822  * Return values:
1823  * 0: Success.
1824  * Else: Failure.
1825  *------------------------------------------------------------------------*/
1826 int
1827 usb_fifo_attach(struct usb_device *udev, void *priv_sc,
1828     struct mtx *priv_mtx, struct usb_fifo_methods *pm,
1829     struct usb_fifo_sc *f_sc, uint16_t unit, int16_t subunit,
1830     uint8_t iface_index, uid_t uid, gid_t gid, int mode)
1831 {
1832         struct usb_fifo *f_tx;
1833         struct usb_fifo *f_rx;
1834         char devname[32];
1835         uint8_t n;
1836
1837         f_sc->fp[USB_FIFO_TX] = NULL;
1838         f_sc->fp[USB_FIFO_RX] = NULL;
1839
1840         if (pm == NULL)
1841                 return (EINVAL);
1842
1843         /* check the methods */
1844         usb_fifo_check_methods(pm);
1845
1846         if (priv_mtx == NULL)
1847                 priv_mtx = &Giant;
1848
1849         /* search for a free FIFO slot */
1850         for (n = 0;; n += 2) {
1851
1852                 if (n == USB_FIFO_MAX) {
1853                         /* end of FIFOs reached */
1854                         return (ENOMEM);
1855                 }
1856                 /* Check for TX FIFO */
1857                 if (udev->fifo[n + USB_FIFO_TX] != NULL) {
1858                         continue;
1859                 }
1860                 /* Check for RX FIFO */
1861                 if (udev->fifo[n + USB_FIFO_RX] != NULL) {
1862                         continue;
1863                 }
1864                 break;
1865         }
1866
1867         f_tx = usb_fifo_alloc(priv_mtx);
1868         f_rx = usb_fifo_alloc(priv_mtx);
1869
1870         if ((f_tx == NULL) || (f_rx == NULL)) {
1871                 usb_fifo_free(f_tx);
1872                 usb_fifo_free(f_rx);
1873                 return (ENOMEM);
1874         }
1875         /* initialise FIFO structures */
1876
1877         f_tx->fifo_index = n + USB_FIFO_TX;
1878         f_tx->dev_ep_index = -1;
1879         f_tx->priv_sc0 = priv_sc;
1880         f_tx->methods = pm;
1881         f_tx->iface_index = iface_index;
1882         f_tx->udev = udev;
1883
1884         f_rx->fifo_index = n + USB_FIFO_RX;
1885         f_rx->dev_ep_index = -1;
1886         f_rx->priv_sc0 = priv_sc;
1887         f_rx->methods = pm;
1888         f_rx->iface_index = iface_index;
1889         f_rx->udev = udev;
1890
1891         f_sc->fp[USB_FIFO_TX] = f_tx;
1892         f_sc->fp[USB_FIFO_RX] = f_rx;
1893
1894         mtx_lock(&usb_ref_lock);
1895         udev->fifo[f_tx->fifo_index] = f_tx;
1896         udev->fifo[f_rx->fifo_index] = f_rx;
1897         mtx_unlock(&usb_ref_lock);
1898
1899         for (n = 0; n != 4; n++) {
1900
1901                 if (pm->basename[n] == NULL) {
1902                         continue;
1903                 }
1904                 if (subunit < 0) {
1905                         if (snprintf(devname, sizeof(devname),
1906                             "%s%u%s", pm->basename[n],
1907                             unit, pm->postfix[n] ?
1908                             pm->postfix[n] : "")) {
1909                                 /* ignore */
1910                         }
1911                 } else {
1912                         if (snprintf(devname, sizeof(devname),
1913                             "%s%u.%d%s", pm->basename[n],
1914                             unit, subunit, pm->postfix[n] ?
1915                             pm->postfix[n] : "")) {
1916                                 /* ignore */
1917                         }
1918                 }
1919
1920                 /*
1921                  * Distribute the symbolic links into two FIFO structures:
1922                  */
1923                 if (n & 1) {
1924                         f_rx->symlink[n / 2] =
1925                             usb_alloc_symlink(devname);
1926                 } else {
1927                         f_tx->symlink[n / 2] =
1928                             usb_alloc_symlink(devname);
1929                 }
1930
1931                 /* Create the device */
1932                 f_sc->dev = usb_make_dev(udev, devname, -1,
1933                     f_tx->fifo_index & f_rx->fifo_index,
1934                     FREAD|FWRITE, uid, gid, mode);
1935         }
1936
1937         DPRINTFN(2, "attached %p/%p\n", f_tx, f_rx);
1938         return (0);
1939 }
1940
1941 /*------------------------------------------------------------------------*
1942  *      usb_fifo_alloc_buffer
1943  *
1944  * Return values:
1945  * 0: Success
1946  * Else failure
1947  *------------------------------------------------------------------------*/
1948 int
1949 usb_fifo_alloc_buffer(struct usb_fifo *f, usb_size_t bufsize,
1950     uint16_t nbuf)
1951 {
1952         usb_fifo_free_buffer(f);
1953
1954         /* allocate an endpoint */
1955         f->free_q.ifq_maxlen = nbuf;
1956         f->used_q.ifq_maxlen = nbuf;
1957
1958         f->queue_data = usb_alloc_mbufs(
1959             M_USBDEV, &f->free_q, bufsize, nbuf);
1960
1961         if ((f->queue_data == NULL) && bufsize && nbuf) {
1962                 return (ENOMEM);
1963         }
1964         return (0);                     /* success */
1965 }
1966
1967 /*------------------------------------------------------------------------*
1968  *      usb_fifo_free_buffer
1969  *
1970  * This function will free the buffers associated with a FIFO. This
1971  * function can be called multiple times in a row.
1972  *------------------------------------------------------------------------*/
1973 void
1974 usb_fifo_free_buffer(struct usb_fifo *f)
1975 {
1976         if (f->queue_data) {
1977                 /* free old buffer */
1978                 free(f->queue_data, M_USBDEV);
1979                 f->queue_data = NULL;
1980         }
1981         /* reset queues */
1982
1983         memset(&f->free_q, 0, sizeof(f->free_q));
1984         memset(&f->used_q, 0, sizeof(f->used_q));
1985 }
1986
1987 void
1988 usb_fifo_detach(struct usb_fifo_sc *f_sc)
1989 {
1990         if (f_sc == NULL) {
1991                 return;
1992         }
1993         usb_fifo_free(f_sc->fp[USB_FIFO_TX]);
1994         usb_fifo_free(f_sc->fp[USB_FIFO_RX]);
1995
1996         f_sc->fp[USB_FIFO_TX] = NULL;
1997         f_sc->fp[USB_FIFO_RX] = NULL;
1998
1999         usb_destroy_dev(f_sc->dev);
2000
2001         f_sc->dev = NULL;
2002
2003         DPRINTFN(2, "detached %p\n", f_sc);
2004 }
2005
2006 usb_size_t
2007 usb_fifo_put_bytes_max(struct usb_fifo *f)
2008 {
2009         struct usb_mbuf *m;
2010         usb_size_t len;
2011
2012         USB_IF_POLL(&f->free_q, m);
2013
2014         if (m) {
2015                 len = m->max_data_len;
2016         } else {
2017                 len = 0;
2018         }
2019         return (len);
2020 }
2021
2022 /*------------------------------------------------------------------------*
2023  *      usb_fifo_put_data
2024  *
2025  * what:
2026  *  0 - normal operation
2027  *  1 - set last packet flag to enforce framing
2028  *------------------------------------------------------------------------*/
2029 void
2030 usb_fifo_put_data(struct usb_fifo *f, struct usb_page_cache *pc,
2031     usb_frlength_t offset, usb_frlength_t len, uint8_t what)
2032 {
2033         struct usb_mbuf *m;
2034         usb_frlength_t io_len;
2035
2036         while (len || (what == 1)) {
2037
2038                 USB_IF_DEQUEUE(&f->free_q, m);
2039
2040                 if (m) {
2041                         USB_MBUF_RESET(m);
2042
2043                         io_len = MIN(len, m->cur_data_len);
2044
2045                         usbd_copy_out(pc, offset, m->cur_data_ptr, io_len);
2046
2047                         m->cur_data_len = io_len;
2048                         offset += io_len;
2049                         len -= io_len;
2050
2051                         if ((len == 0) && (what == 1)) {
2052                                 m->last_packet = 1;
2053                         }
2054                         USB_IF_ENQUEUE(&f->used_q, m);
2055
2056                         usb_fifo_wakeup(f);
2057
2058                         if ((len == 0) || (what == 1)) {
2059                                 break;
2060                         }
2061                 } else {
2062                         break;
2063                 }
2064         }
2065 }
2066
2067 void
2068 usb_fifo_put_data_linear(struct usb_fifo *f, void *ptr,
2069     usb_size_t len, uint8_t what)
2070 {
2071         struct usb_mbuf *m;
2072         usb_size_t io_len;
2073
2074         while (len || (what == 1)) {
2075
2076                 USB_IF_DEQUEUE(&f->free_q, m);
2077
2078                 if (m) {
2079                         USB_MBUF_RESET(m);
2080
2081                         io_len = MIN(len, m->cur_data_len);
2082
2083                         memcpy(m->cur_data_ptr, ptr, io_len);
2084
2085                         m->cur_data_len = io_len;
2086                         ptr = USB_ADD_BYTES(ptr, io_len);
2087                         len -= io_len;
2088
2089                         if ((len == 0) && (what == 1)) {
2090                                 m->last_packet = 1;
2091                         }
2092                         USB_IF_ENQUEUE(&f->used_q, m);
2093
2094                         usb_fifo_wakeup(f);
2095
2096                         if ((len == 0) || (what == 1)) {
2097                                 break;
2098                         }
2099                 } else {
2100                         break;
2101                 }
2102         }
2103 }
2104
2105 uint8_t
2106 usb_fifo_put_data_buffer(struct usb_fifo *f, void *ptr, usb_size_t len)
2107 {
2108         struct usb_mbuf *m;
2109
2110         USB_IF_DEQUEUE(&f->free_q, m);
2111
2112         if (m) {
2113                 m->cur_data_len = len;
2114                 m->cur_data_ptr = ptr;
2115                 USB_IF_ENQUEUE(&f->used_q, m);
2116                 usb_fifo_wakeup(f);
2117                 return (1);
2118         }
2119         return (0);
2120 }
2121
2122 void
2123 usb_fifo_put_data_error(struct usb_fifo *f)
2124 {
2125         f->flag_iserror = 1;
2126         usb_fifo_wakeup(f);
2127 }
2128
2129 /*------------------------------------------------------------------------*
2130  *      usb_fifo_get_data
2131  *
2132  * what:
2133  *  0 - normal operation
2134  *  1 - only get one "usb_mbuf"
2135  *
2136  * returns:
2137  *  0 - no more data
2138  *  1 - data in buffer
2139  *------------------------------------------------------------------------*/
2140 uint8_t
2141 usb_fifo_get_data(struct usb_fifo *f, struct usb_page_cache *pc,
2142     usb_frlength_t offset, usb_frlength_t len, usb_frlength_t *actlen,
2143     uint8_t what)
2144 {
2145         struct usb_mbuf *m;
2146         usb_frlength_t io_len;
2147         uint8_t tr_data = 0;
2148
2149         actlen[0] = 0;
2150
2151         while (1) {
2152
2153                 USB_IF_DEQUEUE(&f->used_q, m);
2154
2155                 if (m) {
2156
2157                         tr_data = 1;
2158
2159                         io_len = MIN(len, m->cur_data_len);
2160
2161                         usbd_copy_in(pc, offset, m->cur_data_ptr, io_len);
2162
2163                         len -= io_len;
2164                         offset += io_len;
2165                         actlen[0] += io_len;
2166                         m->cur_data_ptr += io_len;
2167                         m->cur_data_len -= io_len;
2168
2169                         if ((m->cur_data_len == 0) || (what == 1)) {
2170                                 USB_IF_ENQUEUE(&f->free_q, m);
2171
2172                                 usb_fifo_wakeup(f);
2173
2174                                 if (what == 1) {
2175                                         break;
2176                                 }
2177                         } else {
2178                                 USB_IF_PREPEND(&f->used_q, m);
2179                         }
2180                 } else {
2181
2182                         if (tr_data) {
2183                                 /* wait for data to be written out */
2184                                 break;
2185                         }
2186                         if (f->flag_flushing) {
2187                                 /* check if we should send a short packet */
2188                                 if (f->flag_short != 0) {
2189                                         f->flag_short = 0;
2190                                         tr_data = 1;
2191                                         break;
2192                                 }
2193                                 /* flushing complete */
2194                                 f->flag_flushing = 0;
2195                                 usb_fifo_wakeup(f);
2196                         }
2197                         break;
2198                 }
2199                 if (len == 0) {
2200                         break;
2201                 }
2202         }
2203         return (tr_data);
2204 }
2205
2206 uint8_t
2207 usb_fifo_get_data_linear(struct usb_fifo *f, void *ptr,
2208     usb_size_t len, usb_size_t *actlen, uint8_t what)
2209 {
2210         struct usb_mbuf *m;
2211         usb_size_t io_len;
2212         uint8_t tr_data = 0;
2213
2214         actlen[0] = 0;
2215
2216         while (1) {
2217
2218                 USB_IF_DEQUEUE(&f->used_q, m);
2219
2220                 if (m) {
2221
2222                         tr_data = 1;
2223
2224                         io_len = MIN(len, m->cur_data_len);
2225
2226                         memcpy(ptr, m->cur_data_ptr, io_len);
2227
2228                         len -= io_len;
2229                         ptr = USB_ADD_BYTES(ptr, io_len);
2230                         actlen[0] += io_len;
2231                         m->cur_data_ptr += io_len;
2232                         m->cur_data_len -= io_len;
2233
2234                         if ((m->cur_data_len == 0) || (what == 1)) {
2235                                 USB_IF_ENQUEUE(&f->free_q, m);
2236
2237                                 usb_fifo_wakeup(f);
2238
2239                                 if (what == 1) {
2240                                         break;
2241                                 }
2242                         } else {
2243                                 USB_IF_PREPEND(&f->used_q, m);
2244                         }
2245                 } else {
2246
2247                         if (tr_data) {
2248                                 /* wait for data to be written out */
2249                                 break;
2250                         }
2251                         if (f->flag_flushing) {
2252                                 /* check if we should send a short packet */
2253                                 if (f->flag_short != 0) {
2254                                         f->flag_short = 0;
2255                                         tr_data = 1;
2256                                         break;
2257                                 }
2258                                 /* flushing complete */
2259                                 f->flag_flushing = 0;
2260                                 usb_fifo_wakeup(f);
2261                         }
2262                         break;
2263                 }
2264                 if (len == 0) {
2265                         break;
2266                 }
2267         }
2268         return (tr_data);
2269 }
2270
2271 uint8_t
2272 usb_fifo_get_data_buffer(struct usb_fifo *f, void **pptr, usb_size_t *plen)
2273 {
2274         struct usb_mbuf *m;
2275
2276         USB_IF_POLL(&f->used_q, m);
2277
2278         if (m) {
2279                 *plen = m->cur_data_len;
2280                 *pptr = m->cur_data_ptr;
2281
2282                 return (1);
2283         }
2284         return (0);
2285 }
2286
2287 void
2288 usb_fifo_get_data_error(struct usb_fifo *f)
2289 {
2290         f->flag_iserror = 1;
2291         usb_fifo_wakeup(f);
2292 }
2293
2294 /*------------------------------------------------------------------------*
2295  *      usb_alloc_symlink
2296  *
2297  * Return values:
2298  * NULL: Failure
2299  * Else: Pointer to symlink entry
2300  *------------------------------------------------------------------------*/
2301 struct usb_symlink *
2302 usb_alloc_symlink(const char *target)
2303 {
2304         struct usb_symlink *ps;
2305
2306         ps = malloc(sizeof(*ps), M_USBDEV, M_WAITOK);
2307         if (ps == NULL) {
2308                 return (ps);
2309         }
2310         /* XXX no longer needed */
2311         strlcpy(ps->src_path, target, sizeof(ps->src_path));
2312         ps->src_len = strlen(ps->src_path);
2313         strlcpy(ps->dst_path, target, sizeof(ps->dst_path));
2314         ps->dst_len = strlen(ps->dst_path);
2315
2316         sx_xlock(&usb_sym_lock);
2317         TAILQ_INSERT_TAIL(&usb_sym_head, ps, sym_entry);
2318         sx_unlock(&usb_sym_lock);
2319         return (ps);
2320 }
2321
2322 /*------------------------------------------------------------------------*
2323  *      usb_free_symlink
2324  *------------------------------------------------------------------------*/
2325 void
2326 usb_free_symlink(struct usb_symlink *ps)
2327 {
2328         if (ps == NULL) {
2329                 return;
2330         }
2331         sx_xlock(&usb_sym_lock);
2332         TAILQ_REMOVE(&usb_sym_head, ps, sym_entry);
2333         sx_unlock(&usb_sym_lock);
2334
2335         free(ps, M_USBDEV);
2336 }
2337
2338 /*------------------------------------------------------------------------*
2339  *      usb_read_symlink
2340  *
2341  * Return value:
2342  * 0: Success
2343  * Else: Failure
2344  *------------------------------------------------------------------------*/
2345 int
2346 usb_read_symlink(uint8_t *user_ptr, uint32_t startentry, uint32_t user_len)
2347 {
2348         struct usb_symlink *ps;
2349         uint32_t temp;
2350         uint32_t delta = 0;
2351         uint8_t len;
2352         int error = 0;
2353
2354         sx_xlock(&usb_sym_lock);
2355
2356         TAILQ_FOREACH(ps, &usb_sym_head, sym_entry) {
2357
2358                 /*
2359                  * Compute total length of source and destination symlink
2360                  * strings pluss one length byte and two NUL bytes:
2361                  */
2362                 temp = ps->src_len + ps->dst_len + 3;
2363
2364                 if (temp > 255) {
2365                         /*
2366                          * Skip entry because this length cannot fit
2367                          * into one byte:
2368                          */
2369                         continue;
2370                 }
2371                 if (startentry != 0) {
2372                         /* decrement read offset */
2373                         startentry--;
2374                         continue;
2375                 }
2376                 if (temp > user_len) {
2377                         /* out of buffer space */
2378                         break;
2379                 }
2380                 len = temp;
2381
2382                 /* copy out total length */
2383
2384                 error = copyout(&len,
2385                     USB_ADD_BYTES(user_ptr, delta), 1);
2386                 if (error) {
2387                         break;
2388                 }
2389                 delta += 1;
2390
2391                 /* copy out source string */
2392
2393                 error = copyout(ps->src_path,
2394                     USB_ADD_BYTES(user_ptr, delta), ps->src_len);
2395                 if (error) {
2396                         break;
2397                 }
2398                 len = 0;
2399                 delta += ps->src_len;
2400                 error = copyout(&len,
2401                     USB_ADD_BYTES(user_ptr, delta), 1);
2402                 if (error) {
2403                         break;
2404                 }
2405                 delta += 1;
2406
2407                 /* copy out destination string */
2408
2409                 error = copyout(ps->dst_path,
2410                     USB_ADD_BYTES(user_ptr, delta), ps->dst_len);
2411                 if (error) {
2412                         break;
2413                 }
2414                 len = 0;
2415                 delta += ps->dst_len;
2416                 error = copyout(&len,
2417                     USB_ADD_BYTES(user_ptr, delta), 1);
2418                 if (error) {
2419                         break;
2420                 }
2421                 delta += 1;
2422
2423                 user_len -= temp;
2424         }
2425
2426         /* a zero length entry indicates the end */
2427
2428         if ((user_len != 0) && (error == 0)) {
2429
2430                 len = 0;
2431
2432                 error = copyout(&len,
2433                     USB_ADD_BYTES(user_ptr, delta), 1);
2434         }
2435         sx_unlock(&usb_sym_lock);
2436         return (error);
2437 }
2438
2439 void
2440 usb_fifo_set_close_zlp(struct usb_fifo *f, uint8_t onoff)
2441 {
2442         if (f == NULL)
2443                 return;
2444
2445         /* send a Zero Length Packet, ZLP, before close */
2446         f->flag_short = onoff;
2447 }
2448
2449 void
2450 usb_fifo_set_write_defrag(struct usb_fifo *f, uint8_t onoff)
2451 {
2452         if (f == NULL)
2453                 return;
2454
2455         /* defrag written data */
2456         f->flag_write_defrag = onoff;
2457         /* reset defrag state */
2458         f->flag_have_fragment = 0;
2459 }
2460
2461 void *
2462 usb_fifo_softc(struct usb_fifo *f)
2463 {
2464         return (f->priv_sc0);
2465 }
2466 #endif  /* USB_HAVE_UGEN */