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