Home | History | Annotate | Download | only in printer
      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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     22  * Use is subject to license terms.
     23  */
     24 
     25 
     26 /*
     27  * Printer Class Driver for USB
     28  *
     29  * This driver supports devices that adhere to the USB Printer Class
     30  * specification 1.0.
     31  *
     32  * NOTE: This driver is not DDI compliant in that it uses undocumented
     33  * functions for logging (USB_DPRINTF_L*, usb_alloc_log_hdl, usb_free_log_hdl),
     34  * and serialization (usb_serialize_access, usb_release_access,
     35  * usb_init_serialization, usb_fini_serialization)
     36  *
     37  * Undocumented functions may go away in a future Solaris OS release.
     38  *
     39  * Please see the DDK for sample code of these functions, and for the usbskel
     40  * skeleton template driver which contains scaled-down versions of these
     41  * functions written in a DDI-compliant way.
     42  */
     43 
     44 #if defined(lint) && !defined(DEBUG)
     45 #define	DEBUG
     46 #endif
     47 #ifdef __lock_lint
     48 #define	_MULTI_DATAMODEL
     49 #endif
     50 
     51 #define	USBDRV_MAJOR_VER	2
     52 #define	USBDRV_MINOR_VER	0
     53 
     54 #include <sys/usb/usba.h>
     55 #include <sys/usb/usba/usba_ugen.h>
     56 #include <sys/bpp_io.h>
     57 #include <sys/ecppsys.h>
     58 #include <sys/prnio.h>
     59 #include <sys/errno.h>
     60 #include <sys/usb/clients/printer/usb_printer.h>
     61 #include <sys/usb/clients/printer/usbprn.h>
     62 #include <sys/strsun.h>
     63 
     64 /* Debugging support */
     65 uint_t	usbprn_errmask		= (uint_t)PRINT_MASK_ALL;
     66 uint_t	usbprn_errlevel 	= USB_LOG_L4;
     67 uint_t	usbprn_instance_debug	= (uint_t)-1;
     68 
     69 /* local variables */
     70 static uint_t usbprn_ifcap =
     71 	PRN_HOTPLUG | PRN_1284_DEVID | PRN_1284_STATUS | PRN_TIMEOUTS;
     72 
     73 /*
     74  * Function Prototypes
     75  */
     76 static int	usbprn_attach(dev_info_t *, ddi_attach_cmd_t);
     77 static int	usbprn_detach(dev_info_t *, ddi_detach_cmd_t);
     78 static int	usbprn_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
     79 static void	usbprn_cleanup(dev_info_t *, usbprn_state_t *);
     80 
     81 static int	usbprn_get_descriptors(usbprn_state_t *);
     82 static int	usbprn_get_device_id(usbprn_state_t *);
     83 static int	usbprn_get_port_status(usbprn_state_t *);
     84 
     85 static int	usbprn_open(dev_t *, int, int, cred_t *);
     86 static int	usbprn_close(dev_t, int, int, cred_t *);
     87 static int	usbprn_open_usb_pipes(usbprn_state_t *);
     88 static void	usbprn_close_usb_pipes(usbprn_state_t *);
     89 static int	usbprn_write(dev_t, struct uio *, cred_t *);
     90 static int	usbprn_read(dev_t, struct uio *, cred_t *);
     91 static int	usbprn_poll(dev_t, short, int, short *, struct pollhead **);
     92 
     93 static int	usbprn_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
     94 static void	usbprn_minphys(struct buf *);
     95 static int	usbprn_strategy(struct buf *);
     96 static int	usbprn_setparms(usbprn_state_t *, intptr_t arg, int);
     97 static int	usbprn_getparms(usbprn_state_t *, intptr_t, int);
     98 static void	usbprn_geterr(usbprn_state_t *, intptr_t, int);
     99 static int	usbprn_testio(usbprn_state_t  *, int);
    100 static int	usbprn_ioctl_get_status(usbprn_state_t *);
    101 static int	usbprn_prnio_get_status(usbprn_state_t *, intptr_t, int);
    102 static int	usbprn_prnio_get_1284_status(usbprn_state_t *, intptr_t, int);
    103 static int	usbprn_prnio_get_ifcap(usbprn_state_t *, intptr_t, int);
    104 static int	usbprn_prnio_set_ifcap(usbprn_state_t *, intptr_t, int);
    105 static int	usbprn_prnio_get_ifinfo(usbprn_state_t *, intptr_t, int);
    106 static int	usbprn_prnio_get_1284_devid(usbprn_state_t *, intptr_t, int);
    107 static int	usbprn_prnio_get_timeouts(usbprn_state_t *, intptr_t, int);
    108 static int	usbprn_prnio_set_timeouts(usbprn_state_t *, intptr_t, int);
    109 
    110 static void	usbprn_send_async_bulk_data(usbprn_state_t *);
    111 
    112 static void	usbprn_bulk_xfer_cb(usb_pipe_handle_t, usb_bulk_req_t *);
    113 static void	usbprn_bulk_xfer_exc_cb(usb_pipe_handle_t,
    114 		    usb_bulk_req_t *);
    115 
    116 static void	usbprn_biodone(usbprn_state_t *, int, int);
    117 static char	usbprn_error_state(uchar_t);
    118 static void	usbprn_print_long(usbprn_state_t *, char *, int);
    119 
    120 /* event handling */
    121 static	void	usbprn_restore_device_state(dev_info_t *, usbprn_state_t *);
    122 static	int	usbprn_disconnect_event_cb(dev_info_t *);
    123 static	int	usbprn_reconnect_event_cb(dev_info_t *);
    124 static	int	usbprn_cpr_suspend(dev_info_t *);
    125 static	void	usbprn_cpr_resume(dev_info_t *);
    126 
    127 static usb_event_t usbprn_events = {
    128 	usbprn_disconnect_event_cb,
    129 	usbprn_reconnect_event_cb,
    130 	NULL, NULL
    131 };
    132 
    133 /* PM handling */
    134 static	void	usbprn_create_pm_components(dev_info_t *, usbprn_state_t *);
    135 static	int	usbprn_power(dev_info_t *, int comp, int level);
    136 static	int	usbprn_pwrlvl0(usbprn_state_t *);
    137 static	int	usbprn_pwrlvl1(usbprn_state_t *);
    138 static	int	usbprn_pwrlvl2(usbprn_state_t *);
    139 static	int	usbprn_pwrlvl3(usbprn_state_t *);
    140 static	void	usbprn_pm_busy_component(usbprn_state_t *);
    141 static	void	usbprn_pm_idle_component(usbprn_state_t *);
    142 
    143 /* module loading stuff */
    144 struct cb_ops usbprn_cb_ops = {
    145 	usbprn_open,		/* open  */
    146 	usbprn_close,		/* close */
    147 	nulldev,		/* strategy */
    148 	nulldev,		/* print */
    149 	nulldev,		/* dump */
    150 	usbprn_read,		/* read */
    151 	usbprn_write,		/* write */
    152 	usbprn_ioctl,		/* ioctl */
    153 	nulldev,		/* devmap */
    154 	nulldev,		/* mmap */
    155 	nulldev,		/* segmap */
    156 	usbprn_poll,		/* poll */
    157 	ddi_prop_op,		/* cb_prop_op */
    158 	NULL,			/* streamtab  */
    159 	D_64BIT | D_MP
    160 };
    161 
    162 static struct dev_ops usbprn_ops = {
    163 	DEVO_REV,		/* devo_rev, */
    164 	0,			/* refcnt  */
    165 	usbprn_info,		/* info */
    166 	nulldev,		/* identify */
    167 	nulldev,		/* probe */
    168 	usbprn_attach,		/* attach */
    169 	usbprn_detach,		/* detach */
    170 	nodev,			/* reset */
    171 	&usbprn_cb_ops,		/* driver operations */
    172 	NULL,			/* bus operations */
    173 	usbprn_power,		/* power */
    174 	ddi_quiesce_not_needed,	/* devo_quiesce */
    175 };
    176 
    177 static struct modldrv usbprnmodldrv =	{
    178 	&mod_driverops,
    179 	"USB printer client driver",
    180 	&usbprn_ops
    181 };
    182 
    183 static struct modlinkage modlinkage = {
    184 	MODREV_1,
    185 	&usbprnmodldrv,
    186 	NULL,
    187 };
    188 
    189 /* local variables */
    190 
    191 /* soft state structures */
    192 #define	USBPRN_INITIAL_SOFT_SPACE	1
    193 static void *usbprn_statep;
    194 
    195 static int usbprn_max_xfer_size = USBPRN_MAX_XFER_SIZE;
    196 
    197 /* prnio support */
    198 static const char usbprn_prnio_ifinfo[] = PRN_USB;
    199 
    200 
    201 int
    202 _init(void)
    203 {
    204 	int rval;
    205 
    206 	if ((rval = ddi_soft_state_init(&usbprn_statep,
    207 	    sizeof (usbprn_state_t), USBPRN_INITIAL_SOFT_SPACE)) != 0) {
    208 
    209 		return (rval);
    210 	}
    211 
    212 	if ((rval = mod_install(&modlinkage)) != 0) {
    213 		ddi_soft_state_fini(&usbprn_statep);
    214 	}
    215 
    216 	return (rval);
    217 }
    218 
    219 
    220 int
    221 _fini(void)
    222 {
    223 	int rval;
    224 
    225 	if ((rval = mod_remove(&modlinkage)) != 0) {
    226 
    227 		return (rval);
    228 	}
    229 
    230 	ddi_soft_state_fini(&usbprn_statep);
    231 
    232 	return (rval);
    233 }
    234 
    235 
    236 int
    237 _info(struct modinfo *modinfop)
    238 {
    239 	return (mod_info(&modlinkage, modinfop));
    240 }
    241 
    242 
    243 /*
    244  * usbprn_info:
    245  *	Get minor number, soft state structure, etc.
    246  */
    247 /*ARGSUSED*/
    248 static int
    249 usbprn_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
    250 			void *arg, void **result)
    251 {
    252 	usbprn_state_t	*usbprnp;
    253 	int		error = DDI_FAILURE;
    254 	minor_t		minor = getminor((dev_t)arg);
    255 	int		instance = USBPRN_MINOR_TO_INSTANCE(minor);
    256 
    257 	switch (infocmd) {
    258 	case DDI_INFO_DEVT2DEVINFO:
    259 		if ((usbprnp = ddi_get_soft_state(usbprn_statep,
    260 		    instance)) != NULL) {
    261 			*result = usbprnp->usbprn_dip;
    262 			if (*result != NULL) {
    263 				error = DDI_SUCCESS;
    264 			}
    265 		} else {
    266 			*result = NULL;
    267 		}
    268 
    269 		break;
    270 	case DDI_INFO_DEVT2INSTANCE:
    271 		*result = (void *)(uintptr_t)instance;
    272 		error = DDI_SUCCESS;
    273 
    274 		break;
    275 	default:
    276 
    277 		break;
    278 	}
    279 
    280 	return (error);
    281 }
    282 
    283 
    284 /*
    285  * usbprn_attach:
    286  *	Attach driver
    287  *	Get the descriptor information
    288  *	Get the device id
    289  *	Reset the device
    290  *	Get the port status
    291  */
    292 static int
    293 usbprn_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
    294 {
    295 	int			instance = ddi_get_instance(dip);
    296 	usbprn_state_t		*usbprnp = NULL;
    297 	size_t			sz;
    298 	usb_ugen_info_t 	usb_ugen_info;
    299 
    300 	switch (cmd) {
    301 	case DDI_ATTACH:
    302 
    303 		break;
    304 	case DDI_RESUME:
    305 		usbprn_cpr_resume(dip);
    306 
    307 		return (DDI_SUCCESS);
    308 	default:
    309 
    310 		return (DDI_FAILURE);
    311 	}
    312 
    313 	if (ddi_soft_state_zalloc(usbprn_statep, instance) == DDI_SUCCESS) {
    314 		usbprnp = ddi_get_soft_state(usbprn_statep, instance);
    315 	}
    316 	if (usbprnp == NULL)  {
    317 
    318 		return (DDI_FAILURE);
    319 	}
    320 
    321 	usbprnp->usbprn_instance = instance;
    322 	usbprnp->usbprn_dip	= dip;
    323 	usbprnp->usbprn_log_handle = usb_alloc_log_hdl(dip,
    324 	    "prn", &usbprn_errlevel,
    325 	    &usbprn_errmask, &usbprn_instance_debug, 0);
    326 
    327 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    328 	    "usbprn_attach: cmd=%x", cmd);
    329 
    330 	if (usb_client_attach(dip, USBDRV_VERSION, 0) != USB_SUCCESS) {
    331 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    332 		    "usb_client_attach failed");
    333 
    334 		goto fail;
    335 	}
    336 	if (usb_get_dev_data(dip, &usbprnp->usbprn_dev_data,
    337 	    USB_PARSE_LVL_IF, 0) != USB_SUCCESS) {
    338 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    339 		    "usb_get_dev_data failed");
    340 
    341 		goto fail;
    342 	}
    343 
    344 	/* Initialize locks and conditional variables */
    345 	mutex_init(&usbprnp->usbprn_mutex, NULL, MUTEX_DRIVER,
    346 	    usbprnp->usbprn_dev_data->dev_iblock_cookie);
    347 	usbprnp->usbprn_write_acc = usb_init_serialization(dip,
    348 	    USB_INIT_SER_CHECK_SAME_THREAD);
    349 	usbprnp->usbprn_ser_acc = usb_init_serialization(dip,
    350 	    USB_INIT_SER_CHECK_SAME_THREAD);
    351 	usbprnp->usbprn_dev_acc = usb_init_serialization(dip, 0);
    352 
    353 	usbprnp->usbprn_flags |= USBPRN_LOCKS_INIT_DONE;
    354 
    355 	/* Obtain all the relevant descriptors */
    356 	if (usbprn_get_descriptors(usbprnp) != USB_SUCCESS) {
    357 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    358 		    "usb get descriptors failed");
    359 
    360 		goto fail;
    361 	}
    362 
    363 	usbprnp->usbprn_def_ph = usbprnp->usbprn_dev_data->dev_default_ph;
    364 
    365 	/* Obtain the device id */
    366 	(void) usbprn_get_device_id(usbprnp);
    367 
    368 	/* Get the port status */
    369 	if (usbprn_get_port_status(usbprnp) != USB_SUCCESS) {
    370 		/* some printers fail on the first */
    371 		if (usbprn_get_port_status(usbprnp) != USB_SUCCESS) {
    372 			USB_DPRINTF_L2(PRINT_MASK_ATTA,
    373 			    usbprnp->usbprn_log_handle,
    374 			    "usb get port status failed");
    375 
    376 			goto fail;
    377 		}
    378 	}
    379 
    380 	USB_DPRINTF_L3(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    381 	    "usbprn_attach: printer status=0x%x", usbprnp->usbprn_last_status);
    382 
    383 	if ((usbprnp->usbprn_last_status & USB_PRINTER_PORT_NO_ERROR) == 0) {
    384 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    385 		    "usbprn_attach: error occurred with the printer");
    386 	}
    387 
    388 	/*
    389 	 * Create minor node based on information from the
    390 	 * descriptors
    391 	 */
    392 	if ((ddi_create_minor_node(dip, "printer", S_IFCHR,
    393 	    instance << USBPRN_MINOR_INSTANCE_SHIFT,
    394 	    DDI_NT_PRINTER, 0)) != DDI_SUCCESS) {
    395 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    396 		    "usbprn_attach: cannot create minor node");
    397 
    398 		goto fail;
    399 	}
    400 
    401 	usbprnp->usbprn_setparms.write_timeout = USBPRN_XFER_TIMEOUT;
    402 	usbprnp->usbprn_setparms.mode =  ECPP_CENTRONICS;
    403 	usbprnp->usbprn_dev_state = USB_DEV_ONLINE;
    404 
    405 	if (usb_pipe_get_max_bulk_transfer_size(usbprnp->usbprn_dip, &sz)) {
    406 
    407 		goto fail;
    408 	}
    409 
    410 	usbprnp->usbprn_max_bulk_xfer_size = sz;
    411 
    412 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbprnp->usbprn_log_handle,
    413 	    "usbprn_attach: xfer_size=0x%lx", sz);
    414 
    415 	/* enable PM */
    416 	usbprn_create_pm_components(dip, usbprnp);
    417 
    418 	/* Register for events */
    419 	if (usb_register_event_cbs(dip, &usbprn_events, 0) != USB_SUCCESS) {
    420 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    421 		    "usbprn_attach: usb_register_event_cbs failed");
    422 
    423 		goto fail;
    424 	}
    425 
    426 	usb_free_dev_data(dip, usbprnp->usbprn_dev_data);
    427 	usbprnp->usbprn_dev_data = NULL;
    428 
    429 	if (usb_owns_device(dip)) {
    430 		/* get a ugen handle */
    431 		bzero(&usb_ugen_info, sizeof (usb_ugen_info));
    432 
    433 		usb_ugen_info.usb_ugen_flags = 0;
    434 		usb_ugen_info.usb_ugen_minor_node_ugen_bits_mask =
    435 		    (dev_t)USBPRN_MINOR_UGEN_BITS_MASK;
    436 		usb_ugen_info.usb_ugen_minor_node_instance_mask =
    437 		    (dev_t)~USBPRN_MINOR_UGEN_BITS_MASK;
    438 		usbprnp->usbprn_ugen_hdl =
    439 		    usb_ugen_get_hdl(dip, &usb_ugen_info);
    440 
    441 		if (usb_ugen_attach(usbprnp->usbprn_ugen_hdl, cmd) !=
    442 		    USB_SUCCESS) {
    443 			USB_DPRINTF_L2(PRINT_MASK_ATTA,
    444 			    usbprnp->usbprn_log_handle,
    445 			    "usb_ugen_attach failed");
    446 
    447 			usb_ugen_release_hdl(usbprnp->usbprn_ugen_hdl);
    448 			usbprnp->usbprn_ugen_hdl = NULL;
    449 		}
    450 	}
    451 
    452 	/* Report device */
    453 	ddi_report_dev(dip);
    454 
    455 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    456 	    "usbprn_attach: done");
    457 
    458 	return (DDI_SUCCESS);
    459 
    460 fail:
    461 	if (usbprnp) {
    462 		usbprn_cleanup(dip, usbprnp);
    463 	}
    464 
    465 	return (DDI_FAILURE);
    466 }
    467 
    468 
    469 /*
    470  * usbprn_detach:
    471  *	detach or suspend driver instance
    472  */
    473 static int
    474 usbprn_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
    475 {
    476 	int		instance = ddi_get_instance(dip);
    477 	usbprn_state_t	*usbprnp;
    478 	int		rval = DDI_FAILURE;
    479 
    480 	usbprnp = ddi_get_soft_state(usbprn_statep, instance);
    481 
    482 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    483 	    "usbprn_detach: cmd=%x", cmd);
    484 
    485 	switch (cmd) {
    486 	case DDI_DETACH:
    487 		ASSERT((usbprnp->usbprn_flags & USBPRN_OPEN) == 0);
    488 		usbprn_cleanup(dip, usbprnp);
    489 
    490 		return (DDI_SUCCESS);
    491 	case DDI_SUSPEND:
    492 		rval = usbprn_cpr_suspend(dip);
    493 
    494 		return ((rval == USB_SUCCESS) ? DDI_SUCCESS :
    495 		    DDI_FAILURE);
    496 	default:
    497 
    498 		return (rval);
    499 	}
    500 }
    501 
    502 
    503 /*
    504  * usbprn_cleanup:
    505  *	clean up the driver state
    506  */
    507 static void
    508 usbprn_cleanup(dev_info_t *dip, usbprn_state_t *usbprnp)
    509 {
    510 	usbprn_power_t	*usbprnpm = usbprnp->usbprn_pm;
    511 	int		rval = 0;
    512 
    513 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    514 	    "usbprn_cleanup: Start");
    515 
    516 	ASSERT(usbprnp != NULL);
    517 
    518 	if (usbprnp->usbprn_flags & USBPRN_LOCKS_INIT_DONE) {
    519 		/*
    520 		 * Disable the event callbacks first, after this point, event
    521 		 * callbacks will never get called. Note we shouldn't hold
    522 		 * mutex while unregistering events because there may be a
    523 		 * competing event callback thread. Event callbacks are done
    524 		 * with ndi mutex held and this can cause a potential deadlock.
    525 		 */
    526 		usb_unregister_event_cbs(dip, &usbprn_events);
    527 
    528 		mutex_enter(&usbprnp->usbprn_mutex);
    529 		if ((usbprnpm) &&
    530 		    (usbprnp->usbprn_dev_state != USB_DEV_DISCONNECTED)) {
    531 
    532 			mutex_exit(&usbprnp->usbprn_mutex);
    533 			usbprn_pm_busy_component(usbprnp);
    534 			mutex_enter(&usbprnp->usbprn_mutex);
    535 
    536 			if (usbprnpm->usbprn_wakeup_enabled) {
    537 
    538 				mutex_exit(&usbprnp->usbprn_mutex);
    539 
    540 				(void) pm_raise_power(dip, 0,
    541 				    USB_DEV_OS_FULL_PWR);
    542 
    543 				if ((rval = usb_handle_remote_wakeup(dip,
    544 				    USB_REMOTE_WAKEUP_DISABLE)) !=
    545 				    USB_SUCCESS) {
    546 					USB_DPRINTF_L2(PRINT_MASK_ALL,
    547 					    usbprnp->usbprn_log_handle,
    548 					    "usbprn_cleanup: "
    549 					    "disable remote wakeup "
    550 					    "failed, rval=%d", rval);
    551 				}
    552 			} else {
    553 				mutex_exit(&usbprnp->usbprn_mutex);
    554 			}
    555 
    556 			(void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF);
    557 			usbprn_pm_idle_component(usbprnp);
    558 
    559 			mutex_enter(&usbprnp->usbprn_mutex);
    560 		}
    561 
    562 		ddi_remove_minor_node(dip, NULL);
    563 
    564 		mutex_exit(&usbprnp->usbprn_mutex);
    565 
    566 		if (usbprnp->usbprn_device_id) {
    567 			kmem_free(usbprnp->usbprn_device_id,
    568 			    usbprnp->usbprn_device_id_len + 1);
    569 		}
    570 
    571 		mutex_destroy(&usbprnp->usbprn_mutex);
    572 		usb_fini_serialization(usbprnp->usbprn_dev_acc);
    573 		usb_fini_serialization(usbprnp->usbprn_ser_acc);
    574 		usb_fini_serialization(usbprnp->usbprn_write_acc);
    575 	}
    576 
    577 	if (usbprnpm) {
    578 		kmem_free(usbprnpm, sizeof (usbprn_power_t));
    579 	}
    580 
    581 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    582 	    "usbprn_cleanup: End");
    583 
    584 	if (usbprnp->usbprn_ugen_hdl) {
    585 		(void) usb_ugen_detach(usbprnp->usbprn_ugen_hdl, DDI_DETACH);
    586 		usb_ugen_release_hdl(usbprnp->usbprn_ugen_hdl);
    587 	}
    588 
    589 	/* unregister with USBA */
    590 	usb_client_detach(dip, usbprnp->usbprn_dev_data);
    591 
    592 	usb_free_log_hdl(usbprnp->usbprn_log_handle);
    593 	ddi_prop_remove_all(dip);
    594 	ddi_soft_state_free(usbprn_statep, usbprnp->usbprn_instance);
    595 }
    596 
    597 
    598 /*
    599  * usbprn_cpr_suspend:
    600  *	prepare to be suspended
    601  */
    602 static int
    603 usbprn_cpr_suspend(dev_info_t *dip)
    604 {
    605 	usbprn_state_t	*usbprnp;
    606 	int		instance = ddi_get_instance(dip);
    607 	int		rval = USB_FAILURE;
    608 
    609 	usbprnp = ddi_get_soft_state(usbprn_statep, instance);
    610 
    611 	USB_DPRINTF_L4(PRINT_MASK_CPR, usbprnp->usbprn_log_handle,
    612 	    "usbprn_cpr_suspend");
    613 
    614 	(void) usb_serialize_access(usbprnp->usbprn_ser_acc, USB_WAIT, 0);
    615 
    616 	mutex_enter(&usbprnp->usbprn_mutex);
    617 
    618 	if ((usbprnp->usbprn_flags & USBPRN_OPEN) != 0) {
    619 		mutex_exit(&usbprnp->usbprn_mutex);
    620 
    621 		USB_DPRINTF_L2(PRINT_MASK_CPR,
    622 		    usbprnp->usbprn_log_handle,
    623 		    "usbprn_cpr_suspend: "
    624 		    "Device is open.  Can't suspend");
    625 
    626 	} else {
    627 		usbprnp->usbprn_dev_state = USB_DEV_SUSPENDED;
    628 		mutex_exit(&usbprnp->usbprn_mutex);
    629 
    630 		USB_DPRINTF_L4(PRINT_MASK_CPR, usbprnp->usbprn_log_handle,
    631 		    "usbprn_cpr_suspend: SUCCESS");
    632 		rval = USB_SUCCESS;
    633 	}
    634 	usb_release_access(usbprnp->usbprn_ser_acc);
    635 
    636 	if ((rval == USB_SUCCESS) && usbprnp->usbprn_ugen_hdl) {
    637 		rval = usb_ugen_detach(usbprnp->usbprn_ugen_hdl,
    638 		    DDI_SUSPEND);
    639 	}
    640 
    641 	return (rval);
    642 }
    643 
    644 
    645 static void
    646 usbprn_cpr_resume(dev_info_t *dip)
    647 {
    648 	int		instance = ddi_get_instance(dip);
    649 	usbprn_state_t	*usbprnp = ddi_get_soft_state(usbprn_statep, instance);
    650 
    651 	USB_DPRINTF_L4(PRINT_MASK_CPR, usbprnp->usbprn_log_handle,
    652 	    "usbprn_cpr_resume");
    653 
    654 	/* Needed as power up state of dev is "unknown" to system */
    655 	usbprn_pm_busy_component(usbprnp);
    656 	(void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR);
    657 
    658 	usbprn_restore_device_state(dip, usbprnp);
    659 
    660 	usbprn_pm_idle_component(usbprnp);
    661 
    662 	if (usbprnp->usbprn_ugen_hdl) {
    663 		(void) usb_ugen_attach(usbprnp->usbprn_ugen_hdl,
    664 		    DDI_RESUME);
    665 	}
    666 }
    667 
    668 
    669 /*
    670  * usbprn_get_descriptors:
    671  *	Obtain all the descriptors for the device
    672  */
    673 static int
    674 usbprn_get_descriptors(usbprn_state_t *usbprnp)
    675 {
    676 	int			interface;
    677 	usb_client_dev_data_t	*dev_data =
    678 	    usbprnp->usbprn_dev_data;
    679 	usb_alt_if_data_t	*altif_data;
    680 	usb_cfg_data_t		*cfg_data;
    681 	usb_ep_data_t		*ep_data;
    682 	dev_info_t		*dip = usbprnp->usbprn_dip;
    683 	int			alt, rval;
    684 
    685 	ASSERT(!mutex_owned(&usbprnp->usbprn_mutex));
    686 
    687 	/*
    688 	 * Section 4.2.1 of the spec says the printer could have
    689 	 * multiple configurations.  This driver is just for one
    690 	 * configuration interface and one interface.
    691 	 */
    692 	interface = dev_data->dev_curr_if;
    693 	cfg_data = dev_data->dev_curr_cfg;
    694 
    695 	/* find alternate that supports BI/UNI protocol */
    696 	for (alt = 0; alt < cfg_data->cfg_if[interface].if_n_alt; alt++) {
    697 		altif_data = &cfg_data->cfg_if[interface].if_alt[alt];
    698 
    699 		if ((altif_data->altif_descr.bInterfaceProtocol ==
    700 		    USB_PROTO_PRINTER_UNI) ||
    701 		    (altif_data->altif_descr.bInterfaceProtocol ==
    702 		    USB_PROTO_PRINTER_BI)) {
    703 
    704 			break;
    705 		} else {
    706 			USB_DPRINTF_L3(PRINT_MASK_ATTA,
    707 			    usbprnp->usbprn_log_handle,
    708 			    "alternate %d not supported", alt);
    709 		}
    710 	}
    711 
    712 	if (alt == cfg_data->cfg_if[interface].if_n_alt) {
    713 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    714 		    "usbprn_get_descriptors: no alternate");
    715 
    716 		return (USB_FAILURE);
    717 	}
    718 
    719 
    720 	if ((rval = usb_set_alt_if(dip, interface, alt, USB_FLAGS_SLEEP,
    721 	    NULL, NULL)) != USB_SUCCESS) {
    722 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    723 		    "usbprn_get_descriptors: set alternate failed (%d)",
    724 		    rval);
    725 
    726 		return (rval);
    727 	}
    728 
    729 	usbprnp->usbprn_config_descr = cfg_data->cfg_descr;
    730 	usbprnp->usbprn_if_descr = altif_data->altif_descr;
    731 
    732 	/*
    733 	 * find the endpoint descriptors. There will be a bulk-out endpoint
    734 	 * and an optional bulk-in endpoint.
    735 	 */
    736 	if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, alt, 0,
    737 	    USB_EP_ATTR_BULK, USB_EP_DIR_OUT)) != NULL) {
    738 		usbprnp->usbprn_bulk_out.ps_ept_descr = ep_data->ep_descr;
    739 	}
    740 	if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, alt, 0,
    741 	    USB_EP_ATTR_BULK, USB_EP_DIR_IN)) != NULL) {
    742 		usbprnp->usbprn_bulk_in.ps_ept_descr = ep_data->ep_descr;
    743 	}
    744 
    745 	return (USB_SUCCESS);
    746 }
    747 
    748 
    749 /*
    750  * usbprn_get_device_id:
    751  *	Get the device id as described in 4.2.1 of the specification
    752  *	Lexmark printer returns 2 bytes when asked for 8 bytes
    753  *	We are ignoring data over and underrun.
    754  *	This is a synchronous function
    755  */
    756 static int
    757 usbprn_get_device_id(usbprn_state_t *usbprnp)
    758 {
    759 	int			len, n;
    760 	mblk_t			*data = NULL;
    761 	usb_cr_t		completion_reason;
    762 	usb_cb_flags_t		cb_flags;
    763 	int			rval = USB_FAILURE;
    764 	usb_ctrl_setup_t setup = {
    765 	    USB_DEV_REQ_DEV_TO_HOST |	/* bmRequestType */
    766 	    USB_DEV_REQ_TYPE_CLASS |
    767 	    USB_DEV_REQ_RCPT_IF,
    768 	    USB_PRINTER_GET_DEVICE_ID,	/* bRequest */
    769 	    0,				/* wValue: fill in later */
    770 	    0,				/* wIndex: fill in later  */
    771 	    0,				/* wLength: fill in later */
    772 	    0				/* attributes */
    773 	    };
    774 	void			*ptr;
    775 
    776 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    777 	    "usbprn_get_device_id: Begin");
    778 
    779 	ASSERT(!mutex_owned(&usbprnp->usbprn_mutex));
    780 
    781 	setup.wIndex = (usbprnp->usbprn_if_descr.bInterfaceNumber << 0x8) |
    782 	    (usbprnp->usbprn_if_descr.bAlternateSetting);
    783 	setup.wLength = USBPRN_MAX_DEVICE_ID_LENGTH;
    784 	setup.wValue = usbprnp->usbprn_config_descr.iConfiguration;
    785 
    786 	/*
    787 	 * This is always a sync request as this will never
    788 	 * be called in interrupt context.
    789 	 * First get the first two bytes that gives the length
    790 	 * of the device id string; then get the whole string
    791 	 */
    792 	if (usb_pipe_ctrl_xfer_wait(usbprnp->usbprn_def_ph, &setup,
    793 	    &data, &completion_reason, &cb_flags, 0) != USB_SUCCESS) {
    794 
    795 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    796 		    "usbprn_get_device_id: First sync command failed, cr=%d ",
    797 		    completion_reason);
    798 
    799 		/*
    800 		 * some devices return more than requested. as long as
    801 		 * we get the first two bytes, we can continue
    802 		 */
    803 		if (((completion_reason != USB_CR_DATA_OVERRUN) &&
    804 		    (completion_reason != USB_CR_DATA_UNDERRUN)) ||
    805 		    (data == NULL)) {
    806 
    807 			goto done;
    808 		}
    809 	}
    810 
    811 	ASSERT(data);
    812 	n = MBLKL(data);
    813 
    814 	if (n < 2) {
    815 
    816 		goto done;
    817 	}
    818 
    819 	len = (((*data->b_rptr) << 0x8) | (*(data->b_rptr+1)));
    820 
    821 	/*
    822 	 * Std 1284-1994, chapter 7.6:
    823 	 *	Length values of x'0000', x'0001' and x'0002' are reserved
    824 	 */
    825 	if (len < 3) {
    826 
    827 		goto done;
    828 	}
    829 
    830 	USB_DPRINTF_L3(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    831 	    "usbprn_get_device_id: device id length=%d", len);
    832 
    833 	/* did we get enough data */
    834 	if (len > n) {
    835 		freemsg(data);
    836 		data = NULL;
    837 
    838 		setup.wLength = (uint16_t)len;
    839 		if ((rval = usb_pipe_ctrl_xfer_wait(usbprnp->usbprn_def_ph,
    840 		    &setup, &data, &completion_reason, &cb_flags, 0)) !=
    841 		    USB_SUCCESS) {
    842 			USB_DPRINTF_L2(PRINT_MASK_ATTA,
    843 			    usbprnp->usbprn_log_handle,
    844 			    "usbprn_get_device_id: 2nd command failed "
    845 			    "cr=%d cb_flags=0x%x",
    846 			    completion_reason, cb_flags);
    847 
    848 			goto done;
    849 		}
    850 
    851 		ASSERT(len == MBLKL(data));
    852 	}
    853 
    854 	USB_DPRINTF_L3(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    855 	    "usbprn_get_device_id: returned data length=%ld",
    856 	    (long)(MBLKL(data)));
    857 
    858 	ptr = kmem_zalloc(len + 1, KM_SLEEP);
    859 
    860 	mutex_enter(&usbprnp->usbprn_mutex);
    861 	usbprnp->usbprn_device_id_len = len;
    862 	usbprnp->usbprn_device_id = ptr;
    863 
    864 	bcopy(data->b_rptr, usbprnp->usbprn_device_id,
    865 	    usbprnp->usbprn_device_id_len);
    866 	usbprnp->usbprn_device_id[usbprnp->usbprn_device_id_len] = '\0';
    867 
    868 	/* Length is in the first two bytes, dump string in logbuf */
    869 	usbprn_print_long(usbprnp, usbprnp->usbprn_device_id + 2,
    870 	    usbprnp->usbprn_device_id_len - 2);
    871 	mutex_exit(&usbprnp->usbprn_mutex);
    872 
    873 	rval = USB_SUCCESS;
    874 done:
    875 	freemsg(data);
    876 
    877 	USB_DPRINTF_L4(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
    878 	    "usbprn_get_device_id: rval=%d", rval);
    879 
    880 	return (rval);
    881 }
    882 
    883 
    884 /*
    885  * usbprn_get_port_status:
    886  *	Get the port status.
    887  *	This is a synchronous function
    888  */
    889 static int
    890 usbprn_get_port_status(usbprn_state_t  *usbprnp)
    891 {
    892 	mblk_t			*data = NULL;
    893 	usb_cr_t		completion_reason;
    894 	usb_cb_flags_t		cb_flags;
    895 	usb_ctrl_setup_t setup = {
    896 	    USB_DEV_REQ_DEV_TO_HOST |	/* bmRequestType */
    897 	    USB_DEV_REQ_TYPE_CLASS |
    898 	    USB_DEV_REQ_RCPT_IF,
    899 	    USB_PRINTER_GET_PORT_STATUS, /* bRequest */
    900 	    0,				/* wValue */
    901 	    0,				/* wIndex: fill in later  */
    902 	    1,				/* wLength */
    903 	    0				/* attributes */
    904 	    };
    905 	ASSERT(!mutex_owned(&usbprnp->usbprn_mutex));
    906 
    907 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
    908 	    "usbprn_get_port_status: Begin");
    909 
    910 	setup.wIndex = usbprnp->usbprn_if_descr.bInterfaceNumber;
    911 	if (usb_pipe_ctrl_xfer_wait(usbprnp->usbprn_def_ph,
    912 	    &setup, &data, &completion_reason, &cb_flags, 0) !=
    913 	    USB_SUCCESS) {
    914 		USB_DPRINTF_L2(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
    915 		    "usbprn_get_port_status: Sync command failed "
    916 		    "cr=%d cb_flags=0x%x", completion_reason, cb_flags);
    917 
    918 		freemsg(data);
    919 
    920 		return (USB_FAILURE);
    921 	} else {
    922 		mutex_enter(&usbprnp->usbprn_mutex);
    923 
    924 		ASSERT(data);
    925 		ASSERT(MBLKL(data) == 1);
    926 
    927 		usbprnp->usbprn_last_status = *data->b_rptr;
    928 
    929 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
    930 		    "usbprn_get_port_status(sync): status=0x%x",
    931 		    usbprnp->usbprn_last_status);
    932 
    933 		mutex_exit(&usbprnp->usbprn_mutex);
    934 		freemsg(data);
    935 
    936 		return (USB_SUCCESS);
    937 	}
    938 }
    939 
    940 
    941 /*
    942  * usbprn_open:
    943  *	Open the pipes
    944  */
    945 /*ARGSUSED*/
    946 static int
    947 usbprn_open(dev_t *devp, int flag, int sflag, cred_t *credp)
    948 {
    949 	usbprn_state_t *usbprnp = ddi_get_soft_state(usbprn_statep,
    950 	    USBPRN_MINOR_TO_INSTANCE(getminor(*devp)));
    951 	int rval = 0;
    952 
    953 	if (usbprnp == NULL) {
    954 
    955 		return (ENXIO);
    956 	}
    957 
    958 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbprnp->usbprn_log_handle,
    959 	    "usbprn_open:");
    960 
    961 	(void) usb_serialize_access(usbprnp->usbprn_ser_acc, USB_WAIT, 0);
    962 
    963 	/* Fail open on a disconnected device */
    964 	mutex_enter(&usbprnp->usbprn_mutex);
    965 	if (usbprnp->usbprn_dev_state == USB_DEV_DISCONNECTED) {
    966 		mutex_exit(&usbprnp->usbprn_mutex);
    967 		usb_release_access(usbprnp->usbprn_ser_acc);
    968 
    969 		return (ENODEV);
    970 	}
    971 
    972 	/* cannot happen? but just in case */
    973 	if (usbprnp->usbprn_dev_state == USB_DEV_SUSPENDED) {
    974 		mutex_exit(&usbprnp->usbprn_mutex);
    975 		usb_release_access(usbprnp->usbprn_ser_acc);
    976 
    977 		return (EIO);
    978 	}
    979 
    980 	if (getminor(*devp) & USBPRN_MINOR_UGEN_BITS_MASK) {
    981 		mutex_exit(&usbprnp->usbprn_mutex);
    982 
    983 		rval = usb_ugen_open(usbprnp->usbprn_ugen_hdl,
    984 		    devp, flag, sflag, credp);
    985 
    986 		usb_release_access(usbprnp->usbprn_ser_acc);
    987 
    988 		return (rval);
    989 	}
    990 
    991 	/* Exit if this instance is already open */
    992 	if (usbprnp->usbprn_flags & USBPRN_OPEN) {
    993 		mutex_exit(&usbprnp->usbprn_mutex);
    994 		usb_release_access(usbprnp->usbprn_ser_acc);
    995 
    996 		return (EBUSY);
    997 	}
    998 	mutex_exit(&usbprnp->usbprn_mutex);
    999 
   1000 	/* raise power */
   1001 	usbprn_pm_busy_component(usbprnp);
   1002 	(void) pm_raise_power(usbprnp->usbprn_dip,
   1003 	    0, USB_DEV_OS_FULL_PWR);
   1004 	/* initialize some softstate data */
   1005 	mutex_enter(&usbprnp->usbprn_mutex);
   1006 	usbprnp->usbprn_prn_timeouts.tmo_forward =
   1007 	    usbprnp->usbprn_setparms.write_timeout;
   1008 	usbprnp->usbprn_prn_timeouts.tmo_reverse = 0;
   1009 	mutex_exit(&usbprnp->usbprn_mutex);
   1010 
   1011 	if (usbprn_open_usb_pipes(usbprnp) != USB_SUCCESS) {
   1012 
   1013 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
   1014 		    "usbprn_open: pipe open failed");
   1015 
   1016 		usb_release_access(usbprnp->usbprn_ser_acc);
   1017 		usbprn_pm_idle_component(usbprnp);
   1018 
   1019 		return (EIO);
   1020 	}
   1021 
   1022 	mutex_enter(&usbprnp->usbprn_mutex);
   1023 	usbprnp->usbprn_flags |= USBPRN_OPEN;
   1024 
   1025 	/* set last status to online */
   1026 	usbprnp->usbprn_last_status &= ~USB_PRINTER_PORT_NO_SELECT;
   1027 	mutex_exit(&usbprnp->usbprn_mutex);
   1028 
   1029 	usb_release_access(usbprnp->usbprn_ser_acc);
   1030 
   1031 	USB_DPRINTF_L4(PRINT_MASK_OPEN, usbprnp->usbprn_log_handle,
   1032 	    "usbprn_open: End");
   1033 
   1034 	return (rval);
   1035 }
   1036 
   1037 
   1038 /*
   1039  * usbprn_close:
   1040  *	Close the pipes
   1041  */
   1042 /*ARGSUSED*/
   1043 static int
   1044 usbprn_close(dev_t dev, int flag, int otyp, cred_t *credp)
   1045 {
   1046 	usbprn_state_t	*usbprnp = ddi_get_soft_state(usbprn_statep,
   1047 	    USBPRN_MINOR_TO_INSTANCE(getminor(dev)));
   1048 	int		rval = 0;
   1049 
   1050 	if (usbprnp == NULL) {
   1051 
   1052 		return (ENXIO);
   1053 	}
   1054 
   1055 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, usbprnp->usbprn_log_handle,
   1056 	    "usbprn_close:");
   1057 
   1058 	if (getminor(dev) & USBPRN_MINOR_UGEN_BITS_MASK) {
   1059 		rval = usb_ugen_close(usbprnp->usbprn_ugen_hdl,
   1060 		    dev, flag, otyp, credp);
   1061 
   1062 		return (rval);
   1063 	}
   1064 
   1065 	/* avoid races with connect/disconnect */
   1066 	(void) usb_serialize_access(usbprnp->usbprn_ser_acc, USB_WAIT, 0);
   1067 	(void) usb_serialize_access(usbprnp->usbprn_dev_acc, USB_WAIT, 0);
   1068 
   1069 	/* Close all usb pipes */
   1070 	usbprn_close_usb_pipes(usbprnp);
   1071 
   1072 	/* prevent any accesses by setting flags to closed */
   1073 	mutex_enter(&usbprnp->usbprn_mutex);
   1074 	usbprnp->usbprn_flags &= ~USBPRN_OPEN;
   1075 	mutex_exit(&usbprnp->usbprn_mutex);
   1076 
   1077 	usb_release_access(usbprnp->usbprn_dev_acc);
   1078 	usb_release_access(usbprnp->usbprn_ser_acc);
   1079 
   1080 	usbprn_pm_idle_component(usbprnp);
   1081 
   1082 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, usbprnp->usbprn_log_handle,
   1083 	    "usbprn_close: End");
   1084 
   1085 	return (rval);
   1086 }
   1087 
   1088 
   1089 /*
   1090  * usbprn_read:
   1091  *	Read entry point (TBD)
   1092  */
   1093 /* ARGSUSED */
   1094 static int
   1095 usbprn_read(dev_t dev, struct uio *uiop, cred_t *credp)
   1096 {
   1097 	usbprn_state_t *usbprnp = ddi_get_soft_state(usbprn_statep,
   1098 	    USBPRN_MINOR_TO_INSTANCE(getminor(dev)));
   1099 
   1100 	if (usbprnp == NULL) {
   1101 
   1102 		return (ENXIO);
   1103 	}
   1104 
   1105 	if (getminor(dev) & USBPRN_MINOR_UGEN_BITS_MASK) {
   1106 		int rval;
   1107 
   1108 		/* raise power */
   1109 		usbprn_pm_busy_component(usbprnp);
   1110 		(void) pm_raise_power(usbprnp->usbprn_dip,
   1111 		    0, USB_DEV_OS_FULL_PWR);
   1112 
   1113 		if (usb_serialize_access(usbprnp->usbprn_write_acc,
   1114 		    USB_WAIT_SIG, 0) == 0) {
   1115 			usbprn_pm_idle_component(usbprnp);
   1116 
   1117 			return (EINTR);
   1118 		}
   1119 
   1120 		rval = usb_ugen_read(usbprnp->usbprn_ugen_hdl, dev,
   1121 		    uiop, credp);
   1122 
   1123 		usb_release_access(usbprnp->usbprn_write_acc);
   1124 
   1125 		usbprn_pm_idle_component(usbprnp);
   1126 
   1127 		return (rval);
   1128 	}
   1129 
   1130 	/* Do a bulk-in from the printer */
   1131 
   1132 	return (EIO);
   1133 }
   1134 
   1135 
   1136 /*
   1137  * usbprn_write:
   1138  *	Write to the printer
   1139  */
   1140 /* ARGSUSED2 */
   1141 static int
   1142 usbprn_write(dev_t dev, struct uio *uiop, cred_t *credp)
   1143 {
   1144 	usbprn_state_t *usbprnp = ddi_get_soft_state(usbprn_statep,
   1145 	    USBPRN_MINOR_TO_INSTANCE(getminor(dev)));
   1146 	usbprn_ps_t	*bulk_in = &usbprnp->usbprn_bulk_in;
   1147 	usbprn_ps_t	*bulk_out = &usbprnp->usbprn_bulk_out;
   1148 	int		rval;
   1149 
   1150 	if (usbprnp == NULL) {
   1151 
   1152 		return (ENXIO);
   1153 	}
   1154 
   1155 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1156 	    "usbprn_write: Begin usbprnp=0x%p ", (void *)usbprnp);
   1157 
   1158 	if (getminor(dev) & USBPRN_MINOR_UGEN_BITS_MASK) {
   1159 		/* raise power */
   1160 		usbprn_pm_busy_component(usbprnp);
   1161 		(void) pm_raise_power(usbprnp->usbprn_dip,
   1162 		    0, USB_DEV_OS_FULL_PWR);
   1163 
   1164 		if (usb_serialize_access(usbprnp->usbprn_write_acc,
   1165 		    USB_WAIT_SIG, 0) == 0) {
   1166 			usbprn_pm_idle_component(usbprnp);
   1167 
   1168 			return (EINTR);
   1169 		}
   1170 
   1171 		rval = usb_ugen_write(usbprnp->usbprn_ugen_hdl, dev,
   1172 		    uiop, credp);
   1173 
   1174 		usb_release_access(usbprnp->usbprn_write_acc);
   1175 
   1176 		usbprn_pm_idle_component(usbprnp);
   1177 
   1178 		return (rval);
   1179 	}
   1180 
   1181 	/*
   1182 	 * serialize writes
   1183 	 * we cannot use usbprn_ser_acc sync object at this point because
   1184 	 * that would block out the ioctls for the full duration of the write.
   1185 	 */
   1186 	if (usb_serialize_access(usbprnp->usbprn_write_acc,
   1187 	    USB_WAIT_SIG, 0) == 0) {
   1188 
   1189 		return (EINTR);
   1190 	}
   1191 
   1192 	/*
   1193 	 * Check the status of the pipe.  If it's not idle,
   1194 	 * then wait.
   1195 	 */
   1196 	mutex_enter(&usbprnp->usbprn_mutex);
   1197 
   1198 	/* if device is disconnected or pipes closed, fail immediately */
   1199 	if (!(USBPRN_DEVICE_ACCESS_OK(usbprnp))) {
   1200 		mutex_exit(&usbprnp->usbprn_mutex);
   1201 
   1202 		USB_DPRINTF_L2(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1203 		    "usbprn_write: device can't be accessed");
   1204 
   1205 		usb_release_access(usbprnp->usbprn_write_acc);
   1206 
   1207 		return (EIO);
   1208 	}
   1209 
   1210 	/* all pipes must be idle */
   1211 	ASSERT(bulk_out->ps_flags == USBPRN_PS_IDLE);
   1212 	ASSERT(bulk_in->ps_flags == USBPRN_PS_IDLE);
   1213 
   1214 	mutex_exit(&usbprnp->usbprn_mutex);
   1215 
   1216 	/*
   1217 	 * Call physio to do the transfer.  physio will
   1218 	 * call the strategy routine, and then call
   1219 	 * biowait() to block until the transfer completes.
   1220 	 */
   1221 	rval = physio(usbprn_strategy, (struct buf *)0, dev,
   1222 	    B_WRITE, usbprn_minphys, uiop);
   1223 
   1224 	usb_release_access(usbprnp->usbprn_write_acc);
   1225 
   1226 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1227 	    "usbprn_write: End");
   1228 
   1229 	return (rval);
   1230 }
   1231 
   1232 
   1233 /*
   1234  * usbprn_poll
   1235  */
   1236 static int
   1237 usbprn_poll(dev_t dev, short events,
   1238     int anyyet,  short *reventsp, struct pollhead **phpp)
   1239 {
   1240 	usbprn_state_t *usbprnp = ddi_get_soft_state(usbprn_statep,
   1241 	    USBPRN_MINOR_TO_INSTANCE(getminor(dev)));
   1242 
   1243 	if (usbprnp == NULL) {
   1244 
   1245 		return (ENXIO);
   1246 	}
   1247 
   1248 	if (getminor(dev) & USBPRN_MINOR_UGEN_BITS_MASK) {
   1249 		return (usb_ugen_poll(usbprnp->usbprn_ugen_hdl, dev, events,
   1250 		    anyyet, reventsp, phpp));
   1251 	}
   1252 
   1253 	return (ENXIO);
   1254 }
   1255 
   1256 
   1257 /*
   1258  * usbprn_strategy:
   1259  *	service a request to the device.
   1260  */
   1261 static int
   1262 usbprn_strategy(struct buf *bp)
   1263 {
   1264 	usbprn_state_t *usbprnp = ddi_get_soft_state(usbprn_statep,
   1265 	    USBPRN_MINOR_TO_INSTANCE(getminor(bp->b_edev)));
   1266 	usbprn_ps_t	*bulk_out = &usbprnp->usbprn_bulk_out;
   1267 
   1268 	bp_mapin(bp);
   1269 
   1270 	/*
   1271 	 * serialize to avoid races
   1272 	 * access is released in usbprn_biodone()
   1273 	 */
   1274 	(void) usb_serialize_access(usbprnp->usbprn_dev_acc, USB_WAIT, 0);
   1275 
   1276 	mutex_enter(&usbprnp->usbprn_mutex);
   1277 	if (!(USBPRN_DEVICE_ACCESS_OK(usbprnp))) {
   1278 		usbprn_biodone(usbprnp, EIO, 0);
   1279 		mutex_exit(&usbprnp->usbprn_mutex);
   1280 
   1281 		USB_DPRINTF_L2(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1282 		    "usbprn_strategy: device can't be accessed");
   1283 
   1284 		return (0);
   1285 	}
   1286 
   1287 	bulk_out->ps_flags = USBPRN_PS_NEED_TO_XFER;
   1288 
   1289 	ASSERT(usbprnp->usbprn_bp == NULL);
   1290 	usbprnp->usbprn_bp = bp;
   1291 
   1292 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1293 	    "usbprn_strategy: usbprnp=0x%p bp=0x%p count=%lu",
   1294 	    (void *)usbprnp, (void *)bp, bp->b_bcount);
   1295 
   1296 	ASSERT(usbprnp->usbprn_bulk_mp == NULL);
   1297 
   1298 	usbprnp->usbprn_bulk_mp = allocb(bp->b_bcount, BPRI_HI);
   1299 
   1300 	if (usbprnp->usbprn_bulk_mp == NULL) {
   1301 		bulk_out->ps_flags = USBPRN_PS_IDLE;
   1302 		usbprn_biodone(usbprnp, EIO, 0);
   1303 		mutex_exit(&usbprnp->usbprn_mutex);
   1304 
   1305 		USB_DPRINTF_L2(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1306 		    "usbprn_strategy: allocb failed");
   1307 
   1308 		return (0);
   1309 	}
   1310 
   1311 	bcopy((caddr_t)bp->b_un.b_addr,
   1312 	    usbprnp->usbprn_bulk_mp->b_datap->db_base, bp->b_bcount);
   1313 	usbprnp->usbprn_bulk_mp->b_wptr += bp->b_bcount;
   1314 	mutex_exit(&usbprnp->usbprn_mutex);
   1315 
   1316 	usbprn_send_async_bulk_data(usbprnp);
   1317 
   1318 	return (0);
   1319 }
   1320 
   1321 
   1322 /*
   1323  * usbprn_ioctl:
   1324  *	handle the ioctl
   1325  */
   1326 /*ARGSUSED4*/
   1327 static int
   1328 usbprn_ioctl(dev_t dev, int cmd, intptr_t arg, int flag,
   1329 		cred_t *credp, int *rvalp)
   1330 {
   1331 	int		err = 0;
   1332 	usbprn_state_t	*usbprnp = ddi_get_soft_state(usbprn_statep,
   1333 	    USBPRN_MINOR_TO_INSTANCE(getminor(dev)));
   1334 	struct ecpp_device_id	usbprn_devid;
   1335 	int		len;
   1336 
   1337 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1338 	    "usbprn_ioctl: Begin ");
   1339 
   1340 	(void) usb_serialize_access(usbprnp->usbprn_ser_acc, USB_WAIT, 0);
   1341 	mutex_enter(&usbprnp->usbprn_mutex);
   1342 
   1343 	/*
   1344 	 * only for PRNIOC_GET_STATUS cmd:
   1345 	 * if device is disconnected or pipes closed, fail immediately
   1346 	 */
   1347 	if ((cmd == PRNIOC_GET_STATUS) &&
   1348 	    !(USBPRN_DEVICE_ACCESS_OK(usbprnp))) {
   1349 		mutex_exit(&usbprnp->usbprn_mutex);
   1350 
   1351 		USB_DPRINTF_L2(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1352 		    "usbprn_write: device can't be accessed");
   1353 
   1354 		usb_release_access(usbprnp->usbprn_ser_acc);
   1355 
   1356 		return (EIO);
   1357 	}
   1358 	mutex_exit(&usbprnp->usbprn_mutex);
   1359 
   1360 	switch (cmd) {
   1361 	case ECPPIOC_GETDEVID:
   1362 		/*
   1363 		 * With genericized ioctls this interface should change.
   1364 		 * We ignore the mode in USB printer driver because
   1365 		 * it need not be in nibble mode in usb driver unlike
   1366 		 * ecpp to retrieve the device id string. Also we do
   1367 		 * not expect the application to call this twice since
   1368 		 * it doesn't change since attach time and we take care
   1369 		 * of calling it twice: once for getting the length and
   1370 		 * once for getting the actual device id string. So we
   1371 		 * set both the lengths to actual device id string length.
   1372 		 * Ref: PSARC/2000/018
   1373 		 */
   1374 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1375 		    "usbprn_ioctl: ECPPIOC_GETDEVID(0x%x)", cmd);
   1376 
   1377 		bzero(&usbprn_devid, sizeof (usbprn_devid));
   1378 
   1379 		ASSERT(!(mutex_owned(&usbprnp->usbprn_mutex)));
   1380 #ifdef _MULTI_DATAMODEL
   1381 		switch (ddi_model_convert_from(flag & FMODELS)) {
   1382 		case DDI_MODEL_ILP32: {
   1383 			struct ecpp_device_id32	usbprn_devid32;
   1384 
   1385 			if (ddi_copyin((caddr_t)arg, &usbprn_devid32,
   1386 			    sizeof (struct ecpp_device_id32), flag)) {
   1387 				err = EFAULT;
   1388 
   1389 				break;
   1390 			}
   1391 
   1392 			if (usbprnp->usbprn_device_id == NULL) {
   1393 				err = EIO;
   1394 
   1395 				break;
   1396 			}
   1397 			ASSERT(usbprnp->usbprn_device_id_len > 2);
   1398 
   1399 			usbprn_devid32.rlen = usbprnp->usbprn_device_id_len - 2;
   1400 			len = min(usbprn_devid32.len, usbprn_devid32.rlen);
   1401 
   1402 			if (ddi_copyout(usbprnp->usbprn_device_id + 2,
   1403 			    (caddr_t)(uintptr_t)usbprn_devid32.addr,
   1404 			    len, flag)) {
   1405 				err = EFAULT;
   1406 
   1407 				break;
   1408 			}
   1409 
   1410 			if (ddi_copyout(&usbprn_devid32, (caddr_t)arg,
   1411 			    sizeof (struct ecpp_device_id32), flag)) {
   1412 				err = EFAULT;
   1413 
   1414 				break;
   1415 			}
   1416 
   1417 			break;
   1418 		}
   1419 		case DDI_MODEL_NONE:
   1420 			if (ddi_copyin((caddr_t)arg, &usbprn_devid,
   1421 			    sizeof (struct ecpp_device_id), flag)) {
   1422 				err = EFAULT;
   1423 
   1424 				break;
   1425 			}
   1426 
   1427 			if (usbprnp->usbprn_device_id == NULL) {
   1428 				err = EIO;
   1429 
   1430 				break;
   1431 			}
   1432 			ASSERT(usbprnp->usbprn_device_id_len > 2);
   1433 
   1434 			usbprn_devid.rlen = usbprnp->usbprn_device_id_len - 2;
   1435 			len = min(usbprn_devid.len, usbprn_devid.rlen);
   1436 
   1437 			if (ddi_copyout(usbprnp->usbprn_device_id + 2,
   1438 			    usbprn_devid.addr, len, flag)) {
   1439 				err = EFAULT;
   1440 
   1441 				break;
   1442 			}
   1443 
   1444 			if (ddi_copyout(&usbprn_devid, (caddr_t)arg,
   1445 			    sizeof (struct ecpp_device_id), flag)) {
   1446 				err = EFAULT;
   1447 
   1448 				break;
   1449 			}
   1450 
   1451 			break;
   1452 		}
   1453 
   1454 		break;
   1455 #else
   1456 		if (ddi_copyin((caddr_t)arg, &usbprn_devid,
   1457 		    sizeof (struct ecpp_device_id), flag)) {
   1458 			err = EFAULT;
   1459 
   1460 			break;
   1461 		}
   1462 
   1463 
   1464 		if (usbprnp->usbprn_device_id == NULL) {
   1465 			err = EIO;
   1466 
   1467 			break;
   1468 		}
   1469 		ASSERT(usbprnp->usbprn_device_id_len > 2);
   1470 
   1471 		usbprn_devid.rlen = usbprnp->usbprn_device_id_len - 2;
   1472 		len = min(usbprn_devid.len, usbprn_devid.rlen);
   1473 
   1474 		if (ddi_copyout(usbprnp->usbprn_device_id + 2,
   1475 		    usbprn_devid.addr, len, flag)) {
   1476 			err = EFAULT;
   1477 
   1478 			break;
   1479 		}
   1480 
   1481 		if (ddi_copyout(&usbprn_devid, (caddr_t)arg,
   1482 		    sizeof (struct ecpp_device_id), flag)) {
   1483 			err = EFAULT;
   1484 
   1485 			break;
   1486 		}
   1487 
   1488 		break;
   1489 #endif
   1490 	case ECPPIOC_SETPARMS:
   1491 		err = usbprn_setparms(usbprnp, arg, flag);
   1492 
   1493 		break;
   1494 	case ECPPIOC_GETPARMS:
   1495 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1496 		    "usbprn_ioctl: ECPPIOC_GETPARMS(0x%x)", cmd);
   1497 
   1498 		/* Get the parameters */
   1499 		err = usbprn_getparms(usbprnp, arg, flag);
   1500 
   1501 		break;
   1502 	case BPPIOC_GETERR:
   1503 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1504 		    "usbprn_ioctl: ECPPIOC_GETERR(0x%x)", cmd);
   1505 
   1506 		/* Get the error state */
   1507 		usbprn_geterr(usbprnp, arg, flag);
   1508 
   1509 		break;
   1510 	case BPPIOC_TESTIO:
   1511 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1512 		    "usbprn_ioctl: BPPIOC_TESTIO(0x%x)",  cmd);
   1513 
   1514 		/* Get the port status */
   1515 		err = usbprn_testio(usbprnp, flag);
   1516 
   1517 		break;
   1518 	case PRNIOC_GET_IFCAP:
   1519 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1520 		    "usbprn_ioctl : PRNIOC_GET_IFCAP(0x%x)",  cmd);
   1521 
   1522 		/* get interface capabilities */
   1523 		err = usbprn_prnio_get_ifcap(usbprnp, arg, flag);
   1524 
   1525 		break;
   1526 	case PRNIOC_SET_IFCAP:
   1527 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1528 		    "usbprn_ioctl : PRNIOC_SET_IFCAP(0x%x)",  cmd);
   1529 
   1530 		/* get interface capabilities */
   1531 		err = usbprn_prnio_set_ifcap(usbprnp, arg, flag);
   1532 
   1533 		break;
   1534 	case PRNIOC_GET_IFINFO:
   1535 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1536 		    "usbprn_ioctl : PRNIOC_GET_IFINFO(0x%x)",  cmd);
   1537 
   1538 		/* get interface information */
   1539 		err = usbprn_prnio_get_ifinfo(usbprnp, arg, flag);
   1540 
   1541 		break;
   1542 	case PRNIOC_GET_STATUS:
   1543 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1544 		    "usbprn_ioctl : PRNIOC_GET_STATUS(0x%x)",  cmd);
   1545 
   1546 		/* get prnio status */
   1547 		err = usbprn_prnio_get_status(usbprnp, arg, flag);
   1548 
   1549 		break;
   1550 	case PRNIOC_GET_1284_DEVID:
   1551 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1552 		    "usbprn_ioctl : PRNIOC_GET_1284_DEVID(0x%x)",  cmd);
   1553 
   1554 		/* get device ID */
   1555 		err = usbprn_prnio_get_1284_devid(usbprnp, arg, flag);
   1556 
   1557 		break;
   1558 	case PRNIOC_GET_1284_STATUS:
   1559 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1560 		    "usbprn_ioctl : PRNIOC_GET_1284_STATUS(0x%x)",  cmd);
   1561 
   1562 		/* get prnio status */
   1563 		err = usbprn_prnio_get_1284_status(usbprnp, arg, flag);
   1564 
   1565 		break;
   1566 	case PRNIOC_GET_TIMEOUTS:
   1567 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1568 		    "usbprn_ioctl : PRNIOC_GET_TIMEOUTS(0x%x)", cmd);
   1569 
   1570 		/* Get the parameters */
   1571 		err = usbprn_prnio_get_timeouts(usbprnp, arg, flag);
   1572 
   1573 		break;
   1574 	case PRNIOC_SET_TIMEOUTS:
   1575 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1576 		    "usbprn_ioctl : PRNIOC_SET_TIMEOUTS(0x%x)", cmd);
   1577 
   1578 		/* Get the parameters */
   1579 		err = usbprn_prnio_set_timeouts(usbprnp, arg, flag);
   1580 
   1581 		break;
   1582 	case PRNIOC_RESET:
   1583 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1584 		    "usbprn_ioctl : PRNIOC_RESET(0x%x)",  cmd);
   1585 
   1586 		/* nothing */
   1587 		err = 0;
   1588 
   1589 		break;
   1590 	default:
   1591 		USB_DPRINTF_L2(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1592 		    "usbprn_ioctl: unknown(0x%x)", cmd);
   1593 		err = EINVAL;
   1594 	}
   1595 
   1596 	usb_release_access(usbprnp->usbprn_ser_acc);
   1597 
   1598 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1599 	    "usbprn_ioctl: End ");
   1600 
   1601 	return (err);
   1602 }
   1603 
   1604 
   1605 /*
   1606  * breakup by physio
   1607  */
   1608 static void
   1609 usbprn_minphys(struct buf *bp)
   1610 {
   1611 	usbprn_state_t *usbprnp = ddi_get_soft_state(usbprn_statep,
   1612 	    USBPRN_MINOR_TO_INSTANCE(getminor(bp->b_edev)));
   1613 
   1614 	mutex_enter(&usbprnp->usbprn_mutex);
   1615 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1616 	    "usbprn_minphys: bcount=%lu", bp->b_bcount);
   1617 
   1618 	if (bp->b_bcount > usbprnp->usbprn_max_bulk_xfer_size) {
   1619 		bp->b_bcount = min(usbprn_max_xfer_size,
   1620 		    usbprnp->usbprn_max_bulk_xfer_size);
   1621 	} else {
   1622 		bp->b_bcount = min(usbprn_max_xfer_size, bp->b_bcount);
   1623 	}
   1624 	mutex_exit(&usbprnp->usbprn_mutex);
   1625 }
   1626 
   1627 
   1628 /*
   1629  * usbprn_open_usb_pipes:
   1630  *	Open all pipes on the device
   1631  */
   1632 static int
   1633 usbprn_open_usb_pipes(usbprn_state_t *usbprnp)
   1634 {
   1635 	usb_pipe_policy_t *policy;
   1636 	usbprn_ps_t	*bulk_in = &usbprnp->usbprn_bulk_in;
   1637 	usbprn_ps_t	*bulk_out = &usbprnp->usbprn_bulk_out;
   1638 
   1639 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1640 	    "usbprn_open_usb_pipes:");
   1641 
   1642 	/*
   1643 	 * Intitialize the pipe policy for the bulk out pipe
   1644 	 */
   1645 	mutex_enter(&usbprnp->usbprn_mutex);
   1646 	policy = &(bulk_out->ps_policy);
   1647 	policy->pp_max_async_reqs = 1;
   1648 	mutex_exit(&usbprnp->usbprn_mutex);
   1649 
   1650 	/* Open bulk_out pipe */
   1651 	if (usb_pipe_open(usbprnp->usbprn_dip, &bulk_out->ps_ept_descr,
   1652 	    policy, USB_FLAGS_SLEEP, &bulk_out->ps_handle) != USB_SUCCESS) {
   1653 
   1654 		return (USB_FAILURE);
   1655 	}
   1656 
   1657 #ifdef LATER
   1658 	mutex_enter(&usbprnp->usbprn_mutex);
   1659 	/* Open the bulk in pipe if one exists */
   1660 	if (bulk_in->ps_ept_descr->bLength) {
   1661 		/*
   1662 		 * Initialize the pipe policy for the Bulk In pipe
   1663 		 */
   1664 		policy = &bulk_in->ps_policy;
   1665 		bulk_in->ps_flags = USBPRN_PS_IDLE;
   1666 		policy->pp_max_async_reqs = 1;
   1667 		mutex_exit(&usbprnp->usbprn_mutex);
   1668 
   1669 		/* Open bulk_in pipe */
   1670 		if (usb_pipe_open(usbprnp->usbprn_dip, bulk_in->ps_ept_descr,
   1671 		    policy, USB_FLAGS_SLEEP, &bulk_in->ps_handle) !=
   1672 		    USB_SUCCESS) {
   1673 
   1674 			return (USB_FAILURE);
   1675 		}
   1676 	} else {
   1677 		mutex_exit(&usbprnp->usbprn_mutex);
   1678 	}
   1679 #else
   1680 	mutex_enter(&usbprnp->usbprn_mutex);
   1681 	bulk_in->ps_flags = USBPRN_PS_IDLE;
   1682 	mutex_exit(&usbprnp->usbprn_mutex);
   1683 #endif
   1684 
   1685 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1686 	    "usbprn_open_usb_pipes: success");
   1687 
   1688 	return (USB_SUCCESS);
   1689 }
   1690 
   1691 
   1692 /*
   1693  * usbprn_close_usb_pipes:
   1694  *	Close the default/bulk in/out pipes synchronously
   1695  */
   1696 static void
   1697 usbprn_close_usb_pipes(usbprn_state_t *usbprnp)
   1698 {
   1699 	usbprn_ps_t	*bulk_in = &usbprnp->usbprn_bulk_in;
   1700 	usbprn_ps_t	*bulk_out = &usbprnp->usbprn_bulk_out;
   1701 
   1702 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1703 	    "usbprn_close_usb_pipes:");
   1704 #ifdef DEBUG
   1705 	mutex_enter(&usbprnp->usbprn_mutex);
   1706 	ASSERT(bulk_out->ps_flags == USBPRN_PS_IDLE);
   1707 	ASSERT(bulk_in->ps_flags == USBPRN_PS_IDLE);
   1708 	mutex_exit(&usbprnp->usbprn_mutex);
   1709 #endif
   1710 
   1711 	/*
   1712 	 * close the pipe, if another thread is already closing the
   1713 	 * pipe, we get USB_INVALID_PIPE
   1714 	 */
   1715 	if (bulk_out->ps_handle) {
   1716 
   1717 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1718 		    "usbprn_close_usb_pipes: Closing bulk out pipe");
   1719 
   1720 		usb_pipe_close(usbprnp->usbprn_dip, bulk_out->ps_handle,
   1721 		    USB_FLAGS_SLEEP, NULL, NULL);
   1722 		bulk_out->ps_handle = NULL;
   1723 	}
   1724 	if (bulk_in->ps_handle) {
   1725 
   1726 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1727 		    "usbprn_close_usb_pipes: Closing bulk in pipe");
   1728 
   1729 		usb_pipe_close(usbprnp->usbprn_dip, bulk_in->ps_handle,
   1730 		    USB_FLAGS_SLEEP, NULL, NULL);
   1731 		bulk_in->ps_handle = NULL;
   1732 	}
   1733 }
   1734 
   1735 
   1736 /*
   1737  * usbprn_getparms:
   1738  *	Get the parameters for the device
   1739  */
   1740 static int
   1741 usbprn_getparms(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   1742 {
   1743 	ASSERT(!(mutex_owned(&usbprnp->usbprn_mutex)));
   1744 
   1745 	if (ddi_copyout(&usbprnp->usbprn_setparms,
   1746 	    (caddr_t)arg, sizeof (struct ecpp_transfer_parms), flag)) {
   1747 
   1748 		return (EFAULT);
   1749 	}
   1750 
   1751 	return (0);
   1752 }
   1753 
   1754 
   1755 /*
   1756  * usbprn_setparms:
   1757  *	Set the parameters for the device
   1758  */
   1759 static int
   1760 usbprn_setparms(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   1761 {
   1762 	struct ecpp_transfer_parms xfer;
   1763 
   1764 	ASSERT(!(mutex_owned(&usbprnp->usbprn_mutex)));
   1765 
   1766 	if (ddi_copyin((caddr_t)arg, &xfer,
   1767 	    sizeof (struct ecpp_transfer_parms), flag)) {
   1768 
   1769 		return (EFAULT);
   1770 	}
   1771 	if ((xfer.write_timeout < USBPRN_XFER_TIMEOUT_MIN) ||
   1772 	    (xfer.write_timeout > USBPRN_XFER_TIMEOUT_MAX)) {
   1773 
   1774 		return (EINVAL);
   1775 	}
   1776 	if (!((xfer.mode == ECPP_CENTRONICS) ||
   1777 	    (xfer.mode == ECPP_COMPAT_MODE) ||
   1778 	    (xfer.mode == ECPP_NIBBLE_MODE) ||
   1779 	    (xfer.mode == ECPP_ECP_MODE) ||
   1780 	    (xfer.mode == ECPP_DIAG_MODE))) {
   1781 
   1782 		return (EINVAL);
   1783 
   1784 	}
   1785 	if (xfer.mode != ECPP_CENTRONICS) {
   1786 
   1787 		return (EPROTONOSUPPORT);
   1788 	}
   1789 
   1790 	mutex_enter(&usbprnp->usbprn_mutex);
   1791 	usbprnp->usbprn_setparms = xfer;
   1792 	usbprnp->usbprn_prn_timeouts.tmo_forward = xfer.write_timeout;
   1793 	mutex_exit(&usbprnp->usbprn_mutex);
   1794 
   1795 	return (0);
   1796 }
   1797 
   1798 
   1799 /*
   1800  * usbprn_geterr:
   1801  *	Return the any device error state
   1802  */
   1803 static void
   1804 usbprn_geterr(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   1805 {
   1806 	struct bpp_error_status bpp_status;
   1807 
   1808 	bzero(&bpp_status, sizeof (bpp_status));
   1809 
   1810 	mutex_enter(&usbprnp->usbprn_mutex);
   1811 	bpp_status.bus_error = 0;
   1812 	bpp_status.timeout_occurred = 0;
   1813 	bpp_status.pin_status = usbprn_error_state(usbprnp->usbprn_last_status);
   1814 
   1815 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1816 	    "usbprn_geterr: status=0x%x", usbprnp->usbprn_last_status);
   1817 
   1818 	mutex_exit(&usbprnp->usbprn_mutex);
   1819 
   1820 	(void) ddi_copyout(&bpp_status,
   1821 	    (caddr_t)arg, sizeof (struct bpp_error_status), flag);
   1822 }
   1823 
   1824 
   1825 /*
   1826  * usbprn_error_state:
   1827  *	Map the driver error state to that of the application
   1828  */
   1829 static char
   1830 usbprn_error_state(uchar_t status)
   1831 {
   1832 	uchar_t app_err_status = 0;
   1833 
   1834 	if (!(status & USB_PRINTER_PORT_NO_ERROR)) {
   1835 		app_err_status |= USB_PRINTER_ERR_ERR;
   1836 	}
   1837 	if (status & USB_PRINTER_PORT_EMPTY) {
   1838 		app_err_status |= USB_PRINTER_PE_ERR;
   1839 	}
   1840 	if (!(status & USB_PRINTER_PORT_NO_SELECT)) {
   1841 		app_err_status |= USB_PRINTER_SLCT_ERR;
   1842 	}
   1843 
   1844 	return (app_err_status);
   1845 }
   1846 
   1847 
   1848 static int
   1849 usbprn_ioctl_get_status(usbprn_state_t *usbprnp)
   1850 {
   1851 	/* Check the transfer mode */
   1852 	mutex_enter(&usbprnp->usbprn_mutex);
   1853 
   1854 	/* if device is disconnected or pipes closed, fail immediately */
   1855 	if (!(USBPRN_DEVICE_ACCESS_OK(usbprnp))) {
   1856 		mutex_exit(&usbprnp->usbprn_mutex);
   1857 
   1858 		USB_DPRINTF_L2(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1859 		    "usbprn_ioctl_get_status: device can't be accessed");
   1860 
   1861 		return (EIO);
   1862 	}
   1863 	mutex_exit(&usbprnp->usbprn_mutex);
   1864 
   1865 	if (usbprn_get_port_status(usbprnp) != USB_SUCCESS) {
   1866 
   1867 		return (EIO);
   1868 	}
   1869 
   1870 	return (0);
   1871 }
   1872 
   1873 
   1874 /*
   1875  * usbprn_testio:
   1876  *	Execute the ECPP_TESTIO ioctl
   1877  */
   1878 /* ARGSUSED1 */
   1879 static int
   1880 usbprn_testio(usbprn_state_t *usbprnp, int flag)
   1881 {
   1882 	int	err;
   1883 
   1884 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1885 	    "usbprn_testio: begin");
   1886 
   1887 	if ((err = usbprn_ioctl_get_status(usbprnp)) != 0) {
   1888 
   1889 		return (err);
   1890 	}
   1891 
   1892 	/* There is an error.  Return it to the user */
   1893 	mutex_enter(&usbprnp->usbprn_mutex);
   1894 
   1895 	if (usbprn_error_state(usbprnp->usbprn_last_status) != 0) {
   1896 		mutex_exit(&usbprnp->usbprn_mutex);
   1897 
   1898 		return (EIO);
   1899 
   1900 	} else {
   1901 		mutex_exit(&usbprnp->usbprn_mutex);
   1902 
   1903 		return (0);
   1904 	}
   1905 }
   1906 
   1907 
   1908 /*
   1909  * usbprn_prnio_get_status:
   1910  *	Execute the PRNIOC_GET_STATUS ioctl
   1911  */
   1912 static int
   1913 usbprn_prnio_get_status(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   1914 {
   1915 	uint_t	prnio_status = 0;
   1916 	int	err;
   1917 
   1918 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1919 	    "usbprn_prnio_get_status: begin");
   1920 
   1921 	/* capture printer status */
   1922 	err = usbprn_ioctl_get_status(usbprnp);
   1923 
   1924 	mutex_enter(&usbprnp->usbprn_mutex);
   1925 
   1926 	if (usbprnp->usbprn_dev_state == USB_DEV_ONLINE) {
   1927 		prnio_status |= PRN_ONLINE;
   1928 	}
   1929 	if ((err == 0) &&
   1930 	    (usbprnp->usbprn_last_status & USB_PRINTER_PORT_NO_ERROR)) {
   1931 		prnio_status |= PRN_READY;
   1932 	}
   1933 
   1934 	mutex_exit(&usbprnp->usbprn_mutex);
   1935 
   1936 	if (ddi_copyout(&prnio_status,
   1937 	    (caddr_t)arg, sizeof (prnio_status), flag)) {
   1938 
   1939 		return (EFAULT);
   1940 	}
   1941 
   1942 	return (0);
   1943 }
   1944 
   1945 
   1946 /*
   1947  * usbprn_prnio_get_1284_status:
   1948  *	Execute the PRNIOC_GET_1284_STATUS ioctl
   1949  */
   1950 static int
   1951 usbprn_prnio_get_1284_status(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   1952 {
   1953 	uchar_t		status;
   1954 	int		err;
   1955 
   1956 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   1957 	    "usbprn_prnio_get_1284_status: begin");
   1958 
   1959 	if ((err = usbprn_ioctl_get_status(usbprnp)) != 0) {
   1960 
   1961 		return (err);
   1962 	}
   1963 
   1964 	/* status was captured successfully */
   1965 	mutex_enter(&usbprnp->usbprn_mutex);
   1966 
   1967 	status = usbprnp->usbprn_last_status & (USB_PRINTER_PORT_NO_ERROR |
   1968 	    USB_PRINTER_PORT_NO_SELECT | USB_PRINTER_PORT_EMPTY);
   1969 
   1970 	mutex_exit(&usbprnp->usbprn_mutex);
   1971 
   1972 	if (ddi_copyout(&status, (caddr_t)arg, sizeof (status), flag)) {
   1973 
   1974 		return (EFAULT);
   1975 	}
   1976 
   1977 	return (0);
   1978 }
   1979 
   1980 
   1981 /*
   1982  * usbprn_prnio_get_ifcap:
   1983  *	Execute the PRNIOC_GET_IFCAP ioctl
   1984  */
   1985 /* ARGSUSED */
   1986 static int
   1987 usbprn_prnio_get_ifcap(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   1988 {
   1989 	ASSERT(!(mutex_owned(&usbprnp->usbprn_mutex)));
   1990 
   1991 	if (ddi_copyout(&usbprn_ifcap, (caddr_t)arg, sizeof (usbprn_ifcap),
   1992 	    flag)) {
   1993 
   1994 		return (EFAULT);
   1995 	}
   1996 
   1997 	return (0);
   1998 }
   1999 
   2000 
   2001 /*
   2002  * usbprn_prnio_get_ifcap:
   2003  *	Execute the PRNIOC_SET_IFCAP ioctl
   2004  */
   2005 /* ARGSUSED */
   2006 static int
   2007 usbprn_prnio_set_ifcap(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   2008 {
   2009 	uint_t	new_ifcap;
   2010 
   2011 	ASSERT(!(mutex_owned(&usbprnp->usbprn_mutex)));
   2012 
   2013 	if (ddi_copyin((caddr_t)arg, &new_ifcap, sizeof (new_ifcap), flag)) {
   2014 
   2015 		return (EFAULT);
   2016 	}
   2017 
   2018 	/* no settable capabilities */
   2019 	if (usbprn_ifcap != new_ifcap) {
   2020 
   2021 		return (EINVAL);
   2022 	}
   2023 
   2024 	return (0);
   2025 }
   2026 
   2027 
   2028 /*
   2029  * usbprn_prnio_get_ifinfo:
   2030  *	Execute the PRNIOC_GET_IFINFO ioctl
   2031  */
   2032 /* ARGSUSED */
   2033 static int
   2034 usbprn_prnio_get_ifinfo(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   2035 {
   2036 	struct prn_interface_info	prn_info;
   2037 	int	rlen, len;
   2038 
   2039 	rlen = strlen(usbprn_prnio_ifinfo);
   2040 
   2041 #ifdef _MULTI_DATAMODEL
   2042 	ASSERT(!(mutex_owned(&usbprnp->usbprn_mutex)));
   2043 
   2044 	switch (ddi_model_convert_from(flag & FMODELS)) {
   2045 	case DDI_MODEL_ILP32: {
   2046 		struct prn_interface_info32	prn_info32;
   2047 
   2048 		if (ddi_copyin((caddr_t)arg, &prn_info32,
   2049 		    sizeof (struct prn_interface_info32), flag)) {
   2050 
   2051 			return (EFAULT);
   2052 		}
   2053 
   2054 		prn_info32.if_rlen = rlen;
   2055 		len = min(rlen, prn_info32.if_len);
   2056 
   2057 		if (ddi_copyout(&usbprn_prnio_ifinfo[0],
   2058 		    (caddr_t)(uintptr_t)prn_info32.if_data, len, flag)) {
   2059 
   2060 			return (EFAULT);
   2061 		}
   2062 
   2063 		if (ddi_copyout(&prn_info32, (caddr_t)arg,
   2064 		    sizeof (struct prn_interface_info32), flag)) {
   2065 
   2066 			return (EFAULT);
   2067 		}
   2068 
   2069 		break;
   2070 	}
   2071 	case DDI_MODEL_NONE:
   2072 #endif /* _MULTI_DATAMODEL */
   2073 		ASSERT(!(mutex_owned(&usbprnp->usbprn_mutex)));
   2074 
   2075 		if (ddi_copyin((caddr_t)arg, &prn_info,
   2076 		    sizeof (struct prn_interface_info), flag)) {
   2077 
   2078 			return (EFAULT);
   2079 		}
   2080 
   2081 		prn_info.if_rlen = rlen;
   2082 		len = min(rlen, prn_info.if_len);
   2083 
   2084 		if (ddi_copyout(&usbprn_prnio_ifinfo[0],
   2085 		    prn_info.if_data, len, flag)) {
   2086 
   2087 			return (EFAULT);
   2088 		}
   2089 
   2090 		if (ddi_copyout(&prn_info, (caddr_t)arg,
   2091 		    sizeof (struct prn_interface_info), flag)) {
   2092 
   2093 			return (EFAULT);
   2094 		}
   2095 #ifdef _MULTI_DATAMODEL
   2096 
   2097 		break;
   2098 	}
   2099 #endif /* _MULTI_DATAMODEL */
   2100 
   2101 	return (0);
   2102 }
   2103 
   2104 
   2105 /*
   2106  * usbprn_prnio_getdevid:
   2107  *	Execute the PRNIOC_GET_1284_DEVID ioctl
   2108  */
   2109 static int
   2110 usbprn_prnio_get_1284_devid(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   2111 {
   2112 	struct prn_1284_device_id prn_devid;
   2113 	int	len;
   2114 
   2115 	ASSERT(!(mutex_owned(&usbprnp->usbprn_mutex)));
   2116 
   2117 #ifdef _MULTI_DATAMODEL
   2118 	switch (ddi_model_convert_from(flag & FMODELS)) {
   2119 	case DDI_MODEL_ILP32: {
   2120 		struct prn_1284_device_id32	prn_devid32;
   2121 
   2122 		if (ddi_copyin((caddr_t)arg, &prn_devid32,
   2123 		    sizeof (struct prn_1284_device_id32), flag)) {
   2124 
   2125 			return (EFAULT);
   2126 		}
   2127 
   2128 		prn_devid32.id_rlen = usbprnp->usbprn_device_id_len - 2;
   2129 		len = min(prn_devid32.id_rlen, prn_devid32.id_len);
   2130 
   2131 		if (ddi_copyout(usbprnp->usbprn_device_id + 2,
   2132 		    (caddr_t)(uintptr_t)prn_devid32.id_data, len, flag)) {
   2133 
   2134 			return (EFAULT);
   2135 		}
   2136 
   2137 		if (ddi_copyout(&prn_devid32, (caddr_t)arg,
   2138 		    sizeof (struct prn_1284_device_id32), flag)) {
   2139 
   2140 			return (EFAULT);
   2141 		}
   2142 
   2143 		break;
   2144 	}
   2145 	case DDI_MODEL_NONE:
   2146 #endif /* _MULTI_DATAMODEL */
   2147 		if (ddi_copyin((caddr_t)arg, &prn_devid,
   2148 		    sizeof (struct prn_1284_device_id), flag)) {
   2149 
   2150 			return (EFAULT);
   2151 		}
   2152 
   2153 		prn_devid.id_rlen = usbprnp->usbprn_device_id_len - 2;
   2154 		len = min(prn_devid.id_rlen, prn_devid.id_len);
   2155 
   2156 		if (ddi_copyout(usbprnp->usbprn_device_id + 2,
   2157 		    prn_devid.id_data, len, flag)) {
   2158 
   2159 			return (EFAULT);
   2160 		}
   2161 
   2162 		if (ddi_copyout(&prn_devid, (caddr_t)arg,
   2163 		    sizeof (struct prn_1284_device_id), flag)) {
   2164 
   2165 			return (EFAULT);
   2166 		}
   2167 #ifdef _MULTI_DATAMODEL
   2168 
   2169 		break;
   2170 	}
   2171 #endif /* _MULTI_DATAMODEL */
   2172 
   2173 	return (0);
   2174 }
   2175 
   2176 
   2177 /*
   2178  * usbprn_prnio_get_timeouts:
   2179  *	Return timeout
   2180  */
   2181 static int
   2182 usbprn_prnio_get_timeouts(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   2183 {
   2184 	ASSERT(!(mutex_owned(&usbprnp->usbprn_mutex)));
   2185 
   2186 	if (ddi_copyout(&usbprnp->usbprn_prn_timeouts,
   2187 	    (caddr_t)arg, sizeof (struct prn_timeouts), flag)) {
   2188 
   2189 		return (EFAULT);
   2190 	}
   2191 
   2192 	return (0);
   2193 }
   2194 
   2195 
   2196 /*
   2197  * usbprn_prnio_set_timeouts:
   2198  *	Set write timeout and prn timeout
   2199  */
   2200 static int
   2201 usbprn_prnio_set_timeouts(usbprn_state_t *usbprnp, intptr_t arg, int flag)
   2202 {
   2203 	struct prn_timeouts prn_timeouts;
   2204 
   2205 	ASSERT(!(mutex_owned(&usbprnp->usbprn_mutex)));
   2206 
   2207 	if (ddi_copyin((caddr_t)arg, &prn_timeouts,
   2208 	    sizeof (struct prn_timeouts), flag)) {
   2209 
   2210 		return (EFAULT);
   2211 	}
   2212 
   2213 	if ((prn_timeouts.tmo_forward < USBPRN_XFER_TIMEOUT_MIN) ||
   2214 	    (prn_timeouts.tmo_forward > USBPRN_XFER_TIMEOUT_MAX)) {
   2215 
   2216 		return (EINVAL);
   2217 	}
   2218 
   2219 	mutex_enter(&usbprnp->usbprn_mutex);
   2220 
   2221 	usbprnp->usbprn_prn_timeouts = prn_timeouts;
   2222 	usbprnp->usbprn_setparms.write_timeout = prn_timeouts.tmo_forward;
   2223 
   2224 	mutex_exit(&usbprnp->usbprn_mutex);
   2225 
   2226 	return (0);
   2227 }
   2228 
   2229 
   2230 /*
   2231  * usbprn_biodone:
   2232  *	If there is a bp, complete it
   2233  */
   2234 static void
   2235 usbprn_biodone(usbprn_state_t *usbprnp, int err, int bytes_remaining)
   2236 {
   2237 	struct buf *bp = usbprnp->usbprn_bp;
   2238 	usbprn_ps_t	*bulk_out = &usbprnp->usbprn_bulk_out;
   2239 	usbprn_ps_t	*bulk_in = &usbprnp->usbprn_bulk_in;
   2240 
   2241 	ASSERT(mutex_owned(&usbprnp->usbprn_mutex));
   2242 
   2243 	/* all pipes must be idle now */
   2244 	ASSERT(bulk_out->ps_flags == USBPRN_PS_IDLE);
   2245 	ASSERT(bulk_in->ps_flags == USBPRN_PS_IDLE);
   2246 
   2247 	if (bp) {
   2248 		bp->b_resid = bytes_remaining;
   2249 
   2250 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2251 		    "usbprn_biodone: "
   2252 		    "bp=0x%p bcount=0x%lx resid=0x%lx remaining=0x%x err=%d",
   2253 		    (void *)bp, bp->b_bcount, bp->b_resid, bytes_remaining,
   2254 		    err);
   2255 
   2256 		if (err) {
   2257 			bioerror(bp, err);
   2258 		}
   2259 
   2260 		usbprnp->usbprn_bp = NULL;
   2261 		biodone(bp);
   2262 	}
   2263 
   2264 	/* release access */
   2265 	usb_release_access(usbprnp->usbprn_dev_acc);
   2266 }
   2267 
   2268 
   2269 /*
   2270  * usbprn_send_async_bulk_data:
   2271  *	Send bulk data down to the device through the bulk out pipe
   2272  */
   2273 static void
   2274 usbprn_send_async_bulk_data(usbprn_state_t *usbprnp)
   2275 {
   2276 	int		rval;
   2277 	int		timeout;
   2278 	mblk_t		*mp;
   2279 	size_t		max_xfer_count, xfer_count;
   2280 	usbprn_ps_t	*bulk_out = &usbprnp->usbprn_bulk_out;
   2281 	usb_bulk_req_t *req;
   2282 
   2283 	mutex_enter(&usbprnp->usbprn_mutex);
   2284 	ASSERT(bulk_out->ps_flags == USBPRN_PS_NEED_TO_XFER);
   2285 
   2286 	timeout = usbprnp->usbprn_setparms.write_timeout;
   2287 	max_xfer_count = usbprnp->usbprn_bp->b_bcount;
   2288 	mp = usbprnp->usbprn_bulk_mp;
   2289 	ASSERT(mp != NULL);
   2290 	xfer_count = MBLKL(mp);
   2291 	mutex_exit(&usbprnp->usbprn_mutex);
   2292 
   2293 	req = usb_alloc_bulk_req(usbprnp->usbprn_dip, 0, USB_FLAGS_SLEEP);
   2294 	req->bulk_len		= (uint_t)xfer_count;
   2295 	req->bulk_data		= mp;
   2296 	req->bulk_timeout	= timeout;
   2297 	req->bulk_cb		= usbprn_bulk_xfer_cb;
   2298 	req->bulk_exc_cb	= usbprn_bulk_xfer_exc_cb;
   2299 	req->bulk_client_private = (usb_opaque_t)usbprnp;
   2300 	req->bulk_attributes	= USB_ATTRS_AUTOCLEARING;
   2301 
   2302 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2303 	    "usbprn_send_async_bulk_data: req = 0x%p "
   2304 	    "max_bulk_xfer_size=%lu mp=0x%p xfer_cnt=%lu timeout=%x",
   2305 	    (void *)req, max_xfer_count, (void *)mp, xfer_count, timeout);
   2306 
   2307 	ASSERT(xfer_count <= max_xfer_count);
   2308 
   2309 
   2310 	if ((rval = usb_pipe_bulk_xfer(bulk_out->ps_handle, req, 0)) !=
   2311 	    USB_SUCCESS) {
   2312 
   2313 		USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2314 		    "usbprn_send_async_bulk_data: Bulk mp=0x%p "
   2315 		    "rval=%d", (void *)mp, rval);
   2316 
   2317 		mutex_enter(&usbprnp->usbprn_mutex);
   2318 		bulk_out->ps_flags = USBPRN_PS_IDLE;
   2319 		usbprnp->usbprn_bulk_mp = NULL;
   2320 		usbprn_biodone(usbprnp, EIO, 0);
   2321 		mutex_exit(&usbprnp->usbprn_mutex);
   2322 
   2323 		usb_free_bulk_req(req);
   2324 	} else {
   2325 		mutex_enter(&usbprnp->usbprn_mutex);
   2326 		usbprnp->usbprn_bulk_mp = NULL;
   2327 		mutex_exit(&usbprnp->usbprn_mutex);
   2328 	}
   2329 }
   2330 
   2331 
   2332 /*
   2333  * usbprn_bulk_xfer_cb
   2334  *	Callback for a normal transfer for both bulk pipes.
   2335  */
   2336 /*ARGSUSED*/
   2337 static void
   2338 usbprn_bulk_xfer_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
   2339 {
   2340 	usbprn_state_t	*usbprnp = (usbprn_state_t *)req->bulk_client_private;
   2341 	usbprn_ps_t	*bulk_out = &usbprnp->usbprn_bulk_out;
   2342 
   2343 	ASSERT(usbprnp != NULL);
   2344 	ASSERT(!mutex_owned(&usbprnp->usbprn_mutex));
   2345 
   2346 	mutex_enter(&usbprnp->usbprn_mutex);
   2347 
   2348 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2349 	    "usbprn_bulk_xfer_cb: mp=0x%p ", (void *)usbprnp->usbprn_bulk_mp);
   2350 
   2351 	ASSERT(bulk_out->ps_flags == USBPRN_PS_NEED_TO_XFER);
   2352 	ASSERT(usbprnp->usbprn_bp != NULL);
   2353 	ASSERT((req->bulk_cb_flags & USB_CB_INTR_CONTEXT) == 0);
   2354 
   2355 	/*
   2356 	 * if device is disconnected or driver close called, return
   2357 	 * The pipe could be closed, or a timeout could have
   2358 	 * come in and the pipe is being reset.  If the
   2359 	 * state isn't transferring, then return
   2360 	 */
   2361 	if (!(USBPRN_DEVICE_ACCESS_OK(usbprnp)) ||
   2362 	    (bulk_out->ps_flags != USBPRN_PS_NEED_TO_XFER)) {
   2363 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2364 		    "usbprn_bulk_xfer_cb: no access or pipe closed");
   2365 
   2366 		bulk_out->ps_flags = USBPRN_PS_IDLE;
   2367 		usbprn_biodone(usbprnp, EIO, 0);
   2368 	} else {
   2369 
   2370 		/*
   2371 		 * data has been xferred, complete the bp.
   2372 		 */
   2373 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2374 		    "usbprn_bulk_xfer_cb: transaction over");
   2375 
   2376 		bulk_out->ps_flags = USBPRN_PS_IDLE;
   2377 		usbprn_biodone(usbprnp, 0, 0);
   2378 	}
   2379 
   2380 	mutex_exit(&usbprnp->usbprn_mutex);
   2381 
   2382 	usb_free_bulk_req(req);
   2383 }
   2384 
   2385 
   2386 /*
   2387  * usbprn_bulk_xfer_exc_cb:
   2388  *	Exception callback for the bulk pipes
   2389  */
   2390 static void
   2391 usbprn_bulk_xfer_exc_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
   2392 {
   2393 	usbprn_state_t	*usbprnp = (usbprn_state_t *)req->bulk_client_private;
   2394 	usbprn_ps_t	*bulk_out = &usbprnp->usbprn_bulk_out;
   2395 	int		bytes_remaining = 0;
   2396 	mblk_t		*data = req->bulk_data;
   2397 	usb_cr_t	completion_reason = req->bulk_completion_reason;
   2398 	usb_cb_flags_t	cb_flags = req->bulk_cb_flags;
   2399 
   2400 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2401 	    "usbprn_bulk_xfer_exc_cb: "
   2402 	    "pipe=0x%p req=0x%p cr=%d cb_flags=0x%x data=0x%p",
   2403 	    (void *)pipe, (void *)req, completion_reason, cb_flags,
   2404 	    (void *)data);
   2405 
   2406 	ASSERT((req->bulk_cb_flags & USB_CB_INTR_CONTEXT) == 0);
   2407 	ASSERT(data != NULL);
   2408 	mutex_enter(&usbprnp->usbprn_mutex);
   2409 
   2410 	ASSERT(bulk_out->ps_flags == USBPRN_PS_NEED_TO_XFER);
   2411 	bulk_out->ps_flags = USBPRN_PS_IDLE;
   2412 	bulk_out->ps_cr = completion_reason;
   2413 
   2414 	if (data) {
   2415 		bytes_remaining = MBLKL(data);
   2416 	}
   2417 
   2418 	/*
   2419 	 * If the pipe is closed or device not responding or not in
   2420 	 * need of transfer, just give up on this bp.
   2421 	 */
   2422 	if (!(USBPRN_DEVICE_ACCESS_OK(usbprnp)) ||
   2423 	    (req->bulk_completion_reason == USB_CR_DEV_NOT_RESP)) {
   2424 		USB_DPRINTF_L2(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2425 		    "usbprn_bulk_xfer_exc_cb: "
   2426 		    "device not accesible or wrong state");
   2427 		usbprn_biodone(usbprnp, EIO, 0);
   2428 	} else {
   2429 		if (completion_reason == USB_CR_TIMEOUT) {
   2430 			USB_DPRINTF_L2(PRINT_MASK_ALL,
   2431 			    usbprnp->usbprn_log_handle,
   2432 			    "usbprn_bulk_xfer_exc_cb: timeout error, "
   2433 			    "xferred %lu bytes",
   2434 			    ((usbprnp->usbprn_bp->b_bcount) -
   2435 			    bytes_remaining));
   2436 			usbprn_biodone(usbprnp, 0, bytes_remaining);
   2437 		} else {
   2438 			usbprn_biodone(usbprnp, EIO, 0);
   2439 		}
   2440 
   2441 	}
   2442 
   2443 	mutex_exit(&usbprnp->usbprn_mutex);
   2444 
   2445 	usb_free_bulk_req(req);
   2446 }
   2447 
   2448 
   2449 /*
   2450  * usbprn_reconnect_event_cb:
   2451  *	Called upon when the device is hotplugged back; event handling
   2452  */
   2453 /*ARGSUSED*/
   2454 static int
   2455 usbprn_reconnect_event_cb(dev_info_t *dip)
   2456 {
   2457 	usbprn_state_t	*usbprnp =
   2458 	    (usbprn_state_t *)ddi_get_soft_state(usbprn_statep,
   2459 	    ddi_get_instance(dip));
   2460 
   2461 	ASSERT(usbprnp != NULL);
   2462 
   2463 	USB_DPRINTF_L3(PRINT_MASK_EVENTS, usbprnp->usbprn_log_handle,
   2464 	    "usbprn_reconnect_event_cb:");
   2465 
   2466 	(void) usb_serialize_access(usbprnp->usbprn_ser_acc, USB_WAIT, 0);
   2467 
   2468 	mutex_enter(&usbprnp->usbprn_mutex);
   2469 	ASSERT(usbprnp->usbprn_dev_state == USB_DEV_DISCONNECTED);
   2470 
   2471 	mutex_exit(&usbprnp->usbprn_mutex);
   2472 
   2473 	usbprn_restore_device_state(dip, usbprnp);
   2474 
   2475 	if (usbprnp->usbprn_ugen_hdl) {
   2476 		(void) usb_ugen_reconnect_ev_cb(usbprnp->usbprn_ugen_hdl);
   2477 	}
   2478 
   2479 	usb_release_access(usbprnp->usbprn_ser_acc);
   2480 
   2481 	return (USB_SUCCESS);
   2482 }
   2483 
   2484 
   2485 /*
   2486  * usbprn_disconnect_event_cb:
   2487  *	callback for disconnect events
   2488  */
   2489 /*ARGSUSED*/
   2490 static int
   2491 usbprn_disconnect_event_cb(dev_info_t *dip)
   2492 {
   2493 	usbprn_state_t	*usbprnp = (usbprn_state_t *)ddi_get_soft_state(
   2494 	    usbprn_statep, ddi_get_instance(dip));
   2495 
   2496 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2497 	    "usbprn_disconnect_event_cb: Begin");
   2498 
   2499 	(void) usb_serialize_access(usbprnp->usbprn_ser_acc, USB_WAIT, 0);
   2500 
   2501 	mutex_enter(&usbprnp->usbprn_mutex);
   2502 	usbprnp->usbprn_dev_state = USB_DEV_DISCONNECTED;
   2503 
   2504 	if (usbprnp->usbprn_flags & USBPRN_OPEN) {
   2505 		USB_DPRINTF_L0(PRINT_MASK_EVENTS, usbprnp->usbprn_log_handle,
   2506 		    "device was disconnected while open. "
   2507 		    "Data may have been lost");
   2508 	}
   2509 
   2510 	/* For now, we set the offline bit in usbprn_last_status */
   2511 	usbprnp->usbprn_last_status |= USB_PRINTER_PORT_NO_SELECT;
   2512 
   2513 	mutex_exit(&usbprnp->usbprn_mutex);
   2514 
   2515 	if (usbprnp->usbprn_ugen_hdl) {
   2516 		(void) usb_ugen_disconnect_ev_cb(usbprnp->usbprn_ugen_hdl);
   2517 	}
   2518 
   2519 	usb_release_access(usbprnp->usbprn_ser_acc);
   2520 
   2521 	USB_DPRINTF_L4(PRINT_MASK_EVENTS, usbprnp->usbprn_log_handle,
   2522 	    "usbprn_disconnect_event_cb: End");
   2523 
   2524 	return (USB_SUCCESS);
   2525 }
   2526 
   2527 
   2528 /*
   2529  * usbprn_restore_device_state:
   2530  *	set original configuration of the device
   2531  *	Restores data xfer
   2532  */
   2533 static void
   2534 usbprn_restore_device_state(dev_info_t *dip, usbprn_state_t *usbprnp)
   2535 {
   2536 	int alt, rval, iface;
   2537 
   2538 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2539 	    "usbprn_restore_device_state:");
   2540 
   2541 	mutex_enter(&usbprnp->usbprn_mutex);
   2542 	ASSERT((usbprnp->usbprn_dev_state == USB_DEV_DISCONNECTED) ||
   2543 	    (usbprnp->usbprn_dev_state == USB_DEV_SUSPENDED));
   2544 
   2545 	mutex_exit(&usbprnp->usbprn_mutex);
   2546 
   2547 	/* Check if we are talking to the same device */
   2548 	if (usb_check_same_device(dip, usbprnp->usbprn_log_handle,
   2549 	    USB_LOG_L0, PRINT_MASK_ALL,
   2550 	    USB_CHK_ALL, NULL) != USB_SUCCESS) {
   2551 
   2552 		/* change the device state from suspended to disconnected */
   2553 		mutex_enter(&usbprnp->usbprn_mutex);
   2554 		usbprnp->usbprn_dev_state = USB_DEV_DISCONNECTED;
   2555 		mutex_exit(&usbprnp->usbprn_mutex);
   2556 
   2557 		return;
   2558 	}
   2559 
   2560 	USB_DPRINTF_L0(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2561 	    "Printer has been reconnected but data may have been lost");
   2562 
   2563 	mutex_enter(&usbprnp->usbprn_mutex);
   2564 
   2565 	/* set last status to online */
   2566 	usbprnp->usbprn_last_status &= ~USB_PRINTER_PORT_NO_SELECT;
   2567 	mutex_exit(&usbprnp->usbprn_mutex);
   2568 
   2569 	/* Get the port status */
   2570 	if (usbprn_get_port_status(usbprnp) != USB_SUCCESS) {
   2571 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
   2572 		    "usbprn_restore_device_state: port status failed");
   2573 
   2574 		return;
   2575 	}
   2576 
   2577 	mutex_enter(&usbprnp->usbprn_mutex);
   2578 
   2579 	if ((usbprnp->usbprn_last_status & USB_PRINTER_PORT_NO_ERROR) == 0) {
   2580 		USB_DPRINTF_L2(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2581 		    "usbprn_restore_device_state: An error with the printer");
   2582 	}
   2583 
   2584 	if (usbprnp->usbprn_flags & USBPRN_OPEN) {
   2585 		mutex_exit(&usbprnp->usbprn_mutex);
   2586 		usbprn_close_usb_pipes(usbprnp);
   2587 		mutex_enter(&usbprnp->usbprn_mutex);
   2588 	}
   2589 
   2590 	/* restore alternate */
   2591 	alt = usbprnp->usbprn_if_descr.bAlternateSetting,
   2592 	    mutex_exit(&usbprnp->usbprn_mutex);
   2593 
   2594 	iface = usb_owns_device(dip) ? 0 :  usb_get_if_number(dip);
   2595 	if ((rval = usb_set_alt_if(dip, iface, alt,
   2596 	    USB_FLAGS_SLEEP, NULL, NULL)) != USB_SUCCESS) {
   2597 		USB_DPRINTF_L2(PRINT_MASK_ATTA, usbprnp->usbprn_log_handle,
   2598 		    "usbprn_restore_device_state: set alternate failed (%d)",
   2599 		    rval);
   2600 
   2601 		return;
   2602 	}
   2603 
   2604 	mutex_enter(&usbprnp->usbprn_mutex);
   2605 
   2606 	if (usbprnp->usbprn_flags & USBPRN_OPEN) {
   2607 
   2608 		mutex_exit(&usbprnp->usbprn_mutex);
   2609 		(void) usbprn_open_usb_pipes(usbprnp);
   2610 		mutex_enter(&usbprnp->usbprn_mutex);
   2611 	}
   2612 
   2613 	if (usbprnp->usbprn_pm && usbprnp->usbprn_pm->usbprn_wakeup_enabled) {
   2614 		mutex_exit(&usbprnp->usbprn_mutex);
   2615 		(void) usb_handle_remote_wakeup(usbprnp->usbprn_dip,
   2616 		    USB_REMOTE_WAKEUP_ENABLE);
   2617 		mutex_enter(&usbprnp->usbprn_mutex);
   2618 	}
   2619 
   2620 	usbprnp->usbprn_dev_state = USB_DEV_ONLINE;
   2621 	mutex_exit(&usbprnp->usbprn_mutex);
   2622 
   2623 	USB_DPRINTF_L4(PRINT_MASK_ALL, usbprnp->usbprn_log_handle,
   2624 	    "usbprn_restore_device_state: End");
   2625 }
   2626 
   2627 
   2628 /*
   2629  *	Create power managements components
   2630  */
   2631 static void
   2632 usbprn_create_pm_components(dev_info_t *dip, usbprn_state_t *usbprnp)
   2633 {
   2634 	usbprn_power_t	*usbprnpm;
   2635 	uint_t		pwr_states;
   2636 
   2637 	USB_DPRINTF_L4(PRINT_MASK_PM, usbprnp->usbprn_log_handle,
   2638 	    "usbprn_create_pm_components: Begin");
   2639 
   2640 	/* Allocate the state structure */
   2641 	usbprnpm = kmem_zalloc(sizeof (usbprn_power_t),
   2642 	    KM_SLEEP);
   2643 	usbprnp->usbprn_pm = usbprnpm;
   2644 	usbprnpm->usbprn_pm_capabilities = 0;
   2645 	usbprnpm->usbprn_current_power = USB_DEV_OS_FULL_PWR;
   2646 
   2647 	if (usb_create_pm_components(dip, &pwr_states) ==
   2648 	    USB_SUCCESS) {
   2649 		USB_DPRINTF_L4(PRINT_MASK_PM,
   2650 		    usbprnp->usbprn_log_handle,
   2651 		    "usbprn_create_pm_components: "
   2652 		    "created PM components");
   2653 
   2654 		if (usb_handle_remote_wakeup(dip,
   2655 		    USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) {
   2656 			usbprnpm->usbprn_wakeup_enabled = 1;
   2657 		}
   2658 		usbprnpm->usbprn_pwr_states = (uint8_t)pwr_states;
   2659 		(void) pm_raise_power(usbprnp->usbprn_dip, 0,
   2660 		    USB_DEV_OS_FULL_PWR);
   2661 	} else {
   2662 		USB_DPRINTF_L2(PRINT_MASK_PM,
   2663 		    usbprnp->usbprn_log_handle,
   2664 		    "usbprn_create_pm_components: Failed");
   2665 	}
   2666 
   2667 	USB_DPRINTF_L4(PRINT_MASK_PM, usbprnp->usbprn_log_handle,
   2668 	    "usbprn_create_pm_components: END");
   2669 }
   2670 
   2671 
   2672 /*
   2673  * usbprn_pwrlvl0:
   2674  * Functions to handle power transition for OS levels 0 -> 3
   2675  */
   2676 static int
   2677 usbprn_pwrlvl0(usbprn_state_t *usbprnp)
   2678 {
   2679 	int	rval;
   2680 
   2681 	USB_DPRINTF_L4(PRINT_MASK_PM, usbprnp->usbprn_log_handle,
   2682 	    "usbprn_pwrlvl0:");
   2683 
   2684 	switch (usbprnp->usbprn_dev_state) {
   2685 	case USB_DEV_ONLINE:
   2686 		/* Deny the powerdown request if the device is busy */
   2687 		if (usbprnp->usbprn_pm->usbprn_pm_busy != 0) {
   2688 
   2689 			return (USB_FAILURE);
   2690 		}
   2691 
   2692 		/* Issue USB D3 command to the device here */
   2693 		rval = usb_set_device_pwrlvl3(usbprnp->usbprn_dip);
   2694 		ASSERT(rval == USB_SUCCESS);
   2695 
   2696 		usbprnp->usbprn_dev_state = USB_DEV_PWRED_DOWN;
   2697 		usbprnp->usbprn_pm->usbprn_current_power =
   2698 		    USB_DEV_OS_PWR_OFF;
   2699 		/* FALLTHRU */
   2700 	case USB_DEV_DISCONNECTED:
   2701 	case USB_DEV_SUSPENDED:
   2702 		/* allow a disconnect/cpr'ed device to go to lower power */
   2703 
   2704 		return (USB_SUCCESS);
   2705 	case USB_DEV_PWRED_DOWN:
   2706 	default:
   2707 		USB_DPRINTF_L2(PRINT_MASK_PM, usbprnp->usbprn_log_handle,
   2708 		    "usbprn_pwrlvl0: illegal dev state");
   2709 
   2710 		return (USB_FAILURE);
   2711 	}
   2712 }
   2713 
   2714 
   2715 /*
   2716  * usbprn_pwrlvl1:
   2717  *	Functions to handle power transition to OS levels -> 2
   2718  */
   2719 static int
   2720 usbprn_pwrlvl1(usbprn_state_t *usbprnp)
   2721 {
   2722 	int	rval;
   2723 
   2724 	USB_DPRINTF_L4(PRINT_MASK_PM, usbprnp->usbprn_log_handle,
   2725 	    "usbprn_pwrlvl1:");
   2726 
   2727 	/* Issue USB D2 command to the device here */
   2728 	rval = usb_set_device_pwrlvl2(usbprnp->usbprn_dip);
   2729 	ASSERT(rval == USB_SUCCESS);
   2730 
   2731 	return (USB_FAILURE);
   2732 }
   2733 
   2734 
   2735 /*
   2736  * usbprn_pwrlvl2:
   2737  *	Functions to handle power transition to OS levels -> 1
   2738  */
   2739 static int
   2740 usbprn_pwrlvl2(usbprn_state_t *usbprnp)
   2741 {
   2742 	int	rval;
   2743 
   2744 	USB_DPRINTF_L4(PRINT_MASK_PM, usbprnp->usbprn_log_handle,
   2745 	    "usbprn_pwrlvl2:");
   2746 
   2747 	/* Issue USB D1 command to the device here */
   2748 	rval = usb_set_device_pwrlvl1(usbprnp->usbprn_dip);
   2749 	ASSERT(rval == USB_SUCCESS);
   2750 
   2751 	return (USB_FAILURE);
   2752 }
   2753 
   2754 
   2755 /*
   2756  * usbprn_pwrlvl3:
   2757  *	Functions to handle power transition to OS level -> 0
   2758  */
   2759 static int
   2760 usbprn_pwrlvl3(usbprn_state_t *usbprnp)
   2761 {
   2762 	USB_DPRINTF_L4(PRINT_MASK_PM, usbprnp->usbprn_log_handle,
   2763 	    "usbprn_pwrlvl3:");
   2764 
   2765 	switch (usbprnp->usbprn_dev_state) {
   2766 	case USB_DEV_PWRED_DOWN:
   2767 		/* Issue USB D0 command to the device here */
   2768 		(void) usb_set_device_pwrlvl0(usbprnp->usbprn_dip);
   2769 
   2770 		usbprnp->usbprn_dev_state = USB_DEV_ONLINE;
   2771 		usbprnp->usbprn_pm->usbprn_current_power =
   2772 		    USB_DEV_OS_FULL_PWR;
   2773 
   2774 		/* FALLTHRU */
   2775 	case USB_DEV_ONLINE:
   2776 		/* we are already in full power */
   2777 		/* FALLTHRU */
   2778 	case USB_DEV_DISCONNECTED:
   2779 	case USB_DEV_SUSPENDED:
   2780 		/*
   2781 		 * PM framework tries to put us in full power
   2782 		 * during system shutdown. If we are disconnected/cpr'ed
   2783 		 * return success anyways
   2784 		 */
   2785 
   2786 		return (USB_SUCCESS);
   2787 	default:
   2788 		USB_DPRINTF_L4(PRINT_MASK_PM, usbprnp->usbprn_log_handle,
   2789 		    "usbprn_pwrlvl3:");
   2790 
   2791 
   2792 		return (USB_FAILURE);
   2793 	}
   2794 }
   2795 
   2796 
   2797 /*
   2798  * usbprn_power :
   2799  *	Power entry point
   2800  */
   2801 /* ARGSUSED */
   2802 static int
   2803 usbprn_power(dev_info_t *dip, int comp, int level)
   2804 {
   2805 	usbprn_state_t	*usbprnp;
   2806 	usbprn_power_t	*pm;
   2807 	int		rval = USB_FAILURE;
   2808 
   2809 	usbprnp = (usbprn_state_t *)ddi_get_soft_state(usbprn_statep,
   2810 	    ddi_get_instance(dip));
   2811 
   2812 	USB_DPRINTF_L3(PRINT_MASK_PM, usbprnp->usbprn_log_handle,
   2813 	    "usbprn_power: Begin: level=%d", level);
   2814 
   2815 	(void) usb_serialize_access(usbprnp->usbprn_ser_acc, USB_WAIT, 0);
   2816 
   2817 	mutex_enter(&usbprnp->usbprn_mutex);
   2818 	pm = usbprnp->usbprn_pm;
   2819 	ASSERT(pm != NULL);
   2820 
   2821 	/* Check if we are transitioning to a legal power level */
   2822 	if (USB_DEV_PWRSTATE_OK(pm->usbprn_pwr_states, level)) {
   2823 		USB_DPRINTF_L2(PRINT_MASK_PM, usbprnp->usbprn_log_handle,
   2824 		    "usbprn_power: illegal power level=%d "
   2825 		    "pwr_states=0x%x", level, pm->usbprn_pwr_states);
   2826 
   2827 		goto done;
   2828 	}
   2829 
   2830 	switch (level) {
   2831 	case USB_DEV_OS_PWR_OFF :
   2832 		rval = usbprn_pwrlvl0(usbprnp);
   2833 
   2834 		break;
   2835 	case USB_DEV_OS_PWR_1 :
   2836 		rval = usbprn_pwrlvl1(usbprnp);
   2837 
   2838 		break;
   2839 	case USB_DEV_OS_PWR_2 :
   2840 		rval = usbprn_pwrlvl2(usbprnp);
   2841 
   2842 		break;
   2843 	case USB_DEV_OS_FULL_PWR :
   2844 		rval = usbprn_pwrlvl3(usbprnp);
   2845 
   2846 		break;
   2847 	}
   2848 
   2849 done:
   2850 	mutex_exit(&usbprnp->usbprn_mutex);
   2851 
   2852 	usb_release_access(usbprnp->usbprn_ser_acc);
   2853 
   2854 	return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
   2855 }
   2856 
   2857 
   2858 /*
   2859  * usbprn_print_long:
   2860  *	Breakup a string which is > USBPRN_PRINT_MAXLINE and print it
   2861  */
   2862 static void
   2863 usbprn_print_long(usbprn_state_t *usbprnp, char *str, int len)
   2864 {
   2865 	char *tmp = str;
   2866 	char pbuf[USBPRN_PRINT_MAXLINE];
   2867 
   2868 	for (;;) {
   2869 		if (len <= USBPRN_PRINT_MAXLINE) {
   2870 			USB_DPRINTF_L4(PRINT_MASK_ATTA,
   2871 			    usbprnp->usbprn_log_handle, "%s", tmp);
   2872 
   2873 			break;
   2874 		} else {
   2875 			bcopy(tmp, pbuf, USBPRN_PRINT_MAXLINE);
   2876 			USB_DPRINTF_L4(PRINT_MASK_ATTA,
   2877 			    usbprnp->usbprn_log_handle, "%s", pbuf);
   2878 			tmp += USBPRN_PRINT_MAXLINE;
   2879 			len -= USBPRN_PRINT_MAXLINE;
   2880 		}
   2881 	}
   2882 }
   2883 
   2884 
   2885 static void
   2886 usbprn_pm_busy_component(usbprn_state_t *usbprn_statep)
   2887 {
   2888 	ASSERT(!mutex_owned(&usbprn_statep->usbprn_mutex));
   2889 	if (usbprn_statep->usbprn_pm != NULL) {
   2890 		mutex_enter(&usbprn_statep->usbprn_mutex);
   2891 		usbprn_statep->usbprn_pm->usbprn_pm_busy++;
   2892 
   2893 		USB_DPRINTF_L4(PRINT_MASK_PM, usbprn_statep->usbprn_log_handle,
   2894 		    "usbprn_pm_busy_component: %d",
   2895 		    usbprn_statep->usbprn_pm->usbprn_pm_busy);
   2896 
   2897 		mutex_exit(&usbprn_statep->usbprn_mutex);
   2898 
   2899 		if (pm_busy_component(usbprn_statep->usbprn_dip, 0) !=
   2900 		    DDI_SUCCESS) {
   2901 			mutex_enter(&usbprn_statep->usbprn_mutex);
   2902 			usbprn_statep->usbprn_pm->usbprn_pm_busy--;
   2903 
   2904 			USB_DPRINTF_L2(PRINT_MASK_PM,
   2905 			    usbprn_statep->usbprn_log_handle,
   2906 			    "usbprn_pm_busy_component: %d",
   2907 			    usbprn_statep->usbprn_pm->usbprn_pm_busy);
   2908 
   2909 			mutex_exit(&usbprn_statep->usbprn_mutex);
   2910 		}
   2911 
   2912 	}
   2913 }
   2914 
   2915 
   2916 static void
   2917 usbprn_pm_idle_component(usbprn_state_t *usbprn_statep)
   2918 {
   2919 	ASSERT(!mutex_owned(&usbprn_statep->usbprn_mutex));
   2920 	if (usbprn_statep->usbprn_pm != NULL) {
   2921 		if (pm_idle_component(usbprn_statep->usbprn_dip, 0) ==
   2922 		    DDI_SUCCESS) {
   2923 			mutex_enter(&usbprn_statep->usbprn_mutex);
   2924 			ASSERT(usbprn_statep->usbprn_pm->usbprn_pm_busy > 0);
   2925 			usbprn_statep->usbprn_pm->usbprn_pm_busy--;
   2926 
   2927 			USB_DPRINTF_L4(PRINT_MASK_PM,
   2928 			    usbprn_statep->usbprn_log_handle,
   2929 			    "usbprn_pm_idle_component: %d",
   2930 			    usbprn_statep->usbprn_pm->usbprn_pm_busy);
   2931 
   2932 			mutex_exit(&usbprn_statep->usbprn_mutex);
   2933 		}
   2934 
   2935 	}
   2936 }
   2937