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
_init(void)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
_fini(void)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
_info(struct modinfo * modinfop)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
usbprn_info(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)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
usbprn_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)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
usbprn_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)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
usbprn_cleanup(dev_info_t * dip,usbprn_state_t * usbprnp)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
usbprn_cpr_suspend(dev_info_t * dip)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
usbprn_cpr_resume(dev_info_t * dip)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
usbprn_get_descriptors(usbprn_state_t * usbprnp)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
usbprn_get_device_id(usbprn_state_t * usbprnp)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
usbprn_get_port_status(usbprn_state_t * usbprnp)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
usbprn_open(dev_t * devp,int flag,int sflag,cred_t * credp)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
usbprn_close(dev_t dev,int flag,int otyp,cred_t * credp)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
usbprn_read(dev_t dev,struct uio * uiop,cred_t * credp)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
usbprn_write(dev_t dev,struct uio * uiop,cred_t * credp)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
usbprn_poll(dev_t dev,short events,int anyyet,short * reventsp,struct pollhead ** phpp)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
usbprn_strategy(struct buf * bp)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
usbprn_ioctl(dev_t dev,int cmd,intptr_t arg,int flag,cred_t * credp,int * rvalp)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
usbprn_minphys(struct buf * bp)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
usbprn_open_usb_pipes(usbprn_state_t * usbprnp)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
usbprn_close_usb_pipes(usbprn_state_t * usbprnp)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
usbprn_getparms(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_setparms(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_geterr(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_error_state(uchar_t status)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
usbprn_ioctl_get_status(usbprn_state_t * usbprnp)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
usbprn_testio(usbprn_state_t * usbprnp,int flag)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
usbprn_prnio_get_status(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_prnio_get_1284_status(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_prnio_get_ifcap(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_prnio_set_ifcap(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_prnio_get_ifinfo(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_prnio_get_1284_devid(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_prnio_get_timeouts(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_prnio_set_timeouts(usbprn_state_t * usbprnp,intptr_t arg,int flag)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
usbprn_biodone(usbprn_state_t * usbprnp,int err,int bytes_remaining)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
usbprn_send_async_bulk_data(usbprn_state_t * usbprnp)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
usbprn_bulk_xfer_cb(usb_pipe_handle_t pipe,usb_bulk_req_t * req)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
usbprn_bulk_xfer_exc_cb(usb_pipe_handle_t pipe,usb_bulk_req_t * req)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
usbprn_reconnect_event_cb(dev_info_t * dip)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
usbprn_disconnect_event_cb(dev_info_t * dip)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
usbprn_restore_device_state(dev_info_t * dip,usbprn_state_t * usbprnp)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
usbprn_create_pm_components(dev_info_t * dip,usbprn_state_t * usbprnp)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
usbprn_pwrlvl0(usbprn_state_t * usbprnp)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
usbprn_pwrlvl1(usbprn_state_t * usbprnp)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
usbprn_pwrlvl2(usbprn_state_t * usbprnp)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
usbprn_pwrlvl3(usbprn_state_t * usbprnp)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
usbprn_power(dev_info_t * dip,int comp,int level)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
usbprn_print_long(usbprn_state_t * usbprnp,char * str,int len)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
usbprn_pm_busy_component(usbprn_state_t * usbprn_statep)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
usbprn_pm_idle_component(usbprn_state_t * usbprn_statep)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