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