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