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