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