1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
22 * Use is subject to license terms.
23 */
24
25
26 /*
27 * Printer Class Driver for USB
28 *
29 * This driver supports devices that adhere to the USB Printer Class
30 * specification 1.0.
31 *
32 * NOTE: This driver is not DDI compliant in that it uses undocumented
33 * functions for logging (USB_DPRINTF_L*, usb_alloc_log_hdl, usb_free_log_hdl),
34 * and serialization (usb_serialize_access, usb_release_access,
35 * usb_init_serialization, usb_fini_serialization)
36 *
37 * Undocumented functions may go away in a future Solaris OS release.
38 *
39 * Please see the DDK for sample code of these functions, and for the usbskel
40 * skeleton template driver which contains scaled-down versions of these
41 * functions written in a DDI-compliant way.
42 */
43
44 #if defined(lint) && !defined(DEBUG)
45 #define DEBUG
46 #endif
47 #ifdef __lock_lint
48 #define _MULTI_DATAMODEL
49 #endif
50
51 #define USBDRV_MAJOR_VER 2
52 #define USBDRV_MINOR_VER 0
53
54 #include <sys/usb/usba.h>
55 #include <sys/usb/usba/usba_ugen.h>
56 #include <sys/bpp_io.h>
57 #include <sys/ecppsys.h>
58 #include <sys/prnio.h>
59 #include <sys/errno.h>
60 #include <sys/usb/clients/printer/usb_printer.h>
61 #include <sys/usb/clients/printer/usbprn.h>
62 #include <sys/strsun.h>
63
64 /* Debugging support */
65 uint_t usbprn_errmask = (uint_t)PRINT_MASK_ALL;
66 uint_t usbprn_errlevel = USB_LOG_L4;
67 uint_t usbprn_instance_debug = (uint_t)-1;
68
69 /* local variables */
70 static uint_t usbprn_ifcap =
71 PRN_HOTPLUG | PRN_1284_DEVID | PRN_1284_STATUS | PRN_TIMEOUTS;
72
73 /*
74 * Function Prototypes
75 */
76 static int usbprn_attach(dev_info_t *, ddi_attach_cmd_t);
77 static int usbprn_detach(dev_info_t *, ddi_detach_cmd_t);
78 static int usbprn_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
79 static void usbprn_cleanup(dev_info_t *, usbprn_state_t *);
80
81 static int usbprn_get_descriptors(usbprn_state_t *);
82 static int usbprn_get_device_id(usbprn_state_t *);
83 static int usbprn_get_port_status(usbprn_state_t *);
84
85 static int usbprn_open(dev_t *, int, int, cred_t *);
86 static int usbprn_close(dev_t, int, int, cred_t *);
87 static int usbprn_open_usb_pipes(usbprn_state_t *);
88 static void usbprn_close_usb_pipes(usbprn_state_t *);
89 static int usbprn_write(dev_t, struct uio *, cred_t *);
90 static int usbprn_read(dev_t, struct uio *, cred_t *);
91 static int usbprn_poll(dev_t, short, int, short *, struct pollhead **);
92
93 static int usbprn_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
94 static void usbprn_minphys(struct buf *);
95 static int usbprn_strategy(struct buf *);
96 static int usbprn_setparms(usbprn_state_t *, intptr_t arg, int);
97 static int usbprn_getparms(usbprn_state_t *, intptr_t, int);
98 static void usbprn_geterr(usbprn_state_t *, intptr_t, int);
99 static int usbprn_testio(usbprn_state_t *, int);
100 static int usbprn_ioctl_get_status(usbprn_state_t *);
101 static int usbprn_prnio_get_status(usbprn_state_t *, intptr_t, int);
102 static int usbprn_prnio_get_1284_status(usbprn_state_t *, intptr_t, int);
103 static int usbprn_prnio_get_ifcap(usbprn_state_t *, intptr_t, int);
104 static int usbprn_prnio_set_ifcap(usbprn_state_t *, intptr_t, int);
105 static int usbprn_prnio_get_ifinfo(usbprn_state_t *, intptr_t, int);
106 static int usbprn_prnio_get_1284_devid(usbprn_state_t *, intptr_t, int);
107 static int usbprn_prnio_get_timeouts(usbprn_state_t *, intptr_t, int);
108 static int usbprn_prnio_set_timeouts(usbprn_state_t *, intptr_t, int);
109
110 static void usbprn_send_async_bulk_data(usbprn_state_t *);
111
112 static void usbprn_bulk_xfer_cb(usb_pipe_handle_t, usb_bulk_req_t *);
113 static void usbprn_bulk_xfer_exc_cb(usb_pipe_handle_t,
114 usb_bulk_req_t *);
115
116 static void usbprn_biodone(usbprn_state_t *, int, int);
117 static char usbprn_error_state(uchar_t);
118 static void usbprn_print_long(usbprn_state_t *, char *, int);
119
120 /* event handling */
121 static void usbprn_restore_device_state(dev_info_t *, usbprn_state_t *);
122 static int usbprn_disconnect_event_cb(dev_info_t *);
123 static int usbprn_reconnect_event_cb(dev_info_t *);
124 static int usbprn_cpr_suspend(dev_info_t *);
125 static void usbprn_cpr_resume(dev_info_t *);
126
127 static usb_event_t usbprn_events = {
128 usbprn_disconnect_event_cb,
129 usbprn_reconnect_event_cb,
130 NULL, NULL
131 };
132
133 /* PM handling */
134 static void usbprn_create_pm_components(dev_info_t *, usbprn_state_t *);
135 static int usbprn_power(dev_info_t *, int comp, int level);
136 static int usbprn_pwrlvl0(usbprn_state_t *);
137 static int usbprn_pwrlvl1(usbprn_state_t *);
138 static int usbprn_pwrlvl2(usbprn_state_t *);
139 static int usbprn_pwrlvl3(usbprn_state_t *);
140 static void usbprn_pm_busy_component(usbprn_state_t *);
141 static void usbprn_pm_idle_component(usbprn_state_t *);
142
143 /* module loading stuff */
144 struct cb_ops usbprn_cb_ops = {
145 usbprn_open, /* open */
146 usbprn_close, /* close */
147 nulldev, /* strategy */
148 nulldev, /* print */
149 nulldev, /* dump */
150 usbprn_read, /* read */
151 usbprn_write, /* write */
152 usbprn_ioctl, /* ioctl */
153 nulldev, /* devmap */
154 nulldev, /* mmap */
155 nulldev, /* segmap */
156 usbprn_poll, /* poll */
157 ddi_prop_op, /* cb_prop_op */
158 NULL, /* streamtab */
159 D_64BIT | D_MP
160 };
161
162 static struct dev_ops usbprn_ops = {
163 DEVO_REV, /* devo_rev, */
164 0, /* refcnt */
165 usbprn_info, /* info */
166 nulldev, /* identify */
167 nulldev, /* probe */
168 usbprn_attach, /* attach */
169 usbprn_detach, /* detach */
170 nodev, /* reset */
171 &usbprn_cb_ops, /* driver operations */
172 NULL, /* bus operations */
173 usbprn_power, /* power */
174 ddi_quiesce_not_needed, /* devo_quiesce */
175 };
176
177 static struct modldrv usbprnmodldrv = {
178 &mod_driverops,
179 "USB printer client driver",
180 &usbprn_ops
181 };
182
183 static struct modlinkage modlinkage = {
184 MODREV_1,
185 { &usbprnmodldrv, 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 }