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