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/usbser/usbser_keyspan/usbser_keyspan.c
+++ new/usr/src/uts/common/io/usb/clients/usbser/usbser_keyspan/usbser_keyspan.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
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27
28 28 /*
29 29 * This driver includes code for Keyspan USA49WG/USA49WLC/USA19HS adapters. It
30 30 * is a device-specific driver (DSD) working with USB generic serial driver
31 31 * (GSD). It implements the USB-to-serial device-specific driver interface
32 32 * (DSDI) which is offered by GSD. The interface is defined by ds_ops_t
33 33 * structure.
34 34 *
35 35 * For USA49WLC, it's necessary to download firmware every time the device is
36 36 * plugged. Before the firmware is downloaded, we say that the device is in
37 37 * "firmware mode", and the attach routin is keyspan_pre_attach(). After
38 38 * downloading, the device's product id will change to 0x12a. Then the device
39 39 * will be enumerated again and another attach for the new product id will
40 40 * begin. No firmware is included in the driver. The functions of USA49WLC is
41 41 * disabled.
42 42 *
43 43 * For USA49WG and USA19HS, no need to download firmware since it can be kept
44 44 * in the device's memory.
45 45 *
46 46 * For USA49WLC and USA19HS, it's necessary to check and switch their
47 47 * configrations at the beginning of attach, since each of them has two
48 48 * configrations. This driver uses the one whose endpoints are all bulk.
49 49 *
50 50 * For USA49WG, this driver uses the third configuration which has 6 endpoints,
51 51 * 3 bulk out eps, 1 bulk in ep, 1 intr in ep, 1 intr out ep. Bulk in ep is
52 52 * shared by 4 ports for receiving data.
53 53 *
54 54 * Some of Keyspan adapters have only one port, some have two or four ports.
55 55 * This driver supports up to four ports. Each port has its own states (traced
56 56 * by keyspan_port structure) and can be operated independently.
57 57 *
58 58 * port_state:
59 59 *
60 60 * KEYSPAN_PORT_NOT_INIT
61 61 * |
62 62 * |
63 63 * attach_ports
64 64 * |
65 65 * |
66 66 * |
67 67 * v
68 68 * KEYSPAN_PORT_CLOSED <-----close-------<---- +
69 69 * | |
70 70 * | |
71 71 * | |
72 72 * open_port |
73 73 * | |
74 74 * | |
75 75 * v |
76 76 * KEYSPAN_PORT_OPENING ---open_hw_port---> USBSER_PORT_OPEN
77 77 *
78 78 * Each port has its own data in/out pipes and each pipe also has its own states
79 79 * (traced by keyspan_pipe structure). The pipe states is as following:
80 80 *
81 81 * pipe_state:
82 82 *
83 83 * KEYSPAN_PIPE_NOT_INIT
84 84 * | ^
85 85 * | |
86 86 * keyspan_init_pipes keyspan_fini_pipes
87 87 * | |
88 88 * v |
89 89 * KEYSPAN_PIPE_CLOSED ------------->-----------+
90 90 * ^ |
91 91 * | reconnect/resume/open_port
92 92 * | |
93 93 * disconnect/suspend/close_port |
94 94 * | v
95 95 * +---------<------------------ KEYSPAN_PIPE_OPEN
96 96 *
97 97 * To control the device and get its status in a timely way, this driver makes
98 98 * use of two global bulk endpoints for cmd and status on the device. The pipes
99 99 * for cmd/status will be opened during attach. For multi-port devices, one of
100 100 * the cmd/status message fields will designate which port this message is for.
101 101 *
102 102 * This driver can be easily extended to support more Keyspan adapter models.
103 103 * You need the following steps to reach the aim:
104 104 * 1. Add the model specific data structures, like cmd/status message structure.
105 105 * 2. If the device need firmware downloaded, add the firmware code as a header
106 106 * file, and add code to keyspan_pre_attach() as what were done for USA49WLC.
107 107 * 3. Add several model specific functions, like keyspan_build_cmd_msg_*,
108 108 * keyspan_default_port_params_*, keyspan_save_port_params_*, etc. The functions
109 109 * for USA19HS and USA49WLC can be taken as examples.
110 110 * 4. Add model specific code to the "switch (id_product) {...}" sentences.
111 111 */
112 112
113 113 /*
114 114 *
115 115 * keyspan driver glue code
116 116 *
117 117 */
118 118 #include <sys/types.h>
119 119 #include <sys/param.h>
120 120 #include <sys/stream.h>
121 121 #include <sys/conf.h>
122 122 #include <sys/ddi.h>
123 123 #include <sys/sunddi.h>
124 124
125 125 #define USBDRV_MAJOR_VER 2
126 126 #define USBDRV_MINOR_VER 0
127 127
128 128 #include <sys/usb/usba.h>
129 129
130 130 #include <sys/usb/clients/usbser/usbser.h>
131 131 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_var.h>
132 132
133 133 #include <sys/byteorder.h>
134 134 #include <sys/strsun.h>
135 135
136 136 /* configuration entry points */
137 137 static int usbser_keyspan_getinfo(dev_info_t *, ddi_info_cmd_t, void *,
138 138 void **);
139 139 static int usbser_keyspan_attach(dev_info_t *, ddi_attach_cmd_t);
140 140 static int usbser_keyspan_detach(dev_info_t *, ddi_detach_cmd_t);
141 141 static int usbser_keyspan_open(queue_t *, dev_t *, int, int, cred_t *);
142 142
143 143 /* functions related with set config or firmware download */
144 144 static int keyspan_pre_attach(dev_info_t *, ddi_attach_cmd_t, void *);
145 145 static int keyspan_set_cfg(dev_info_t *, uint8_t);
146 146 static int keyspan_pre_detach(dev_info_t *, ddi_detach_cmd_t, void *);
147 147 static boolean_t keyspan_need_fw(usb_client_dev_data_t *);
148 148 static int keyspan_set_reg(keyspan_pipe_t *, uchar_t);
149 149 static int keyspan_write_memory(keyspan_pipe_t *, uint16_t, uchar_t *,
150 150 uint16_t, uint8_t);
151 151 static int keyspan_download_firmware(keyspan_pre_state_t *);
152 152
153 153 static void *usbser_keyspan_statep; /* soft state */
154 154
155 155 extern ds_ops_t keyspan_ds_ops; /* DSD operations */
156 156
157 157 /*
158 158 * STREAMS structures
159 159 */
160 160 struct module_info usbser_keyspan_modinfo = {
161 161 0, /* module id */
162 162 "usbsksp", /* module name */
163 163 USBSER_MIN_PKTSZ, /* min pkt size */
164 164 USBSER_MAX_PKTSZ, /* max pkt size */
165 165 USBSER_HIWAT, /* hi watermark */
166 166 USBSER_LOWAT /* low watermark */
167 167 };
168 168
169 169 static struct qinit usbser_keyspan_rinit = {
170 170 putq,
171 171 usbser_rsrv,
172 172 usbser_keyspan_open,
173 173 usbser_close,
174 174 NULL,
175 175 &usbser_keyspan_modinfo,
176 176 NULL
177 177 };
178 178
179 179 static struct qinit usbser_keyspan_winit = {
180 180 usbser_wput,
181 181 usbser_wsrv,
182 182 NULL,
183 183 NULL,
184 184 NULL,
185 185 &usbser_keyspan_modinfo,
186 186 NULL
187 187 };
188 188
189 189 struct streamtab usbser_keyspan_str_info = {
190 190 &usbser_keyspan_rinit, &usbser_keyspan_winit, NULL, NULL
191 191 };
192 192
193 193 static struct cb_ops usbser_keyspan_cb_ops = {
194 194 nodev, /* cb_open */
195 195 nodev, /* cb_close */
196 196 nodev, /* cb_strategy */
197 197 nodev, /* cb_print */
198 198 nodev, /* cb_dump */
199 199 nodev, /* cb_read */
200 200 nodev, /* cb_write */
201 201 nodev, /* cb_ioctl */
202 202 nodev, /* cb_devmap */
203 203 nodev, /* cb_mmap */
204 204 nodev, /* cb_segmap */
205 205 nochpoll, /* cb_chpoll */
206 206 ddi_prop_op, /* cb_prop_op */
207 207 &usbser_keyspan_str_info, /* cb_stream */
208 208 (int)(D_64BIT | D_NEW | D_MP | D_HOTPLUG) /* cb_flag */
209 209 };
210 210
211 211 /*
212 212 * auto configuration ops
213 213 */
214 214 struct dev_ops usbser_keyspan_ops = {
215 215 DEVO_REV, /* devo_rev */
216 216 0, /* devo_refcnt */
217 217 usbser_keyspan_getinfo, /* devo_getinfo */
218 218 nulldev, /* devo_identify */
219 219 nulldev, /* devo_probe */
220 220 usbser_keyspan_attach, /* devo_attach */
221 221 usbser_keyspan_detach, /* devo_detach */
222 222 nodev, /* devo_reset */
223 223 &usbser_keyspan_cb_ops, /* devo_cb_ops */
224 224 (struct bus_ops *)NULL, /* devo_bus_ops */
225 225 usbser_power, /* devo_power */
226 226 ddi_quiesce_not_needed, /* devo_quiesce */
227 227 };
↓ open down ↓ |
227 lines elided |
↑ open up ↑ |
228 228
229 229 extern struct mod_ops mod_driverops;
230 230
231 231 static struct modldrv modldrv = {
232 232 &mod_driverops, /* type of module - driver */
233 233 "USB keyspan usb2serial driver",
234 234 &usbser_keyspan_ops,
235 235 };
236 236
237 237 static struct modlinkage modlinkage = {
238 - MODREV_1, &modldrv, 0
238 + MODREV_1, { &modldrv, NULL }
239 239 };
240 240
241 241 /* debug support */
242 242 static uint_t keyspan_pre_errlevel = USB_LOG_L4;
243 243 static uint_t keyspan_pre_errmask = DPRINT_MASK_ALL;
244 244 static uint_t keyspan_pre_instance_debug = (uint_t)-1;
245 245
246 246 /* firmware support for usa49wlc model */
247 247 extern usbser_keyspan_fw_record_t *keyspan_usa49wlc_fw(void);
248 248 #pragma weak keyspan_usa49wlc_fw
249 249
250 250 /*
251 251 * configuration entry points
252 252 * --------------------------
253 253 */
254 254 int
255 255 _init(void)
256 256 {
257 257 int error;
258 258
259 259 if ((error = mod_install(&modlinkage)) == 0) {
260 260 error = ddi_soft_state_init(&usbser_keyspan_statep,
261 261 max(usbser_soft_state_size(),
262 262 sizeof (keyspan_pre_state_t)), 1);
263 263 }
264 264
265 265 return (error);
266 266 }
267 267
268 268
269 269 int
270 270 _fini(void)
271 271 {
272 272 int error;
273 273
274 274 if ((error = mod_remove(&modlinkage)) == 0) {
275 275 ddi_soft_state_fini(&usbser_keyspan_statep);
276 276 }
277 277
278 278 return (error);
279 279 }
280 280
281 281
282 282 int
283 283 _info(struct modinfo *modinfop)
284 284 {
285 285 return (mod_info(&modlinkage, modinfop));
286 286 }
287 287
288 288
289 289 /*ARGSUSED*/
290 290 int
291 291 usbser_keyspan_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
292 292 void **result)
293 293 {
294 294 return (usbser_getinfo(dip, infocmd, arg, result,
295 295 usbser_keyspan_statep));
296 296 }
297 297
298 298
299 299 static int
300 300 usbser_keyspan_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
301 301 {
302 302 int rval;
303 303
304 304 /*
305 305 * Once the device is plugged, we need set its cfg. And need download
306 306 * firmware for some of them.
307 307 */
308 308 rval = keyspan_pre_attach(dip, cmd, usbser_keyspan_statep);
309 309
310 310 /*
311 311 * After the cfg is set, and the firmware is downloaded,
312 312 * do the real attach.
313 313 */
314 314 if (rval == DDI_ECONTEXT) {
315 315
316 316 return (usbser_attach(dip, cmd, usbser_keyspan_statep,
317 317 &keyspan_ds_ops));
318 318 } else {
319 319
320 320 return (rval);
321 321 }
322 322 }
323 323
324 324
325 325 static int
326 326 usbser_keyspan_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
327 327 {
328 328
329 329 if (ddi_get_driver_private(dip) == NULL) {
330 330
331 331 return (keyspan_pre_detach(dip, cmd, usbser_keyspan_statep));
332 332 } else {
333 333
334 334
335 335 return (usbser_detach(dip, cmd, usbser_keyspan_statep));
336 336
337 337
338 338 }
339 339
340 340 }
341 341
342 342
343 343 static int
344 344 usbser_keyspan_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr)
345 345 {
346 346 return (usbser_open(rq, dev, flag, sflag, cr, usbser_keyspan_statep));
347 347 }
348 348
349 349 /*
350 350 * Switch config or download firmware
351 351 */
352 352 /*ARGSUSED*/
353 353 static int
354 354 keyspan_pre_attach(dev_info_t *dip, ddi_attach_cmd_t cmd, void *statep)
355 355 {
356 356
357 357 int instance = ddi_get_instance(dip);
358 358 keyspan_pre_state_t *kbp = NULL;
359 359 usb_client_dev_data_t *dev_data = NULL;
360 360 int rval = DDI_FAILURE;
361 361
362 362 switch (cmd) {
363 363 case DDI_ATTACH:
364 364
365 365 break;
366 366 case DDI_RESUME:
367 367
368 368 return (DDI_SUCCESS);
369 369 default:
370 370
371 371 return (DDI_FAILURE);
372 372 }
373 373
374 374 /* attach driver to USBA */
375 375 if (usb_client_attach(dip, USBDRV_VERSION, 0) == USB_SUCCESS) {
376 376 (void) usb_get_dev_data(dip, &dev_data, USB_PARSE_LVL_IF, 0);
377 377 }
378 378 if (dev_data == NULL) {
379 379
380 380 goto fail;
381 381 }
382 382
383 383 /*
384 384 * If 19HS or 49WG, needn't download firmware, but need check the
385 385 * current cfg.
386 386 * If 49WLC, need check the current cfg before download fw. And after
387 387 * download, the product id will change to KEYSPAN_USA49WLC_PID.
388 388 */
389 389 if (dev_data->dev_descr->idProduct == KEYSPAN_USA19HS_PID ||
390 390 dev_data->dev_descr->idProduct == KEYSPAN_USA49WLC_PID) {
391 391 if (keyspan_set_cfg(dip, 1) == USB_SUCCESS) {
392 392 /* Go to keyspan_attach() by return DDI_ECONTEXT. */
393 393 rval = DDI_ECONTEXT;
394 394 }
395 395
396 396 goto fail;
397 397 } else if (dev_data->dev_descr->idProduct == KEYSPAN_USA49WG_PID) {
398 398 if (keyspan_set_cfg(dip, 2) == USB_SUCCESS) {
399 399 /* Go to keyspan_attach() by return DDI_ECONTEXT. */
400 400 rval = DDI_ECONTEXT;
401 401 }
402 402
403 403 goto fail;
404 404 }
405 405
406 406
407 407 /*
408 408 * By checking KEYSPAN_FW_FLAG, we can check whether the firmware
409 409 * has been downloaded.
410 410 * If firmware is already there, then do normal attach.
411 411 */
412 412 if (!keyspan_need_fw(dev_data)) {
413 413 /* Go to keyspan_attach() by return DDI_ECONTEXT. */
414 414 rval = DDI_ECONTEXT;
415 415
416 416 goto fail;
417 417 }
418 418
419 419 /* Go on to download firmware. */
420 420
421 421 if (ddi_soft_state_zalloc(statep, instance) == DDI_SUCCESS) {
422 422 kbp = ddi_get_soft_state(statep, instance);
423 423 }
424 424 if (kbp) {
425 425 kbp->kb_dip = dip;
426 426 kbp->kb_instance = instance;
427 427 kbp->kb_dev_data = dev_data;
428 428 kbp->kb_def_pipe.pipe_handle = kbp->kb_dev_data->dev_default_ph;
429 429 kbp->kb_lh = usb_alloc_log_hdl(kbp->kb_dip, "keyspan[*].",
430 430 &keyspan_pre_errlevel, &keyspan_pre_errmask,
431 431 &keyspan_pre_instance_debug, 0);
432 432
433 433 kbp->kb_def_pipe.pipe_lh = kbp->kb_lh;
434 434
435 435 if (keyspan_download_firmware(kbp) == USB_SUCCESS) {
436 436 USB_DPRINTF_L4(DPRINT_ATTACH, kbp->kb_lh,
437 437 "keyspan_pre_attach: completed.");
438 438
439 439 /* keyspan download firmware done. */
440 440
441 441 return (DDI_SUCCESS);
442 442 }
443 443 }
444 444 fail:
445 445 if (kbp) {
446 446 usb_free_log_hdl(kbp->kb_lh);
447 447 ddi_soft_state_free(statep, instance);
448 448 }
449 449 usb_client_detach(dip, dev_data);
450 450
451 451 return (rval);
452 452 }
453 453
454 454
455 455 static int
456 456 keyspan_pre_detach(dev_info_t *dip, ddi_detach_cmd_t cmd, void *statep)
457 457 {
458 458 int instance = ddi_get_instance(dip);
459 459 keyspan_pre_state_t *kbp;
460 460
461 461 kbp = ddi_get_soft_state(statep, instance);
462 462
463 463 switch (cmd) {
464 464 case DDI_DETACH:
465 465
466 466 break;
467 467 case DDI_SUSPEND:
468 468
469 469 return (DDI_SUCCESS);
470 470 default:
471 471
472 472 return (DDI_FAILURE);
473 473 }
474 474
475 475 usb_free_log_hdl(kbp->kb_lh);
476 476 usb_client_detach(dip, kbp->kb_dev_data);
477 477 ddi_soft_state_free(statep, instance);
478 478
479 479 return (DDI_SUCCESS);
480 480 }
481 481
482 482
483 483 /* Set cfg for the device which has more than one cfg */
484 484 static int
485 485 keyspan_set_cfg(dev_info_t *dip, uint8_t cfg_num)
486 486 {
487 487
488 488 if (usb_set_cfg(dip, cfg_num, USB_FLAGS_SLEEP,
489 489 NULL, NULL) != USB_SUCCESS) {
490 490
491 491 return (USB_FAILURE);
492 492 }
493 493
494 494 return (USB_SUCCESS);
495 495 }
496 496
497 497
498 498 /* Return TRUE if need download firmware to the device. */
499 499 static boolean_t
500 500 keyspan_need_fw(usb_client_dev_data_t *dev_data)
501 501 {
502 502 uint16_t bcd_descr;
503 503 uint16_t bcd_descr_change;
504 504
505 505 /* need to convert to Little-Endian */
506 506 bcd_descr = dev_data->dev_descr->bcdDevice;
507 507
508 508 /*
509 509 * According to Keyspan's interface spec, this flag indicates
510 510 * if need download fw.
511 511 */
512 512 bcd_descr_change = bcd_descr & KEYSPAN_FW_FLAG;
513 513
514 514 return (bcd_descr_change == KEYSPAN_FW_FLAG);
515 515 }
516 516
517 517 /* Set the device's register. */
518 518 static int
519 519 keyspan_set_reg(keyspan_pipe_t *pipe, uchar_t bit)
520 520 {
521 521 int rval;
522 522
523 523 /*
524 524 * (0x7f92) is the reg addr we want to set.
525 525 * We set this reg before/after downloading firmware.
526 526 */
527 527 rval = keyspan_write_memory(pipe, 0x7f92, &bit, 1, KEYSPAN_REQ_SET);
528 528
529 529 return (rval);
530 530 }
531 531
532 532 /*
533 533 * Download firmware or set register to the device by default ctrl pipe
534 534 */
535 535 static int
536 536 keyspan_write_memory(keyspan_pipe_t *pipe, uint16_t addr, uchar_t *buf,
537 537 uint16_t len, uint8_t bRequest)
538 538 {
539 539 mblk_t *data;
540 540 usb_ctrl_setup_t setup;
541 541
542 542 usb_cb_flags_t cb_flags;
543 543 usb_cr_t cr;
544 544 uint8_t retry = 0;
545 545
546 546 /* reuse previous mblk if possible */
547 547 if ((data = allocb(len, BPRI_HI)) == NULL) {
548 548
549 549 return (USB_FAILURE);
550 550 }
551 551
552 552 bcopy(buf, data->b_rptr, len);
553 553
554 554 setup.bmRequestType = USB_DEV_REQ_TYPE_VENDOR;
555 555
556 556 /* This is a req defined by hardware vendor. */
557 557 setup.bRequest = bRequest;
558 558 setup.wValue = addr;
559 559 setup.wIndex = 0;
560 560 setup.wLength = len;
561 561 setup.attrs = 0;
562 562
563 563 while (usb_pipe_ctrl_xfer_wait(pipe->pipe_handle, &setup, &data,
564 564 &cr, &cb_flags, 0) != USB_SUCCESS) {
565 565
566 566 /* KEYSPAN_RETRY */
567 567 if (++retry > 3) {
568 568 if (data) {
569 569 freemsg(data);
570 570 }
571 571
572 572 return (USB_FAILURE);
573 573 }
574 574 }
575 575
576 576 if (data) {
577 577 freemsg(data);
578 578 }
579 579
580 580 return (USB_SUCCESS);
581 581 }
582 582
583 583 /* Download firmware into device */
584 584 static int
585 585 keyspan_download_firmware(keyspan_pre_state_t *kbp)
586 586 {
587 587 usbser_keyspan_fw_record_t *record = NULL;
588 588
589 589 /* If the firmware module exists, then download it to device. */
590 590 if (&keyspan_usa49wlc_fw) {
591 591
592 592 record = keyspan_usa49wlc_fw();
593 593 }
594 594
595 595 if (!record) {
596 596 USB_DPRINTF_L1(DPRINT_ATTACH, kbp->kb_lh,
597 597 "No firmware available for Keyspan usa49wlc"
598 598 " usb-to-serial adapter. Refer to usbsksp(7D)"
599 599 " for details.");
600 600
601 601 return (USB_FAILURE);
602 602 }
603 603
604 604 /* Set bit 1 before downloading firmware. */
605 605 if (keyspan_set_reg(&kbp->kb_def_pipe, 1) != USB_SUCCESS) {
606 606 USB_DPRINTF_L2(DPRINT_ATTACH, kbp->kb_lh,
607 607 "keyspan_pre_attach: Set register failed.");
608 608
609 609 return (USB_FAILURE);
610 610 }
611 611
612 612 /* Write until the last record of the firmware */
613 613 while (record->address != 0xffff) {
614 614 if (keyspan_write_memory(&kbp->kb_def_pipe,
615 615 record->address, (uchar_t *)record->data,
616 616 record->data_len, KEYSPAN_REQ_SET) != USB_SUCCESS) {
617 617 USB_DPRINTF_L2(DPRINT_ATTACH, kbp->kb_lh,
618 618 "keyspan_pre_attach: download firmware failed.");
619 619
620 620 return (USB_FAILURE);
621 621 }
622 622 record++;
623 623 }
624 624
625 625 /*
626 626 * Set bit 0, device will be enumerated again after a while,
627 627 * and then go to keyspan_attach()
628 628 */
629 629 if (keyspan_set_reg(&kbp->kb_def_pipe, 0) != USB_SUCCESS) {
630 630
631 631 return (USB_FAILURE);
632 632 }
633 633
634 634 return (USB_SUCCESS);
635 635 }
↓ open down ↓ |
387 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX