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