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