ig4 - Only enable interrupts when we want them. Otherwise keep mask at 0.
[dragonfly.git] / sys / bus / u4b / usb_dev.c
blob51c9b92e74b0b1fcc8440edbc72dedaa7010cad3
1 /* $FreeBSD: head/sys/dev/usb/usb_dev.c 272480 2014-10-03 16:09:46Z hselasky $ */
2 /*-
3 * Copyright (c) 2006-2008 Hans Petter Selasky. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
27 * usb_dev.c - An abstraction layer for creating devices under /dev/...
30 #include <sys/stdint.h>
31 #include <sys/param.h>
32 #include <sys/queue.h>
33 #include <sys/types.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/thread2.h>
37 #include <sys/bus.h>
38 #include <sys/module.h>
39 #include <sys/lock.h>
40 #include <sys/mutex.h>
41 #include <sys/condvar.h>
42 #include <sys/sysctl.h>
43 #include <sys/unistd.h>
44 #include <sys/callout.h>
45 #include <sys/malloc.h>
46 #include <sys/priv.h>
47 #include <sys/vnode.h>
48 #include <sys/conf.h>
49 #include <sys/fcntl.h>
50 #include <sys/devfs.h>
52 #include <bus/u4b/usb.h>
53 #include <bus/u4b/usb_ioctl.h>
54 #include <bus/u4b/usbdi.h>
55 #include <bus/u4b/usbdi_util.h>
57 #define USB_DEBUG_VAR usb_fifo_debug
59 #include <bus/u4b/usb_core.h>
60 #include <bus/u4b/usb_dev.h>
61 #include <bus/u4b/usb_mbuf.h>
62 #include <bus/u4b/usb_process.h>
63 #include <bus/u4b/usb_device.h>
64 #include <bus/u4b/usb_debug.h>
65 #include <bus/u4b/usb_busdma.h>
66 #include <bus/u4b/usb_generic.h>
67 #include <bus/u4b/usb_dynamic.h>
68 #include <bus/u4b/usb_util.h>
70 #include <bus/u4b/usb_controller.h>
71 #include <bus/u4b/usb_bus.h>
73 #include <sys/filio.h>
74 #include <sys/ttycom.h>
75 #include <sys/kern_syscall.h>
77 #include <machine/stdarg.h>
79 #if USB_HAVE_UGEN
81 #ifdef USB_DEBUG
82 static int usb_fifo_debug = 0;
84 static SYSCTL_NODE(_hw_usb, OID_AUTO, dev, CTLFLAG_RW, 0, "USB device");
85 SYSCTL_INT(_hw_usb_dev, OID_AUTO, debug, CTLFLAG_RW,
86 &usb_fifo_debug, 0, "Debug Level");
88 TUNABLE_INT("hw.usb.dev.debug", &usb_fifo_debug);
89 #endif
91 #define USB_UCRED struct ucred *ucred,
93 /* prototypes */
95 static int usb_fifo_open(struct usb_cdev_privdata *,
96 struct usb_fifo *, int);
97 static void usb_fifo_close(struct usb_fifo *, int);
98 static void usb_dev_init(void *);
99 static void usb_dev_init_post(void *);
100 static void usb_dev_uninit(void *);
101 static int usb_fifo_uiomove(struct usb_fifo *, void *, int,
102 struct uio *);
103 static void usb_fifo_check_methods(struct usb_fifo_methods *);
104 static struct usb_fifo *usb_fifo_alloc(struct lock *lock);
105 static struct usb_endpoint *usb_dev_get_ep(struct usb_device *, uint8_t,
106 uint8_t);
107 static void usb_loc_fill(struct usb_fs_privdata *,
108 struct usb_cdev_privdata *);
109 static usb_error_t usb_ref_device(struct usb_cdev_privdata *, struct usb_cdev_refdata *, int);
110 static usb_error_t usb_usb_ref_device(struct usb_cdev_privdata *, struct usb_cdev_refdata *);
111 static void usb_unref_device(struct usb_cdev_privdata *, struct usb_cdev_refdata *);
113 static void usb_cdevpriv_dtor(void *cd);
115 static void usb_filter_detach(struct knote *kn);
116 static int usb_filter_read(struct knote *kn, long hint);
117 static int usb_filter_write(struct knote *kn, long hint);
119 static d_open_t usb_open;
120 static d_close_t usb_close;
121 static d_ioctl_t usb_ioctl;
122 static d_read_t usb_read;
123 static d_write_t usb_write;
124 static d_kqfilter_t usb_kqfilter;
126 static d_ioctl_t usb_static_ioctl;
127 static d_open_t usb_static_open;
128 static d_close_t usb_static_close;
130 static usb_fifo_open_t usb_fifo_dummy_open;
131 static usb_fifo_close_t usb_fifo_dummy_close;
132 static usb_fifo_ioctl_t usb_fifo_dummy_ioctl;
133 static usb_fifo_cmd_t usb_fifo_dummy_cmd;
135 /* character device structure used for devices (/dev/ugenX.Y and /dev/uXXX) */
136 struct dev_ops usb_ops = {
137 { "usbdev", 0, D_MPSAFE | D_MEM },
138 .d_open = usb_open,
139 .d_close = usb_close,
140 .d_ioctl = usb_ioctl,
141 .d_read = usb_read,
142 .d_write = usb_write,
143 .d_kqfilter = usb_kqfilter
146 static struct cdev* usb_dev = NULL;
148 /* character device structure used for /bus/u4b */
149 static struct dev_ops usb_static_ops = {
150 { "usb", 0, D_MPSAFE | D_MEM },
151 .d_open = usb_static_open,
152 .d_close = usb_static_close,
153 .d_ioctl = usb_static_ioctl,
156 static TAILQ_HEAD(, usb_symlink) usb_sym_head;
157 static struct lock usb_sym_lock;
159 struct lock usb_ref_lock;
161 #if 0
162 static struct kqinfo usb_kqevent;
163 #endif
165 /*------------------------------------------------------------------------*
166 * usb_loc_fill
168 * This is used to fill out a usb_cdev_privdata structure based on the
169 * device's address as contained in usb_fs_privdata.
170 *------------------------------------------------------------------------*/
171 static void
172 usb_loc_fill(struct usb_fs_privdata* pd, struct usb_cdev_privdata *cpd)
174 cpd->bus_index = pd->bus_index;
175 cpd->dev_index = pd->dev_index;
176 cpd->ep_addr = pd->ep_addr;
177 cpd->fifo_index = pd->fifo_index;
180 /*------------------------------------------------------------------------*
181 * usb_ref_device
183 * This function is used to atomically refer an USB device by its
184 * device location. If this function returns success the USB device
185 * will not dissappear until the USB device is unreferenced.
187 * Return values:
188 * 0: Success, refcount incremented on the given USB device.
189 * Else: Failure.
190 *------------------------------------------------------------------------*/
191 static usb_error_t
192 usb_ref_device(struct usb_cdev_privdata *cpd,
193 struct usb_cdev_refdata *crd, int need_uref)
195 struct usb_fifo **ppf;
196 struct usb_fifo *f;
198 DPRINTFN(2, "cpd=%p need uref=%d\n", cpd, need_uref);
200 /* clear all refs */
201 memset(crd, 0, sizeof(*crd));
203 lockmgr(&usb_ref_lock, LK_EXCLUSIVE);
204 cpd->bus = devclass_get_softc(usb_devclass_ptr, cpd->bus_index);
205 if (cpd->bus == NULL) {
206 DPRINTFN(2, "no bus at %u\n", cpd->bus_index);
207 goto error;
209 cpd->udev = cpd->bus->devices[cpd->dev_index];
210 if (cpd->udev == NULL) {
211 DPRINTFN(2, "no device at %u\n", cpd->dev_index);
212 goto error;
214 if (cpd->udev->state == USB_STATE_DETACHED &&
215 (need_uref != 2)) {
216 DPRINTFN(2, "device is detached\n");
217 goto error;
219 if (need_uref) {
220 DPRINTFN(2, "ref udev - needed\n");
222 if (cpd->udev->refcount == USB_DEV_REF_MAX) {
223 DPRINTFN(2, "no dev ref\n");
224 goto error;
226 cpd->udev->refcount++;
228 lockmgr(&usb_ref_lock, LK_RELEASE);
231 * We need to grab the sx-lock before grabbing the
232 * FIFO refs to avoid deadlock at detach!
234 crd->do_unlock = usbd_enum_lock(cpd->udev);
236 lockmgr(&usb_ref_lock, LK_EXCLUSIVE);
239 * Set "is_uref" after grabbing the default SX lock
241 crd->is_uref = 1;
244 /* check if we are doing an open */
245 if (cpd->fflags == 0) {
246 /* use zero defaults */
247 } else {
248 /* check for write */
249 if (cpd->fflags & FWRITE) {
250 ppf = cpd->udev->fifo;
251 f = ppf[cpd->fifo_index + USB_FIFO_TX];
252 crd->txfifo = f;
253 crd->is_write = 1; /* ref */
254 if (f == NULL || f->refcount == USB_FIFO_REF_MAX)
255 goto error;
256 if (f->curr_cpd != cpd)
257 goto error;
258 /* check if USB-FS is active */
259 if (f->fs_ep_max != 0) {
260 crd->is_usbfs = 1;
264 /* check for read */
265 if (cpd->fflags & FREAD) {
266 ppf = cpd->udev->fifo;
267 f = ppf[cpd->fifo_index + USB_FIFO_RX];
268 crd->rxfifo = f;
269 crd->is_read = 1; /* ref */
270 if (f == NULL || f->refcount == USB_FIFO_REF_MAX)
271 goto error;
272 if (f->curr_cpd != cpd)
273 goto error;
274 /* check if USB-FS is active */
275 if (f->fs_ep_max != 0) {
276 crd->is_usbfs = 1;
281 /* when everything is OK we increment the refcounts */
282 if (crd->is_write) {
283 DPRINTFN(2, "ref write\n");
284 crd->txfifo->refcount++;
286 if (crd->is_read) {
287 DPRINTFN(2, "ref read\n");
288 crd->rxfifo->refcount++;
290 lockmgr(&usb_ref_lock, LK_RELEASE);
292 return (0);
294 error:
295 if (crd->do_unlock)
296 usbd_enum_unlock(cpd->udev);
298 if (crd->is_uref) {
299 if (--(cpd->udev->refcount) == 0)
300 cv_broadcast(&cpd->udev->ref_cv);
302 lockmgr(&usb_ref_lock, LK_RELEASE);
303 DPRINTFN(2, "fail\n");
305 /* clear all refs */
306 memset(crd, 0, sizeof(*crd));
308 return (USB_ERR_INVAL);
311 /*------------------------------------------------------------------------*
312 * usb_usb_ref_device
314 * This function is used to upgrade an USB reference to include the
315 * USB device reference on a USB location.
317 * Return values:
318 * 0: Success, refcount incremented on the given USB device.
319 * Else: Failure.
320 *------------------------------------------------------------------------*/
321 static usb_error_t
322 usb_usb_ref_device(struct usb_cdev_privdata *cpd,
323 struct usb_cdev_refdata *crd)
326 * Check if we already got an USB reference on this location:
328 if (crd->is_uref)
329 return (0); /* success */
332 * To avoid deadlock at detach we need to drop the FIFO ref
333 * and re-acquire a new ref!
335 usb_unref_device(cpd, crd);
337 return (usb_ref_device(cpd, crd, 1 /* need uref */));
340 /*------------------------------------------------------------------------*
341 * usb_unref_device
343 * This function will release the reference count by one unit for the
344 * given USB device.
345 *------------------------------------------------------------------------*/
346 static void
347 usb_unref_device(struct usb_cdev_privdata *cpd,
348 struct usb_cdev_refdata *crd)
351 DPRINTFN(2, "cpd=%p is_uref=%d\n", cpd, crd->is_uref);
353 if (crd->do_unlock)
354 usbd_enum_unlock(cpd->udev);
356 lockmgr(&usb_ref_lock, LK_EXCLUSIVE);
357 if (crd->is_read) {
358 if (--(crd->rxfifo->refcount) == 0) {
359 cv_signal(&crd->rxfifo->cv_drain);
361 crd->is_read = 0;
363 if (crd->is_write) {
364 if (--(crd->txfifo->refcount) == 0) {
365 cv_signal(&crd->txfifo->cv_drain);
367 crd->is_write = 0;
369 if (crd->is_uref) {
370 crd->is_uref = 0;
371 if (--(cpd->udev->refcount) == 0)
372 cv_broadcast(&cpd->udev->ref_cv);
374 lockmgr(&usb_ref_lock, LK_RELEASE);
377 static struct usb_fifo *
378 usb_fifo_alloc(struct lock *lock)
380 struct usb_fifo *f;
382 f = kmalloc(sizeof(*f), M_USBDEV, M_WAITOK | M_ZERO);
383 if (f != NULL) {
384 cv_init(&f->cv_io, "FIFO-IO");
385 cv_init(&f->cv_drain, "FIFO-DRAIN");
386 f->priv_lock = lock;
387 f->refcount = 1;
388 /* mpf: knlist_init_mtx? the lock is used here in free */
390 return (f);
393 /*------------------------------------------------------------------------*
394 * usb_fifo_create
395 *------------------------------------------------------------------------*/
396 static int
397 usb_fifo_create(struct usb_cdev_privdata *cpd,
398 struct usb_cdev_refdata *crd)
400 struct usb_device *udev = cpd->udev;
401 struct usb_fifo *f;
402 struct usb_endpoint *ep;
403 uint8_t n;
404 uint8_t is_tx;
405 uint8_t is_rx;
406 uint8_t no_null;
407 uint8_t is_busy;
408 int e = cpd->ep_addr;
410 is_tx = (cpd->fflags & FWRITE) ? 1 : 0;
411 is_rx = (cpd->fflags & FREAD) ? 1 : 0;
412 no_null = 1;
413 is_busy = 0;
415 /* Preallocated FIFO */
416 if (e < 0) {
417 DPRINTFN(5, "Preallocated FIFO\n");
418 if (is_tx) {
419 f = udev->fifo[cpd->fifo_index + USB_FIFO_TX];
420 if (f == NULL)
421 return (EINVAL);
422 crd->txfifo = f;
424 if (is_rx) {
425 f = udev->fifo[cpd->fifo_index + USB_FIFO_RX];
426 if (f == NULL)
427 return (EINVAL);
428 crd->rxfifo = f;
430 return (0);
433 KASSERT(e >= 0 && e <= 15, ("endpoint %d out of range", e));
435 /* search for a free FIFO slot */
436 DPRINTFN(5, "Endpoint device, searching for 0x%02x\n", e);
437 for (n = 0;; n += 2) {
439 if (n == USB_FIFO_MAX) {
440 if (no_null) {
441 no_null = 0;
442 n = 0;
443 } else {
444 /* end of FIFOs reached */
445 DPRINTFN(5, "out of FIFOs\n");
446 return (ENOMEM);
449 /* Check for TX FIFO */
450 if (is_tx) {
451 f = udev->fifo[n + USB_FIFO_TX];
452 if (f != NULL) {
453 if (f->dev_ep_index != e) {
454 /* wrong endpoint index */
455 continue;
457 if (f->curr_cpd != NULL) {
458 /* FIFO is opened */
459 is_busy = 1;
460 continue;
462 } else if (no_null) {
463 continue;
466 /* Check for RX FIFO */
467 if (is_rx) {
468 f = udev->fifo[n + USB_FIFO_RX];
469 if (f != NULL) {
470 if (f->dev_ep_index != e) {
471 /* wrong endpoint index */
472 continue;
474 if (f->curr_cpd != NULL) {
475 /* FIFO is opened */
476 is_busy = 1;
477 continue;
479 } else if (no_null) {
480 continue;
483 break;
486 if (no_null == 0) {
487 if (e >= (USB_EP_MAX / 2)) {
488 /* we don't create any endpoints in this range */
489 DPRINTFN(5, "ep out of range\n");
490 return (is_busy ? EBUSY : EINVAL);
494 if ((e != 0) && is_busy) {
496 * Only the default control endpoint is allowed to be
497 * opened multiple times!
499 DPRINTFN(5, "busy\n");
500 return (EBUSY);
503 /* Check TX FIFO */
504 if (is_tx &&
505 (udev->fifo[n + USB_FIFO_TX] == NULL)) {
506 ep = usb_dev_get_ep(udev, e, USB_FIFO_TX);
507 DPRINTFN(5, "dev_get_endpoint(%d, 0x%x)\n", e, USB_FIFO_TX);
508 if (ep == NULL) {
509 DPRINTFN(5, "dev_get_endpoint returned NULL\n");
510 return (EINVAL);
512 f = usb_fifo_alloc(&udev->device_lock);
513 if (f == NULL) {
514 DPRINTFN(5, "could not alloc tx fifo\n");
515 return (ENOMEM);
517 /* update some fields */
518 f->fifo_index = n + USB_FIFO_TX;
519 f->dev_ep_index = e;
520 f->priv_sc0 = ep;
521 f->methods = &usb_ugen_methods;
522 f->iface_index = ep->iface_index;
523 f->udev = udev;
524 lockmgr(&usb_ref_lock, LK_EXCLUSIVE);
525 udev->fifo[n + USB_FIFO_TX] = f;
526 lockmgr(&usb_ref_lock, LK_RELEASE);
528 /* Check RX FIFO */
529 if (is_rx &&
530 (udev->fifo[n + USB_FIFO_RX] == NULL)) {
532 ep = usb_dev_get_ep(udev, e, USB_FIFO_RX);
533 DPRINTFN(5, "dev_get_endpoint(%d, 0x%x)\n", e, USB_FIFO_RX);
534 if (ep == NULL) {
535 DPRINTFN(5, "dev_get_endpoint returned NULL\n");
536 return (EINVAL);
538 f = usb_fifo_alloc(&udev->device_lock);
539 if (f == NULL) {
540 DPRINTFN(5, "could not alloc rx fifo\n");
541 return (ENOMEM);
543 /* update some fields */
544 f->fifo_index = n + USB_FIFO_RX;
545 f->dev_ep_index = e;
546 f->priv_sc0 = ep;
547 f->methods = &usb_ugen_methods;
548 f->iface_index = ep->iface_index;
549 f->udev = udev;
550 lockmgr(&usb_ref_lock, LK_EXCLUSIVE);
551 udev->fifo[n + USB_FIFO_RX] = f;
552 lockmgr(&usb_ref_lock, LK_RELEASE);
554 if (is_tx) {
555 crd->txfifo = udev->fifo[n + USB_FIFO_TX];
557 if (is_rx) {
558 crd->rxfifo = udev->fifo[n + USB_FIFO_RX];
560 /* fill out fifo index */
561 DPRINTFN(5, "fifo index = %d\n", n);
562 cpd->fifo_index = n;
564 /* complete */
566 return (0);
569 void
570 usb_fifo_free(struct usb_fifo *f)
572 uint8_t n;
574 if (f == NULL) {
575 /* be NULL safe */
576 return;
578 /* destroy symlink devices, if any */
579 for (n = 0; n != 2; n++) {
580 if (f->symlink[n]) {
581 usb_free_symlink(f->symlink[n]);
582 f->symlink[n] = NULL;
585 lockmgr(&usb_ref_lock, LK_EXCLUSIVE);
587 /* delink ourselves to stop calls from userland */
588 if ((f->fifo_index < USB_FIFO_MAX) &&
589 (f->udev != NULL) &&
590 (f->udev->fifo[f->fifo_index] == f)) {
591 f->udev->fifo[f->fifo_index] = NULL;
592 } else {
593 DPRINTFN(0, "USB FIFO %p has not been linked\n", f);
596 /* decrease refcount */
597 f->refcount--;
598 /* need to wait until all callers have exited */
599 while (f->refcount != 0) {
600 lockmgr(&usb_ref_lock, LK_RELEASE); /* avoid LOR */
601 lockmgr(f->priv_lock, LK_EXCLUSIVE);
602 /* prevent write flush, if any */
603 f->flag_iserror = 1;
604 /* get I/O thread out of any sleep state */
605 if (f->flag_sleeping) {
606 f->flag_sleeping = 0;
607 cv_broadcast(&f->cv_io);
609 lockmgr(f->priv_lock, LK_RELEASE);
610 lockmgr(&usb_ref_lock, LK_EXCLUSIVE);
613 * Check if the "f->refcount" variable reached zero
614 * during the unlocked time before entering wait:
616 if (f->refcount == 0)
617 break;
619 /* wait for sync */
620 cv_wait(&f->cv_drain, &usb_ref_lock);
622 lockmgr(&usb_ref_lock, LK_RELEASE);
624 /* take care of closing the device here, if any */
625 usb_fifo_close(f, 0);
627 cv_destroy(&f->cv_io);
628 cv_destroy(&f->cv_drain);
630 #if 0 /* XXX mpf */
631 knlist_clear(&f->selinfo.si_note, 0);
632 seldrain(&f->selinfo);
633 knlist_destroy(&f->selinfo.si_note);
634 #endif
635 kfree(f, M_USBDEV);
638 static struct usb_endpoint *
639 usb_dev_get_ep(struct usb_device *udev, uint8_t ep_index, uint8_t dir)
641 struct usb_endpoint *ep;
642 uint8_t ep_dir;
644 if (ep_index == 0) {
645 ep = &udev->ctrl_ep;
646 } else {
647 if (dir == USB_FIFO_RX) {
648 if (udev->flags.usb_mode == USB_MODE_HOST) {
649 ep_dir = UE_DIR_IN;
650 } else {
651 ep_dir = UE_DIR_OUT;
653 } else {
654 if (udev->flags.usb_mode == USB_MODE_HOST) {
655 ep_dir = UE_DIR_OUT;
656 } else {
657 ep_dir = UE_DIR_IN;
660 ep = usbd_get_ep_by_addr(udev, ep_index | ep_dir);
663 if (ep == NULL) {
664 /* if the endpoint does not exist then return */
665 return (NULL);
667 if (ep->edesc == NULL) {
668 /* invalid endpoint */
669 return (NULL);
671 return (ep); /* success */
674 /*------------------------------------------------------------------------*
675 * usb_fifo_open
677 * Returns:
678 * 0: Success
679 * Else: Failure
680 *------------------------------------------------------------------------*/
681 static int
682 usb_fifo_open(struct usb_cdev_privdata *cpd,
683 struct usb_fifo *f, int fflags)
685 int err;
687 if (f == NULL) {
688 /* no FIFO there */
689 DPRINTFN(2, "no FIFO\n");
690 return (ENXIO);
692 /* remove FWRITE and FREAD flags */
693 fflags &= ~(FWRITE | FREAD);
695 /* set correct file flags */
696 if ((f->fifo_index & 1) == USB_FIFO_TX) {
697 fflags |= FWRITE;
698 } else {
699 fflags |= FREAD;
702 /* check if we are already opened */
703 /* we don't need any locks when checking this variable */
704 if (f->curr_cpd != NULL) {
705 err = EBUSY;
706 goto done;
709 /* reset short flag before open */
710 f->flag_short = 0;
712 /* call open method */
713 err = (f->methods->f_open) (f, fflags);
714 if (err) {
715 goto done;
717 lockmgr(f->priv_lock, LK_EXCLUSIVE);
719 /* reset sleep flag */
720 f->flag_sleeping = 0;
722 /* reset error flag */
723 f->flag_iserror = 0;
725 /* reset complete flag */
726 f->flag_iscomplete = 0;
728 /* reset select flag */
729 f->flag_isselect = 0;
731 /* reset flushing flag */
732 f->flag_flushing = 0;
734 /* reset ASYNC proc flag */
735 f->async_p = NULL;
737 lockmgr(&usb_ref_lock, LK_EXCLUSIVE);
738 /* flag the fifo as opened to prevent others */
739 f->curr_cpd = cpd;
740 lockmgr(&usb_ref_lock, LK_RELEASE);
742 /* reset queue */
743 usb_fifo_reset(f);
745 lockmgr(f->priv_lock, LK_RELEASE);
746 done:
747 return (err);
750 /*------------------------------------------------------------------------*
751 * usb_fifo_reset
752 *------------------------------------------------------------------------*/
753 void
754 usb_fifo_reset(struct usb_fifo *f)
756 struct usb_mbuf *m;
758 if (f == NULL) {
759 return;
761 while (1) {
762 USB_IF_DEQUEUE(&f->used_q, m);
763 if (m) {
764 USB_IF_ENQUEUE(&f->free_q, m);
765 } else {
766 break;
769 /* reset have fragment flag */
770 f->flag_have_fragment = 0;
773 /*------------------------------------------------------------------------*
774 * usb_fifo_close
775 *------------------------------------------------------------------------*/
776 static void
777 usb_fifo_close(struct usb_fifo *f, int fflags)
779 int err;
781 /* check if we are not opened */
782 if (f->curr_cpd == NULL) {
783 /* nothing to do - already closed */
784 return;
786 lockmgr(f->priv_lock, LK_EXCLUSIVE);
788 /* clear current cdev private data pointer */
789 lockmgr(&usb_ref_lock, LK_EXCLUSIVE);
790 f->curr_cpd = NULL;
791 lockmgr(&usb_ref_lock, LK_RELEASE);
793 /* check if we are selected */
794 if (f->flag_isselect) {
795 KNOTE(&f->selinfo.ki_note, 0);
796 wakeup(&f->selinfo.ki_note);
798 f->flag_isselect = 0;
800 /* check if a thread wants SIGIO */
801 if (f->async_p != NULL && lwkt_trytoken(&f->async_p->p_token)) {
802 ksignal(f->async_p, SIGIO);
803 lwkt_reltoken(&f->async_p->p_token);
804 f->async_p = NULL;
806 /* remove FWRITE and FREAD flags */
807 fflags &= ~(FWRITE | FREAD);
809 /* flush written data, if any */
810 if ((f->fifo_index & 1) == USB_FIFO_TX) {
812 if (!f->flag_iserror) {
814 /* set flushing flag */
815 f->flag_flushing = 1;
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);
827 /* start write transfer, if not already started */
828 (f->methods->f_start_write) (f);
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_wait_sig(&f->cv_io, f->priv_lock);
836 if (err) {
837 DPRINTF("signal received\n");
838 break;
842 fflags |= FWRITE;
844 /* stop write transfer, if not already stopped */
845 (f->methods->f_stop_write) (f);
846 } else {
847 fflags |= FREAD;
849 /* stop write transfer, if not already stopped */
850 (f->methods->f_stop_read) (f);
853 /* check if we are sleeping */
854 if (f->flag_sleeping) {
855 DPRINTFN(2, "Sleeping at close!\n");
857 lockmgr(f->priv_lock, LK_RELEASE);
859 /* call close method */
860 (f->methods->f_close) (f, fflags);
862 DPRINTF("closed\n");
865 /*------------------------------------------------------------------------*
866 * usb_open - cdev callback
867 *------------------------------------------------------------------------*/
868 static int
869 usb_open(struct dev_open_args *ap)
871 struct cdev *dev = ap->a_head.a_dev;
872 int fflags = ap->a_oflags;
873 struct usb_fs_privdata* pd = (struct usb_fs_privdata*)dev->si_drv1;
874 struct usb_cdev_refdata refs;
875 struct usb_cdev_privdata *cpd;
876 int err, ep;
878 DPRINTFN(2, "%s fflags=0x%08x\n", devtoname(dev), fflags);
880 KASSERT(fflags & (FREAD|FWRITE), ("invalid open flags"));
881 if (((fflags & FREAD) && !(pd->mode & FREAD)) ||
882 ((fflags & FWRITE) && !(pd->mode & FWRITE))) {
883 DPRINTFN(2, "access mode not supported\n");
884 return (EPERM);
887 cpd = kmalloc(sizeof(*cpd), M_USBDEV, M_WAITOK | M_ZERO);
888 ep = cpd->ep_addr = pd->ep_addr;
890 usb_loc_fill(pd, cpd);
891 err = usb_ref_device(cpd, &refs, 1);
892 if (err) {
893 DPRINTFN(2, "cannot ref device\n");
894 kfree(cpd, M_USBDEV);
895 return (ENXIO);
897 cpd->fflags = fflags; /* access mode for open lifetime */
899 /* create FIFOs, if any */
900 err = usb_fifo_create(cpd, &refs);
901 /* check for error */
902 if (err) {
903 DPRINTFN(2, "cannot create fifo\n");
904 usb_unref_device(cpd, &refs);
905 kfree(cpd, M_USBDEV);
906 return (err);
908 if (fflags & FREAD) {
909 err = usb_fifo_open(cpd, refs.rxfifo, fflags);
910 if (err) {
911 DPRINTFN(2, "read open failed\n");
912 usb_unref_device(cpd, &refs);
913 kfree(cpd, M_USBDEV);
914 return (err);
917 if (fflags & FWRITE) {
918 err = usb_fifo_open(cpd, refs.txfifo, fflags);
919 if (err) {
920 DPRINTFN(2, "write open failed\n");
921 if (fflags & FREAD) {
922 usb_fifo_close(refs.rxfifo, fflags);
924 usb_unref_device(cpd, &refs);
925 kfree(cpd, M_USBDEV);
926 return (err);
929 usb_unref_device(cpd, &refs);
930 err = devfs_set_cdevpriv(ap->a_fp, cpd, &usb_cdevpriv_dtor);
931 DPRINTFN(2, "fp=%p cpd=%p\n", ap->a_fp, cpd);
932 if(err) {
933 DPRINTFN(2, "devfs_set_cdevpriv failed in %s\n", __func__);
934 kfree(cpd, M_USBDEV);
935 return(err);
938 return (0);
942 * Dummy stub.
944 static int
945 usb_close(struct dev_close_args *ap)
947 DPRINTFN(2, "usb_close called\n");
948 return 0;
951 /*------------------------------------------------------------------------*
952 * usb_close - cdev callback
953 *------------------------------------------------------------------------*/
954 static void
955 usb_cdevpriv_dtor(void *cd)
957 struct usb_cdev_privdata *cpd = (struct usb_cdev_privdata *)cd;
958 struct usb_cdev_refdata refs;
959 int err;
961 DPRINTF("dtor called on %p\n", cpd);
963 err = usb_ref_device(cpd, &refs, 2);
964 if (err) {
965 DPRINTFN(0, "Cannot grab USB reference when "
966 "closing USB file handle\n");
967 goto done;
969 if (cpd->fflags & FREAD) {
970 usb_fifo_close(refs.rxfifo, cpd->fflags);
972 if (cpd->fflags & FWRITE) {
973 usb_fifo_close(refs.txfifo, cpd->fflags);
975 usb_unref_device(cpd, &refs);
976 done:
977 kfree(cpd, M_USBDEV);
980 static void
981 usb_dev_init(void *arg)
983 lockinit(&usb_ref_lock, "USB ref mutex", 0, 0);
984 lockinit(&usb_sym_lock, "USB sym mutex", 0, 0);
985 TAILQ_INIT(&usb_sym_head);
987 /* check the UGEN methods */
988 usb_fifo_check_methods(&usb_ugen_methods);
991 /* XXX SI_SUB_KLD? */
992 SYSINIT(usb_dev_init, SI_SUB_PRE_DRIVERS, SI_ORDER_FIRST, usb_dev_init, NULL);
994 static void
995 usb_dev_init_post(void *arg)
998 * Create /dev/usb - this is needed for usbconfig(8), which
999 * needs a well-known device name to access.
1001 usb_dev = make_dev(&usb_static_ops, 0, UID_ROOT, GID_OPERATOR,
1002 0644, USB_DEVICE_NAME);
1003 if (usb_dev == NULL) {
1004 DPRINTFN(0, "Could not create usb bus device\n");
1008 SYSINIT(usb_dev_init_post, SI_SUB_DRIVERS, SI_ORDER_FIRST, usb_dev_init_post,
1009 NULL);
1011 static void
1012 usb_dev_uninit(void *arg)
1014 if (usb_dev != NULL) {
1015 destroy_dev(usb_dev);
1016 usb_dev = NULL;
1018 lockuninit(&usb_ref_lock);
1019 lockuninit(&usb_sym_lock);
1022 SYSUNINIT(usb_dev_uninit, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb_dev_uninit, NULL);
1024 static int
1025 usb_ioctl_f_sub(struct usb_fifo *f, u_long cmd, void *addr,
1026 struct thread *td)
1028 int error = 0;
1030 switch (cmd) {
1031 case FIODTYPE:
1032 *(int *)addr = 0; /* character device */
1033 break;
1035 case FIONBIO:
1036 /* handled by upper FS layer */
1037 break;
1039 case FIOASYNC:
1040 if (*(int *)addr) {
1041 if (f->async_p != NULL) {
1042 error = EBUSY;
1043 break;
1045 f->async_p = USB_TD_GET_PROC(td);
1046 } else {
1047 f->async_p = NULL;
1049 break;
1051 /* XXX this is not the most general solution */
1052 case TIOCSPGRP:
1053 if (f->async_p == NULL) {
1054 error = EINVAL;
1055 break;
1057 if (*(int *)addr != USB_PROC_GET_GID(f->async_p)) {
1058 error = EPERM;
1059 break;
1061 break;
1062 default:
1063 return (ENOIOCTL);
1065 DPRINTFN(3, "cmd 0x%lx = %d\n", cmd, error);
1066 return (error);
1069 /*------------------------------------------------------------------------*
1070 * usb_ioctl - cdev callback
1071 *------------------------------------------------------------------------*/
1072 static int
1073 usb_ioctl(struct dev_ioctl_args *ap)
1075 u_long cmd = ap->a_cmd;
1076 caddr_t addr = ap->a_data;
1077 struct thread *td = curthread;
1078 struct usb_cdev_refdata refs;
1079 struct usb_cdev_privdata* cpd;
1080 struct usb_fifo *f;
1081 int fflags;
1082 int err;
1084 DPRINTFN(2, "cmd=0x%lx\n", cmd);
1086 err = devfs_get_cdevpriv(ap->a_fp, (void **)&cpd);
1087 if (err != 0)
1088 return (err);
1091 * Performance optimisation: We try to check for IOCTL's that
1092 * don't need the USB reference first. Then we grab the USB
1093 * reference if we need it!
1095 err = usb_ref_device(cpd, &refs, 0 /* no uref */ );
1096 if (err)
1097 return (ENXIO);
1099 fflags = cpd->fflags;
1101 f = NULL; /* set default value */
1102 err = ENOIOCTL; /* set default value */
1104 if (fflags & FWRITE) {
1105 f = refs.txfifo;
1106 err = usb_ioctl_f_sub(f, cmd, addr, td);
1108 if (fflags & FREAD) {
1109 f = refs.rxfifo;
1110 err = usb_ioctl_f_sub(f, cmd, addr, td);
1112 KASSERT(f != NULL, ("fifo not found"));
1113 if (err != ENOIOCTL)
1114 goto done;
1116 err = (f->methods->f_ioctl) (f, cmd, addr, fflags);
1118 DPRINTFN(2, "f_ioctl cmd 0x%lx = %d\n", cmd, err);
1120 if (err != ENOIOCTL)
1121 goto done;
1123 if (usb_usb_ref_device(cpd, &refs)) {
1124 err = ENXIO;
1125 goto done;
1128 err = (f->methods->f_ioctl_post) (f, cmd, addr, fflags);
1130 DPRINTFN(2, "f_ioctl_post cmd 0x%lx = %d\n", cmd, err);
1132 if (err == ENOIOCTL)
1133 err = ENOTTY;
1135 if (err)
1136 goto done;
1138 /* Wait for re-enumeration, if any */
1140 while (f->udev->re_enumerate_wait != USB_RE_ENUM_DONE) {
1142 usb_unref_device(cpd, &refs);
1144 usb_pause_mtx(NULL, hz / 128);
1146 if (usb_ref_device(cpd, &refs, 1 /* need uref */)) {
1147 err = ENXIO;
1148 goto done;
1152 done:
1153 usb_unref_device(cpd, &refs);
1154 return (err);
1157 static struct filterops usb_filtops_read =
1158 { FILTEROP_ISFD | FILTEROP_MPSAFE, NULL, usb_filter_detach, usb_filter_read };
1160 static struct filterops usb_filtops_write =
1161 { FILTEROP_ISFD | FILTEROP_MPSAFE, NULL, usb_filter_detach, usb_filter_write };
1163 static int
1164 usb_kqfilter(struct dev_kqfilter_args *ap)
1166 struct knote *kn = ap->a_kn;
1167 struct klist *klist;
1168 struct usb_fifo *f;
1169 struct usb_cdev_refdata refs;
1170 struct usb_cdev_privdata* cpd;
1171 int fflags, err;
1173 err = devfs_get_cdevpriv(ap->a_fp, (void **)&cpd);
1174 if (err != 0)
1175 return (ENXIO);
1176 err = usb_ref_device(cpd, &refs, 0 /* no uref */ );
1177 if (err != 0)
1178 return (ENXIO);
1180 ap->a_result = 0;
1181 fflags = cpd->fflags;
1183 switch(kn->kn_filter) {
1184 case EVFILT_READ:
1185 f = refs.rxfifo;
1186 if(fflags & FREAD) {
1187 lockmgr(f->priv_lock, LK_EXCLUSIVE);
1188 f->flag_isselect = 1;
1189 lockmgr(f->priv_lock, LK_RELEASE);
1190 kn->kn_fop = &usb_filtops_read;
1191 } else {
1192 ap->a_result = EOPNOTSUPP;
1193 return(0);
1195 break;
1196 case EVFILT_WRITE:
1197 f = refs.txfifo;
1198 if(fflags & FWRITE) {
1199 lockmgr(f->priv_lock, LK_EXCLUSIVE);
1200 f->flag_isselect = 1;
1201 lockmgr(f->priv_lock, LK_RELEASE);
1202 kn->kn_fop = &usb_filtops_write;
1203 } else {
1204 ap->a_result = EOPNOTSUPP;
1205 return(0);
1207 break;
1208 default:
1209 DPRINTF("unsupported kqfilter requested\n");
1210 ap->a_result = EOPNOTSUPP;
1211 usb_unref_device(cpd, &refs);
1212 return(0);
1215 kn->kn_hook = (caddr_t)cpd;
1216 klist = &f->selinfo.ki_note;
1217 knote_insert(klist, kn);
1219 usb_unref_device(cpd, &refs);
1220 return(0);
1223 static void
1224 usb_filter_detach(struct knote *kn)
1226 struct usb_fifo *f;
1227 struct usb_cdev_privdata* cpd = (struct usb_cdev_privdata *)kn->kn_hook;
1228 struct usb_cdev_refdata refs;
1229 struct klist *klist;
1230 int err;
1232 DPRINTF("\n");
1234 * The associated cpd has vanished.
1236 if(cpd == NULL) {
1237 return;
1240 err = usb_ref_device(cpd, &refs, 0 /* no uref */ );
1241 if (err) {
1242 return;
1245 switch(kn->kn_filter) {
1246 case EVFILT_READ:
1247 f = refs.rxfifo;
1248 break;
1249 case EVFILT_WRITE:
1250 f = refs.txfifo;
1251 break;
1252 default:
1253 /* Better safe than sorry? (mpf) */
1254 panic("Trying to detach unknown filter");
1255 break;
1258 lockmgr(f->priv_lock, LK_EXCLUSIVE);
1260 /* removed check for f->flag_isselect, because
1261 it is racing completion in the filter leading
1262 to invalid data in the fifo knote list */
1263 klist = &f->selinfo.ki_note;
1264 knote_remove(klist, kn);
1265 f->flag_isselect = 0;
1267 lockmgr(f->priv_lock, LK_RELEASE);
1269 usb_unref_device(cpd, &refs);
1272 static int
1273 usb_filter_read(struct knote *kn, long hint)
1275 struct usb_fifo *f;
1276 struct usb_cdev_privdata *cpd = (struct usb_cdev_privdata *)kn->kn_hook;
1277 struct usb_cdev_refdata refs;
1278 struct usb_mbuf *m;
1279 int err,locked,ready = 0;
1281 DPRINTF("\n");
1284 * The associated file has been closed.
1286 if (cpd == NULL) {
1287 kn->kn_flags |= EV_ERROR;
1288 return (ready);
1291 err = usb_ref_device(cpd, &refs, 0 /* no uref */ );
1292 if (err) {
1293 kn->kn_flags |= EV_ERROR;
1294 return (ready);
1296 /* XXX mpf
1297 For some reason this function is called both
1298 with the priv_lock held and with the priv_lock
1299 not held. We need to find out from where and
1300 why */
1301 f = refs.rxfifo;
1303 locked = lockowned(f->priv_lock);
1304 if(!locked)
1305 lockmgr(f->priv_lock, LK_EXCLUSIVE);
1307 if (!refs.is_usbfs) {
1308 if (f->flag_iserror) {
1309 /* we got an error */
1310 kn->kn_flags |= EV_ERROR;
1311 ready = 1;
1312 } else {
1313 /* start read if not running */
1314 (f->methods->f_start_read)(f);
1315 /* check if any packets are available */
1316 USB_IF_POLL(&f->used_q, m);
1317 if (m) {
1318 ready = 1;
1321 } else {
1322 if (f->flag_iscomplete) {
1323 ready = 1;
1324 } else {
1325 ready = 0;
1329 if(!locked)
1330 lockmgr(f->priv_lock, LK_RELEASE);
1332 usb_unref_device(cpd, &refs);
1334 DPRINTFN(3,"ready %d\n", ready);
1335 return(ready);
1338 static int
1339 usb_filter_write(struct knote *kn, long hint)
1341 struct usb_fifo *f;
1342 struct usb_cdev_privdata *cpd = (struct usb_cdev_privdata *)kn->kn_hook;
1343 struct usb_cdev_refdata refs;
1344 struct usb_mbuf *m;
1345 int err,locked,ready = 0;
1347 DPRINTF("\n");
1350 * The associated file has been closed.
1352 if (cpd == NULL) {
1353 kn->kn_flags |= EV_ERROR;
1354 return (ready);
1357 err = usb_ref_device(cpd, &refs, 0 /* no uref */ );
1358 if (err) {
1359 kn->kn_flags |= EV_ERROR;
1360 return (ready);
1362 /* XXX mpf
1363 For some reason this function is called both
1364 with the priv_lock held and with the priv_lock
1365 not held. We need to find out from where and
1366 why */
1367 f = refs.txfifo;
1369 locked = lockowned(f->priv_lock);
1370 if(!locked)
1371 lockmgr(f->priv_lock, LK_EXCLUSIVE);
1373 if (!refs.is_usbfs) {
1374 if (f->flag_iserror) {
1375 /* we got an error */
1376 kn->kn_flags |= EV_ERROR;
1377 ready = 1;
1378 } else {
1379 if (f->queue_data == NULL) {
1381 * start write transfer, if not
1382 * already started
1384 (f->methods->f_start_write) (f);
1386 /* check if any packets are available */
1387 USB_IF_POLL(&f->free_q, m);
1388 if (m)
1389 ready = 1;
1391 } else {
1392 if (f->flag_iscomplete) {
1393 ready = 1;
1394 } else {
1395 ready = 0;
1399 if(!locked)
1400 lockmgr(f->priv_lock, LK_RELEASE);
1402 usb_unref_device(cpd, &refs);
1404 DPRINTFN(3,"ready %d\n", ready);
1405 return(ready);
1408 #if 0
1409 /* This is implemented above using kqfilter */
1410 /* ARGSUSED */
1411 static int
1412 usb_poll(struct cdev* dev, int events, struct thread* td)
1414 struct usb_cdev_refdata refs;
1415 struct usb_cdev_privdata* cpd;
1416 struct usb_fifo *f;
1417 struct usb_mbuf *m;
1418 int fflags, revents;
1420 if (devfs_get_cdevpriv((void **)&cpd) != 0 ||
1421 usb_ref_device(cpd, &refs, 0) != 0)
1422 return (events &
1423 (POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM));
1425 fflags = cpd->fflags;
1427 /* Figure out who needs service */
1428 revents = 0;
1429 if ((events & (POLLOUT | POLLWRNORM)) &&
1430 (fflags & FWRITE)) {
1432 f = refs.txfifo;
1434 lockmgr(f->priv_lock, LK_EXCLUSIVE);
1436 if (!refs.is_usbfs) {
1437 if (f->flag_iserror) {
1438 /* we got an error */
1439 m = (void *)1;
1440 } else {
1441 if (f->queue_data == NULL) {
1443 * start write transfer, if not
1444 * already started
1446 (f->methods->f_start_write) (f);
1448 /* check if any packets are available */
1449 USB_IF_POLL(&f->free_q, m);
1451 } else {
1452 if (f->flag_iscomplete) {
1453 m = (void *)1;
1454 } else {
1455 m = NULL;
1459 if (m) {
1460 revents |= events & (POLLOUT | POLLWRNORM);
1461 } else {
1462 f->flag_isselect = 1;
1463 selrecord(td, &f->selinfo);
1466 lockmgr(f->priv_lock);
1468 if ((events & (POLLIN | POLLRDNORM)) &&
1469 (fflags & FREAD)) {
1471 f = refs.rxfifo;
1473 lockmgr(f->priv_lock, LK_EXCLUSIVE);
1475 if (!refs.is_usbfs) {
1476 if (f->flag_iserror) {
1477 /* we have and error */
1478 m = (void *)1;
1479 } else {
1480 if (f->queue_data == NULL) {
1482 * start read transfer, if not
1483 * already started
1485 (f->methods->f_start_read) (f);
1487 /* check if any packets are available */
1488 USB_IF_POLL(&f->used_q, m);
1490 } else {
1491 if (f->flag_iscomplete) {
1492 m = (void *)1;
1493 } else {
1494 m = NULL;
1498 if (m) {
1499 revents |= events & (POLLIN | POLLRDNORM);
1500 } else {
1501 f->flag_isselect = 1;
1502 selrecord(td, &f->selinfo);
1504 if (!refs.is_usbfs) {
1505 /* start reading data */
1506 (f->methods->f_start_read) (f);
1510 lockmgr(f->priv_lock, LK_RELEASE);
1512 usb_unref_device(cpd, &refs);
1513 return (revents);
1515 #endif
1517 static int
1518 usb_read(struct dev_read_args *ap)
1520 struct uio *uio = ap->a_uio;
1521 int ioflag = ap->a_ioflag;
1522 struct usb_cdev_refdata refs;
1523 struct usb_cdev_privdata* cpd;
1524 struct usb_fifo *f;
1525 struct usb_mbuf *m;
1526 int fflags;
1527 int resid;
1528 int io_len;
1529 int err;
1530 uint8_t tr_data = 0;
1532 err = devfs_get_cdevpriv(ap->a_fp, (void **)&cpd);
1533 if (err != 0)
1534 return (err);
1535 err = usb_ref_device(cpd, &refs, 0 /* no uref */ );
1536 if (err) {
1537 return (ENXIO);
1539 fflags = cpd->fflags;
1541 f = refs.rxfifo;
1542 if (f == NULL) {
1543 /* should not happen */
1544 usb_unref_device(cpd, &refs);
1545 return (EPERM);
1548 resid = uio->uio_resid;
1550 lockmgr(f->priv_lock, LK_EXCLUSIVE);
1552 /* check for permanent read error */
1553 if (f->flag_iserror) {
1554 err = EIO;
1555 goto done;
1557 /* check if USB-FS interface is active */
1558 if (refs.is_usbfs) {
1560 * The queue is used for events that should be
1561 * retrieved using the "USB_FS_COMPLETE" ioctl.
1563 err = EINVAL;
1564 goto done;
1566 while (uio->uio_resid > 0) {
1568 USB_IF_DEQUEUE(&f->used_q, m);
1570 if (m == NULL) {
1572 /* start read transfer, if not already started */
1574 (f->methods->f_start_read) (f);
1576 if (ioflag & IO_NDELAY) {
1577 if (tr_data) {
1578 /* return length before error */
1579 break;
1581 err = EWOULDBLOCK;
1582 break;
1584 DPRINTF("sleeping\n");
1586 err = usb_fifo_wait(f);
1587 if (err) {
1588 break;
1590 continue;
1592 if (f->methods->f_filter_read) {
1594 * Sometimes it is convenient to process data at the
1595 * expense of a userland process instead of a kernel
1596 * process.
1598 (f->methods->f_filter_read) (f, m);
1600 tr_data = 1;
1602 io_len = MIN(m->cur_data_len, uio->uio_resid);
1604 DPRINTFN(2, "transfer %d bytes from %p\n",
1605 io_len, m->cur_data_ptr);
1607 err = usb_fifo_uiomove(f,
1608 m->cur_data_ptr, io_len, uio);
1610 m->cur_data_len -= io_len;
1611 m->cur_data_ptr += io_len;
1613 if (m->cur_data_len == 0) {
1615 uint8_t last_packet;
1617 last_packet = m->last_packet;
1619 USB_IF_ENQUEUE(&f->free_q, m);
1621 if (last_packet) {
1622 /* keep framing */
1623 break;
1625 } else {
1626 USB_IF_PREPEND(&f->used_q, m);
1627 usb_fifo_wakeup(f);
1630 if (err) {
1631 break;
1634 done:
1635 lockmgr(f->priv_lock, LK_RELEASE);
1637 usb_unref_device(cpd, &refs);
1639 return (err);
1642 static int
1643 usb_write(struct dev_write_args *ap)
1645 struct uio *uio = ap->a_uio;
1646 int ioflag = ap->a_ioflag;
1647 struct usb_cdev_refdata refs;
1648 struct usb_cdev_privdata* cpd;
1649 struct usb_fifo *f;
1650 struct usb_mbuf *m;
1651 uint8_t *pdata;
1652 int fflags;
1653 int resid;
1654 int io_len;
1655 int err;
1656 uint8_t tr_data = 0;
1658 DPRINTFN(2, "\n");
1660 err = devfs_get_cdevpriv(ap->a_fp, (void **)&cpd);
1661 if (err != 0)
1662 return (err);
1663 err = usb_ref_device(cpd, &refs, 0 /* no uref */ );
1664 if (err) {
1665 return (ENXIO);
1667 fflags = cpd->fflags;
1669 f = refs.txfifo;
1670 if (f == NULL) {
1671 /* should not happen */
1672 usb_unref_device(cpd, &refs);
1673 return (EPERM);
1675 resid = uio->uio_resid;
1677 lockmgr(f->priv_lock, LK_EXCLUSIVE);
1679 /* check for permanent write error */
1680 if (f->flag_iserror) {
1681 err = EIO;
1682 goto done;
1684 /* check if USB-FS interface is active */
1685 if (refs.is_usbfs) {
1687 * The queue is used for events that should be
1688 * retrieved using the "USB_FS_COMPLETE" ioctl.
1690 err = EINVAL;
1691 goto done;
1693 if (f->queue_data == NULL) {
1694 /* start write transfer, if not already started */
1695 (f->methods->f_start_write) (f);
1697 /* we allow writing zero length data */
1698 do {
1699 USB_IF_DEQUEUE(&f->free_q, m);
1701 if (m == NULL) {
1703 if (ioflag & IO_NDELAY) {
1704 if (tr_data) {
1705 /* return length before error */
1706 break;
1708 err = EWOULDBLOCK;
1709 break;
1711 DPRINTF("sleeping\n");
1713 err = usb_fifo_wait(f);
1714 if (err) {
1715 break;
1717 continue;
1719 tr_data = 1;
1721 if (f->flag_have_fragment == 0) {
1722 USB_MBUF_RESET(m);
1723 io_len = m->cur_data_len;
1724 pdata = m->cur_data_ptr;
1725 if (io_len > uio->uio_resid)
1726 io_len = uio->uio_resid;
1727 m->cur_data_len = io_len;
1728 } else {
1729 io_len = m->max_data_len - m->cur_data_len;
1730 pdata = m->cur_data_ptr + m->cur_data_len;
1731 if (io_len > uio->uio_resid)
1732 io_len = uio->uio_resid;
1733 m->cur_data_len += io_len;
1736 DPRINTFN(2, "transfer %d bytes to %p\n",
1737 io_len, pdata);
1739 err = usb_fifo_uiomove(f, pdata, io_len, uio);
1741 if (err) {
1742 f->flag_have_fragment = 0;
1743 USB_IF_ENQUEUE(&f->free_q, m);
1744 break;
1747 /* check if the buffer is ready to be transmitted */
1749 if ((f->flag_write_defrag == 0) ||
1750 (m->cur_data_len == m->max_data_len)) {
1751 f->flag_have_fragment = 0;
1754 * Check for write filter:
1756 * Sometimes it is convenient to process data
1757 * at the expense of a userland process
1758 * instead of a kernel process.
1760 if (f->methods->f_filter_write) {
1761 (f->methods->f_filter_write) (f, m);
1764 /* Put USB mbuf in the used queue */
1765 USB_IF_ENQUEUE(&f->used_q, m);
1767 /* Start writing data, if not already started */
1768 (f->methods->f_start_write) (f);
1769 } else {
1770 /* Wait for more data or close */
1771 f->flag_have_fragment = 1;
1772 USB_IF_PREPEND(&f->free_q, m);
1775 } while (uio->uio_resid > 0);
1776 done:
1777 lockmgr(f->priv_lock, LK_RELEASE);
1779 usb_unref_device(cpd, &refs);
1781 return (err);
1785 usb_static_open(struct dev_open_args *ap)
1787 return 0;
1791 usb_static_close(struct dev_close_args *ap)
1793 return 0;
1797 usb_static_ioctl(struct dev_ioctl_args *ap)
1799 u_long cmd = ap->a_cmd;
1800 caddr_t data = ap->a_data;
1801 struct thread *td = curthread; /* XXX: curthread the correct choice? */
1802 int fflag = ap->a_fflag;
1803 union {
1804 struct usb_read_dir *urd;
1805 void* data;
1806 } u;
1807 int err;
1809 u.data = data;
1810 switch (cmd) {
1811 case USB_READ_DIR:
1812 err = usb_read_symlink(u.urd->urd_data,
1813 u.urd->urd_startentry, u.urd->urd_maxlen);
1814 break;
1815 case USB_DEV_QUIRK_GET:
1816 case USB_QUIRK_NAME_GET:
1817 case USB_DEV_QUIRK_ADD:
1818 case USB_DEV_QUIRK_REMOVE:
1819 err = usb_quirk_ioctl_p(cmd, data, fflag, td);
1820 break;
1821 case USB_GET_TEMPLATE:
1822 *(int *)data = usb_template;
1823 err = 0;
1824 break;
1825 case USB_SET_TEMPLATE:
1826 err = priv_check(curthread, PRIV_DRIVER);
1827 if (err)
1828 break;
1829 usb_template = *(int *)data;
1830 break;
1831 default:
1832 err = ENOTTY;
1833 break;
1835 return (err);
1838 static int
1839 usb_fifo_uiomove(struct usb_fifo *f, void *cp,
1840 int n, struct uio *uio)
1842 int error;
1844 lockmgr(f->priv_lock, LK_RELEASE);
1847 * "uiomove()" can sleep so one needs to make a wrapper,
1848 * exiting the mutex and checking things:
1850 error = uiomove(cp, n, uio);
1852 lockmgr(f->priv_lock, LK_EXCLUSIVE);
1854 return (error);
1858 usb_fifo_wait(struct usb_fifo *f)
1860 int err;
1862 KKASSERT(lockowned(f->priv_lock));
1864 if (f->flag_iserror) {
1865 /* we are gone */
1866 return (EIO);
1868 f->flag_sleeping = 1;
1870 err = cv_wait_sig(&f->cv_io, f->priv_lock);
1872 if (f->flag_iserror) {
1873 /* we are gone */
1874 err = EIO;
1876 return (err);
1879 void
1880 usb_fifo_signal(struct usb_fifo *f)
1882 if (f->flag_sleeping) {
1883 f->flag_sleeping = 0;
1884 cv_broadcast(&f->cv_io);
1888 void
1889 usb_fifo_wakeup(struct usb_fifo *f)
1891 usb_fifo_signal(f);
1893 KNOTE(&f->selinfo.ki_note, 0);
1895 if (f->flag_isselect) {
1896 wakeup(&f->selinfo.ki_note);
1898 if (f->async_p != NULL && lwkt_trytoken(&f->async_p->p_token)) {
1899 ksignal(f->async_p, SIGIO);
1900 lwkt_reltoken(&f->async_p->p_token);
1904 static int
1905 usb_fifo_dummy_open(struct usb_fifo *fifo, int fflags)
1907 return (0);
1910 static void
1911 usb_fifo_dummy_close(struct usb_fifo *fifo, int fflags)
1913 return;
1916 static int
1917 usb_fifo_dummy_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags)
1919 return (ENOIOCTL);
1922 static void
1923 usb_fifo_dummy_cmd(struct usb_fifo *fifo)
1925 fifo->flag_flushing = 0; /* not flushing */
1928 static void
1929 usb_fifo_check_methods(struct usb_fifo_methods *pm)
1931 /* check that all callback functions are OK */
1933 if (pm->f_open == NULL)
1934 pm->f_open = &usb_fifo_dummy_open;
1936 if (pm->f_close == NULL)
1937 pm->f_close = &usb_fifo_dummy_close;
1939 if (pm->f_ioctl == NULL)
1940 pm->f_ioctl = &usb_fifo_dummy_ioctl;
1942 if (pm->f_ioctl_post == NULL)
1943 pm->f_ioctl_post = &usb_fifo_dummy_ioctl;
1945 if (pm->f_start_read == NULL)
1946 pm->f_start_read = &usb_fifo_dummy_cmd;
1948 if (pm->f_stop_read == NULL)
1949 pm->f_stop_read = &usb_fifo_dummy_cmd;
1951 if (pm->f_start_write == NULL)
1952 pm->f_start_write = &usb_fifo_dummy_cmd;
1954 if (pm->f_stop_write == NULL)
1955 pm->f_stop_write = &usb_fifo_dummy_cmd;
1958 /*------------------------------------------------------------------------*
1959 * usb_fifo_attach
1961 * The following function will create a duplex FIFO.
1963 * Return values:
1964 * 0: Success.
1965 * Else: Failure.
1966 *------------------------------------------------------------------------*/
1968 usb_fifo_attach(struct usb_device *udev, void *priv_sc,
1969 struct lock *priv_lock, struct usb_fifo_methods *pm,
1970 struct usb_fifo_sc *f_sc, uint16_t unit, int16_t subunit,
1971 uint8_t iface_index, uid_t uid, gid_t gid, int mode)
1973 struct usb_fifo *f_tx;
1974 struct usb_fifo *f_rx;
1975 char devname[32];
1976 uint8_t n;
1978 f_sc->fp[USB_FIFO_TX] = NULL;
1979 f_sc->fp[USB_FIFO_RX] = NULL;
1981 if (pm == NULL)
1982 return (EINVAL);
1984 /* check the methods */
1985 usb_fifo_check_methods(pm);
1987 if (priv_lock == NULL) {
1988 DPRINTF("null priv_lock set\n");
1991 /* search for a free FIFO slot */
1992 for (n = 0;; n += 2) {
1994 if (n == USB_FIFO_MAX) {
1995 /* end of FIFOs reached */
1996 return (ENOMEM);
1998 /* Check for TX FIFO */
1999 if (udev->fifo[n + USB_FIFO_TX] != NULL) {
2000 continue;
2002 /* Check for RX FIFO */
2003 if (udev->fifo[n + USB_FIFO_RX] != NULL) {
2004 continue;
2006 break;
2009 f_tx = usb_fifo_alloc(priv_lock);
2010 f_rx = usb_fifo_alloc(priv_lock);
2012 if ((f_tx == NULL) || (f_rx == NULL)) {
2013 usb_fifo_free(f_tx);
2014 usb_fifo_free(f_rx);
2015 return (ENOMEM);
2017 /* initialise FIFO structures */
2019 f_tx->fifo_index = n + USB_FIFO_TX;
2020 f_tx->dev_ep_index = -1;
2021 f_tx->priv_lock = priv_lock;
2022 f_tx->priv_sc0 = priv_sc;
2023 f_tx->methods = pm;
2024 f_tx->iface_index = iface_index;
2025 f_tx->udev = udev;
2027 f_rx->fifo_index = n + USB_FIFO_RX;
2028 f_rx->dev_ep_index = -1;
2029 f_rx->priv_lock = priv_lock;
2030 f_rx->priv_sc0 = priv_sc;
2031 f_rx->methods = pm;
2032 f_rx->iface_index = iface_index;
2033 f_rx->udev = udev;
2035 f_sc->fp[USB_FIFO_TX] = f_tx;
2036 f_sc->fp[USB_FIFO_RX] = f_rx;
2038 lockmgr(&usb_ref_lock, LK_EXCLUSIVE);
2039 udev->fifo[f_tx->fifo_index] = f_tx;
2040 udev->fifo[f_rx->fifo_index] = f_rx;
2041 lockmgr(&usb_ref_lock, LK_RELEASE);
2043 for (n = 0; n != 4; n++) {
2045 if (pm->basename[n] == NULL) {
2046 continue;
2048 if (subunit < 0) {
2049 if (ksnprintf(devname, sizeof(devname),
2050 "%s%u%s", pm->basename[n],
2051 unit, pm->postfix[n] ?
2052 pm->postfix[n] : "")) {
2053 /* ignore */
2055 } else {
2056 if (ksnprintf(devname, sizeof(devname),
2057 "%s%u.%u%s", pm->basename[n],
2058 unit, subunit, pm->postfix[n] ?
2059 pm->postfix[n] : "")) {
2060 /* ignore */
2065 * Distribute the symbolic links into two FIFO structures:
2067 if (n & 1) {
2068 f_rx->symlink[n / 2] =
2069 usb_alloc_symlink(devname);
2070 } else {
2071 f_tx->symlink[n / 2] =
2072 usb_alloc_symlink(devname);
2075 /* Create the device */
2076 f_sc->dev = usb_make_dev(udev, devname, -1,
2077 f_tx->fifo_index & f_rx->fifo_index,
2078 FREAD|FWRITE, uid, gid, mode);
2081 DPRINTFN(2, "attached %p/%p\n", f_tx, f_rx);
2082 return (0);
2085 /*------------------------------------------------------------------------*
2086 * usb_fifo_alloc_buffer
2088 * Return values:
2089 * 0: Success
2090 * Else failure
2091 *------------------------------------------------------------------------*/
2093 usb_fifo_alloc_buffer(struct usb_fifo *f, usb_size_t bufsize,
2094 uint16_t nbuf)
2096 usb_fifo_free_buffer(f);
2098 /* allocate an endpoint */
2099 f->free_q.ifq_maxlen = nbuf;
2100 f->used_q.ifq_maxlen = nbuf;
2102 f->queue_data = usb_alloc_mbufs(
2103 M_USBDEV, &f->free_q, bufsize, nbuf);
2105 if ((f->queue_data == NULL) && bufsize && nbuf) {
2106 return (ENOMEM);
2108 return (0); /* success */
2111 /*------------------------------------------------------------------------*
2112 * usb_fifo_free_buffer
2114 * This function will free the buffers associated with a FIFO. This
2115 * function can be called multiple times in a row.
2116 *------------------------------------------------------------------------*/
2117 void
2118 usb_fifo_free_buffer(struct usb_fifo *f)
2120 if (f->queue_data) {
2121 /* free old buffer */
2122 kfree(f->queue_data, M_USBDEV);
2123 f->queue_data = NULL;
2125 /* reset queues */
2127 memset(&f->free_q, 0, sizeof(f->free_q));
2128 memset(&f->used_q, 0, sizeof(f->used_q));
2131 void
2132 usb_fifo_detach(struct usb_fifo_sc *f_sc)
2134 if (f_sc == NULL) {
2135 return;
2137 usb_fifo_free(f_sc->fp[USB_FIFO_TX]);
2138 usb_fifo_free(f_sc->fp[USB_FIFO_RX]);
2140 f_sc->fp[USB_FIFO_TX] = NULL;
2141 f_sc->fp[USB_FIFO_RX] = NULL;
2143 usb_destroy_dev(f_sc->dev);
2145 f_sc->dev = NULL;
2147 DPRINTFN(2, "detached %p\n", f_sc);
2150 usb_size_t
2151 usb_fifo_put_bytes_max(struct usb_fifo *f)
2153 struct usb_mbuf *m;
2154 usb_size_t len;
2156 USB_IF_POLL(&f->free_q, m);
2158 if (m) {
2159 len = m->max_data_len;
2160 } else {
2161 len = 0;
2163 return (len);
2166 /*------------------------------------------------------------------------*
2167 * usb_fifo_put_data
2169 * what:
2170 * 0 - normal operation
2171 * 1 - set last packet flag to enforce framing
2172 *------------------------------------------------------------------------*/
2173 void
2174 usb_fifo_put_data(struct usb_fifo *f, struct usb_page_cache *pc,
2175 usb_frlength_t offset, usb_frlength_t len, uint8_t what)
2177 struct usb_mbuf *m;
2178 usb_frlength_t io_len;
2180 while (len || (what == 1)) {
2182 USB_IF_DEQUEUE(&f->free_q, m);
2184 if (m) {
2185 USB_MBUF_RESET(m);
2187 io_len = MIN(len, m->cur_data_len);
2189 usbd_copy_out(pc, offset, m->cur_data_ptr, io_len);
2191 m->cur_data_len = io_len;
2192 offset += io_len;
2193 len -= io_len;
2195 if ((len == 0) && (what == 1)) {
2196 m->last_packet = 1;
2198 USB_IF_ENQUEUE(&f->used_q, m);
2200 usb_fifo_wakeup(f);
2202 if ((len == 0) || (what == 1)) {
2203 break;
2205 } else {
2206 break;
2211 void
2212 usb_fifo_put_data_linear(struct usb_fifo *f, void *ptr,
2213 usb_size_t len, uint8_t what)
2215 struct usb_mbuf *m;
2216 usb_size_t io_len;
2218 while (len || (what == 1)) {
2220 USB_IF_DEQUEUE(&f->free_q, m);
2222 if (m) {
2223 USB_MBUF_RESET(m);
2225 io_len = MIN(len, m->cur_data_len);
2227 memcpy(m->cur_data_ptr, ptr, io_len);
2229 m->cur_data_len = io_len;
2230 ptr = USB_ADD_BYTES(ptr, io_len);
2231 len -= io_len;
2233 if ((len == 0) && (what == 1)) {
2234 m->last_packet = 1;
2236 USB_IF_ENQUEUE(&f->used_q, m);
2238 usb_fifo_wakeup(f);
2240 if ((len == 0) || (what == 1)) {
2241 break;
2243 } else {
2244 break;
2249 uint8_t
2250 usb_fifo_put_data_buffer(struct usb_fifo *f, void *ptr, usb_size_t len)
2252 struct usb_mbuf *m;
2254 USB_IF_DEQUEUE(&f->free_q, m);
2256 if (m) {
2257 m->cur_data_len = len;
2258 m->cur_data_ptr = ptr;
2259 USB_IF_ENQUEUE(&f->used_q, m);
2260 usb_fifo_wakeup(f);
2261 return (1);
2263 return (0);
2266 void
2267 usb_fifo_put_data_error(struct usb_fifo *f)
2269 f->flag_iserror = 1;
2270 usb_fifo_wakeup(f);
2273 /*------------------------------------------------------------------------*
2274 * usb_fifo_get_data
2276 * what:
2277 * 0 - normal operation
2278 * 1 - only get one "usb_mbuf"
2280 * returns:
2281 * 0 - no more data
2282 * 1 - data in buffer
2283 *------------------------------------------------------------------------*/
2284 uint8_t
2285 usb_fifo_get_data(struct usb_fifo *f, struct usb_page_cache *pc,
2286 usb_frlength_t offset, usb_frlength_t len, usb_frlength_t *actlen,
2287 uint8_t what)
2289 struct usb_mbuf *m;
2290 usb_frlength_t io_len;
2291 uint8_t tr_data = 0;
2293 actlen[0] = 0;
2295 while (1) {
2297 USB_IF_DEQUEUE(&f->used_q, m);
2299 if (m) {
2301 tr_data = 1;
2303 io_len = MIN(len, m->cur_data_len);
2305 usbd_copy_in(pc, offset, m->cur_data_ptr, io_len);
2307 len -= io_len;
2308 offset += io_len;
2309 actlen[0] += io_len;
2310 m->cur_data_ptr += io_len;
2311 m->cur_data_len -= io_len;
2313 if ((m->cur_data_len == 0) || (what == 1)) {
2314 USB_IF_ENQUEUE(&f->free_q, m);
2316 usb_fifo_wakeup(f);
2318 if (what == 1) {
2319 break;
2321 } else {
2322 USB_IF_PREPEND(&f->used_q, m);
2323 usb_fifo_wakeup(f);
2325 } else {
2327 if (tr_data) {
2328 /* wait for data to be written out */
2329 break;
2331 if (f->flag_flushing) {
2332 /* check if we should send a short packet */
2333 if (f->flag_short != 0) {
2334 f->flag_short = 0;
2335 tr_data = 1;
2336 break;
2338 /* flushing complete */
2339 f->flag_flushing = 0;
2340 usb_fifo_wakeup(f);
2342 break;
2344 if (len == 0) {
2345 break;
2348 return (tr_data);
2351 uint8_t
2352 usb_fifo_get_data_linear(struct usb_fifo *f, void *ptr,
2353 usb_size_t len, usb_size_t *actlen, uint8_t what)
2355 struct usb_mbuf *m;
2356 usb_size_t io_len;
2357 uint8_t tr_data = 0;
2359 actlen[0] = 0;
2361 while (1) {
2363 USB_IF_DEQUEUE(&f->used_q, m);
2365 if (m) {
2367 tr_data = 1;
2369 io_len = MIN(len, m->cur_data_len);
2371 memcpy(ptr, m->cur_data_ptr, io_len);
2373 len -= io_len;
2374 ptr = USB_ADD_BYTES(ptr, io_len);
2375 actlen[0] += io_len;
2376 m->cur_data_ptr += io_len;
2377 m->cur_data_len -= io_len;
2379 if ((m->cur_data_len == 0) || (what == 1)) {
2380 USB_IF_ENQUEUE(&f->free_q, m);
2382 usb_fifo_wakeup(f);
2384 if (what == 1) {
2385 break;
2387 } else {
2388 USB_IF_PREPEND(&f->used_q, m);
2389 usb_fifo_wakeup(f);
2391 } else {
2393 if (tr_data) {
2394 /* wait for data to be written out */
2395 break;
2397 if (f->flag_flushing) {
2398 /* check if we should send a short packet */
2399 if (f->flag_short != 0) {
2400 f->flag_short = 0;
2401 tr_data = 1;
2402 break;
2404 /* flushing complete */
2405 f->flag_flushing = 0;
2406 usb_fifo_wakeup(f);
2408 break;
2410 if (len == 0) {
2411 break;
2414 return (tr_data);
2417 uint8_t
2418 usb_fifo_get_data_buffer(struct usb_fifo *f, void **pptr, usb_size_t *plen)
2420 struct usb_mbuf *m;
2422 USB_IF_POLL(&f->used_q, m);
2424 if (m) {
2425 *plen = m->cur_data_len;
2426 *pptr = m->cur_data_ptr;
2428 return (1);
2430 return (0);
2433 void
2434 usb_fifo_get_data_error(struct usb_fifo *f)
2436 f->flag_iserror = 1;
2437 usb_fifo_wakeup(f);
2440 /*------------------------------------------------------------------------*
2441 * usb_alloc_symlink
2443 * Return values:
2444 * NULL: Failure
2445 * Else: Pointer to symlink entry
2446 *------------------------------------------------------------------------*/
2447 struct usb_symlink *
2448 usb_alloc_symlink(const char *target)
2450 struct usb_symlink *ps;
2452 ps = kmalloc(sizeof(*ps), M_USBDEV, M_WAITOK);
2453 if (ps == NULL) {
2454 return (ps);
2456 /* XXX no longer needed */
2457 strlcpy(ps->src_path, target, sizeof(ps->src_path));
2458 ps->src_len = strlen(ps->src_path);
2459 strlcpy(ps->dst_path, target, sizeof(ps->dst_path));
2460 ps->dst_len = strlen(ps->dst_path);
2462 lockmgr(&usb_sym_lock, LK_EXCLUSIVE);
2463 TAILQ_INSERT_TAIL(&usb_sym_head, ps, sym_entry);
2464 lockmgr(&usb_sym_lock, LK_RELEASE);
2465 return (ps);
2468 /*------------------------------------------------------------------------*
2469 * usb_free_symlink
2470 *------------------------------------------------------------------------*/
2471 void
2472 usb_free_symlink(struct usb_symlink *ps)
2474 if (ps == NULL) {
2475 return;
2477 lockmgr(&usb_sym_lock, LK_EXCLUSIVE);
2478 TAILQ_REMOVE(&usb_sym_head, ps, sym_entry);
2479 lockmgr(&usb_sym_lock, LK_RELEASE);
2481 kfree(ps, M_USBDEV);
2484 /*------------------------------------------------------------------------*
2485 * usb_read_symlink
2487 * Return value:
2488 * 0: Success
2489 * Else: Failure
2490 *------------------------------------------------------------------------*/
2492 usb_read_symlink(uint8_t *user_ptr, uint32_t startentry, uint32_t user_len)
2494 struct usb_symlink *ps;
2495 uint32_t temp;
2496 uint32_t delta = 0;
2497 uint8_t len;
2498 int error = 0;
2500 lockmgr(&usb_sym_lock, LK_EXCLUSIVE);
2502 TAILQ_FOREACH(ps, &usb_sym_head, sym_entry) {
2505 * Compute total length of source and destination symlink
2506 * strings pluss one length byte and two NUL bytes:
2508 temp = ps->src_len + ps->dst_len + 3;
2510 if (temp > 255) {
2512 * Skip entry because this length cannot fit
2513 * into one byte:
2515 continue;
2517 if (startentry != 0) {
2518 /* decrement read offset */
2519 startentry--;
2520 continue;
2522 if (temp > user_len) {
2523 /* out of buffer space */
2524 break;
2526 len = temp;
2528 /* copy out total length */
2530 error = copyout(&len,
2531 USB_ADD_BYTES(user_ptr, delta), 1);
2532 if (error) {
2533 break;
2535 delta += 1;
2537 /* copy out source string */
2539 error = copyout(ps->src_path,
2540 USB_ADD_BYTES(user_ptr, delta), ps->src_len);
2541 if (error) {
2542 break;
2544 len = 0;
2545 delta += ps->src_len;
2546 error = copyout(&len,
2547 USB_ADD_BYTES(user_ptr, delta), 1);
2548 if (error) {
2549 break;
2551 delta += 1;
2553 /* copy out destination string */
2555 error = copyout(ps->dst_path,
2556 USB_ADD_BYTES(user_ptr, delta), ps->dst_len);
2557 if (error) {
2558 break;
2560 len = 0;
2561 delta += ps->dst_len;
2562 error = copyout(&len,
2563 USB_ADD_BYTES(user_ptr, delta), 1);
2564 if (error) {
2565 break;
2567 delta += 1;
2569 user_len -= temp;
2572 /* a zero length entry indicates the end */
2574 if ((user_len != 0) && (error == 0)) {
2576 len = 0;
2578 error = copyout(&len,
2579 USB_ADD_BYTES(user_ptr, delta), 1);
2581 lockmgr(&usb_sym_lock, LK_RELEASE);
2582 return (error);
2585 void
2586 usb_fifo_set_close_zlp(struct usb_fifo *f, uint8_t onoff)
2588 if (f == NULL)
2589 return;
2591 /* send a Zero Length Packet, ZLP, before close */
2592 f->flag_short = onoff;
2595 void
2596 usb_fifo_set_write_defrag(struct usb_fifo *f, uint8_t onoff)
2598 if (f == NULL)
2599 return;
2601 /* defrag written data */
2602 f->flag_write_defrag = onoff;
2603 /* reset defrag state */
2604 f->flag_have_fragment = 0;
2607 void *
2608 usb_fifo_softc(struct usb_fifo *f)
2610 return (f->priv_sc0);
2612 #endif /* USB_HAVE_UGEN */