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