source: rtems-libbsd/freebsd/sys/dev/usb/usb_dev.c @ 3d1e767

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 3d1e767 was 3d1e767, checked in by Sebastian Huber <sebastian.huber@…>, on 04/27/16 at 08:25:22

Directly use <sys/types.h> provided by Newlib

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