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