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