1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 
27 /*
28  * USB video class driver (usbvc(7D))
29  *
30  * 1. Overview
31  * ------------
32  *
33  * This driver supports USB video class devices that used to capture video,
34  * e.g., some webcams. It is developed according to "USB Device Class
35  * Definition for Video Devices" spec. This spec defines detail info needed by
36  * designing a USB video device. It is available at:
37  * http://www.usb.org/developers/devclass_docs
38  *
39  * This driver implements:
40  *
41  *   - V4L2 interfaces for applications to communicate with video devices.
42  *     V4L2 is an API that is widely used by video applications, like Ekiga,
43  *     luvcview, etc. The API spec is at:
44  *     http://www.thedirks.org/v4l2/
45  *     This driver is according to V4L2 spec version 0.20
46  *
47  *   - Video capture function. (Video output is not supported by now.)
48  *
49  *   - Isochronous transfer for video data. (Bulk transfer is not supported.)
50  *
51  *   - read & mmap I/O methods for userland video applications to get video
52  *     data. Userland video applications can use read() system call directly,
53  *     it is the simplest way but not the most efficient way. Applications can
54  *     also use mmap() system call to map several bufs (they are linked as a
55  *     buf list), and then use some specific ioctls to start/stop isoc polling,
56  *     to queue/dequeue bufs.
57  *
58  * 2. Source and header files
59  * ---------------------------
60  *
61  * There are two source files and three header files for this driver:
62  *
63  *   - usbvc.c		Main source file, implements usb video class spec.
64  *
65  *   - usbvc_v4l2.c	V4L2 interface specific code.
66  *
67  *   - usbvc_var.h	Main header file, includes soft state structure.
68  *
69  *   - usbvc.h		The descriptors in usb video class spec.
70  *
71  *   - videodev2.h	This header file is included in V4L2 spec. It defines
72  *     ioctls and data structures that used as an interface between video
73  *     applications and video drivers. This is the only header file that
74  *     usbvc driver should export to userland application.
75  *
76  * 3. USB video class devices overview
77  * -----------------------------------
78  * According to UVC spec, there must be one control interface in a UVC device.
79  * Control interface is used to receive control commands from user, all the
80  * commands are sent through default ctrl pipe. usbvc driver implements V4L2
81  * API, so ioctls are implemented to relay user commands to UVC device.
82  *
83  * There can be no or multiple stream interfaces in a UVC device. Stream
84  * interfaces are used to do video data I/O. In practice, if no stream
85  * interface, the video device can do nothing since it has no data I/O.
86  *
87  * usbvc driver parses descriptors of control interface and stream interfaces.
88  * The descriptors tell the function layout and the capability of the device.
89  * During attach, usbvc driver set up some key data structures according to
90  * the descriptors.
91  *
92  * 4. I/O methods
93  * ---------------
94  *
95  * Userland applications use ioctls to set/get video formats of the device,
96  * and control brightness, contrast, image size, etc.
97  *
98  * Besides implementing standard read I/O method to get video data from
99  * the device, usbvc driver also implements some specific ioctls to implement
100  * mmap I/O method.
101  *
102  * A view from userland application: ioctl and mmap flow chart:
103  *
104  * REQBUFS -> QUERYBUF -> mmap() ->
105  *
106  *    -> QBUF -> STREAMON -> DQBUF -> process image -> QBUF
107  *			       ^			|
108  *			       |			|
109  *			       |			v
110  *			       |---<--------------------
111  *
112  * The above queue and dequeue buf operations can be stopped by issuing a
113  * STREAMOFF ioctl.
114  *
115  * 5. Device states
116  * ----------------
117  *
118  * The device has four states (refer to usbai.h):
119  *
120  *	- USB_DEV_ONLINE: In action or ready for action.
121  *
122  *	- USB_DEV_DISCONNECTED: Hotplug removed, or device not present/correct
123  *				on resume (CPR).
124  *
125  *	- USB_DEV_SUSPENDED: Device has been suspended along with the system.
126  *
127  *	- USB_DEV_PWRED_DOWN: Device has been powered down.  (Note that this
128  *		driver supports only two power states, powered down and
129  *		full power.)
130  *
131  * 6. Serialize
132  * -------------
133  * In order to avoid race conditions between driver entry points, access to
134  * the device is serialized. All the ioctls, and read, open/close are
135  * serialized. The functions usbvc_serialize/release_access are implemented
136  * for this purpose.
137  *
138  * 7. PM & CPR
139  * ------------
140  * PM & CPR are supported. pm_busy_component and pm_idle_component mark
141  * the device as busy or idle to the system.
142  */
143 
144 #if defined(lint) && !defined(DEBUG)
145 #define	DEBUG
146 #endif
147 
148 #define	USBDRV_MAJOR_VER	2
149 #define	USBDRV_MINOR_VER	0
150 
151 #include <sys/usb/usba.h>
152 #include <sys/fcntl.h>
153 #include <sys/cmn_err.h>
154 #include <sys/usb/clients/video/usbvc/usbvc_var.h>
155 #include <sys/videodev2.h> /* V4L2 API header file */
156 
157 /* Descriptors according to USB video class spec */
158 #include <sys/usb/clients/video/usbvc/usbvc.h>
159 
160 static uint_t	usbvc_errmask		= (uint_t)PRINT_MASK_ALL;
161 static uint_t	usbvc_errlevel = 4;
162 static uint_t	usbvc_instance_debug = (uint_t)-1;
163 
164 static char	*name = "usbvc";	/* Driver name, used all over. */
165 
166 /*
167  * Function Prototypes
168  */
169 
170 /* Entries */
171 static int	usbvc_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
172 static int	usbvc_attach(dev_info_t *, ddi_attach_cmd_t);
173 static int	usbvc_detach(dev_info_t *, ddi_detach_cmd_t);
174 static void	usbvc_cleanup(dev_info_t *, usbvc_state_t *);
175 static int	usbvc_open(dev_t *, int, int, cred_t *);
176 static int	usbvc_close(dev_t, int, int, cred_t *);
177 static int	usbvc_read(dev_t, struct uio *uip_p, cred_t *);
178 static int	usbvc_strategy(struct buf *);
179 static void	usbvc_minphys(struct buf *);
180 static int	usbvc_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
181 static int	usbvc_devmap(dev_t, devmap_cookie_t, offset_t,
182 		    size_t, size_t *, uint_t);
183 
184 /* pm and cpr */
185 static int	usbvc_power(dev_info_t *, int, int);
186 static void	usbvc_init_power_mgmt(usbvc_state_t *);
187 static void	usbvc_destroy_power_mgmt(usbvc_state_t *);
188 static void	usbvc_pm_busy_component(usbvc_state_t *);
189 static void	usbvc_pm_idle_component(usbvc_state_t *);
190 static int	usbvc_pwrlvl0(usbvc_state_t *);
191 static int	usbvc_pwrlvl1(usbvc_state_t *);
192 static int	usbvc_pwrlvl2(usbvc_state_t *);
193 static int	usbvc_pwrlvl3(usbvc_state_t *);
194 static void	usbvc_cpr_suspend(dev_info_t *);
195 static void	usbvc_cpr_resume(dev_info_t *);
196 static void	usbvc_restore_device_state(dev_info_t *, usbvc_state_t *);
197 
198 /* Events */
199 static int	usbvc_disconnect_event_cb(dev_info_t *);
200 static int	usbvc_reconnect_event_cb(dev_info_t *);
201 
202 /* Sync objs and lists */
203 static void	usbvc_init_sync_objs(usbvc_state_t *);
204 static void	usbvc_fini_sync_objs(usbvc_state_t *);
205 static void	usbvc_init_lists(usbvc_state_t *);
206 static void	usbvc_fini_lists(usbvc_state_t *);
207 static void	usbvc_free_ctrl_descr(usbvc_state_t *);
208 static void	usbvc_free_stream_descr(usbvc_state_t *);
209 
210 /* Parse descriptors */
211 static int	usbvc_chk_descr_len(uint8_t, uint8_t, uint8_t,
212 		    usb_cvs_data_t *);
213 static usbvc_stream_if_t *usbvc_parse_stream_if(usbvc_state_t *, int);
214 static int	usbvc_parse_ctrl_if(usbvc_state_t *);
215 static int	usbvc_parse_stream_ifs(usbvc_state_t *);
216 static void	usbvc_parse_color_still(usbvc_state_t *,
217 		    usbvc_format_group_t *, usb_cvs_data_t *, uint_t, uint_t);
218 static void	usbvc_parse_frames(usbvc_state_t *, usbvc_format_group_t *,
219 		    usb_cvs_data_t *, uint_t, uint_t);
220 static int	usbvc_parse_format_group(usbvc_state_t *,
221 		    usbvc_format_group_t *, usb_cvs_data_t *, uint_t, uint_t);
222 static int	usbvc_parse_format_groups(usbvc_state_t *, usbvc_stream_if_t *);
223 static int	usbvc_parse_stream_header(usbvc_state_t *, usbvc_stream_if_t *);
224 
225 /* read I/O functions */
226 static int	usbvc_alloc_read_bufs(usbvc_state_t *, usbvc_stream_if_t *);
227 static int	usbvc_read_buf(usbvc_state_t *, struct buf *);
228 static void	usbvc_free_read_buf(usbvc_buf_t *);
229 static void	usbvc_free_read_bufs(usbvc_state_t *, usbvc_stream_if_t *);
230 static void	usbvc_close_isoc_pipe(usbvc_state_t *, usbvc_stream_if_t *);
231 
232 /* callbacks */
233 static void	usbvc_isoc_cb(usb_pipe_handle_t, usb_isoc_req_t *);
234 static void	usbvc_isoc_exc_cb(usb_pipe_handle_t, usb_isoc_req_t *);
235 
236 /* Others */
237 static int	usbvc_set_alt(usbvc_state_t *, usbvc_stream_if_t *);
238 static int	usbvc_decode_stream_header(usbvc_state_t *, usbvc_buf_grp_t *,
239 		    mblk_t *, int);
240 static int	usbvc_serialize_access(usbvc_state_t *, boolean_t);
241 static void	usbvc_release_access(usbvc_state_t *);
242 static int		usbvc_set_default_stream_fmt(usbvc_state_t *);
243 
244 static usb_event_t usbvc_events = {
245 	usbvc_disconnect_event_cb,
246 	usbvc_reconnect_event_cb,
247 	NULL, NULL
248 };
249 
250 /* module loading stuff */
251 struct cb_ops usbvc_cb_ops = {
252 	usbvc_open,		/* open  */
253 	usbvc_close,		/* close */
254 	usbvc_strategy,	/* strategy */
255 	nulldev,		/* print */
256 	nulldev,		/* dump */
257 	usbvc_read,		/* read */
258 	nodev,			/* write */
259 	usbvc_ioctl,		/* ioctl */
260 	usbvc_devmap,		/* devmap */
261 	nodev,			/* mmap */
262 	ddi_devmap_segmap,	/* segmap */
263 	nochpoll,		/* poll */
264 	ddi_prop_op,		/* cb_prop_op */
265 	NULL,			/* streamtab  */
266 	D_MP | D_DEVMAP
267 };
268 
269 static struct dev_ops usbvc_ops = {
270 	DEVO_REV,		/* devo_rev, */
271 	0,			/* refcnt  */
272 	usbvc_info,		/* info */
273 	nulldev,		/* identify */
274 	nulldev,		/* probe */
275 	usbvc_attach,		/* attach */
276 	usbvc_detach,		/* detach */
277 	nodev,			/* reset */
278 	&usbvc_cb_ops,	/* driver operations */
279 	NULL,			/* bus operations */
280 	usbvc_power,		/* power */
281 	ddi_quiesce_not_needed,		/* quiesce */
282 };
283 
284 static struct modldrv usbvc_modldrv =	{
285 	&mod_driverops,
286 	"USB video class driver",
287 	&usbvc_ops
288 };
289 
290 static struct modlinkage modlinkage = {
291 	MODREV_1,
292 	&usbvc_modldrv,
293 	NULL
294 };
295 
296 /* Soft state structures */
297 #define	USBVC_INITIAL_SOFT_SPACE	1
298 static void *usbvc_statep;
299 
300 
301 /*
302  * Module-wide initialization routine.
303  */
304 int
305 _init(void)
306 {
307 	int rval;
308 
309 	if ((rval = ddi_soft_state_init(&usbvc_statep,
310 	    sizeof (usbvc_state_t), USBVC_INITIAL_SOFT_SPACE)) != 0) {
311 
312 		return (rval);
313 	}
314 
315 	if ((rval = mod_install(&modlinkage)) != 0) {
316 		ddi_soft_state_fini(&usbvc_statep);
317 	}
318 
319 	return (rval);
320 }
321 
322 
323 /*
324  * Module-wide tear-down routine.
325  */
326 int
327 _fini(void)
328 {
329 	int rval;
330 
331 	if ((rval = mod_remove(&modlinkage)) != 0) {
332 
333 		return (rval);
334 	}
335 
336 	ddi_soft_state_fini(&usbvc_statep);
337 
338 	return (rval);
339 }
340 
341 
342 int
343 _info(struct modinfo *modinfop)
344 {
345 	return (mod_info(&modlinkage, modinfop));
346 }
347 
348 
349 /*
350  * usbvc_info:
351  *	Get minor number, soft state structure, etc.
352  */
353 /*ARGSUSED*/
354 static int
355 usbvc_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
356 			void *arg, void **result)
357 {
358 	usbvc_state_t	*usbvcp;
359 	int error = DDI_FAILURE;
360 
361 	switch (infocmd) {
362 	case DDI_INFO_DEVT2DEVINFO:
363 		if ((usbvcp = ddi_get_soft_state(usbvc_statep,
364 		    getminor((dev_t)arg))) != NULL) {
365 			*result = usbvcp->usbvc_dip;
366 			if (*result != NULL) {
367 				error = DDI_SUCCESS;
368 			}
369 		} else {
370 			*result = NULL;
371 		}
372 		break;
373 	case DDI_INFO_DEVT2INSTANCE:
374 		*result = (void *)(uintptr_t)getminor((dev_t)arg);
375 		error = DDI_SUCCESS;
376 		break;
377 	default:
378 		break;
379 	}
380 
381 	return (error);
382 }
383 
384 
385 /*
386  * Entry functions.
387  */
388 
389 /*
390  * usbvc_attach:
391  *	Attach or resume.
392  *
393  *	For attach, initialize state and device, including:
394  *		state variables, locks, device node
395  *		device registration with system
396  *		power management, hotplugging
397  *	For resume, restore device and state
398  */
399 static int
400 usbvc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
401 {
402 	int			instance = ddi_get_instance(dip);
403 	usbvc_state_t		*usbvcp = NULL;
404 	int			status;
405 
406 	switch (cmd) {
407 	case DDI_ATTACH:
408 
409 		break;
410 	case DDI_RESUME:
411 		usbvc_cpr_resume(dip);
412 
413 		return (DDI_SUCCESS);
414 	default:
415 
416 		return (DDI_FAILURE);
417 	}
418 
419 	if (ddi_soft_state_zalloc(usbvc_statep, instance) == DDI_SUCCESS) {
420 		usbvcp = ddi_get_soft_state(usbvc_statep, instance);
421 	}
422 	if (usbvcp == NULL)  {
423 
424 		return (DDI_FAILURE);
425 	}
426 
427 	usbvcp->usbvc_dip = dip;
428 
429 	usbvcp->usbvc_log_handle = usb_alloc_log_hdl(dip,
430 	    "usbvc", &usbvc_errlevel,
431 	    &usbvc_errmask, &usbvc_instance_debug, 0);
432 
433 	USB_DPRINTF_L3(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
434 	    "usbvc_attach: enter");
435 
436 	if ((status = usb_client_attach(dip, USBDRV_VERSION, 0)) !=
437 	    USB_SUCCESS) {
438 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
439 		    "usbvc_attach: usb_client_attach failed, error code:%d",
440 		    status);
441 
442 		goto fail;
443 	}
444 
445 	if ((status = usb_get_dev_data(dip, &usbvcp->usbvc_reg,
446 	    USB_PARSE_LVL_ALL, 0)) != USB_SUCCESS) {
447 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
448 		    "usbvc_attach: usb_get_dev_data failed, error code:%d",
449 		    status);
450 
451 		goto fail;
452 	}
453 	usbvc_init_sync_objs(usbvcp);
454 
455 	/* create minor node */
456 	if ((status = ddi_create_minor_node(dip, name, S_IFCHR, instance,
457 	    "usb_video", 0)) != DDI_SUCCESS) {
458 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
459 		    "usbvc_attach: Error creating minor node, error code:%d",
460 		    status);
461 
462 		goto fail;
463 	}
464 
465 	mutex_enter(&usbvcp->usbvc_mutex);
466 	usbvc_init_lists(usbvcp);
467 
468 	usbvcp->usbvc_default_ph = usbvcp->usbvc_reg->dev_default_ph;
469 
470 	/* Put online before PM init as can get power managed afterward. */
471 	usbvcp->usbvc_dev_state = USB_DEV_ONLINE;
472 	mutex_exit(&usbvcp->usbvc_mutex);
473 
474 	/* initialize power management */
475 	usbvc_init_power_mgmt(usbvcp);
476 
477 	if ((status = usbvc_parse_ctrl_if(usbvcp)) != USB_SUCCESS) {
478 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
479 		    "usbvc_attach: parse ctrl interface fail, error code:%d",
480 		    status);
481 
482 		goto fail;
483 	}
484 	if ((status = usbvc_parse_stream_ifs(usbvcp)) != USB_SUCCESS) {
485 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
486 		    "usbvc_attach: parse stream interfaces fail, error code:%d",
487 		    status);
488 
489 		goto fail;
490 	}
491 	(void) usbvc_set_default_stream_fmt(usbvcp);
492 
493 	/* Register for events */
494 	if ((status = usb_register_event_cbs(dip, &usbvc_events, 0)) !=
495 	    USB_SUCCESS) {
496 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
497 		    "usbvc_attach: register_event_cbs failed, error code:%d",
498 		    status);
499 
500 		goto fail;
501 	}
502 
503 	/* Report device */
504 	ddi_report_dev(dip);
505 
506 	return (DDI_SUCCESS);
507 
508 fail:
509 	if (usbvcp) {
510 		usbvc_cleanup(dip, usbvcp);
511 	}
512 
513 	return (DDI_FAILURE);
514 }
515 
516 
517 /*
518  * usbvc_detach:
519  *	detach or suspend driver instance
520  *
521  * Note: in detach, only contention threads is from pm and disconnnect.
522  */
523 static int
524 usbvc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
525 {
526 	int		instance = ddi_get_instance(dip);
527 	usbvc_state_t	*usbvcp = ddi_get_soft_state(usbvc_statep, instance);
528 	int		rval = USB_FAILURE;
529 
530 	switch (cmd) {
531 	case DDI_DETACH:
532 		mutex_enter(&usbvcp->usbvc_mutex);
533 		ASSERT((usbvcp->usbvc_drv_state & USBVC_OPEN) == 0);
534 		mutex_exit(&usbvcp->usbvc_mutex);
535 
536 		USB_DPRINTF_L3(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
537 		    "usbvc_detach: enter for detach");
538 
539 		usbvc_cleanup(dip, usbvcp);
540 		rval = USB_SUCCESS;
541 
542 		break;
543 	case DDI_SUSPEND:
544 		USB_DPRINTF_L3(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
545 		    "usbvc_detach: enter for suspend");
546 
547 		usbvc_cpr_suspend(dip);
548 		rval = USB_SUCCESS;
549 
550 		break;
551 	default:
552 
553 		break;
554 	}
555 
556 	return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
557 }
558 
559 
560 /*
561  * usbvc_cleanup:
562  *	clean up the driver state for detach
563  */
564 static void
565 usbvc_cleanup(dev_info_t *dip, usbvc_state_t *usbvcp)
566 {
567 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
568 	    "Cleanup: enter");
569 
570 	if (usbvcp->usbvc_locks_initialized) {
571 
572 		/* This must be done 1st to prevent more events from coming. */
573 		usb_unregister_event_cbs(dip, &usbvc_events);
574 
575 		/*
576 		 * At this point, no new activity can be initiated. The driver
577 		 * has disabled hotplug callbacks. The Solaris framework has
578 		 * disabled new opens on a device being detached, and does not
579 		 * allow detaching an open device.
580 		 *
581 		 * The following ensures that all driver activity has drained.
582 		 */
583 		mutex_enter(&usbvcp->usbvc_mutex);
584 		(void) usbvc_serialize_access(usbvcp, USBVC_SER_NOSIG);
585 		usbvc_release_access(usbvcp);
586 		mutex_exit(&usbvcp->usbvc_mutex);
587 
588 		/* All device activity has died down. */
589 		usbvc_destroy_power_mgmt(usbvcp);
590 		mutex_enter(&usbvcp->usbvc_mutex);
591 		usbvc_fini_lists(usbvcp);
592 		mutex_exit(&usbvcp->usbvc_mutex);
593 
594 		ddi_remove_minor_node(dip, NULL);
595 		usbvc_fini_sync_objs(usbvcp);
596 	}
597 
598 	usb_client_detach(dip, usbvcp->usbvc_reg);
599 	usb_free_log_hdl(usbvcp->usbvc_log_handle);
600 	ddi_soft_state_free(usbvc_statep, ddi_get_instance(dip));
601 	ddi_prop_remove_all(dip);
602 }
603 
604 
605 /*ARGSUSED*/
606 static int
607 usbvc_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
608 {
609 	usbvc_state_t	*usbvcp =
610 	    ddi_get_soft_state(usbvc_statep, getminor(*devp));
611 
612 	if (usbvcp == NULL) {
613 
614 		return (ENXIO);
615 	}
616 
617 	/*
618 	 * Keep it simple: one client at a time.
619 	 * Exclusive open only
620 	 */
621 	mutex_enter(&usbvcp->usbvc_mutex);
622 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
623 	    "usbvc_open: enter, dev_stat=%d", usbvcp->usbvc_dev_state);
624 
625 	if (usbvcp->usbvc_dev_state == USB_DEV_DISCONNECTED) {
626 		mutex_exit(&usbvcp->usbvc_mutex);
627 
628 		return (ENODEV);
629 	}
630 	if (usbvcp->usbvc_dev_state == USB_DEV_SUSPENDED) {
631 		mutex_exit(&usbvcp->usbvc_mutex);
632 
633 		return (EIO);
634 	}
635 	if ((usbvcp->usbvc_drv_state & USBVC_OPEN) != 0) {
636 		mutex_exit(&usbvcp->usbvc_mutex);
637 
638 		return (EBUSY);
639 	}
640 	usbvcp->usbvc_drv_state |= USBVC_OPEN;
641 
642 	if (usbvc_serialize_access(usbvcp, USBVC_SER_SIG) == 0) {
643 		usbvcp->usbvc_drv_state &= ~USBVC_OPEN;
644 		usbvcp->usbvc_serial_inuse = B_FALSE;
645 		mutex_exit(&usbvcp->usbvc_mutex);
646 
647 		return (EINTR);
648 	}
649 
650 	/* raise power */
651 	usbvc_pm_busy_component(usbvcp);
652 	if (usbvcp->usbvc_pm->usbvc_current_power != USB_DEV_OS_FULL_PWR) {
653 		usbvcp->usbvc_pm->usbvc_raise_power = B_TRUE;
654 		mutex_exit(&usbvcp->usbvc_mutex);
655 		(void) pm_raise_power(usbvcp->usbvc_dip,
656 		    0, USB_DEV_OS_FULL_PWR);
657 		mutex_enter(&usbvcp->usbvc_mutex);
658 		usbvcp->usbvc_pm->usbvc_raise_power = B_FALSE;
659 	}
660 
661 	/* Device is idle until it is used. */
662 	usbvc_release_access(usbvcp);
663 	mutex_exit(&usbvcp->usbvc_mutex);
664 
665 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
666 	    "usbvc_open: end.");
667 
668 	return (0);
669 }
670 
671 
672 /*ARGSUSED*/
673 static int
674 usbvc_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
675 {
676 	usbvc_stream_if_t *strm_if;
677 	int		if_num;
678 	usbvc_state_t	*usbvcp =
679 	    ddi_get_soft_state(usbvc_statep, getminor(dev));
680 
681 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, usbvcp->usbvc_log_handle,
682 	    "close: enter");
683 
684 	mutex_enter(&usbvcp->usbvc_mutex);
685 	(void) usbvc_serialize_access(usbvcp, USBVC_SER_NOSIG);
686 	mutex_exit(&usbvcp->usbvc_mutex);
687 
688 	/* Perform device session cleanup here. */
689 
690 	USB_DPRINTF_L3(PRINT_MASK_CLOSE, usbvcp->usbvc_log_handle,
691 	    "close: cleaning up...");
692 
693 	/*
694 	 * USBA automatically flushes/resets active non-default pipes
695 	 * when they are closed.  We can't reset default pipe, but we
696 	 * can wait for all requests on it from this dip to drain.
697 	 */
698 	(void) usb_pipe_drain_reqs(usbvcp->usbvc_dip,
699 	    usbvcp->usbvc_reg->dev_default_ph, 0,
700 	    USB_FLAGS_SLEEP, NULL, 0);
701 
702 	mutex_enter(&usbvcp->usbvc_mutex);
703 	strm_if = usbvcp->usbvc_curr_strm;
704 	if (strm_if->start_polling == 1) {
705 		mutex_exit(&usbvcp->usbvc_mutex);
706 		usb_pipe_stop_isoc_polling(strm_if->datain_ph, USB_FLAGS_SLEEP);
707 		mutex_enter(&usbvcp->usbvc_mutex);
708 		strm_if->start_polling = 0;
709 	}
710 	usbvc_close_isoc_pipe(usbvcp, strm_if);
711 	if_num = strm_if->if_descr->if_alt->altif_descr.bInterfaceNumber;
712 	mutex_exit(&usbvcp->usbvc_mutex);
713 
714 	/* reset alternate to the default one. */
715 	(void) usb_set_alt_if(usbvcp->usbvc_dip, if_num, 0,
716 	    USB_FLAGS_SLEEP, NULL, NULL);
717 	mutex_enter(&usbvcp->usbvc_mutex);
718 
719 	usbvc_free_read_bufs(usbvcp, strm_if);
720 
721 	/* reset the desired read buf number to the default value on close */
722 	strm_if->buf_read_num = USBVC_DEFAULT_READ_BUF_NUM;
723 
724 	usbvc_free_map_bufs(usbvcp, strm_if);
725 	usbvcp->usbvc_drv_state &= ~USBVC_OPEN;
726 
727 	usbvc_release_access(usbvcp);
728 	usbvc_pm_idle_component(usbvcp);
729 	mutex_exit(&usbvcp->usbvc_mutex);
730 
731 	return (0);
732 }
733 
734 
735 /*ARGSUSED*/
736 /* Read isoc data from usb video devices */
737 static int
738 usbvc_read(dev_t dev, struct uio *uio_p, cred_t *cred_p)
739 {
740 	int			rval;
741 	usbvc_stream_if_t	*strm_if;
742 	usbvc_state_t	*usbvcp =
743 	    ddi_get_soft_state(usbvc_statep, getminor(dev));
744 
745 	USB_DPRINTF_L4(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
746 	    "usbvc_read: enter");
747 	mutex_enter(&usbvcp->usbvc_mutex);
748 	if (usbvcp->usbvc_dev_state != USB_DEV_ONLINE) {
749 		USB_DPRINTF_L2(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
750 		    "usbvc_read: Device is not available,"
751 		    " dev_stat=%d", usbvcp->usbvc_dev_state);
752 		mutex_exit(&usbvcp->usbvc_mutex);
753 
754 		return (EFAULT);
755 	}
756 	if ((uio_p->uio_fmode & (FNDELAY|FNONBLOCK)) &&
757 	    (usbvcp->usbvc_serial_inuse != B_FALSE)) {
758 		USB_DPRINTF_L2(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
759 		    "usbvc_read: non-blocking read, return fail.");
760 		mutex_exit(&usbvcp->usbvc_mutex);
761 
762 		return (EAGAIN);
763 	}
764 	if (usbvc_serialize_access(usbvcp, USBVC_SER_SIG) <= 0) {
765 		USB_DPRINTF_L2(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
766 		    "usbvc_read: serialize_access failed.");
767 		rval = EFAULT;
768 
769 		goto fail;
770 	}
771 
772 	/* Get the first stream interface */
773 	strm_if = usbvcp->usbvc_curr_strm;
774 	if (!strm_if) {
775 		USB_DPRINTF_L2(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
776 		    "usbvc_read: no stream interfaces");
777 		rval = EFAULT;
778 
779 		goto fail;
780 	}
781 
782 	/*
783 	 * If it is the first read, open isoc pipe and allocate bufs for
784 	 * read I/O method.
785 	 */
786 	if (strm_if->datain_ph == NULL) {
787 		if (usbvc_open_isoc_pipe(usbvcp, strm_if) != USB_SUCCESS) {
788 			USB_DPRINTF_L2(PRINT_MASK_READ,
789 			    usbvcp->usbvc_log_handle,
790 			    "usbvc_read: first read, open pipe fail");
791 			rval = EFAULT;
792 
793 			goto fail;
794 		}
795 		if (usbvc_alloc_read_bufs(usbvcp, strm_if) != USB_SUCCESS) {
796 			USB_DPRINTF_L2(PRINT_MASK_READ,
797 			    usbvcp->usbvc_log_handle,
798 			    "usbvc_read: allocate rw bufs fail");
799 			rval = EFAULT;
800 
801 			goto fail;
802 		}
803 	}
804 
805 	/* start polling if it is not started yet */
806 	if (strm_if->start_polling != 1) {
807 		if (usbvc_start_isoc_polling(usbvcp, strm_if, NULL) !=
808 		    USB_SUCCESS) {
809 			USB_DPRINTF_L2(PRINT_MASK_READ,
810 			    usbvcp->usbvc_log_handle,
811 			    "usbvc_read: usbvc_start_isoc_polling fail");
812 			rval = EFAULT;
813 
814 			goto fail;
815 		}
816 		strm_if->start_polling = 1;
817 	}
818 
819 	if (list_is_empty(&strm_if->buf_read.uv_buf_done)) {
820 		USB_DPRINTF_L3(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
821 		    "usbvc_read: full buf list is empty.");
822 
823 		if (uio_p->uio_fmode & (FNDELAY | FNONBLOCK)) {
824 			USB_DPRINTF_L2(PRINT_MASK_READ,
825 			    usbvcp->usbvc_log_handle, "usbvc_read: fail, "
826 			    "non-blocking read, done buf is empty.");
827 			rval = EAGAIN;
828 
829 			goto fail;
830 		}
831 
832 		/* no available buffers, block here */
833 		while (list_is_empty(&strm_if->buf_read.uv_buf_done)) {
834 			USB_DPRINTF_L3(PRINT_MASK_READ,
835 			    usbvcp->usbvc_log_handle,
836 			    "usbvc_read: wait for done buf");
837 			if (cv_wait_sig(&usbvcp->usbvc_read_cv,
838 			    &usbvcp->usbvc_mutex) <= 0) {
839 				/* no done buf and cv is signaled */
840 				rval = EINTR;
841 
842 				goto fail;
843 			}
844 			if (usbvcp->usbvc_dev_state != USB_DEV_ONLINE) {
845 
846 				/* Device is disconnected. */
847 				rval = EINTR;
848 
849 				goto fail;
850 			}
851 		}
852 
853 	}
854 
855 	mutex_exit(&usbvcp->usbvc_mutex);
856 	rval = physio(usbvc_strategy, NULL, dev, B_READ,
857 	    usbvc_minphys, uio_p);
858 
859 	mutex_enter(&usbvcp->usbvc_mutex);
860 	usbvc_release_access(usbvcp);
861 	mutex_exit(&usbvcp->usbvc_mutex);
862 
863 	return (rval);
864 
865 fail:
866 	usbvc_release_access(usbvcp);
867 	mutex_exit(&usbvcp->usbvc_mutex);
868 
869 	return (rval);
870 }
871 
872 
873 /*
874  * strategy:
875  *	Called through physio to setup and start the transfer.
876  */
877 static int
878 usbvc_strategy(struct buf *bp)
879 {
880 	usbvc_state_t *usbvcp = ddi_get_soft_state(usbvc_statep,
881 	    getminor(bp->b_edev));
882 
883 	USB_DPRINTF_L4(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
884 	    "usbvc_strategy: enter");
885 
886 	/*
887 	 * Initialize residual count here in case transfer doesn't even get
888 	 * started.
889 	 */
890 	bp->b_resid = bp->b_bcount;
891 
892 	/* Needed as this is a character driver. */
893 	if (bp->b_flags & (B_PHYS | B_PAGEIO)) {
894 		bp_mapin(bp);
895 	}
896 
897 	mutex_enter(&usbvcp->usbvc_mutex);
898 
899 	/* Make sure device has not been disconnected. */
900 	if (usbvcp->usbvc_dev_state != USB_DEV_ONLINE) {
901 		USB_DPRINTF_L2(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
902 		    "usbvc_strategy: device can't be accessed");
903 		mutex_exit(&usbvcp->usbvc_mutex);
904 
905 		goto fail;
906 	}
907 
908 	/* read data from uv_buf_done list */
909 	if (usbvc_read_buf(usbvcp, bp) != USB_SUCCESS) {
910 		USB_DPRINTF_L2(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
911 		    "usbvc_strategy: read full buf list fail");
912 		mutex_exit(&usbvcp->usbvc_mutex);
913 
914 		goto fail;
915 	}
916 
917 	mutex_exit(&usbvcp->usbvc_mutex);
918 
919 	biodone(bp);
920 
921 	return (0);
922 
923 fail:
924 	USB_DPRINTF_L2(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
925 	    "usbvc_strategy: strategy fail");
926 	bp->b_private = NULL;
927 
928 	bioerror(bp, EIO);
929 	biodone(bp);
930 
931 	return (0);
932 }
933 
934 
935 static void
936 usbvc_minphys(struct buf *bp)
937 {
938 	dev_t			dev = bp->b_edev;
939 	usbvc_stream_if_t	*strm_if;
940 	uint32_t		maxsize;
941 	usbvc_state_t		*usbvcp =
942 	    ddi_get_soft_state(usbvc_statep, getminor(dev));
943 
944 	mutex_enter(&usbvcp->usbvc_mutex);
945 	strm_if = usbvcp->usbvc_curr_strm;
946 	LE_TO_UINT32(strm_if->ctrl_pc.dwMaxVideoFrameSize, 0, maxsize);
947 	USB_DPRINTF_L3(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
948 	    "usbvc_minphys: max read size=%d", maxsize);
949 
950 	if (bp->b_bcount > maxsize) {
951 		bp->b_bcount = maxsize;
952 	}
953 	mutex_exit(&usbvcp->usbvc_mutex);
954 }
955 
956 
957 /*
958  * ioctl entry.
959  */
960 /*ARGSUSED*/
961 static int
962 usbvc_ioctl(dev_t dev, int cmd, intptr_t arg,
963 		int mode, cred_t *cred_p, int *rval_p)
964 {
965 	int		rv = 0;
966 	usbvc_state_t	*usbvcp =
967 	    ddi_get_soft_state(usbvc_statep, getminor(dev));
968 
969 	if (usbvcp == NULL) {
970 
971 		return (ENXIO);
972 	}
973 	USB_DPRINTF_L4(PRINT_MASK_IOCTL, usbvcp->usbvc_log_handle,
974 	    "ioctl enter, cmd=%x", cmd);
975 	mutex_enter(&usbvcp->usbvc_mutex);
976 	if (usbvcp->usbvc_dev_state != USB_DEV_ONLINE) {
977 		USB_DPRINTF_L2(PRINT_MASK_IOCTL, usbvcp->usbvc_log_handle,
978 		    "ioctl: Device is not online,"
979 		    " dev_stat=%d", usbvcp->usbvc_dev_state);
980 		mutex_exit(&usbvcp->usbvc_mutex);
981 
982 		return (EFAULT);
983 	}
984 	if (usbvc_serialize_access(usbvcp, USBVC_SER_SIG) <= 0) {
985 		usbvcp->usbvc_serial_inuse = B_FALSE;
986 		mutex_exit(&usbvcp->usbvc_mutex);
987 		USB_DPRINTF_L2(PRINT_MASK_IOCTL, usbvcp->usbvc_log_handle,
988 		    "serialize_access failed.");
989 
990 		return (EFAULT);
991 	}
992 	mutex_exit(&usbvcp->usbvc_mutex);
993 
994 	rv = usbvc_v4l2_ioctl(usbvcp, cmd, arg, mode);
995 
996 	mutex_enter(&usbvcp->usbvc_mutex);
997 	usbvc_release_access(usbvcp);
998 	mutex_exit(&usbvcp->usbvc_mutex);
999 
1000 	USB_DPRINTF_L4(PRINT_MASK_IOCTL, usbvcp->usbvc_log_handle,
1001 	    "usbvc_ioctl exit");
1002 
1003 	return (rv);
1004 }
1005 
1006 
1007 /* Entry for mmap system call */
1008 static int
1009 usbvc_devmap(dev_t dev, devmap_cookie_t handle, offset_t off,
1010 	size_t len, size_t *maplen, uint_t model)
1011 {
1012 	usbvc_state_t		*usbvcp;
1013 	int			error, i;
1014 	usbvc_buf_t		*buf = NULL;
1015 	usbvc_stream_if_t	*strm_if;
1016 	usbvc_buf_grp_t		*bufgrp;
1017 
1018 	usbvcp = ddi_get_soft_state(usbvc_statep, getminor(dev));
1019 	if (usbvcp == NULL) {
1020 		USB_DPRINTF_L2(PRINT_MASK_DEVMAP, usbvcp->usbvc_log_handle,
1021 		    "usbvc_devmap: usbvcp == NULL");
1022 
1023 		return (ENXIO);
1024 	}
1025 
1026 	USB_DPRINTF_L3(PRINT_MASK_DEVMAP, usbvcp->usbvc_log_handle,
1027 	    "devmap: memory map for instance(%d), off=%llx,"
1028 	    "len=%ld, maplen=%ld, model=%d", getminor(dev), off,
1029 	    len, *maplen, model);
1030 
1031 	mutex_enter(&usbvcp->usbvc_mutex);
1032 	(void) usbvc_serialize_access(usbvcp, USBVC_SER_NOSIG);
1033 	strm_if = usbvcp->usbvc_curr_strm;
1034 	if (!strm_if) {
1035 		USB_DPRINTF_L2(PRINT_MASK_DEVMAP, usbvcp->usbvc_log_handle,
1036 		    "usbvc_devmap: No current strm if");
1037 		mutex_exit(&usbvcp->usbvc_mutex);
1038 
1039 		return (ENXIO);
1040 	}
1041 	bufgrp = &strm_if->buf_map;
1042 	for (i = 0; i < bufgrp->buf_cnt; i++) {
1043 		if (bufgrp->buf_head[i].v4l2_buf.m.offset == off) {
1044 			buf = &bufgrp->buf_head[i];
1045 
1046 			break;
1047 		}
1048 	}
1049 	USB_DPRINTF_L3(PRINT_MASK_DEVMAP, usbvcp->usbvc_log_handle,
1050 	    "usbvc_devmap: idx=%d", i);
1051 	if (buf == NULL) {
1052 		mutex_exit(&usbvcp->usbvc_mutex);
1053 
1054 		return (ENXIO);
1055 	}
1056 	/*
1057 	 * round up len to a multiple of a page size, according to chapter
1058 	 * 10 of "writing device drivers"
1059 	 */
1060 	len = ptob(btopr(len));
1061 	if (len > ptob(btopr(buf->len))) {
1062 		USB_DPRINTF_L2(PRINT_MASK_DEVMAP, usbvcp->usbvc_log_handle,
1063 		    "usbvc_devmap: len=0x%lx", len);
1064 		mutex_exit(&usbvcp->usbvc_mutex);
1065 
1066 		return (ENXIO);
1067 	}
1068 	mutex_exit(&usbvcp->usbvc_mutex);
1069 
1070 	error = devmap_umem_setup(handle, usbvcp->usbvc_dip, NULL,
1071 	    buf->umem_cookie, off, len, PROT_ALL, DEVMAP_DEFAULTS, NULL);
1072 	mutex_enter(&usbvcp->usbvc_mutex);
1073 	*maplen = len;
1074 	if (error == 0 && buf->status == USBVC_BUF_INIT) {
1075 		buf->status = USBVC_BUF_MAPPED;
1076 	} else {
1077 		USB_DPRINTF_L3(PRINT_MASK_DEVMAP, usbvcp->usbvc_log_handle,
1078 		    "usbvc_devmap: devmap_umem_setup, err=%d", error);
1079 	}
1080 
1081 	(void) usbvc_release_access(usbvcp);
1082 	mutex_exit(&usbvcp->usbvc_mutex);
1083 
1084 	return (error);
1085 }
1086 
1087 /*
1088  * pm and cpr
1089  */
1090 
1091 /*
1092  *  usbvc_power :
1093  *	Power entry point, the workhorse behind pm_raise_power, pm_lower_power,
1094  *	usb_req_raise_power and usb_req_lower_power.
1095  */
1096 /* ARGSUSED */
1097 static int
1098 usbvc_power(dev_info_t *dip, int comp, int level)
1099 {
1100 	usbvc_state_t	*usbvcp;
1101 	usbvc_power_t	*pm;
1102 	int		rval = USB_FAILURE;
1103 
1104 	usbvcp = ddi_get_soft_state(usbvc_statep, ddi_get_instance(dip));
1105 	mutex_enter(&usbvcp->usbvc_mutex);
1106 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1107 	    "usbvc_power: enter: level = %d, dev_state: %x",
1108 	    level, usbvcp->usbvc_dev_state);
1109 
1110 	if (usbvcp->usbvc_pm == NULL) {
1111 
1112 		goto done;
1113 	}
1114 
1115 	pm = usbvcp->usbvc_pm;
1116 
1117 	/* Check if we are transitioning to a legal power level */
1118 	if (USB_DEV_PWRSTATE_OK(pm->usbvc_pwr_states, level)) {
1119 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
1120 		    "usbvc_power: illegal power level = %d "
1121 		    "pwr_states: %x", level, pm->usbvc_pwr_states);
1122 
1123 		goto done;
1124 	}
1125 	/*
1126 	 * if we are about to raise power and asked to lower power, fail
1127 	 */
1128 	if (pm->usbvc_raise_power && (level < (int)pm->usbvc_current_power)) {
1129 
1130 		goto done;
1131 	}
1132 	switch (level) {
1133 	case USB_DEV_OS_PWR_OFF :
1134 		rval = usbvc_pwrlvl0(usbvcp);
1135 
1136 		break;
1137 	case USB_DEV_OS_PWR_1 :
1138 		rval = usbvc_pwrlvl1(usbvcp);
1139 
1140 		break;
1141 	case USB_DEV_OS_PWR_2 :
1142 		rval = usbvc_pwrlvl2(usbvcp);
1143 
1144 		break;
1145 	case USB_DEV_OS_FULL_PWR :
1146 		rval = usbvc_pwrlvl3(usbvcp);
1147 
1148 		break;
1149 	}
1150 
1151 done:
1152 	mutex_exit(&usbvcp->usbvc_mutex);
1153 
1154 	return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
1155 }
1156 
1157 
1158 /*
1159  * usbvc_init_power_mgmt:
1160  *	Initialize power management and remote wakeup functionality.
1161  *	No mutex is necessary in this function as it's called only by attach.
1162  */
1163 static void
1164 usbvc_init_power_mgmt(usbvc_state_t *usbvcp)
1165 {
1166 	usbvc_power_t	*usbvcpm;
1167 	uint_t		pwr_states;
1168 
1169 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1170 	    "init_power_mgmt enter");
1171 
1172 	/* Allocate the state structure */
1173 	usbvcpm = kmem_zalloc(sizeof (usbvc_power_t), KM_SLEEP);
1174 	mutex_enter(&usbvcp->usbvc_mutex);
1175 	usbvcp->usbvc_pm = usbvcpm;
1176 	usbvcpm->usbvc_state = usbvcp;
1177 	usbvcpm->usbvc_pm_capabilities = 0;
1178 	usbvcpm->usbvc_current_power = USB_DEV_OS_FULL_PWR;
1179 	mutex_exit(&usbvcp->usbvc_mutex);
1180 
1181 	if (usb_create_pm_components(usbvcp->usbvc_dip, &pwr_states) ==
1182 	    USB_SUCCESS) {
1183 		USB_DPRINTF_L2(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1184 		    "usbvc_init_power_mgmt: created PM components");
1185 
1186 		if (usb_handle_remote_wakeup(usbvcp->usbvc_dip,
1187 		    USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) {
1188 			usbvcpm->usbvc_wakeup_enabled = 1;
1189 		} else {
1190 			USB_DPRINTF_L2(PRINT_MASK_ATTA,
1191 			    usbvcp->usbvc_log_handle, "usbvc_init_power_mgmt:"
1192 			    " remote wakeup not supported");
1193 		}
1194 
1195 		mutex_enter(&usbvcp->usbvc_mutex);
1196 		usbvcpm->usbvc_pwr_states = (uint8_t)pwr_states;
1197 		usbvc_pm_busy_component(usbvcp);
1198 		usbvcpm->usbvc_raise_power = B_TRUE;
1199 		mutex_exit(&usbvcp->usbvc_mutex);
1200 
1201 		(void) pm_raise_power(
1202 		    usbvcp->usbvc_dip, 0, USB_DEV_OS_FULL_PWR);
1203 
1204 		mutex_enter(&usbvcp->usbvc_mutex);
1205 		usbvcpm->usbvc_raise_power = B_FALSE;
1206 		usbvc_pm_idle_component(usbvcp);
1207 		mutex_exit(&usbvcp->usbvc_mutex);
1208 
1209 	}
1210 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1211 	    "usbvc_init_power_mgmt: end");
1212 }
1213 
1214 
1215 /*
1216  *  usbvc_destroy_power_mgmt:
1217  *	Shut down and destroy power management and remote wakeup functionality.
1218  */
1219 static void
1220 usbvc_destroy_power_mgmt(usbvc_state_t *usbvcp)
1221 {
1222 	usbvc_power_t	*pm;
1223 	int		rval;
1224 
1225 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1226 	    "destroy_power_mgmt enter");
1227 	mutex_enter(&usbvcp->usbvc_mutex);
1228 	pm = usbvcp->usbvc_pm;
1229 	if (pm && (usbvcp->usbvc_dev_state != USB_DEV_DISCONNECTED)) {
1230 
1231 		usbvc_pm_busy_component(usbvcp);
1232 		if (pm->usbvc_wakeup_enabled) {
1233 			pm->usbvc_raise_power = B_TRUE;
1234 			mutex_exit(&usbvcp->usbvc_mutex);
1235 
1236 			/* First bring the device to full power */
1237 			(void) pm_raise_power(usbvcp->usbvc_dip, 0,
1238 			    USB_DEV_OS_FULL_PWR);
1239 			if ((rval = usb_handle_remote_wakeup(
1240 			    usbvcp->usbvc_dip,
1241 			    USB_REMOTE_WAKEUP_DISABLE)) !=
1242 			    USB_SUCCESS) {
1243 				USB_DPRINTF_L2(PRINT_MASK_ATTA,
1244 				    usbvcp->usbvc_log_handle,
1245 				    "usbvc_destroy_power_mgmt: "
1246 				    "Error disabling rmt wakeup: rval = %d",
1247 				    rval);
1248 			}
1249 			mutex_enter(&usbvcp->usbvc_mutex);
1250 			pm->usbvc_raise_power = B_FALSE;
1251 
1252 		}
1253 		mutex_exit(&usbvcp->usbvc_mutex);
1254 
1255 		/*
1256 		 * Since remote wakeup is disabled now,
1257 		 * no one can raise power
1258 		 * and get to device once power is lowered here.
1259 		 */
1260 		(void) pm_lower_power(usbvcp->usbvc_dip, 0, USB_DEV_OS_PWR_OFF);
1261 		mutex_enter(&usbvcp->usbvc_mutex);
1262 		usbvc_pm_idle_component(usbvcp);
1263 	}
1264 
1265 	if (pm) {
1266 		kmem_free(pm, sizeof (usbvc_power_t));
1267 		usbvcp->usbvc_pm = NULL;
1268 	}
1269 	mutex_exit(&usbvcp->usbvc_mutex);
1270 }
1271 
1272 
1273 static void
1274 usbvc_pm_busy_component(usbvc_state_t *usbvcp)
1275 {
1276 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
1277 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1278 	    "usbvc_pm_busy_component: enter");
1279 
1280 	usbvcp->usbvc_pm->usbvc_pm_busy++;
1281 	mutex_exit(&usbvcp->usbvc_mutex);
1282 
1283 	if (pm_busy_component(usbvcp->usbvc_dip, 0) !=
1284 	    DDI_SUCCESS) {
1285 		mutex_enter(&usbvcp->usbvc_mutex);
1286 		USB_DPRINTF_L2(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1287 		    "usbvc_pm_busy_component: pm busy fail, usbvc_pm_busy=%d",
1288 		    usbvcp->usbvc_pm->usbvc_pm_busy);
1289 
1290 		usbvcp->usbvc_pm->usbvc_pm_busy--;
1291 		mutex_exit(&usbvcp->usbvc_mutex);
1292 	}
1293 	mutex_enter(&usbvcp->usbvc_mutex);
1294 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1295 	    "usbvc_pm_busy_component: exit");
1296 }
1297 
1298 
1299 static void
1300 usbvc_pm_idle_component(usbvc_state_t *usbvcp)
1301 {
1302 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
1303 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1304 	    "usbvc_pm_idle_component: enter");
1305 
1306 	if (usbvcp->usbvc_pm != NULL) {
1307 		mutex_exit(&usbvcp->usbvc_mutex);
1308 		if (pm_idle_component(usbvcp->usbvc_dip, 0) ==
1309 		    DDI_SUCCESS) {
1310 			mutex_enter(&usbvcp->usbvc_mutex);
1311 			ASSERT(usbvcp->usbvc_pm->usbvc_pm_busy > 0);
1312 			usbvcp->usbvc_pm->usbvc_pm_busy--;
1313 			mutex_exit(&usbvcp->usbvc_mutex);
1314 		}
1315 		mutex_enter(&usbvcp->usbvc_mutex);
1316 		USB_DPRINTF_L2(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1317 		    "usbvc_pm_idle_component: %d",
1318 		    usbvcp->usbvc_pm->usbvc_pm_busy);
1319 	}
1320 }
1321 
1322 
1323 /*
1324  * usbvc_pwrlvl0:
1325  * Functions to handle power transition for OS levels 0 -> 3
1326  */
1327 static int
1328 usbvc_pwrlvl0(usbvc_state_t *usbvcp)
1329 {
1330 	int rval;
1331 
1332 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1333 	    "usbvc_pwrlvl0, dev_state: %x", usbvcp->usbvc_dev_state);
1334 
1335 	switch (usbvcp->usbvc_dev_state) {
1336 	case USB_DEV_ONLINE:
1337 		/* Deny the powerdown request if the device is busy */
1338 		if (usbvcp->usbvc_pm->usbvc_pm_busy != 0) {
1339 		USB_DPRINTF_L2(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1340 		    "usbvc_pwrlvl0: usbvc_pm_busy");
1341 
1342 			return (USB_FAILURE);
1343 		}
1344 
1345 		/* Issue USB D3 command to the device here */
1346 		rval = usb_set_device_pwrlvl3(usbvcp->usbvc_dip);
1347 		ASSERT(rval == USB_SUCCESS);
1348 
1349 		usbvcp->usbvc_dev_state = USB_DEV_PWRED_DOWN;
1350 		usbvcp->usbvc_pm->usbvc_current_power = USB_DEV_OS_PWR_OFF;
1351 
1352 		/* FALLTHRU */
1353 	case USB_DEV_DISCONNECTED:
1354 	case USB_DEV_SUSPENDED:
1355 		/* allow a disconnect/cpr'ed device to go to lower power */
1356 
1357 		return (USB_SUCCESS);
1358 	case USB_DEV_PWRED_DOWN:
1359 	default:
1360 		USB_DPRINTF_L2(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1361 		    "usbvc_pwrlvl0: illegal dev state");
1362 
1363 		return (USB_FAILURE);
1364 	}
1365 }
1366 
1367 
1368 /*
1369  * usbvc_pwrlvl1:
1370  *	Functions to handle power transition to OS levels -> 2
1371  */
1372 static int
1373 usbvc_pwrlvl1(usbvc_state_t *usbvcp)
1374 {
1375 	int	rval;
1376 
1377 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1378 	    "usbvc_pwrlvl1");
1379 
1380 	/* Issue USB D2 command to the device here */
1381 	rval = usb_set_device_pwrlvl2(usbvcp->usbvc_dip);
1382 	ASSERT(rval == USB_SUCCESS);
1383 
1384 	return (USB_FAILURE);
1385 }
1386 
1387 
1388 /*
1389  * usbvc_pwrlvl2:
1390  *	Functions to handle power transition to OS levels -> 1
1391  */
1392 static int
1393 usbvc_pwrlvl2(usbvc_state_t *usbvcp)
1394 {
1395 	int	rval;
1396 
1397 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1398 	    "usbvc_pwrlvl2");
1399 
1400 	/* Issue USB D1 command to the device here */
1401 	rval = usb_set_device_pwrlvl1(usbvcp->usbvc_dip);
1402 	ASSERT(rval == USB_SUCCESS);
1403 
1404 	return (USB_FAILURE);
1405 }
1406 
1407 
1408 /*
1409  * usbvc_pwrlvl3:
1410  *	Functions to handle power transition to OS level -> 0
1411  */
1412 static int
1413 usbvc_pwrlvl3(usbvc_state_t *usbvcp)
1414 {
1415 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1416 	    "usbvc_pwrlvl3, dev_stat=%d", usbvcp->usbvc_dev_state);
1417 
1418 	switch (usbvcp->usbvc_dev_state) {
1419 	case USB_DEV_PWRED_DOWN:
1420 		/* Issue USB D0 command to the device here */
1421 		(void) usb_set_device_pwrlvl0(usbvcp->usbvc_dip);
1422 
1423 		usbvcp->usbvc_dev_state = USB_DEV_ONLINE;
1424 		usbvcp->usbvc_pm->usbvc_current_power =
1425 		    USB_DEV_OS_FULL_PWR;
1426 
1427 		/* FALLTHRU */
1428 	case USB_DEV_ONLINE:
1429 		/* we are already in full power */
1430 		/* FALLTHRU */
1431 	case USB_DEV_DISCONNECTED:
1432 	case USB_DEV_SUSPENDED:
1433 		/*
1434 		 * PM framework tries to put us in full power
1435 		 * during system shutdown. If we are disconnected/cpr'ed
1436 		 * return success anyways
1437 		 */
1438 
1439 		return (USB_SUCCESS);
1440 	default:
1441 		USB_DPRINTF_L2(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1442 		    "usbvc_pwrlvl3: illegal dev state");
1443 
1444 		return (USB_FAILURE);
1445 	}
1446 }
1447 
1448 
1449 /*
1450  * usbvc_cpr_suspend:
1451  *	Clean up device.
1452  *	Wait for any IO to finish, then close pipes.
1453  *	Quiesce device.
1454  */
1455 static void
1456 usbvc_cpr_suspend(dev_info_t *dip)
1457 {
1458 	int		instance = ddi_get_instance(dip);
1459 	usbvc_state_t	*usbvcp = ddi_get_soft_state(usbvc_statep, instance);
1460 
1461 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1462 	    "usbvc_cpr_suspend enter");
1463 
1464 	mutex_enter(&usbvcp->usbvc_mutex);
1465 
1466 	/*
1467 	 * Set dev_state to suspended so other driver threads don't start any
1468 	 * new I/O.
1469 	 */
1470 	usbvcp->usbvc_dev_state = USB_DEV_SUSPENDED;
1471 
1472 	/*
1473 	 * Wake up the read threads in case there are any threads are blocking.
1474 	 * After being waked up, those threads will quit immediately since the
1475 	 * dev_state is not ONLINE
1476 	 */
1477 	if (usbvcp->usbvc_io_type == V4L2_MEMORY_MMAP) {
1478 		cv_broadcast(&usbvcp->usbvc_mapio_cv);
1479 	} else {
1480 		cv_broadcast(&usbvcp->usbvc_read_cv);
1481 	}
1482 	/* Wait for the other threads to quit */
1483 	(void) usbvc_serialize_access(usbvcp, USBVC_SER_NOSIG);
1484 	usbvc_release_access(usbvcp);
1485 	mutex_exit(&usbvcp->usbvc_mutex);
1486 
1487 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
1488 	    "usbvc_cpr_suspend: return");
1489 }
1490 
1491 
1492 /*
1493  * usbvc_cpr_resume:
1494  *
1495  *	usbvc_restore_device_state marks success by putting device back online
1496  */
1497 static void
1498 usbvc_cpr_resume(dev_info_t *dip)
1499 {
1500 	int		instance = ddi_get_instance(dip);
1501 	usbvc_state_t	*usbvcp = ddi_get_soft_state(usbvc_statep, instance);
1502 
1503 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
1504 	    "resume: enter");
1505 
1506 	/*
1507 	 * NOTE: A pm_raise_power in usbvc_restore_device_state will bring
1508 	 * the power-up state of device into synch with the system.
1509 	 */
1510 	mutex_enter(&usbvcp->usbvc_mutex);
1511 	usbvc_restore_device_state(dip, usbvcp);
1512 	mutex_exit(&usbvcp->usbvc_mutex);
1513 }
1514 
1515 
1516 /*
1517  *  usbvc_restore_device_state:
1518  *	Called during hotplug-reconnect and resume.
1519  *		reenable power management
1520  *		Verify the device is the same as before the disconnect/suspend.
1521  *		Restore device state
1522  *		Thaw any IO which was frozen.
1523  *		Quiesce device.  (Other routines will activate if thawed IO.)
1524  *		Set device online.
1525  *		Leave device disconnected if there are problems.
1526  */
1527 static void
1528 usbvc_restore_device_state(dev_info_t *dip, usbvc_state_t *usbvcp)
1529 {
1530 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1531 	    "usbvc_restore_device_state: enter");
1532 
1533 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
1534 
1535 	ASSERT((usbvcp->usbvc_dev_state == USB_DEV_DISCONNECTED) ||
1536 	    (usbvcp->usbvc_dev_state == USB_DEV_SUSPENDED));
1537 
1538 	usbvc_pm_busy_component(usbvcp);
1539 	usbvcp->usbvc_pm->usbvc_raise_power = B_TRUE;
1540 	mutex_exit(&usbvcp->usbvc_mutex);
1541 	(void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR);
1542 
1543 	/* Check if we are talking to the same device */
1544 	if (usb_check_same_device(dip, usbvcp->usbvc_log_handle,
1545 	    USB_LOG_L0, PRINT_MASK_ALL,
1546 	    USB_CHK_BASIC|USB_CHK_CFG, NULL) != USB_SUCCESS) {
1547 
1548 		goto fail;
1549 	}
1550 
1551 	mutex_enter(&usbvcp->usbvc_mutex);
1552 	usbvcp->usbvc_pm->usbvc_raise_power = B_FALSE;
1553 	usbvcp->usbvc_dev_state = USB_DEV_ONLINE;
1554 	mutex_exit(&usbvcp->usbvc_mutex);
1555 
1556 	if (usbvcp->usbvc_pm->usbvc_wakeup_enabled) {
1557 
1558 		/* Failure here means device disappeared again. */
1559 		if (usb_handle_remote_wakeup(dip, USB_REMOTE_WAKEUP_ENABLE) !=
1560 		    USB_SUCCESS) {
1561 			USB_DPRINTF_L2(PRINT_MASK_ATTA,
1562 			    usbvcp->usbvc_log_handle,
1563 			    "device may or may not be accessible. "
1564 			    "Please verify reconnection");
1565 		}
1566 	}
1567 	mutex_enter(&usbvcp->usbvc_mutex);
1568 
1569 	usbvc_pm_idle_component(usbvcp);
1570 
1571 	USB_DPRINTF_L4(PRINT_MASK_PM, usbvcp->usbvc_log_handle,
1572 	    "usbvc_restore_device_state: end");
1573 
1574 	return;
1575 
1576 fail:
1577 	/* change the device state from suspended to disconnected */
1578 	mutex_enter(&usbvcp->usbvc_mutex);
1579 	usbvcp->usbvc_dev_state = USB_DEV_DISCONNECTED;
1580 	usbvc_pm_idle_component(usbvcp);
1581 }
1582 
1583 
1584 /* Events */
1585 
1586 /*
1587  * usbvc_disconnect_event_cb:
1588  *	Called when device hotplug-removed.
1589  *		Close pipes. (This does not attempt to contact device.)
1590  *		Set state to DISCONNECTED
1591  */
1592 static int
1593 usbvc_disconnect_event_cb(dev_info_t *dip)
1594 {
1595 	int		instance = ddi_get_instance(dip);
1596 	usbvc_state_t	*usbvcp = ddi_get_soft_state(usbvc_statep, instance);
1597 
1598 	USB_DPRINTF_L4(PRINT_MASK_HOTPLUG, usbvcp->usbvc_log_handle,
1599 	    "disconnect: enter");
1600 
1601 	mutex_enter(&usbvcp->usbvc_mutex);
1602 	/*
1603 	 * Save any state of device or IO in progress required by
1604 	 * usbvc_restore_device_state for proper device "thawing" later.
1605 	 */
1606 	usbvcp->usbvc_dev_state = USB_DEV_DISCONNECTED;
1607 
1608 	/*
1609 	 * wake up the read threads in case there are any threads are blocking,
1610 	 * after being waked up, those threads will quit fail immediately since
1611 	 * we have changed the dev_stat.
1612 	 */
1613 	if (usbvcp->usbvc_io_type == V4L2_MEMORY_MMAP) {
1614 		cv_broadcast(&usbvcp->usbvc_mapio_cv);
1615 	} else {
1616 		cv_broadcast(&usbvcp->usbvc_read_cv);
1617 	}
1618 	/* Wait for the other threads to quit */
1619 	(void) usbvc_serialize_access(usbvcp, USBVC_SER_SIG);
1620 	usbvc_release_access(usbvcp);
1621 	mutex_exit(&usbvcp->usbvc_mutex);
1622 
1623 	return (USB_SUCCESS);
1624 }
1625 
1626 
1627 /*
1628  * usbvc_reconnect_event_cb:
1629  *	Called with device hotplug-inserted
1630  *		Restore state
1631  */
1632 static int
1633 usbvc_reconnect_event_cb(dev_info_t *dip)
1634 {
1635 	int		instance = ddi_get_instance(dip);
1636 	usbvc_state_t	*usbvcp = ddi_get_soft_state(usbvc_statep, instance);
1637 
1638 	USB_DPRINTF_L4(PRINT_MASK_HOTPLUG, usbvcp->usbvc_log_handle,
1639 	    "reconnect: enter");
1640 
1641 	mutex_enter(&usbvcp->usbvc_mutex);
1642 	(void) usbvc_serialize_access(usbvcp, USBVC_SER_SIG);
1643 	usbvc_restore_device_state(dip, usbvcp);
1644 	usbvc_release_access(usbvcp);
1645 	mutex_exit(&usbvcp->usbvc_mutex);
1646 
1647 	return (USB_SUCCESS);
1648 }
1649 
1650 /* Sync objs and lists */
1651 
1652 /*
1653  * init/fini sync objects during attach
1654  */
1655 static void
1656 usbvc_init_sync_objs(usbvc_state_t *usbvcp)
1657 {
1658 	mutex_init(&usbvcp->usbvc_mutex, NULL, MUTEX_DRIVER,
1659 	    usbvcp->usbvc_reg->dev_iblock_cookie);
1660 
1661 	cv_init(&usbvcp->usbvc_serial_cv, NULL, CV_DRIVER, NULL);
1662 	cv_init(&usbvcp->usbvc_read_cv, NULL, CV_DRIVER, NULL);
1663 	cv_init(&usbvcp->usbvc_mapio_cv, NULL, CV_DRIVER, NULL);
1664 
1665 	usbvcp->usbvc_serial_inuse = B_FALSE;
1666 
1667 	usbvcp->usbvc_locks_initialized = B_TRUE;
1668 }
1669 
1670 
1671 static void
1672 usbvc_fini_sync_objs(usbvc_state_t *usbvcp)
1673 {
1674 	cv_destroy(&usbvcp->usbvc_serial_cv);
1675 	cv_destroy(&usbvcp->usbvc_read_cv);
1676 	cv_destroy(&usbvcp->usbvc_mapio_cv);
1677 
1678 	mutex_destroy(&usbvcp->usbvc_mutex);
1679 }
1680 
1681 
1682 static void
1683 usbvc_init_lists(usbvc_state_t *usbvcp)
1684 {
1685 	/* video terminals */
1686 	list_create(&(usbvcp->usbvc_term_list), sizeof (usbvc_terms_t),
1687 	    offsetof(usbvc_terms_t, term_node));
1688 
1689 	/* video units */
1690 	list_create(&(usbvcp->usbvc_unit_list), sizeof (usbvc_units_t),
1691 	    offsetof(usbvc_units_t, unit_node));
1692 
1693 	/* stream interfaces */
1694 	list_create(&(usbvcp->usbvc_stream_list), sizeof (usbvc_stream_if_t),
1695 	    offsetof(usbvc_stream_if_t, stream_if_node));
1696 }
1697 
1698 
1699 /*
1700  * Free all the data structures allocated when parsing descriptors of ctrl
1701  * and stream interfaces. It is safe to call this function because it always
1702  * checks the pointer before free mem.
1703  */
1704 static void
1705 usbvc_fini_lists(usbvc_state_t *usbvcp)
1706 {
1707 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, usbvcp->usbvc_log_handle,
1708 	    "usbvc_fini_lists: enter");
1709 
1710 	usbvc_free_ctrl_descr(usbvcp);
1711 
1712 	/* Free all video stream structure and the sub-structures */
1713 	usbvc_free_stream_descr(usbvcp);
1714 
1715 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, usbvcp->usbvc_log_handle,
1716 	    "usbvc_fini_lists: end");
1717 }
1718 
1719 
1720 /*
1721  * Free all the data structures allocated when parsing descriptors of ctrl
1722  * interface.
1723  */
1724 static void
1725 usbvc_free_ctrl_descr(usbvc_state_t *usbvcp)
1726 {
1727 	usbvc_terms_t	*term;
1728 	usbvc_units_t	*unit;
1729 
1730 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, usbvcp->usbvc_log_handle,
1731 	    "usbvc_free_ctrl_descr: enter");
1732 
1733 	if (usbvcp->usbvc_vc_header) {
1734 		kmem_free(usbvcp->usbvc_vc_header, sizeof (usbvc_vc_header_t));
1735 	}
1736 
1737 	/* Free all video terminal structure */
1738 	while (!list_is_empty(&usbvcp->usbvc_term_list)) {
1739 			term = list_head(&usbvcp->usbvc_term_list);
1740 			if (term != NULL) {
1741 				list_remove(&(usbvcp->usbvc_term_list), term);
1742 				kmem_free(term, sizeof (usbvc_terms_t));
1743 			}
1744 	}
1745 
1746 	/* Free all video unit structure */
1747 	while (!list_is_empty(&usbvcp->usbvc_unit_list)) {
1748 			unit = list_head(&usbvcp->usbvc_unit_list);
1749 			if (unit != NULL) {
1750 				list_remove(&(usbvcp->usbvc_unit_list), unit);
1751 				kmem_free(unit, sizeof (usbvc_units_t));
1752 			}
1753 	}
1754 }
1755 
1756 
1757 /*
1758  * Free all the data structures allocated when parsing descriptors of stream
1759  * interfaces.
1760  */
1761 static void
1762 usbvc_free_stream_descr(usbvc_state_t *usbvcp)
1763 {
1764 	usbvc_stream_if_t	*strm;
1765 	usbvc_input_header_t	*in_hdr;
1766 	usbvc_output_header_t	*out_hdr;
1767 	uint8_t			fmt_cnt, frm_cnt;
1768 
1769 	while (!list_is_empty(&usbvcp->usbvc_stream_list)) {
1770 		USB_DPRINTF_L3(PRINT_MASK_CLOSE, usbvcp->usbvc_log_handle,
1771 		    "usbvc_fini_lists: stream list not empty.");
1772 
1773 		strm = list_head(&usbvcp->usbvc_stream_list);
1774 		if (strm != NULL) {
1775 
1776 			/* unlink this stream's data structure from the list */
1777 			list_remove(&(usbvcp->usbvc_stream_list), strm);
1778 		} else {
1779 
1780 			/* No real stream data structure in the list */
1781 			return;
1782 		}
1783 
1784 		in_hdr = strm->input_header;
1785 		out_hdr = strm->output_header;
1786 
1787 		if (in_hdr) {
1788 			fmt_cnt = in_hdr->descr->bNumFormats;
1789 		} else if (out_hdr) {
1790 			fmt_cnt = out_hdr->descr->bNumFormats;
1791 		}
1792 
1793 		USB_DPRINTF_L3(PRINT_MASK_CLOSE,
1794 		    usbvcp->usbvc_log_handle, "usbvc_fini_lists:"
1795 		    " fmtgrp cnt=%d", fmt_cnt);
1796 
1797 		/* Free headers */
1798 		if (in_hdr) {
1799 			kmem_free(in_hdr, sizeof (usbvc_input_header_t));
1800 		}
1801 		if (out_hdr) {
1802 			kmem_free(out_hdr, sizeof (usbvc_output_header_t));
1803 		}
1804 
1805 		/* Free format descriptors */
1806 		if (strm->format_group) {
1807 			int i;
1808 			usbvc_format_group_t *fmtgrp;
1809 
1810 			for (i = 0; i < fmt_cnt; i++) {
1811 				fmtgrp = &strm->format_group[i];
1812 				if (fmtgrp->format == NULL) {
1813 
1814 					break;
1815 				}
1816 				if (fmtgrp->still) {
1817 					kmem_free(fmtgrp->still,
1818 					    sizeof (usbvc_still_image_frame_t));
1819 				}
1820 				frm_cnt = fmtgrp->format->bNumFrameDescriptors;
1821 
1822 				USB_DPRINTF_L3(PRINT_MASK_CLOSE,
1823 				    usbvcp->usbvc_log_handle,
1824 				    "usbvc_fini_lists:"
1825 				    " frame cnt=%d", frm_cnt);
1826 
1827 				if (fmtgrp->frames) {
1828 					kmem_free(fmtgrp->frames,
1829 					    sizeof (usbvc_frames_t) * frm_cnt);
1830 				}
1831 			}
1832 			kmem_free(strm->format_group,
1833 			    sizeof (usbvc_format_group_t) * fmt_cnt);
1834 		}
1835 		USB_DPRINTF_L3(PRINT_MASK_CLOSE,
1836 		    usbvcp->usbvc_log_handle, "usbvc_fini_lists:"
1837 		    " free stream_if_t");
1838 
1839 		kmem_free(strm, sizeof (usbvc_stream_if_t));
1840 	}
1841 }
1842 
1843 /*
1844  * Parse class specific descriptors of the video device
1845  */
1846 
1847 /*
1848  * Check the length of a class specific descriptor. Make sure cvs_buf_len is
1849  * not less than the length expected according to uvc spec.
1850  *
1851  * Args:
1852  * - off_num: the cvs_buf offset of the descriptor element that
1853  *   indicates the number of variable descriptor elements;
1854  * - size: the size of each variable descriptor element, if zero, then the
1855  *   size value is offered by off_size;
1856  * - off_size: the cvs_buf offset of the descriptor element that indicates
1857  *   the size of each variable descriptor element;
1858  */
1859 static int
1860 usbvc_chk_descr_len(uint8_t off_num, uint8_t size, uint8_t off_size,
1861     usb_cvs_data_t *cvs_data)
1862 {
1863 	uchar_t			*cvs_buf;
1864 	uint_t			cvs_buf_len;
1865 
1866 	cvs_buf = cvs_data->cvs_buf;
1867 	cvs_buf_len = cvs_data->cvs_buf_len;
1868 
1869 	if (size == 0) {
1870 		if (cvs_buf_len > off_size) {
1871 			size = cvs_buf[off_size];
1872 		} else {
1873 
1874 			return (USB_FAILURE);
1875 		}
1876 	}
1877 	if (cvs_buf_len < (off_num + 1)) {
1878 
1879 		return (USB_FAILURE);
1880 	}
1881 
1882 	if (cvs_buf_len < (cvs_buf[off_num] * size + off_num +1)) {
1883 
1884 		return (USB_FAILURE);
1885 	}
1886 
1887 	return (USB_SUCCESS);
1888 }
1889 
1890 
1891 /* Parse the descriptors of control interface */
1892 static int
1893 usbvc_parse_ctrl_if(usbvc_state_t *usbvcp)
1894 {
1895 	int			if_num;
1896 	int			cvs_num;
1897 	usb_alt_if_data_t	*if_alt_data;
1898 	usb_cvs_data_t		*cvs_data;
1899 	uchar_t			*cvs_buf;
1900 	uint_t			cvs_buf_len;
1901 	uint16_t		version;
1902 
1903 	if_num = usbvcp->usbvc_reg->dev_curr_if;
1904 	if_alt_data = usbvcp->usbvc_reg->dev_curr_cfg->cfg_if[if_num].if_alt;
1905 	cvs_data = if_alt_data->altif_cvs;
1906 
1907 	for (cvs_num = 0; cvs_num < if_alt_data->altif_n_cvs; cvs_num++) {
1908 		cvs_buf = cvs_data[cvs_num].cvs_buf;
1909 		cvs_buf_len = cvs_data[cvs_num].cvs_buf_len;
1910 		USB_DPRINTF_L3(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
1911 		    "usbvc_parse_ctrl_if: cvs_num= %d, cvs_buf_len=%d",
1912 		    cvs_num, cvs_buf_len);
1913 
1914 		/*
1915 		 * parse interface cvs descriptors here; by checking
1916 		 * bDescriptorType (cvs_buf[1])
1917 		 */
1918 		if (cvs_buf[1] != CS_INTERFACE) {
1919 
1920 			continue;
1921 		}
1922 
1923 		/*
1924 		 * Different descriptors in VC interface; according to
1925 		 * bDescriptorSubType (cvs_buf[2])
1926 		 */
1927 		switch (cvs_buf[2]) {
1928 		case VC_HEADER:
1929 
1930 			/*
1931 			 * According to uvc spec, there must be one and only
1932 			 * be one header. If more than one, return failure.
1933 			 */
1934 			if (usbvcp->usbvc_vc_header) {
1935 
1936 				return (USB_FAILURE);
1937 			}
1938 			/*
1939 			 * Check if it is a valid HEADER descriptor in case of
1940 			 * a device not compliant to uvc spec. This descriptor
1941 			 * is critical, return failure if not a valid one.
1942 			 */
1943 			if (usbvc_chk_descr_len(11, 1, 0, cvs_data) !=
1944 			    USB_SUCCESS) {
1945 
1946 				return (USB_FAILURE);
1947 			}
1948 			usbvcp->usbvc_vc_header =
1949 			    (usbvc_vc_header_t *)kmem_zalloc(
1950 			    sizeof (usbvc_vc_header_t), KM_SLEEP);
1951 			usbvcp->usbvc_vc_header->descr =
1952 			    (usbvc_vc_header_descr_t *)&cvs_buf[0];
1953 
1954 			LE_TO_UINT16(usbvcp->usbvc_vc_header->descr->bcdUVC,
1955 			    0, version);
1956 			USB_DPRINTF_L3(PRINT_MASK_ATTA,
1957 			    usbvcp->usbvc_log_handle, "usbvc_parse_ctrl_if:"
1958 			    " VC header, bcdUVC=%x", version);
1959 			if (usbvcp->usbvc_vc_header->descr->bInCollection ==
1960 			    0) {
1961 				USB_DPRINTF_L3(PRINT_MASK_ATTA,
1962 				    usbvcp->usbvc_log_handle,
1963 				    "usbvc_parse_ctrl_if: no strm interfaces");
1964 
1965 				break;
1966 			}
1967 
1968 			/* stream interface numbers */
1969 			usbvcp->usbvc_vc_header->baInterfaceNr = &cvs_buf[12];
1970 
1971 			break;
1972 		case VC_INPUT_TERMINAL:
1973 		{
1974 			usbvc_terms_t *term;
1975 
1976 			/*
1977 			 * Check if it is a valid descriptor in case of a
1978 			 * device not compliant to uvc spec
1979 			 */
1980 			if (cvs_buf_len < USBVC_I_TERM_LEN_MIN) {
1981 
1982 				break;
1983 			}
1984 			term = (usbvc_terms_t *)
1985 			    kmem_zalloc(sizeof (usbvc_terms_t), KM_SLEEP);
1986 			term->descr = (usbvc_term_descr_t *)cvs_buf;
1987 
1988 			USB_DPRINTF_L3(PRINT_MASK_ATTA,
1989 			    usbvcp->usbvc_log_handle, "usbvc_parse_ctrl_if: "
1990 			    "input term type=%x", term->descr->wTerminalType);
1991 			if (term->descr->wTerminalType == ITT_CAMERA) {
1992 				if (usbvc_chk_descr_len(14, 1, 0, cvs_data) !=
1993 				    USB_SUCCESS) {
1994 					kmem_free(term, sizeof (usbvc_terms_t));
1995 
1996 					break;
1997 				}
1998 				term->bmControls = &cvs_buf[15];
1999 			} else if (cvs_buf_len > 8) { /* other input terms */
2000 				term->bSpecific = &cvs_buf[8];
2001 			}
2002 			list_insert_tail(&(usbvcp->usbvc_term_list), term);
2003 
2004 			break;
2005 		}
2006 		case VC_OUTPUT_TERMINAL:
2007 		{
2008 			usbvc_terms_t *term;
2009 
2010 			if (cvs_buf_len < USBVC_O_TERM_LEN_MIN) {
2011 
2012 				break;
2013 			}
2014 			term = (usbvc_terms_t *)
2015 			    kmem_zalloc(sizeof (usbvc_terms_t), KM_SLEEP);
2016 			term->descr = (usbvc_term_descr_t *)cvs_buf;
2017 
2018 			USB_DPRINTF_L3(PRINT_MASK_ATTA,
2019 			    usbvcp->usbvc_log_handle, "usbvc_parse_ctrl_if:"
2020 			    " output term id= %x", term->descr->bTerminalID);
2021 			if (cvs_buf_len > 9) {
2022 				term->bSpecific = &cvs_buf[9];
2023 			}
2024 			list_insert_tail(&(usbvcp->usbvc_term_list), term);
2025 
2026 			break;
2027 		}
2028 		case VC_PROCESSING_UNIT:
2029 		{
2030 			uint8_t sz;
2031 			usbvc_units_t *unit;
2032 
2033 			if (usbvc_chk_descr_len(7, 1, 0, cvs_data) !=
2034 			    USB_SUCCESS) {
2035 
2036 				break;
2037 			}
2038 
2039 			/* bControlSize */
2040 			sz = cvs_buf[7];
2041 
2042 			if ((sz + 8) >= cvs_buf_len) {
2043 
2044 				break;
2045 			}
2046 			unit = (usbvc_units_t *)
2047 			    kmem_zalloc(sizeof (usbvc_units_t), KM_SLEEP);
2048 
2049 			unit->descr = (usbvc_unit_descr_t *)cvs_buf;
2050 
2051 			USB_DPRINTF_L3(PRINT_MASK_ATTA,
2052 			    usbvcp->usbvc_log_handle, "usbvc_parse_ctrl_if: "
2053 			    "unit type=%x", unit->descr->bDescriptorSubType);
2054 
2055 			if (sz != 0) {
2056 				unit->bmControls = &cvs_buf[8];
2057 			}
2058 			unit->iProcessing = cvs_buf[8 + sz];
2059 
2060 			/*
2061 			 * video class 1.1 version add one element
2062 			 * (bmVideoStandards) to processing unit descriptor
2063 			 */
2064 			if (cvs_buf_len > (9 + sz)) {
2065 				unit->bmVideoStandards = cvs_buf[9 + sz];
2066 			}
2067 			list_insert_tail(&(usbvcp->usbvc_unit_list), unit);
2068 
2069 			break;
2070 		}
2071 		case VC_SELECTOR_UNIT:
2072 		{
2073 			uint8_t  pins;
2074 			usbvc_units_t *unit;
2075 
2076 			if (usbvc_chk_descr_len(4, 1, 0, cvs_data) !=
2077 			    USB_SUCCESS) {
2078 
2079 				break;
2080 			}
2081 			pins = cvs_buf[4];
2082 			if ((pins + 5) >= cvs_buf_len) {
2083 
2084 				break;
2085 			}
2086 			unit = (usbvc_units_t *)
2087 			    kmem_zalloc(sizeof (usbvc_units_t), KM_SLEEP);
2088 
2089 			unit->descr = (usbvc_unit_descr_t *)cvs_buf;
2090 
2091 			USB_DPRINTF_L3(PRINT_MASK_ATTA,
2092 			    usbvcp->usbvc_log_handle, "usbvc_parse_ctrl_if: "
2093 			    "unit type=%x", unit->descr->bDescriptorSubType);
2094 			if (pins > 0) {
2095 				unit->baSourceID = &cvs_buf[5];
2096 			}
2097 			unit->iSelector = cvs_buf[5 + pins];
2098 
2099 			list_insert_tail(&(usbvcp->usbvc_unit_list), unit);
2100 
2101 			break;
2102 		}
2103 		case VC_EXTENSION_UNIT:
2104 		{
2105 			uint8_t  pins, n;
2106 			usbvc_units_t *unit;
2107 
2108 			if (usbvc_chk_descr_len(21, 1, 0, cvs_data) !=
2109 			    USB_SUCCESS) {
2110 
2111 				break;
2112 			}
2113 			pins = cvs_buf[21];
2114 			if ((pins + 22) >= cvs_buf_len) {
2115 
2116 				break;
2117 			}
2118 
2119 			/* Size of bmControls */
2120 			n = cvs_buf[pins + 22];
2121 
2122 			if (usbvc_chk_descr_len(pins + 22, 1, 0, cvs_data) !=
2123 			    USB_SUCCESS) {
2124 
2125 				break;
2126 			}
2127 			if ((23 + pins + n) >= cvs_buf_len) {
2128 
2129 				break;
2130 			}
2131 			unit = (usbvc_units_t *)
2132 			    kmem_zalloc(sizeof (usbvc_units_t), KM_SLEEP);
2133 
2134 			unit->descr = (usbvc_unit_descr_t *)cvs_buf;
2135 
2136 			USB_DPRINTF_L3(PRINT_MASK_ATTA,
2137 			    usbvcp->usbvc_log_handle, "usbvc_parse_ctrl_if: "
2138 			    "unit type=%x", unit->descr->bDescriptorSubType);
2139 			if (pins != 0) {
2140 				unit->baSourceID = &cvs_buf[22];
2141 			}
2142 			unit->bControlSize = cvs_buf[22 + pins];
2143 
2144 			if (unit->bControlSize != 0) {
2145 				unit->bmControls = &cvs_buf[23 + pins];
2146 			}
2147 			unit->iExtension = cvs_buf[23 + pins + n];
2148 
2149 			list_insert_tail(&(usbvcp->usbvc_unit_list), unit);
2150 
2151 			break;
2152 		}
2153 		default:
2154 
2155 			break;
2156 		}
2157 	}
2158 
2159 	/*
2160 	 * For webcam which is not compliant to video class specification
2161 	 * and no header descriptor in VC interface, return USB_FAILURE.
2162 	 */
2163 	if (!usbvcp->usbvc_vc_header) {
2164 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2165 		    "usbvc_parse_ctrl_if: no header descriptor");
2166 
2167 		return (USB_FAILURE);
2168 	}
2169 
2170 	return (USB_SUCCESS);
2171 }
2172 
2173 
2174 /* Parse all the cvs descriptors in one stream interface. */
2175 usbvc_stream_if_t *
2176 usbvc_parse_stream_if(usbvc_state_t *usbvcp, int if_num)
2177 {
2178 	usb_alt_if_data_t	*if_alt_data;
2179 	uint_t			i, j;
2180 	usbvc_stream_if_t	*strm_if;
2181 	uint16_t		pktsize;
2182 	uint8_t			ep_adr;
2183 
2184 	strm_if = (usbvc_stream_if_t *)kmem_zalloc(sizeof (usbvc_stream_if_t),
2185 	    KM_SLEEP);
2186 	strm_if->if_descr = &usbvcp->usbvc_reg->dev_curr_cfg->cfg_if[if_num];
2187 	if_alt_data = strm_if->if_descr->if_alt;
2188 	if (usbvc_parse_stream_header(usbvcp, strm_if) != USB_SUCCESS) {
2189 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2190 		    "usbvc_parse_stream_if: parse header fail");
2191 		kmem_free(strm_if, sizeof (usbvc_stream_if_t));
2192 
2193 		return (NULL);
2194 	}
2195 	if (usbvc_parse_format_groups(usbvcp, strm_if) != USB_SUCCESS) {
2196 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2197 		    "usbvc_parse_stream_if: parse groups fail");
2198 		kmem_free(strm_if, sizeof (usbvc_stream_if_t));
2199 
2200 		return (NULL);
2201 	}
2202 
2203 	/* Parse the alternate settings to find the maximum bandwidth. */
2204 	for (i = 0; i < strm_if->if_descr->if_n_alt; i++) {
2205 		if_alt_data = &strm_if->if_descr->if_alt[i];
2206 		for (j = 0; j < if_alt_data->altif_n_ep; j++) {
2207 			ep_adr =
2208 			    if_alt_data->altif_ep[j].ep_descr.bEndpointAddress;
2209 			if (strm_if->input_header != NULL &&
2210 			    ep_adr !=
2211 			    strm_if->input_header->descr->bEndpointAddress) {
2212 
2213 				continue;
2214 			}
2215 			if (strm_if->output_header != NULL &&
2216 			    ep_adr !=
2217 			    strm_if->output_header->descr->bEndpointAddress) {
2218 
2219 				continue;
2220 			}
2221 			pktsize =
2222 			    if_alt_data->altif_ep[j].ep_descr.wMaxPacketSize;
2223 			pktsize = HS_PKT_SIZE(pktsize);
2224 			if (pktsize > strm_if->max_isoc_payload) {
2225 				strm_if->max_isoc_payload = pktsize;
2226 			}
2227 		}
2228 	}
2229 
2230 	/* initialize MJPEC FID toggle */
2231 	strm_if->fid = 0xff;
2232 
2233 	/*
2234 	 * initialize desired number of buffers used internally in read() mode
2235 	 */
2236 	strm_if->buf_read_num = USBVC_DEFAULT_READ_BUF_NUM;
2237 
2238 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2239 	    "usbvc_parse_stream_if: return. max_isoc_payload=%x",
2240 	    strm_if->max_isoc_payload);
2241 
2242 	return (strm_if);
2243 }
2244 
2245 
2246 /*
2247  * Parse all the stream interfaces asociated with the video control interface.
2248  * This driver will attach to a video control interface on the device,
2249  * there might be multiple video stream interfaces associated with one video
2250  * control interface.
2251  */
2252 static int
2253 usbvc_parse_stream_ifs(usbvc_state_t *usbvcp)
2254 {
2255 	int			i, if_cnt, if_num;
2256 	usbvc_stream_if_t	*strm_if;
2257 
2258 	if_cnt = usbvcp->usbvc_vc_header->descr->bInCollection;
2259 	if (if_cnt == 0) {
2260 		ASSERT(list_is_empty(&usbvcp->usbvc_stream_list));
2261 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2262 		    "usbvc_parse_stream_ifs: no stream interfaces");
2263 
2264 		return (USB_SUCCESS);
2265 	}
2266 	for (i = 0; i < if_cnt; i++) {
2267 		if_num = usbvcp->usbvc_vc_header->baInterfaceNr[i];
2268 		strm_if = usbvc_parse_stream_if(usbvcp, if_num);
2269 		if (strm_if == NULL) {
2270 			USB_DPRINTF_L2(PRINT_MASK_ATTA,
2271 			    usbvcp->usbvc_log_handle, "usbvc_parse_stream_ifs:"
2272 			    " parse stream interface %d failed.", if_num);
2273 
2274 			return (USB_FAILURE);
2275 		}
2276 		/* video data buffers */
2277 		list_create(&(strm_if->buf_map.uv_buf_free),
2278 		    sizeof (usbvc_buf_t), offsetof(usbvc_buf_t, buf_node));
2279 		list_create(&(strm_if->buf_map.uv_buf_done),
2280 		    sizeof (usbvc_buf_t), offsetof(usbvc_buf_t, buf_node));
2281 		list_create(&(strm_if->buf_read.uv_buf_free),
2282 		    sizeof (usbvc_buf_t), offsetof(usbvc_buf_t, buf_node));
2283 		list_create(&(strm_if->buf_read.uv_buf_done),
2284 		    sizeof (usbvc_buf_t), offsetof(usbvc_buf_t, buf_node));
2285 
2286 		list_insert_tail(&(usbvcp->usbvc_stream_list), strm_if);
2287 	}
2288 
2289 	/* Make the first stream interface as the default one. */
2290 	usbvcp->usbvc_curr_strm =
2291 	    (usbvc_stream_if_t *)list_head(&usbvcp->usbvc_stream_list);
2292 
2293 	return (USB_SUCCESS);
2294 }
2295 
2296 
2297 /*
2298  * Parse colorspace descriptor and still image descriptor of a format group.
2299  * There is only one colorspace or still image descriptor in one format group.
2300  */
2301 static void
2302 usbvc_parse_color_still(usbvc_state_t *usbvcp, usbvc_format_group_t *fmtgrp,
2303 	usb_cvs_data_t *cvs_data, uint_t cvs_num, uint_t altif_n_cvs)
2304 {
2305 	uint8_t		frame_cnt;
2306 	uint_t		last_frame, i;
2307 	uchar_t		*cvs_buf;
2308 	uint_t			cvs_buf_len;
2309 
2310 	frame_cnt = fmtgrp->format->bNumFrameDescriptors;
2311 	last_frame = frame_cnt + cvs_num;
2312 
2313 	/*
2314 	 * Find the still image descr and color format descr if there are any.
2315 	 * UVC Spec: only one still image and one color descr is allowed in
2316 	 * one format group.
2317 	 */
2318 	for (i = 1; i <= 2; i++) {
2319 		if ((last_frame + i) >= altif_n_cvs) {
2320 
2321 			break;
2322 		}
2323 		cvs_buf = cvs_data[last_frame + i].cvs_buf;
2324 		cvs_buf_len = cvs_data[last_frame + i].cvs_buf_len;
2325 
2326 		if (cvs_buf[2] == VS_STILL_IMAGE_FRAME) {
2327 			uint8_t m, n, off;
2328 			usbvc_still_image_frame_t *st;
2329 
2330 			if (usbvc_chk_descr_len(4, 4, 0, cvs_data) !=
2331 			    USB_SUCCESS) {
2332 
2333 				continue;
2334 			}
2335 
2336 			/* Number of Image Size patterns of this format */
2337 			n = cvs_buf[4];
2338 
2339 			/* offset of bNumCompressionPattern */
2340 			off = 9 + 4 * n -4;
2341 
2342 			if (off >= cvs_buf_len) {
2343 
2344 				continue;
2345 			}
2346 
2347 			/* Number of compression pattern of this format */
2348 			m = cvs_buf[off];
2349 
2350 			if (usbvc_chk_descr_len(m, 1, 0, cvs_data) !=
2351 			    USB_SUCCESS) {
2352 
2353 				continue;
2354 			}
2355 			fmtgrp->still = (usbvc_still_image_frame_t *)
2356 			    kmem_zalloc(sizeof (usbvc_still_image_frame_t),
2357 			    KM_SLEEP);
2358 			st = fmtgrp->still;
2359 			st->descr = (usbvc_still_image_frame_descr_t *)cvs_buf;
2360 			n = st->descr->bNumImageSizePatterns;
2361 			if (n > 0) {
2362 				st->width_height =
2363 				    (width_height_t *)&cvs_buf[5];
2364 			}
2365 			st->bNumCompressionPattern = cvs_buf[off];
2366 			if (cvs_buf[off] > 0) {
2367 				st->bCompression = &cvs_buf[off + 1];
2368 			}
2369 		}
2370 		if (cvs_buf[2] == VS_COLORFORMAT) {
2371 			fmtgrp->color = (usbvc_color_matching_descr_t *)cvs_buf;
2372 			fmtgrp->v4l2_color = usbvc_v4l2_colorspace(
2373 			    fmtgrp->color->bColorPrimaries);
2374 		}
2375 	}
2376 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2377 	    "usbvc_parse_color_still: still=%p, color=%p",
2378 	    (void *)fmtgrp->still, (void *)fmtgrp->color);
2379 }
2380 
2381 
2382 /*
2383  * Parse frame descriptors of a format group. There might be multi frame
2384  * descriptors in one format group.
2385  */
2386 static void
2387 usbvc_parse_frames(usbvc_state_t *usbvcp, usbvc_format_group_t *fmtgrp,
2388 	usb_cvs_data_t *cvs_data, uint_t cvs_num, uint_t altif_n_cvs)
2389 {
2390 	uint_t		last_frame;
2391 	usbvc_frames_t	*frm;
2392 	usb_cvs_data_t		*cvs;
2393 	uchar_t		*cvs_buf;
2394 	uint_t			cvs_buf_len;
2395 	uint8_t		i;
2396 	uint8_t		frame_cnt = fmtgrp->format->bNumFrameDescriptors;
2397 
2398 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2399 	    "usbvc_parse_format_group: frame_cnt=%d", frame_cnt);
2400 
2401 	if (frame_cnt == 0) {
2402 		fmtgrp->frames = NULL;
2403 
2404 		return;
2405 	}
2406 
2407 	/* All these mem allocated will be freed in cleanup() */
2408 	fmtgrp->frames = (usbvc_frames_t *)
2409 	    kmem_zalloc(sizeof (usbvc_frames_t) * frame_cnt, KM_SLEEP);
2410 
2411 	last_frame = frame_cnt + cvs_num;
2412 	cvs_num++;
2413 	i = 0;
2414 
2415 	/*
2416 	 * Traverse from the format decr's first frame decr to the the last
2417 	 * frame descr.
2418 	 */
2419 	for (; cvs_num <= last_frame; cvs_num++) {
2420 		USB_DPRINTF_L3(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2421 		    "usbvc_parse_frames: cvs_num=%d, i=%d", cvs_num, i);
2422 		if (cvs_num >= altif_n_cvs) {
2423 			USB_DPRINTF_L3(PRINT_MASK_ATTA,
2424 			    usbvcp->usbvc_log_handle,
2425 			    "usbvc_parse_frames: less frames than "
2426 			    "expected, cvs_num=%d, i=%d", cvs_num, i);
2427 
2428 			break;
2429 		}
2430 		cvs = &cvs_data[cvs_num];
2431 		cvs_buf = cvs->cvs_buf;
2432 		cvs_buf_len = cvs->cvs_buf_len;
2433 		if (cvs_buf_len < USBVC_FRAME_LEN_MIN) {
2434 			i++;
2435 
2436 			continue;
2437 		}
2438 		frm = &fmtgrp->frames[i];
2439 		frm->descr = (usbvc_frame_descr_t *)cvs->cvs_buf;
2440 
2441 		/* Descriptor for discrete frame interval */
2442 		if (frm->descr->bFrameIntervalType > 0) {
2443 			if (usbvc_chk_descr_len(25, 4, 0, cvs) != USB_SUCCESS) {
2444 				frm->descr = NULL;
2445 				i++;
2446 
2447 				continue;
2448 			}
2449 
2450 			frm->dwFrameInterval = (uint8_t *)&cvs_buf[26];
2451 		} else {	/* Continuous interval */
2452 			if (cvs_buf_len < USBVC_FRAME_LEN_CON) {
2453 				frm->descr = NULL;
2454 				i++;
2455 
2456 				continue;
2457 			}
2458 
2459 			/* Continuous frame intervals */
2460 			LE_TO_UINT32(cvs_buf, 26, frm->dwMinFrameInterval);
2461 			LE_TO_UINT32(cvs_buf, 30, frm->dwMaxFrameInterval);
2462 			LE_TO_UINT32(cvs_buf, 34, frm->dwFrameIntervalStep);
2463 		}
2464 
2465 		i++;
2466 	}
2467 	fmtgrp->frame_cnt = i;
2468 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2469 	    "usbvc_parse_frames: %d frames are actually parsed",
2470 	    fmtgrp->frame_cnt);
2471 }
2472 
2473 
2474 /* Parse one of the format groups in a stream interface */
2475 static int
2476 usbvc_parse_format_group(usbvc_state_t *usbvcp, usbvc_format_group_t *fmtgrp,
2477 	usb_cvs_data_t *cvs_data, uint_t cvs_num, uint_t altif_n_cvs)
2478 {
2479 	usbvc_format_descr_t *fmt;
2480 
2481 	fmt = fmtgrp->format;
2482 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2483 	    "usbvc_parse_format_group: frame_cnt=%d, cvs_num=%d",
2484 	    fmt->bNumFrameDescriptors, cvs_num);
2485 
2486 	switch (fmt->bDescriptorSubType) {
2487 	case VS_FORMAT_UNCOMPRESSED:
2488 		usbvc_parse_color_still(usbvcp, fmtgrp, cvs_data, cvs_num,
2489 		    altif_n_cvs);
2490 		usbvc_parse_frames(usbvcp, fmtgrp, cvs_data, cvs_num,
2491 		    altif_n_cvs);
2492 		fmtgrp->v4l2_bpp = fmt->fmt.uncompressed.bBitsPerPixel / 8;
2493 		fmtgrp->v4l2_pixelformat = usbvc_v4l2_guid2fcc(
2494 		    (uint8_t *)&fmt->fmt.uncompressed.guidFormat);
2495 
2496 		break;
2497 	case VS_FORMAT_MJPEG:
2498 		usbvc_parse_color_still(usbvcp, fmtgrp, cvs_data, cvs_num,
2499 		    altif_n_cvs);
2500 		usbvc_parse_frames(usbvcp, fmtgrp, cvs_data, cvs_num,
2501 		    altif_n_cvs);
2502 		fmtgrp->v4l2_bpp = 0;
2503 		fmtgrp->v4l2_pixelformat = V4L2_PIX_FMT_MJPEG;
2504 
2505 		break;
2506 	case VS_FORMAT_MPEG2TS:
2507 	case VS_FORMAT_DV:
2508 	case VS_FORMAT_FRAME_BASED:
2509 	case VS_FORMAT_STREAM_BASED:
2510 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2511 		    "usbvc_parse_format_group: format not supported yet.");
2512 
2513 		return (USB_FAILURE);
2514 	default:
2515 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2516 		    "usbvc_parse_format_group: unknown format.");
2517 
2518 		return (USB_FAILURE);
2519 	}
2520 
2521 	return (USB_SUCCESS);
2522 }
2523 
2524 
2525 /* Parse the descriptors belong to one format */
2526 static int
2527 usbvc_parse_format_groups(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if)
2528 {
2529 	usb_alt_if_data_t	*if_alt_data;
2530 	usb_cvs_data_t		*cvs_data;
2531 	uint8_t			fmtgrp_num, fmtgrp_cnt;
2532 	uchar_t			*cvs_buf;
2533 	uint_t			cvs_num = 0;
2534 	usbvc_format_group_t	*fmtgrp;
2535 
2536 	fmtgrp_cnt = 0;
2537 	/*
2538 	 * bNumFormats indicates the number of formats in this stream
2539 	 * interface. On some devices, we see this number is larger than
2540 	 * the truth.
2541 	 */
2542 	if (strm_if->input_header) {
2543 		fmtgrp_cnt = strm_if->input_header->descr->bNumFormats;
2544 	} else if (strm_if->output_header) {
2545 		fmtgrp_cnt = strm_if->output_header->descr->bNumFormats;
2546 	}
2547 	if (!fmtgrp_cnt) {
2548 
2549 		return (USB_FAILURE);
2550 	}
2551 	USB_DPRINTF_L3(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2552 	    "usbvc_parse_format_groups: fmtgrp_cnt=%d", fmtgrp_cnt);
2553 
2554 	fmtgrp = (usbvc_format_group_t *)
2555 	    kmem_zalloc(sizeof (usbvc_format_group_t) * fmtgrp_cnt, KM_SLEEP);
2556 
2557 	if_alt_data = strm_if->if_descr->if_alt;
2558 	cvs_data = if_alt_data->altif_cvs;
2559 
2560 	for (fmtgrp_num = 0; fmtgrp_num < fmtgrp_cnt &&
2561 	    cvs_num < if_alt_data->altif_n_cvs; cvs_num++) {
2562 		cvs_buf = cvs_data[cvs_num].cvs_buf;
2563 		switch (cvs_buf[2]) {
2564 		case VS_FORMAT_UNCOMPRESSED:
2565 		case VS_FORMAT_MJPEG:
2566 		case VS_FORMAT_MPEG2TS:
2567 		case VS_FORMAT_DV:
2568 		case VS_FORMAT_FRAME_BASED:
2569 		case VS_FORMAT_STREAM_BASED:
2570 			fmtgrp[fmtgrp_num].format =
2571 			    (usbvc_format_descr_t *)cvs_buf;
2572 
2573 			/*
2574 			 * Now cvs_data[cvs_num].cvs_buf is format descriptor,
2575 			 * usbvc_parse_format_group will then parse the frame
2576 			 * descriptors following this format descriptor.
2577 			 */
2578 			(void) usbvc_parse_format_group(usbvcp,
2579 			    &fmtgrp[fmtgrp_num], cvs_data, cvs_num,
2580 			    if_alt_data->altif_n_cvs);
2581 
2582 			fmtgrp_num++;
2583 
2584 			break;
2585 		default:
2586 			break;
2587 		}
2588 	}
2589 
2590 	/* Save the number of parsed format groups. */
2591 	strm_if->fmtgrp_cnt = fmtgrp_num;
2592 	USB_DPRINTF_L3(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2593 	    "usbvc_parse_format_groups: acctually %d formats parsed",
2594 	    fmtgrp_num);
2595 
2596 	/*
2597 	 * If can't find any formats, then free all allocated
2598 	 * usbvc_format_group_t, return failure.
2599 	 */
2600 	if (!(fmtgrp[0].format)) {
2601 		kmem_free(fmtgrp, sizeof (usbvc_format_group_t) * fmtgrp_cnt);
2602 		strm_if->format_group = NULL;
2603 
2604 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2605 		    "usbvc_parse_format_groups: can't find any formats");
2606 
2607 		return (USB_FAILURE);
2608 	}
2609 	strm_if->format_group = fmtgrp;
2610 	USB_DPRINTF_L3(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2611 	    "usbvc_parse_format_groups: %d format groups parsed", fmtgrp_num);
2612 
2613 	return (USB_SUCCESS);
2614 }
2615 
2616 
2617 /*
2618  * Parse the input/output header in one stream interface.
2619  * UVC Spec: there must be one and only one header in one stream interface.
2620  */
2621 int
2622 usbvc_parse_stream_header(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if)
2623 {
2624 	usb_alt_if_data_t	*if_alt_data;
2625 	usb_cvs_data_t		*cvs_data;
2626 	int			cvs_num;
2627 	uchar_t			*cvs_buf;
2628 	usbvc_input_header_t	*in_hdr;
2629 	usbvc_output_header_t	*out_hdr;
2630 
2631 	if_alt_data = strm_if->if_descr->if_alt;
2632 	cvs_data = if_alt_data->altif_cvs;
2633 	for (cvs_num = 0; cvs_num < if_alt_data->altif_n_cvs; cvs_num++) {
2634 		cvs_buf = cvs_data[cvs_num].cvs_buf;
2635 		USB_DPRINTF_L3(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2636 		    "usbvc_parse_stream_header: cvs_num= %d", cvs_num);
2637 
2638 		/*
2639 		 * parse interface cvs descriptors here; by checking
2640 		 * bDescriptorType (cvs_buf[1])
2641 		 */
2642 		if (cvs_buf[1] != CS_INTERFACE) {
2643 
2644 			continue;
2645 		}
2646 
2647 		if (cvs_buf[2] == VS_INPUT_HEADER) {
2648 			if (usbvc_chk_descr_len(3, 0, 12, cvs_data) !=
2649 			    USB_SUCCESS) {
2650 
2651 				continue;
2652 			}
2653 
2654 			strm_if->input_header =
2655 			    (usbvc_input_header_t *)
2656 			    kmem_zalloc(sizeof (usbvc_input_header_t),
2657 			    KM_SLEEP);
2658 			in_hdr = strm_if->input_header;
2659 			in_hdr->descr = (usbvc_input_header_descr_t *)cvs_buf;
2660 			if (in_hdr->descr->bNumFormats > 0) {
2661 				in_hdr->bmaControls = &cvs_buf[13];
2662 			}
2663 
2664 			return (USB_SUCCESS);
2665 		} else if (cvs_buf[2] == VS_OUTPUT_HEADER) {
2666 			if (usbvc_chk_descr_len(3, 0, 8, cvs_data) !=
2667 			    USB_SUCCESS) {
2668 
2669 				continue;
2670 			}
2671 			strm_if->output_header =
2672 			    (usbvc_output_header_t *)
2673 			    kmem_zalloc(sizeof (usbvc_output_header_t),
2674 			    KM_SLEEP);
2675 			out_hdr = strm_if->output_header;
2676 			out_hdr->descr =
2677 			    (usbvc_output_header_descr_t *)cvs_buf;
2678 			if (out_hdr->descr->bNumFormats > 0) {
2679 				out_hdr->bmaControls = &cvs_buf[13];
2680 			}
2681 
2682 			return (USB_SUCCESS);
2683 		} else {
2684 
2685 			continue;
2686 		}
2687 	}
2688 	/* Didn't find one header descriptor. */
2689 	USB_DPRINTF_L2(PRINT_MASK_ATTA, usbvcp->usbvc_log_handle,
2690 	    "usbvc_parse_stream_header: FAIL");
2691 
2692 	return (USB_FAILURE);
2693 }
2694 
2695 /* read I/O functions */
2696 
2697 /* Allocate bufs for read I/O method */
2698 static int
2699 usbvc_alloc_read_bufs(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if)
2700 {
2701 	usbvc_buf_t	*buf;
2702 	uchar_t		*data;
2703 	int		i;
2704 	uint32_t	len;
2705 
2706 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
2707 
2708 	LE_TO_UINT32(strm_if->ctrl_pc.dwMaxVideoFrameSize, 0, len);
2709 	if (!len) {
2710 
2711 		return (USB_FAILURE);
2712 	}
2713 	for (i = 0; i < strm_if->buf_read_num; i++) {
2714 		mutex_exit(&usbvcp->usbvc_mutex);
2715 		buf = (usbvc_buf_t *)kmem_zalloc(sizeof (usbvc_buf_t),
2716 		    KM_SLEEP);
2717 		data = (uchar_t *)kmem_zalloc(len, KM_SLEEP);
2718 		mutex_enter(&usbvcp->usbvc_mutex);
2719 		buf->data = data;
2720 		buf->len = len;
2721 		list_insert_tail(&(strm_if->buf_read.uv_buf_free), buf);
2722 	}
2723 	strm_if->buf_read.buf_cnt = strm_if->buf_read_num;
2724 	USB_DPRINTF_L4(PRINT_MASK_READ, usbvcp->usbvc_log_handle,
2725 	    "read_bufs: %d bufs allocated", strm_if->buf_read.buf_cnt);
2726 
2727 	return (USB_SUCCESS);
2728 }
2729 
2730 
2731 /* Read a done buf, copy data to bp. This function is for read I/O method */
2732 static int
2733 usbvc_read_buf(usbvc_state_t *usbvcp, struct buf *bp)
2734 {
2735 	usbvc_buf_t	*buf;
2736 
2737 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
2738 
2739 	/* read a buf from full list and then put it to free list */
2740 	buf = list_head(&usbvcp->usbvc_curr_strm->buf_read.uv_buf_done);
2741 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
2742 	    "usbvc_read_buf: buf=%p, buf->filled=%d, bfu->len=%d,"
2743 	    " bp->b_bcount=%ld, bp->b_resid=%lu",
2744 	    (void *)buf, buf->filled, buf->len, bp->b_bcount, bp->b_resid);
2745 
2746 	list_remove(&usbvcp->usbvc_curr_strm->buf_read.uv_buf_done, buf);
2747 	bcopy(buf->data, bp->b_un.b_addr, buf->filled);
2748 	bp->b_private = NULL;
2749 	bp->b_resid = bp->b_bcount - buf->filled;
2750 	list_insert_tail(&usbvcp->usbvc_curr_strm->buf_read.uv_buf_free, buf);
2751 
2752 	return (USB_SUCCESS);
2753 }
2754 
2755 
2756 /* Free one buf which is for read/write IO style */
2757 static void
2758 usbvc_free_read_buf(usbvc_buf_t *buf)
2759 {
2760 	if (buf != NULL) {
2761 		if (buf->data) {
2762 			kmem_free(buf->data, buf->len);
2763 		}
2764 		kmem_free(buf, sizeof (usbvc_buf_t));
2765 	}
2766 }
2767 
2768 
2769 /* Free all bufs which are for read/write IO style */
2770 static void
2771 usbvc_free_read_bufs(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if)
2772 {
2773 	usbvc_buf_t	*buf;
2774 
2775 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
2776 
2777 	if (!strm_if) {
2778 
2779 		return;
2780 	}
2781 	buf = strm_if->buf_read.buf_filling;
2782 	usbvc_free_read_buf(buf);
2783 	strm_if->buf_read.buf_filling = NULL;
2784 
2785 	while (!list_is_empty(&strm_if->buf_read.uv_buf_free)) {
2786 		buf = list_head(&strm_if->buf_read.uv_buf_free);
2787 		if (buf != NULL) {
2788 			list_remove(&(strm_if->buf_read.uv_buf_free), buf);
2789 			usbvc_free_read_buf(buf);
2790 		}
2791 	}
2792 	while (!list_is_empty(&strm_if->buf_read.uv_buf_done)) {
2793 		buf = list_head(&strm_if->buf_read.uv_buf_done);
2794 		if (buf != NULL) {
2795 			list_remove(&(strm_if->buf_read.uv_buf_done), buf);
2796 			usbvc_free_read_buf(buf);
2797 		}
2798 	}
2799 	strm_if->buf_read.buf_cnt = 0;
2800 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, usbvcp->usbvc_log_handle,
2801 	    "usbvc_free_read_bufs: return");
2802 }
2803 
2804 
2805 /*
2806  * Allocate bufs for mapped I/O , return the number of allocated bufs
2807  * if success, return 0 if fail.
2808  */
2809 int
2810 usbvc_alloc_map_bufs(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if,
2811 	int buf_cnt, int buf_len)
2812 {
2813 	int		i = 0;
2814 	usbvc_buf_t	*bufs;
2815 
2816 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
2817 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
2818 	    "usbvc_alloc_map_bufs: bufcnt=%d, buflen=%d", buf_cnt, buf_len);
2819 	if (buf_len <= 0 || buf_cnt <= 0) {
2820 		USB_DPRINTF_L2(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
2821 		    "usbvc_alloc_map_bufs: len<=0, cnt<=0");
2822 
2823 		return (0);
2824 	}
2825 	mutex_exit(&usbvcp->usbvc_mutex);
2826 
2827 	bufs = (usbvc_buf_t *) kmem_zalloc(sizeof (usbvc_buf_t) * buf_cnt,
2828 	    KM_SLEEP);
2829 
2830 	mutex_enter(&usbvcp->usbvc_mutex);
2831 	strm_if->buf_map.buf_head = bufs;
2832 	buf_len = ptob(btopr(buf_len));
2833 
2834 	mutex_exit(&usbvcp->usbvc_mutex);
2835 	bufs[0].data = ddi_umem_alloc(buf_len * buf_cnt, DDI_UMEM_SLEEP,
2836 	    &bufs[0].umem_cookie);
2837 	mutex_enter(&usbvcp->usbvc_mutex);
2838 
2839 	for (i = 0; i < buf_cnt; i++) {
2840 		bufs[i].len = buf_len;
2841 		bufs[i].data = bufs[0].data + (buf_len * i);
2842 		bufs[i].umem_cookie = bufs[0].umem_cookie;
2843 		bufs[i].status = USBVC_BUF_INIT;
2844 
2845 		bufs[i].v4l2_buf.index = i;
2846 		bufs[i].v4l2_buf.m.offset = i * bufs[i].len;
2847 		bufs[i].v4l2_buf.length = bufs[i].len;
2848 		bufs[i].v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2849 		bufs[i].v4l2_buf.sequence = 0;
2850 		bufs[i].v4l2_buf.field = V4L2_FIELD_NONE;
2851 		bufs[i].v4l2_buf.memory = V4L2_MEMORY_MMAP;
2852 		bufs[i].v4l2_buf.flags = V4L2_MEMORY_MMAP;
2853 
2854 		list_insert_tail(&strm_if->buf_map.uv_buf_free, &bufs[i]);
2855 		USB_DPRINTF_L4(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
2856 		    "usbvc_alloc_map_bufs: prepare %d buffers of %d bytes",
2857 		    buf_cnt, bufs[i].len);
2858 	}
2859 	strm_if->buf_map.buf_cnt = buf_cnt;
2860 	strm_if->buf_map.buf_filling = NULL;
2861 
2862 	return (buf_cnt);
2863 }
2864 
2865 
2866 /* Free all bufs which are for memory map IO style */
2867 void
2868 usbvc_free_map_bufs(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if)
2869 {
2870 	usbvc_buf_t	*buf;
2871 
2872 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
2873 	if (!strm_if) {
2874 
2875 		return;
2876 	}
2877 	strm_if->buf_map.buf_filling = NULL;
2878 	while (!list_is_empty(&strm_if->buf_map.uv_buf_free)) {
2879 		buf = (usbvc_buf_t *)list_head(&strm_if->buf_map.uv_buf_free);
2880 		list_remove(&(strm_if->buf_map.uv_buf_free), buf);
2881 	}
2882 	while (!list_is_empty(&strm_if->buf_map.uv_buf_done)) {
2883 		buf = (usbvc_buf_t *)list_head(&strm_if->buf_map.uv_buf_done);
2884 		list_remove(&(strm_if->buf_map.uv_buf_done), buf);
2885 	}
2886 	buf = strm_if->buf_map.buf_head;
2887 	if (!buf) {
2888 		USB_DPRINTF_L2(PRINT_MASK_CLOSE, usbvcp->usbvc_log_handle,
2889 		    "usbvc_free_map_bufs: no data buf need be freed, return");
2890 
2891 		return;
2892 	}
2893 	if (buf->umem_cookie) {
2894 		ddi_umem_free(buf->umem_cookie);
2895 	}
2896 	kmem_free(buf, sizeof (usbvc_buf_t) * strm_if->buf_map.buf_cnt);
2897 	strm_if->buf_map.buf_cnt = 0;
2898 	strm_if->buf_map.buf_head = NULL;
2899 
2900 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, usbvcp->usbvc_log_handle,
2901 	    "usbvc_free_map_bufs: return");
2902 }
2903 
2904 
2905 /*
2906  * Open the isoc pipe, this pipe is for video data transfer
2907  */
2908 int
2909 usbvc_open_isoc_pipe(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if)
2910 {
2911 	usb_pipe_policy_t policy;
2912 	int	rval = USB_SUCCESS;
2913 
2914 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
2915 
2916 	if ((rval = usbvc_set_alt(usbvcp, strm_if)) != USB_SUCCESS) {
2917 
2918 		return (rval);
2919 	}
2920 	bzero(&policy, sizeof (usb_pipe_policy_t));
2921 	policy.pp_max_async_reqs = 2;
2922 	mutex_exit(&usbvcp->usbvc_mutex);
2923 	if ((rval = usb_pipe_open(usbvcp->usbvc_dip, strm_if->curr_ep, &policy,
2924 	    USB_FLAGS_SLEEP, &strm_if->datain_ph)) != USB_SUCCESS) {
2925 		USB_DPRINTF_L2(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
2926 		    "usbvc_open_isoc_pipe: open pipe fail");
2927 		mutex_enter(&usbvcp->usbvc_mutex);
2928 
2929 		return (rval);
2930 	}
2931 	mutex_enter(&usbvcp->usbvc_mutex);
2932 	strm_if->start_polling = 0;
2933 
2934 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
2935 	    "usbvc_open_isoc_pipe: success, datain_ph=%p",
2936 	    (void *)strm_if->datain_ph);
2937 
2938 	return (rval);
2939 }
2940 
2941 
2942 /*
2943  * Open the isoc pipe
2944  */
2945 static void
2946 usbvc_close_isoc_pipe(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if)
2947 {
2948 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
2949 	if (!strm_if) {
2950 		USB_DPRINTF_L2(PRINT_MASK_CLOSE, usbvcp->usbvc_log_handle,
2951 		    "usbvc_close_isoc_pipe: stream interface is NULL");
2952 
2953 		return;
2954 	}
2955 	if (strm_if->datain_ph) {
2956 		mutex_exit(&usbvcp->usbvc_mutex);
2957 		usb_pipe_close(usbvcp->usbvc_dip, strm_if->datain_ph,
2958 		    USB_FLAGS_SLEEP, NULL, NULL);
2959 		mutex_enter(&usbvcp->usbvc_mutex);
2960 	}
2961 	strm_if->datain_ph = NULL;
2962 }
2963 
2964 
2965 /*
2966  * Start to get video data from isoc pipe in the stream interface,
2967  * issue isoc req.
2968  */
2969 int
2970 usbvc_start_isoc_polling(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if,
2971     uchar_t io_type)
2972 {
2973 	int		rval = USB_SUCCESS;
2974 	uint_t		if_num;
2975 	usb_isoc_req_t	*req;
2976 	ushort_t	pkt_size;
2977 	ushort_t	n_pkt, pkt;
2978 	uint32_t	frame_size;
2979 
2980 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
2981 	pkt_size = HS_PKT_SIZE(strm_if->curr_ep->wMaxPacketSize);
2982 	if_num = strm_if->if_descr->if_alt->altif_descr.bInterfaceNumber;
2983 	LE_TO_UINT32(strm_if->ctrl_pc.dwMaxVideoFrameSize, 0, frame_size);
2984 	n_pkt = (frame_size + (pkt_size) - 1) / (pkt_size);
2985 
2986 	USB_DPRINTF_L3(PRINT_MASK_IOCTL, usbvcp->usbvc_log_handle,
2987 	    "usbvc_start_isoc_polling: if_num=%d, alt=%d, n_pkt=%d,"
2988 	    " pkt_size=0x%x, MaxPacketSize=0x%x(Tsac#=%d), frame_size=0x%x",
2989 	    if_num, strm_if->curr_alt, n_pkt, pkt_size,
2990 	    strm_if->curr_ep->wMaxPacketSize,
2991 	    (1 + ((strm_if->curr_ep->wMaxPacketSize>> 11) & 3)),
2992 	    frame_size);
2993 
2994 	if (n_pkt > USBVC_MAX_PKTS) {
2995 		n_pkt = USBVC_MAX_PKTS;
2996 	}
2997 	USB_DPRINTF_L3(PRINT_MASK_IOCTL, usbvcp->usbvc_log_handle,
2998 	    "usbvc_start_isoc_polling: n_pkt=%d", n_pkt);
2999 
3000 	mutex_exit(&usbvcp->usbvc_mutex);
3001 	if ((req = usb_alloc_isoc_req(usbvcp->usbvc_dip, n_pkt,
3002 	    n_pkt * pkt_size, USB_FLAGS_SLEEP)) != NULL) {
3003 		mutex_enter(&usbvcp->usbvc_mutex);
3004 
3005 		/* Initialize the packet descriptor */
3006 		for (pkt = 0; pkt < n_pkt; pkt++) {
3007 			req->isoc_pkt_descr[pkt].isoc_pkt_length = pkt_size;
3008 		}
3009 
3010 		req->isoc_pkts_count = n_pkt;
3011 
3012 		/*
3013 		 * zero here indicates that HCDs will use
3014 		 * isoc_pkt_descr->isoc_pkt_length to calculate
3015 		 * isoc_pkts_length.
3016 		 */
3017 		req->isoc_pkts_length = 0;
3018 		req->isoc_attributes = USB_ATTRS_ISOC_XFER_ASAP |
3019 		    USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING;
3020 		req->isoc_cb = usbvc_isoc_cb;
3021 		req->isoc_exc_cb = usbvc_isoc_exc_cb;
3022 		usbvcp->usbvc_io_type = io_type;
3023 		req->isoc_client_private = (usb_opaque_t)usbvcp;
3024 		mutex_exit(&usbvcp->usbvc_mutex);
3025 		rval = usb_pipe_isoc_xfer(strm_if->datain_ph, req, 0);
3026 		mutex_enter(&usbvcp->usbvc_mutex);
3027 	} else {
3028 		mutex_enter(&usbvcp->usbvc_mutex);
3029 		USB_DPRINTF_L2(PRINT_MASK_IOCTL, usbvcp->usbvc_log_handle,
3030 		    "usbvc_start_isoc_polling: alloc_isoc_req fail");
3031 
3032 		return (USB_FAILURE);
3033 	}
3034 
3035 	if (rval != USB_SUCCESS) {
3036 		if (req) {
3037 			usb_free_isoc_req(req);
3038 			req = NULL;
3039 		}
3040 	}
3041 	USB_DPRINTF_L4(PRINT_MASK_IOCTL, usbvcp->usbvc_log_handle,
3042 	    "usbvc_start_isoc_polling: return, rval=%d", rval);
3043 
3044 	return (rval);
3045 }
3046 
3047 /* callbacks for receiving video data (isco in transfer) */
3048 
3049 /*ARGSUSED*/
3050 /* Isoc transfer callback, get video data */
3051 static void
3052 usbvc_isoc_cb(usb_pipe_handle_t ph, usb_isoc_req_t *isoc_req)
3053 {
3054 	usbvc_state_t	*usbvcp =
3055 	    (usbvc_state_t *)isoc_req->isoc_client_private;
3056 	int		i;
3057 	mblk_t		*data = isoc_req->isoc_data;
3058 	usbvc_buf_grp_t	*bufgrp;
3059 
3060 	mutex_enter(&usbvcp->usbvc_mutex);
3061 
3062 	USB_DPRINTF_L3(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3063 	    "usbvc_isoc_cb: rq=0x%p, fno=%" PRId64 ", n_pkts=%u, flag=0x%x,"
3064 	    " data=0x%p, cnt=%d",
3065 	    (void *)isoc_req, isoc_req->isoc_frame_no,
3066 	    isoc_req->isoc_pkts_count, isoc_req->isoc_attributes,
3067 	    (void *)isoc_req->isoc_data, isoc_req->isoc_error_count);
3068 
3069 	ASSERT((isoc_req->isoc_cb_flags & USB_CB_INTR_CONTEXT) != 0);
3070 	for (i = 0; i < isoc_req->isoc_pkts_count; i++) {
3071 
3072 		USB_DPRINTF_L3(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3073 		    "\tpkt%d: "
3074 		    "pktsize=%d status=%d resid=%d",
3075 		    i,
3076 		    isoc_req->isoc_pkt_descr[i].isoc_pkt_length,
3077 		    isoc_req->isoc_pkt_descr[i].isoc_pkt_status,
3078 		    isoc_req->isoc_pkt_descr[i].isoc_pkt_actual_length);
3079 
3080 		if (isoc_req->isoc_pkt_descr[i].isoc_pkt_status !=
3081 		    USB_CR_OK) {
3082 			USB_DPRINTF_L3(PRINT_MASK_CB,
3083 			    usbvcp->usbvc_log_handle,
3084 			    "record: pkt=%d status=%s", i, usb_str_cr(
3085 			    isoc_req->isoc_pkt_descr[i].isoc_pkt_status));
3086 		}
3087 
3088 		if (usbvcp->usbvc_io_type == V4L2_MEMORY_MMAP) {
3089 			bufgrp = &usbvcp->usbvc_curr_strm->buf_map;
3090 		} else {
3091 			bufgrp = &usbvcp->usbvc_curr_strm->buf_read;
3092 		}
3093 
3094 		if (isoc_req->isoc_pkt_descr[i].isoc_pkt_actual_length) {
3095 			if (usbvc_decode_stream_header(usbvcp, bufgrp, data,
3096 			    isoc_req->isoc_pkt_descr[i].isoc_pkt_actual_length)
3097 			    != USB_SUCCESS) {
3098 				USB_DPRINTF_L3(PRINT_MASK_CB,
3099 				    usbvcp->usbvc_log_handle, "decode error");
3100 			}
3101 			if (bufgrp->buf_filling &&
3102 			    (bufgrp->buf_filling->status == USBVC_BUF_ERR ||
3103 			    bufgrp->buf_filling->status == USBVC_BUF_DONE)) {
3104 
3105 				/* Move the buf to the full list */
3106 				list_insert_tail(&bufgrp->uv_buf_done,
3107 				    bufgrp->buf_filling);
3108 
3109 				bufgrp->buf_filling = NULL;
3110 
3111 				if (usbvcp->usbvc_io_type == V4L2_MEMORY_MMAP) {
3112 					cv_broadcast(&usbvcp->usbvc_mapio_cv);
3113 				} else {
3114 					cv_broadcast(&usbvcp->usbvc_read_cv);
3115 				}
3116 			}
3117 		}
3118 
3119 		data->b_rptr += isoc_req->isoc_pkt_descr[i].isoc_pkt_length;
3120 	}
3121 	mutex_exit(&usbvcp->usbvc_mutex);
3122 	usb_free_isoc_req(isoc_req);
3123 }
3124 
3125 
3126 /*ARGSUSED*/
3127 static void
3128 usbvc_isoc_exc_cb(usb_pipe_handle_t ph, usb_isoc_req_t *isoc_req)
3129 {
3130 	usbvc_state_t	*usbvcp =
3131 	    (usbvc_state_t *)isoc_req->isoc_client_private;
3132 	usb_cr_t	completion_reason;
3133 	int		rval;
3134 	usbvc_stream_if_t	*strm_if;
3135 
3136 	ASSERT(!list_is_empty(&usbvcp->usbvc_stream_list));
3137 
3138 	mutex_enter(&usbvcp->usbvc_mutex);
3139 
3140 	/* get the first stream interface */
3141 	strm_if = usbvcp->usbvc_curr_strm;
3142 
3143 	completion_reason = isoc_req->isoc_completion_reason;
3144 
3145 	USB_DPRINTF_L3(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3146 	    "usbvc_isoc_exc_cb: ph=0x%p, isoc_req=0x%p, cr=%d",
3147 	    (void *)ph, (void *)isoc_req, completion_reason);
3148 
3149 	ASSERT((isoc_req->isoc_cb_flags & USB_CB_INTR_CONTEXT) == 0);
3150 
3151 	switch (completion_reason) {
3152 	case USB_CR_STOPPED_POLLING:
3153 	case USB_CR_PIPE_CLOSING:
3154 	case USB_CR_PIPE_RESET:
3155 
3156 		break;
3157 	case USB_CR_NO_RESOURCES:
3158 		/*
3159 		 * keep the show going: Since we have the original
3160 		 * request, we just resubmit it
3161 		 */
3162 		rval = usb_pipe_isoc_xfer(strm_if->datain_ph, isoc_req,
3163 		    USB_FLAGS_NOSLEEP);
3164 		USB_DPRINTF_L2(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3165 		    "usbvc_isoc_exc_cb: restart capture rval=%d", rval);
3166 		mutex_exit(&usbvcp->usbvc_mutex);
3167 
3168 		return;
3169 	default:
3170 		mutex_exit(&usbvcp->usbvc_mutex);
3171 		usb_pipe_stop_isoc_polling(ph, USB_FLAGS_NOSLEEP);
3172 		USB_DPRINTF_L2(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3173 		    "usbvc_isoc_exc_cb: stop polling");
3174 		mutex_enter(&usbvcp->usbvc_mutex);
3175 	}
3176 	usb_free_isoc_req(isoc_req);
3177 	strm_if->start_polling = 0;
3178 	USB_DPRINTF_L3(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3179 	    "usbvc_isoc_exc_cb: start_polling=%d cr=%d",
3180 	    strm_if->start_polling, completion_reason);
3181 	mutex_exit(&usbvcp->usbvc_mutex);
3182 }
3183 
3184 /*
3185  * Other utility functions
3186  */
3187 
3188 /*
3189  * Find a proper alternate according to the bandwidth that the current video
3190  * format need;
3191  * Set alternate by calling usb_set_alt_if;
3192  * Called before open pipes in stream interface.
3193  */
3194 static int
3195 usbvc_set_alt(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if)
3196 {
3197 	usb_alt_if_data_t	*alt;
3198 	uint_t			i, j, if_num;
3199 	uint16_t		pktsize, curr_pktsize;
3200 	uint32_t		bandwidth;
3201 	int			rval = USB_SUCCESS;
3202 	usbvc_input_header_t	*ihd;
3203 	usbvc_output_header_t	*ohd;
3204 
3205 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
3206 
3207 	LE_TO_UINT32(strm_if->ctrl_pc.dwMaxPayloadTransferSize, 0, bandwidth);
3208 	if (!bandwidth) {
3209 		USB_DPRINTF_L2(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
3210 		    "usbvc_set_alt: bandwidth is not set yet");
3211 
3212 		return (USB_FAILURE);
3213 	}
3214 	USB_DPRINTF_L3(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
3215 	    "usbvc_set_alt: bandwidth=%x", bandwidth);
3216 
3217 	strm_if->curr_ep = NULL;
3218 	curr_pktsize = 0xffff;
3219 	ohd = strm_if->output_header;
3220 	ihd = strm_if->input_header;
3221 	/*
3222 	 * Find one alternate setting whose isoc ep's max pktsize is just
3223 	 * enough for the bandwidth.
3224 	 */
3225 	for (i = 0; i < strm_if->if_descr->if_n_alt; i++) {
3226 		alt = &strm_if->if_descr->if_alt[i];
3227 
3228 		for (j = 0; j < alt->altif_n_ep; j++) {
3229 
3230 			/* if this stream interface is for input */
3231 			if (ihd != NULL &&
3232 			    alt->altif_ep[j].ep_descr.bEndpointAddress !=
3233 			    ihd->descr->bEndpointAddress) {
3234 
3235 				continue;
3236 			}
3237 			/*  if this stream interface is for output */
3238 			if (ohd != NULL &&
3239 			    alt->altif_ep[j].ep_descr.bEndpointAddress !=
3240 			    ohd->descr->bEndpointAddress) {
3241 
3242 				continue;
3243 			}
3244 			pktsize =
3245 			    alt->altif_ep[j].ep_descr.wMaxPacketSize;
3246 			pktsize = HS_PKT_SIZE(pktsize);
3247 			if (pktsize >= bandwidth && pktsize < curr_pktsize) {
3248 				curr_pktsize = pktsize;
3249 				strm_if->curr_alt = i;
3250 				strm_if->curr_ep = &alt->altif_ep[j].ep_descr;
3251 			}
3252 		}
3253 	}
3254 	if (!strm_if->curr_ep) {
3255 		USB_DPRINTF_L2(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
3256 		    "usbvc_set_alt: can't find a proper ep to satisfy"
3257 		    " the given bandwidth");
3258 
3259 		return (USB_FAILURE);
3260 	}
3261 	USB_DPRINTF_L3(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
3262 	    "usbvc_set_alt: strm_if->curr_alt=%d", strm_if->curr_alt);
3263 	if_num = strm_if->if_descr->if_alt->altif_descr.bInterfaceNumber;
3264 	mutex_exit(&usbvcp->usbvc_mutex);
3265 	if ((rval = usb_set_alt_if(usbvcp->usbvc_dip, if_num, strm_if->curr_alt,
3266 	    USB_FLAGS_SLEEP, NULL, NULL)) != USB_SUCCESS) {
3267 		mutex_enter(&usbvcp->usbvc_mutex);
3268 		USB_DPRINTF_L2(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
3269 		    "usbvc_set_alt: usb_set_alt_if fail, if.alt=%d.%d, rval=%d",
3270 		    if_num, strm_if->curr_alt, rval);
3271 
3272 		return (rval);
3273 	}
3274 	mutex_enter(&usbvcp->usbvc_mutex);
3275 
3276 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbvcp->usbvc_log_handle,
3277 	    "usbvc_set_alt: return, if_num=%d, alt=%d",
3278 	    if_num, strm_if->curr_alt);
3279 
3280 	return (rval);
3281 }
3282 
3283 
3284 /*
3285  * Decode stream header for mjpeg and uncompressed format video data.
3286  * mjpeg and uncompressed format have the same stream header. See their
3287  * payload spec, 2.2 and 2.4
3288  */
3289 static int
3290 usbvc_decode_stream_header(usbvc_state_t *usbvcp, usbvc_buf_grp_t *bufgrp,
3291 	mblk_t *data, int actual_len)
3292 {
3293 	uint32_t len, buf_left, data_len;
3294 	usbvc_stream_if_t *strm_if;
3295 	uchar_t head_flag, head_len;
3296 	usbvc_buf_t *buf_filling;
3297 
3298 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
3299 	USB_DPRINTF_L4(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3300 	    "usbvc_decode_stream_header: enter. actual_len=%x", actual_len);
3301 
3302 	/* header length check. */
3303 	if (actual_len < 2) {
3304 		USB_DPRINTF_L2(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3305 		    "usbvc_decode_stream_header: header is not completed");
3306 
3307 		return (USB_FAILURE);
3308 	}
3309 	head_len = data->b_rptr[0];
3310 	head_flag = data->b_rptr[1];
3311 
3312 	USB_DPRINTF_L3(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3313 	    "usbvc_decode_stream_header: headlen=%x", head_len);
3314 
3315 	/* header length check. */
3316 	if (actual_len < head_len) {
3317 		USB_DPRINTF_L2(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3318 		    "usbvc_decode_stream_header: actual_len < head_len");
3319 
3320 		return (USB_FAILURE);
3321 	}
3322 
3323 	/*
3324 	 * If there is no stream data in this packet and this packet is not
3325 	 * used to indicate the end of a frame, then just skip it.
3326 	 */
3327 	if ((actual_len == head_len) && !(head_flag & USBVC_STREAM_EOF)) {
3328 		USB_DPRINTF_L2(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3329 		    "usbvc_decode_stream_header: only header, no data");
3330 
3331 		return (USB_FAILURE);
3332 	}
3333 
3334 	/* Get the first stream interface */
3335 	strm_if = usbvcp->usbvc_curr_strm;
3336 
3337 	LE_TO_UINT32(strm_if->ctrl_pc.dwMaxVideoFrameSize, 0, len);
3338 	USB_DPRINTF_L3(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3339 	    "usbvc_decode_stream_header: dwMaxVideoFrameSize=%x, head_flag=%x",
3340 	    len, head_flag);
3341 
3342 	/*
3343 	 * if no buf is filling, pick one buf from free list and alloc data
3344 	 * mem for the buf.
3345 	 */
3346 	if (!bufgrp->buf_filling) {
3347 		if (list_is_empty(&bufgrp->uv_buf_free)) {
3348 			strm_if->fid = head_flag & USBVC_STREAM_FID;
3349 			USB_DPRINTF_L2(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3350 			    "usbvc_decode_stream_header: free list are empty");
3351 
3352 			return (USB_FAILURE);
3353 
3354 		} else {
3355 			bufgrp->buf_filling =
3356 			    (usbvc_buf_t *)list_head(&bufgrp->uv_buf_free);
3357 
3358 			/* unlink from buf free list */
3359 			list_remove(&bufgrp->uv_buf_free, bufgrp->buf_filling);
3360 		}
3361 		bufgrp->buf_filling->filled = 0;
3362 		USB_DPRINTF_L3(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3363 		    "usbvc_decode_stream_header: status=%d",
3364 		    bufgrp->buf_filling->status);
3365 		bufgrp->buf_filling->status = USBVC_BUF_EMPTY;
3366 	}
3367 	buf_filling = bufgrp->buf_filling;
3368 	ASSERT(buf_filling->len >= buf_filling->filled);
3369 	buf_left = buf_filling->len - buf_filling->filled;
3370 
3371 	/* if no buf room left, then return with a err status */
3372 	if (buf_left == 0) {
3373 		buf_filling->status = USBVC_BUF_ERR;
3374 
3375 		return (USB_FAILURE);
3376 	}
3377 
3378 	/* get this sample's data length except header */
3379 	data_len = actual_len - head_len;
3380 	USB_DPRINTF_L3(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3381 	    "usbvc_decode_stream_header: fid=%x, len=%x, filled=%x",
3382 	    strm_if->fid, buf_filling->len, buf_filling->filled);
3383 
3384 	/* if the first sample for a frame */
3385 	if (buf_filling->filled == 0) {
3386 		/*
3387 		 * Only if it is the frist packet of a frame,
3388 		 * we will begin filling a frame.
3389 		 */
3390 		if (strm_if->fid != 0xff && strm_if->fid ==
3391 		    (head_flag & USBVC_STREAM_FID)) {
3392 			USB_DPRINTF_L2(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3393 			    "usbvc_decode_stream_header: 1st sample of a frame,"
3394 			    " fid is incorrect.");
3395 
3396 			return (USB_FAILURE);
3397 		}
3398 		strm_if->fid = head_flag & USBVC_STREAM_FID;
3399 
3400 	/* If in the middle of a frame, fid should be consistent. */
3401 	} else if (strm_if->fid != (head_flag & USBVC_STREAM_FID)) {
3402 		USB_DPRINTF_L2(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3403 		    "usbvc_decode_stream_header: fid is incorrect.");
3404 		strm_if->fid = head_flag & USBVC_STREAM_FID;
3405 		buf_filling->status = USBVC_BUF_ERR;
3406 
3407 		return (USB_FAILURE);
3408 	}
3409 	if (data_len) {
3410 		bcopy((void *)(data->b_rptr + head_len),
3411 		    (void *)(buf_filling->data + buf_filling->filled),
3412 		    min(data_len, buf_left));
3413 
3414 		buf_filling->filled += min(data_len, buf_left);
3415 	}
3416 
3417 	/* If the last packet for this frame */
3418 	if (head_flag & USBVC_STREAM_EOF) {
3419 		buf_filling->status = USBVC_BUF_DONE;
3420 	}
3421 	if (data_len > buf_left) {
3422 		buf_filling->status = USBVC_BUF_ERR;
3423 	}
3424 	USB_DPRINTF_L4(PRINT_MASK_CB, usbvcp->usbvc_log_handle,
3425 	    "usbvc_decode_stream_header: buf_status=%d", buf_filling->status);
3426 
3427 	return (USB_SUCCESS);
3428 }
3429 
3430 
3431 /*
3432  * usbvc_serialize_access:
3433  *    Get the serial synchronization object before returning.
3434  *
3435  * Arguments:
3436  *    usbvcp - Pointer to usbvc state structure
3437  *    waitsig - Set to:
3438  *	USBVC_SER_SIG - to wait such that a signal can interrupt
3439  *	USBVC_SER_NOSIG - to wait such that a signal cannot interrupt
3440  */
3441 static int
3442 usbvc_serialize_access(usbvc_state_t *usbvcp, boolean_t waitsig)
3443 {
3444 	int rval = 1;
3445 
3446 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
3447 
3448 	while (usbvcp->usbvc_serial_inuse) {
3449 		if (waitsig == USBVC_SER_SIG) {
3450 			rval = cv_wait_sig(&usbvcp->usbvc_serial_cv,
3451 			    &usbvcp->usbvc_mutex);
3452 		} else {
3453 			cv_wait(&usbvcp->usbvc_serial_cv,
3454 			    &usbvcp->usbvc_mutex);
3455 		}
3456 	}
3457 	usbvcp->usbvc_serial_inuse = B_TRUE;
3458 
3459 	return (rval);
3460 }
3461 
3462 
3463 /*
3464  * usbvc_release_access:
3465  *    Release the serial synchronization object.
3466  */
3467 static void
3468 usbvc_release_access(usbvc_state_t *usbvcp)
3469 {
3470 	ASSERT(mutex_owned(&usbvcp->usbvc_mutex));
3471 	usbvcp->usbvc_serial_inuse = B_FALSE;
3472 	cv_broadcast(&usbvcp->usbvc_serial_cv);
3473 }
3474 
3475 
3476 /* Send req to video control interface to get ctrl */
3477 int
3478 usbvc_vc_get_ctrl(usbvc_state_t *usbvcp, uint8_t req_code, uint8_t entity_id,
3479     uint16_t cs, uint16_t wlength, mblk_t *data)
3480 {
3481 	usb_cb_flags_t	cb_flags;
3482 	usb_cr_t	cr;
3483 	usb_ctrl_setup_t setup;
3484 
3485 	setup.bmRequestType = USBVC_GET_IF;	/* bmRequestType */
3486 	setup.bRequest = req_code;		/* bRequest */
3487 	setup.wValue = cs<<8;
3488 	setup.wIndex = entity_id<<8;
3489 	setup.wLength = wlength;
3490 	setup.attrs = 0;
3491 
3492 	if (usb_pipe_ctrl_xfer_wait(usbvcp->usbvc_default_ph, &setup, &data,
3493 	    &cr, &cb_flags, 0) != USB_SUCCESS) {
3494 		USB_DPRINTF_L2(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3495 		    "usbvc_vc_get_ctrl: cmd failed, cr=%d, cb_flags=%x",
3496 		    cr, cb_flags);
3497 
3498 		return (USB_FAILURE);
3499 	}
3500 
3501 	return (USB_SUCCESS);
3502 }
3503 
3504 
3505 /* Send req to video control interface to get ctrl */
3506 int
3507 usbvc_vc_set_ctrl(usbvc_state_t *usbvcp, uint8_t req_code,  uint8_t entity_id,
3508 	uint16_t cs, uint16_t wlength, mblk_t *data)
3509 {
3510 	usb_cb_flags_t	cb_flags;
3511 	usb_cr_t	cr;
3512 	usb_ctrl_setup_t setup;
3513 
3514 	setup.bmRequestType = USBVC_SET_IF;	/* bmRequestType */
3515 	setup.bRequest = req_code;		/* bRequest */
3516 	setup.wValue = cs<<8;
3517 	setup.wIndex = entity_id<<8;
3518 	setup.wLength = wlength;
3519 	setup.attrs = 0;
3520 
3521 	if (usb_pipe_ctrl_xfer_wait(usbvcp->usbvc_default_ph, &setup, &data,
3522 	    &cr, &cb_flags, 0) != USB_SUCCESS) {
3523 		USB_DPRINTF_L2(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3524 		    "usbvc_vc_set_ctrl: cmd failed, cr=%d, cb_flags=%x",
3525 		    cr, cb_flags);
3526 
3527 		return (USB_FAILURE);
3528 	}
3529 
3530 	return (USB_SUCCESS);
3531 }
3532 
3533 
3534 /* Set probe or commit ctrl for video stream interface */
3535 int
3536 usbvc_vs_set_probe_commit(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if,
3537 	usbvc_vs_probe_commit_t *ctrl_pc, uchar_t cs)
3538 {
3539 	mblk_t *data;
3540 	usb_cb_flags_t	cb_flags;
3541 	usb_cr_t	cr;
3542 	usb_ctrl_setup_t setup;
3543 	int rval;
3544 
3545 	setup.bmRequestType = USBVC_SET_IF;	/* bmRequestType */
3546 	setup.bRequest = SET_CUR;		/* bRequest */
3547 
3548 	/* wValue, VS_PROBE_CONTROL or VS_COMMIT_CONTROL */
3549 	setup.wValue = cs;
3550 
3551 	/* UVC Spec: this value must be put to the high byte */
3552 	setup.wValue = setup.wValue << 8;
3553 
3554 	setup.wIndex = strm_if->if_descr->if_alt->altif_descr.bInterfaceNumber;
3555 	setup.wLength = usbvcp->usbvc_vc_header->descr->bcdUVC[0] ? 34 : 26;
3556 	setup.attrs = 0;
3557 
3558 	USB_DPRINTF_L3(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3559 	    "usbvc_vs_set_probe_commit: wLength=%d", setup.wLength);
3560 
3561 	/* Data block */
3562 	if ((data = allocb(setup.wLength, BPRI_HI)) == NULL) {
3563 		USB_DPRINTF_L2(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3564 		    "usbvc_vs_set_probe_commit: allocb failed");
3565 
3566 		return (USB_FAILURE);
3567 	}
3568 
3569 	bcopy(ctrl_pc, data->b_rptr, setup.wLength);
3570 	data->b_wptr += setup.wLength;
3571 
3572 	if ((rval = usb_pipe_ctrl_xfer_wait(usbvcp->usbvc_default_ph, &setup,
3573 	    &data, &cr, &cb_flags, 0)) != USB_SUCCESS) {
3574 		if (data) {
3575 			freemsg(data);
3576 		}
3577 		USB_DPRINTF_L2(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3578 		    "usbvc_vs_set_probe_commit: fail, rval=%d, cr=%d, "
3579 		    "cb_flags=%x", rval, cr, cb_flags);
3580 
3581 		return (rval);
3582 	}
3583 	if (data) {
3584 		freemsg(data);
3585 	}
3586 
3587 	return (USB_SUCCESS);
3588 }
3589 
3590 
3591 /* Get probe ctrl for vodeo stream interface */
3592 int
3593 usbvc_vs_get_probe(usbvc_state_t *usbvcp, usbvc_stream_if_t *strm_if,
3594 	usbvc_vs_probe_commit_t *ctrl_pc, uchar_t bRequest)
3595 {
3596 	mblk_t *data = NULL;
3597 	usb_cb_flags_t	cb_flags;
3598 	usb_cr_t	cr;
3599 	usb_ctrl_setup_t setup;
3600 
3601 	setup.bmRequestType = USBVC_GET_IF;	/* bmRequestType */
3602 	setup.bRequest = bRequest;		/* bRequest */
3603 	setup.wValue = VS_PROBE_CONTROL;	/* wValue, PROBE or COMMIT */
3604 	setup.wValue = setup.wValue << 8;
3605 	setup.wIndex =
3606 	    (uint16_t)strm_if->if_descr->if_alt->altif_descr.bInterfaceNumber;
3607 	setup.wLength = usbvcp->usbvc_vc_header->descr->bcdUVC[0] ? 34 : 26;
3608 
3609 	setup.attrs = 0;
3610 
3611 	if (usb_pipe_ctrl_xfer_wait(usbvcp->usbvc_default_ph, &setup, &data,
3612 	    &cr, &cb_flags, 0) != USB_SUCCESS) {
3613 		if (data) {
3614 			freemsg(data);
3615 		}
3616 		USB_DPRINTF_L2(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3617 		    "usbvc_vs_get_probe: cmd failed, cr=%d, cb_flags=%x",
3618 		    cr, cb_flags);
3619 
3620 		return (USB_FAILURE);
3621 	}
3622 	bcopy(data->b_rptr, ctrl_pc, setup.wLength);
3623 	if (data) {
3624 		freemsg(data);
3625 	}
3626 
3627 	return (USB_SUCCESS);
3628 }
3629 
3630 
3631 /* Set a default format when open the device */
3632 static int
3633 usbvc_set_default_stream_fmt(usbvc_state_t *usbvcp)
3634 {
3635 	usbvc_vs_probe_commit_t ctrl, ctrl_get;
3636 	usbvc_stream_if_t *strm_if;
3637 	usbvc_format_group_t *curr_fmtgrp;
3638 	uint32_t bandwidth;
3639 	uint8_t  index, i;
3640 
3641 	USB_DPRINTF_L4(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3642 	    "usbvc_set_default_stream_fmt: enter");
3643 
3644 	mutex_enter(&usbvcp->usbvc_mutex);
3645 	if (list_is_empty(&usbvcp->usbvc_stream_list)) {
3646 		USB_DPRINTF_L2(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3647 		    "usbvc_set_default_stream_fmt: no stream interface, fail");
3648 		mutex_exit(&usbvcp->usbvc_mutex);
3649 
3650 		return (USB_FAILURE);
3651 	}
3652 	bzero((void *)&ctrl, sizeof (usbvc_vs_probe_commit_t));
3653 
3654 	/* Get the current stream interface */
3655 	strm_if = usbvcp->usbvc_curr_strm;
3656 
3657 	/* Fill the probe commit req data */
3658 	ctrl.bmHint[0] = 0;
3659 
3660 	for (i = 0; i < strm_if->fmtgrp_cnt; i++) {
3661 		curr_fmtgrp = &strm_if->format_group[i];
3662 
3663 		/*
3664 		 * If v4l2_pixelformat is NULL, then that means there is not
3665 		 * a parsed format in format_group[i].
3666 		 */
3667 		if (!curr_fmtgrp || !curr_fmtgrp->v4l2_pixelformat ||
3668 		    curr_fmtgrp->frame_cnt == 0) {
3669 			USB_DPRINTF_L2(PRINT_MASK_DEVCTRL,
3670 			    usbvcp->usbvc_log_handle,
3671 			    "usbvc_set_default_stream_fmt: no frame, fail");
3672 
3673 			continue;
3674 		} else {
3675 
3676 			break;
3677 		}
3678 	}
3679 	if (!curr_fmtgrp || curr_fmtgrp->frame_cnt == 0) {
3680 		USB_DPRINTF_L2(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3681 		    "usbvc_set_default_stream_fmt: can't find a fmtgrp"
3682 		    "which has a frame, fail");
3683 		mutex_exit(&usbvcp->usbvc_mutex);
3684 
3685 		return (USB_FAILURE);
3686 	}
3687 
3688 	ctrl.bFormatIndex = curr_fmtgrp->format->bFormatIndex;
3689 
3690 	/* use the first frame descr as default */
3691 	ctrl.bFrameIndex = curr_fmtgrp->frames[0].descr->bFrameIndex;
3692 
3693 	/* use bcopy to keep the byte sequence as 32 bit little endian */
3694 	bcopy(&(curr_fmtgrp->frames[0].descr->dwDefaultFrameInterval[0]),
3695 	    &(ctrl.dwFrameInterval[0]), 4);
3696 
3697 	mutex_exit(&usbvcp->usbvc_mutex);
3698 	if (usbvc_vs_set_probe_commit(usbvcp, strm_if, &ctrl, VS_PROBE_CONTROL)
3699 	    != USB_SUCCESS) {
3700 
3701 		return (USB_FAILURE);
3702 	}
3703 	if (usbvc_vs_get_probe(usbvcp, strm_if, &ctrl_get, GET_CUR)
3704 	    != USB_SUCCESS) {
3705 
3706 		return (USB_FAILURE);
3707 	}
3708 
3709 	mutex_enter(&usbvcp->usbvc_mutex);
3710 	LE_TO_UINT32(strm_if->ctrl_pc.dwMaxPayloadTransferSize, 0, bandwidth);
3711 	USB_DPRINTF_L3(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3712 	    "usbvc_set_default_stream_fmt: get bandwidth=%x", bandwidth);
3713 
3714 	mutex_exit(&usbvcp->usbvc_mutex);
3715 	if (usbvc_vs_set_probe_commit(usbvcp, strm_if, &ctrl_get,
3716 	    VS_COMMIT_CONTROL) != USB_SUCCESS) {
3717 
3718 		return (USB_FAILURE);
3719 	}
3720 
3721 	mutex_enter(&usbvcp->usbvc_mutex);
3722 
3723 	/*  it's good to check index here before use it */
3724 	index = ctrl_get.bFormatIndex - curr_fmtgrp->format->bFormatIndex;
3725 	if (index < strm_if->fmtgrp_cnt) {
3726 		strm_if->cur_format_group = &strm_if->format_group[index];
3727 	} else {
3728 		USB_DPRINTF_L2(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3729 		    "usbvc_set_default_stream_fmt: format index out of range");
3730 		mutex_exit(&usbvcp->usbvc_mutex);
3731 
3732 		return (USB_FAILURE);
3733 	}
3734 
3735 	index = ctrl_get.bFrameIndex -
3736 	    strm_if->cur_format_group->frames[0].descr->bFrameIndex;
3737 	if (index < strm_if->cur_format_group->frame_cnt) {
3738 		strm_if->cur_format_group->cur_frame =
3739 		    &strm_if->cur_format_group->frames[index];
3740 	} else {
3741 		USB_DPRINTF_L2(PRINT_MASK_DEVCTRL, usbvcp->usbvc_log_handle,
3742 		    "usbvc_set_default_stream: frame index out of range");
3743 		mutex_exit(&usbvcp->usbvc_mutex);
3744 
3745 		return (USB_FAILURE);
3746 	}
3747 
3748 	/*
3749 	 * by now, the video format is set successfully. record the current
3750 	 * setting to strm_if->ctrl_pc
3751 	 */
3752 	bcopy(&ctrl_get, &strm_if->ctrl_pc, sizeof (usbvc_vs_probe_commit_t));
3753 
3754 	mutex_exit(&usbvcp->usbvc_mutex);
3755 
3756 	return (USB_SUCCESS);
3757 }
3758