source: rtems-libbsd/freebsd/sys/dev/usb/usb_dev.c @ 75b706f

55-freebsd-126-freebsd-12
Last change on this file since 75b706f was 75b706f, checked in by Sebastian Huber <sebastian.huber@…>, on 12/09/16 at 13:19:03

Update to FreeBSD head 2016-12-10

Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.

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