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