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