1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * 31 * keyspanport pipe routines (mostly device-neutral) 32 * 33 */ 34 #include <sys/types.h> 35 #include <sys/param.h> 36 #include <sys/conf.h> 37 #include <sys/stream.h> 38 #include <sys/strsun.h> 39 #include <sys/termio.h> 40 #include <sys/ddi.h> 41 #include <sys/sunddi.h> 42 43 #include <sys/usb/usba.h> 44 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_var.h> 45 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_pipe.h> 46 47 /* 48 * initialize pipe structure with the given parameters 49 */ 50 static void 51 keyspan_init_one_pipe(keyspan_state_t *ksp, keyspan_port_t *kp, 52 keyspan_pipe_t *pipe) 53 { 54 usb_pipe_policy_t *policy; 55 56 USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_init_one_pipe: " 57 "pipe = %p, pipe_stat %x", (void *)pipe, pipe->pipe_state); 58 59 /* init sync primitives */ 60 mutex_init(&pipe->pipe_mutex, NULL, MUTEX_DRIVER, (void *)NULL); 61 62 /* init pipe policy */ 63 policy = &pipe->pipe_policy; 64 policy->pp_max_async_reqs = 2; 65 66 pipe->pipe_ksp = ksp; 67 if (kp == NULL) { 68 /* globle pipes should have device log handle */ 69 pipe->pipe_lh = ksp->ks_lh; 70 } else { 71 /* port pipes should have port log handle */ 72 pipe->pipe_lh = kp->kp_lh; 73 } 74 75 pipe->pipe_state = KEYSPAN_PIPE_CLOSED; 76 } 77 78 79 static void 80 keyspan_fini_one_pipe(keyspan_pipe_t *pipe) 81 { 82 USB_DPRINTF_L4(DPRINT_OPEN, pipe->pipe_ksp->ks_lh, 83 "keyspan_fini_one_pipe: pipe_stat %x", pipe->pipe_state); 84 85 if (pipe->pipe_state != KEYSPAN_PIPE_NOT_INIT) { 86 mutex_destroy(&pipe->pipe_mutex); 87 pipe->pipe_state = KEYSPAN_PIPE_NOT_INIT; 88 } 89 } 90 91 /* 92 * Lookup the endpoints defined in the spec; 93 * Allocate resources, initialize pipe structures. 94 * All are bulk pipes, including data in/out, cmd/status pipes. 95 */ 96 int 97 keyspan_init_pipes(keyspan_state_t *ksp) 98 { 99 usb_client_dev_data_t *dev_data = ksp->ks_dev_data; 100 int ifc, alt, i, j, k = 0; 101 uint8_t port_cnt = ksp->ks_dev_spec.port_cnt; 102 uint8_t ep_addr, ep_cnt; 103 usb_ep_data_t *dataout[KEYSPAN_MAX_PORT_NUM], 104 *datain[KEYSPAN_MAX_PORT_NUM], 105 *status = NULL, *ctrl = NULL, *tmp_ep; 106 usb_alt_if_data_t *alt_data; 107 usb_if_data_t *if_data; 108 109 110 ifc = dev_data->dev_curr_if; 111 alt = 0; 112 if_data = &dev_data->dev_curr_cfg->cfg_if[ifc]; 113 alt_data = &if_data->if_alt[alt]; 114 115 /* 116 * The actual EP number (indicated by bNumEndpoints) is more than 117 * those defined in spec. We have to match those we need according 118 * to EP addresses. And we'll lookup In EPs and Out EPs separately. 119 */ 120 ep_cnt = (alt_data->altif_descr.bNumEndpoints + 1) / 2; 121 122 /* 123 * get DIR_IN EP descriptors, and then match with EP addresses. 124 * Different keyspan devices may has different EP addresses. 125 */ 126 for (i = 0; i < ep_cnt; i++) { 127 tmp_ep = usb_lookup_ep_data(ksp->ks_dip, dev_data, ifc, alt, i, 128 USB_EP_ATTR_BULK, USB_EP_DIR_IN); 129 if (tmp_ep == NULL) { 130 USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh, 131 "keyspan_init_pipes: can't find bulk in ep, i=%d," 132 "ep_cnt=%d", i, ep_cnt); 133 134 continue; 135 } 136 ep_addr = tmp_ep->ep_descr.bEndpointAddress; 137 138 USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh, "keyspan_init_pipes: " 139 "ep_addr =%x, stat_ep_addr=%x, i=%d", ep_addr, 140 ksp->ks_dev_spec.stat_ep_addr, i); 141 142 /* match the status EP */ 143 if (ep_addr == ksp->ks_dev_spec.stat_ep_addr) { 144 status = tmp_ep; 145 146 continue; 147 } 148 149 /* match the EPs of the ports */ 150 for (j = 0; j < port_cnt; j++) { 151 USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh, 152 "keyspan_init_pipes: try to match bulk in data ep," 153 " j=%d", j); 154 if (ep_addr == ksp->ks_dev_spec.datain_ep_addr[j]) { 155 datain[j] = tmp_ep; 156 k++; 157 USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh, 158 "keyspan_init_pipes: matched a bulk in" 159 " data ep"); 160 161 break; 162 } 163 } 164 165 /* if have matched all the necessary endpoints, break out */ 166 if (k >= port_cnt && status != NULL) { 167 168 break; 169 } 170 171 USB_DPRINTF_L4(DPRINT_ATTACH, ksp->ks_lh, "keyspan_init_pipes: " 172 "try to match bulk in data ep, j=%d", j); 173 174 if (j == port_cnt) { 175 /* this ep can't be matched by any addr */ 176 USB_DPRINTF_L4(DPRINT_ATTACH, ksp->ks_lh, 177 "keyspan_init_pipes: can't match bulk in ep," 178 " addr =%x,", ep_addr); 179 } 180 } 181 182 if (k != port_cnt || status == NULL) { 183 184 /* Some of the necessary IN endpoints are not matched */ 185 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 186 "keyspan_init_pipes: matched %d data in endpoints," 187 " not enough", k); 188 189 return (USB_FAILURE); 190 } 191 192 k = 0; 193 194 /* 195 * get DIR_OUT EP descriptors, and then match with ep addrs. 196 * different keyspan devices may has different ep addresses. 197 */ 198 for (i = 0; i < ep_cnt; i++) { 199 tmp_ep = usb_lookup_ep_data(ksp->ks_dip, dev_data, ifc, alt, i, 200 USB_EP_ATTR_BULK, USB_EP_DIR_OUT); 201 if (tmp_ep == NULL) { 202 USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh, 203 "keyspan_init_pipes: can't find bulk out ep, i=%d," 204 "ep_cnt=%d", i, ep_cnt); 205 206 continue; 207 } 208 ep_addr = tmp_ep->ep_descr.bEndpointAddress; 209 210 /* match the status ep */ 211 if (ep_addr == ksp->ks_dev_spec.ctrl_ep_addr) { 212 ctrl = tmp_ep; 213 214 continue; 215 } 216 217 /* match the ep of the ports */ 218 for (j = 0; j < port_cnt; j++) { 219 if (ep_addr == ksp->ks_dev_spec.dataout_ep_addr[j]) { 220 dataout[j] = tmp_ep; 221 k++; 222 223 break; 224 } 225 } 226 /* if have matched all the necessary endpoints, break out */ 227 if (k >= port_cnt && ctrl != NULL) { 228 229 break; 230 } 231 232 if (j == port_cnt) { 233 234 /* this ep can't be matched by any addr */ 235 USB_DPRINTF_L4(DPRINT_ATTACH, ksp->ks_lh, 236 "keyspan_init_pipes: can't match bulk out ep," 237 " ep_addr =%x", ep_addr); 238 239 } 240 } 241 242 if (k != port_cnt || ctrl == NULL) { 243 /* Not all the necessary OUT endpoints are matched */ 244 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 245 "keyspan_init_pipes: matched %d data in endpoints," 246 " not enough", k); 247 248 return (USB_FAILURE); 249 } 250 251 mutex_enter(&ksp->ks_mutex); 252 253 /* 254 * Device globle pipes: a bulk in pipe for status and a bulk out 255 * pipe for controle cmd. 256 */ 257 ksp->ks_statin_pipe.pipe_ep_descr = status->ep_descr; 258 keyspan_init_one_pipe(ksp, NULL, &ksp->ks_statin_pipe); 259 260 ksp->ks_ctrlout_pipe.pipe_ep_descr = ctrl->ep_descr; 261 keyspan_init_one_pipe(ksp, NULL, &ksp->ks_ctrlout_pipe); 262 263 /* for data in/out pipes of each port */ 264 for (i = 0; i < port_cnt; i++) { 265 266 ksp->ks_ports[i].kp_datain_pipe.pipe_ep_descr = 267 datain[i]->ep_descr; 268 keyspan_init_one_pipe(ksp, &ksp->ks_ports[i], 269 &ksp->ks_ports[i].kp_datain_pipe); 270 271 ksp->ks_ports[i].kp_dataout_pipe.pipe_ep_descr = 272 dataout[i]->ep_descr; 273 keyspan_init_one_pipe(ksp, &ksp->ks_ports[i], 274 &ksp->ks_ports[i].kp_dataout_pipe); 275 } 276 277 mutex_exit(&ksp->ks_mutex); 278 279 return (USB_SUCCESS); 280 } 281 282 void 283 keyspan_fini_pipes(keyspan_state_t *ksp) 284 { 285 keyspan_port_t *kp; 286 int i; 287 288 for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) { 289 kp = &ksp->ks_ports[i]; 290 keyspan_fini_one_pipe(&kp->kp_datain_pipe); 291 keyspan_fini_one_pipe(&kp->kp_dataout_pipe); 292 } 293 294 /* fini global pipes */ 295 keyspan_fini_one_pipe(&ksp->ks_statin_pipe); 296 keyspan_fini_one_pipe(&ksp->ks_ctrlout_pipe); 297 } 298 299 300 static int 301 keyspan_open_one_pipe(keyspan_state_t *ksp, keyspan_pipe_t *pipe) 302 { 303 int rval; 304 305 /* don't open for the second time */ 306 mutex_enter(&pipe->pipe_mutex); 307 ASSERT(pipe->pipe_state != KEYSPAN_PIPE_NOT_INIT); 308 if (pipe->pipe_state != KEYSPAN_PIPE_CLOSED) { 309 mutex_exit(&pipe->pipe_mutex); 310 311 return (USB_SUCCESS); 312 } 313 mutex_exit(&pipe->pipe_mutex); 314 315 rval = usb_pipe_open(ksp->ks_dip, &pipe->pipe_ep_descr, 316 &pipe->pipe_policy, USB_FLAGS_SLEEP, &pipe->pipe_handle); 317 318 if (rval == USB_SUCCESS) { 319 mutex_enter(&pipe->pipe_mutex); 320 pipe->pipe_state = KEYSPAN_PIPE_OPEN; 321 mutex_exit(&pipe->pipe_mutex); 322 } 323 324 return (rval); 325 } 326 327 328 /* 329 * close one pipe if open 330 */ 331 static void 332 keyspan_close_one_pipe(keyspan_pipe_t *pipe) 333 { 334 /* 335 * pipe may already be closed, e.g. if device has been physically 336 * disconnected and the driver immediately detached 337 */ 338 if (pipe->pipe_handle != NULL) { 339 usb_pipe_close(pipe->pipe_ksp->ks_dip, pipe->pipe_handle, 340 USB_FLAGS_SLEEP, NULL, NULL); 341 mutex_enter(&pipe->pipe_mutex); 342 pipe->pipe_handle = NULL; 343 pipe->pipe_state = KEYSPAN_PIPE_CLOSED; 344 mutex_exit(&pipe->pipe_mutex); 345 } 346 } 347 348 /* 349 * Open global pipes, a status pipe and a control pipe 350 */ 351 int 352 keyspan_open_dev_pipes(keyspan_state_t *ksp) 353 { 354 int rval; 355 356 USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_open_dev_pipes"); 357 358 rval = keyspan_open_one_pipe(ksp, &ksp->ks_ctrlout_pipe); 359 if (rval != USB_SUCCESS) { 360 USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh, 361 "keyspan_open_dev_pipes: open ctrl pipe failed %d", rval); 362 363 return (rval); 364 } 365 366 rval = keyspan_open_one_pipe(ksp, &ksp->ks_statin_pipe); 367 if (rval != USB_SUCCESS) { 368 USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh, 369 "keyspan_open_dev_pipes: open status pipe failed %d", rval); 370 371 /* close the first opened pipe here */ 372 keyspan_close_one_pipe(&ksp->ks_ctrlout_pipe); 373 374 return (rval); 375 } 376 377 /* start receive device status */ 378 rval = keyspan_receive_status(ksp); 379 if (rval != USB_SUCCESS) { 380 USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh, 381 "keyspan_open_dev_pipes: receive device status failed %d", 382 rval); 383 384 /* close opened pipes here */ 385 keyspan_close_one_pipe(&ksp->ks_statin_pipe); 386 keyspan_close_one_pipe(&ksp->ks_ctrlout_pipe); 387 388 return (rval); 389 } 390 391 return (rval); 392 } 393 394 395 /* 396 * Reopen all pipes if the port had them open 397 */ 398 int 399 keyspan_reopen_pipes(keyspan_state_t *ksp) 400 { 401 keyspan_port_t *kp; 402 int i; 403 404 USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_reopen_pipes"); 405 406 if (keyspan_open_dev_pipes(ksp) != USB_SUCCESS) { 407 408 return (USB_FAILURE); 409 } 410 411 for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) { 412 kp = &ksp->ks_ports[i]; 413 mutex_enter(&kp->kp_mutex); 414 if (kp->kp_state == KEYSPAN_PORT_OPEN) { 415 USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, 416 "keyspan_reopen_pipes() reopen pipe #%d", i); 417 mutex_exit(&kp->kp_mutex); 418 if (keyspan_open_port_pipes(kp) != USB_SUCCESS) { 419 420 return (USB_FAILURE); 421 } 422 mutex_enter(&kp->kp_mutex); 423 kp->kp_no_more_reads = B_FALSE; 424 } 425 mutex_exit(&kp->kp_mutex); 426 } 427 428 return (USB_SUCCESS); 429 } 430 431 void 432 keyspan_close_port_pipes(keyspan_port_t *kp) 433 { 434 USB_DPRINTF_L4(DPRINT_CLOSE, kp->kp_lh, "keyspan_close_port_pipes"); 435 436 keyspan_close_one_pipe(&kp->kp_dataout_pipe); 437 keyspan_close_one_pipe(&kp->kp_datain_pipe); 438 } 439 440 /* 441 * Close IN and OUT bulk pipes of all ports 442 */ 443 void 444 keyspan_close_open_pipes(keyspan_state_t *ksp) 445 { 446 keyspan_port_t *kp; 447 int i; 448 449 USB_DPRINTF_L4(DPRINT_CLOSE, ksp->ks_lh, "keyspan_close_open_pipes"); 450 451 for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) { 452 kp = &ksp->ks_ports[i]; 453 mutex_enter(&kp->kp_mutex); 454 if (kp->kp_state == KEYSPAN_PORT_OPEN) { 455 kp->kp_no_more_reads = B_TRUE; 456 mutex_exit(&kp->kp_mutex); 457 usb_pipe_reset(ksp->ks_dip, 458 kp->kp_datain_pipe.pipe_handle, USB_FLAGS_SLEEP, 459 NULL, NULL); 460 keyspan_close_port_pipes(kp); 461 } else { 462 mutex_exit(&kp->kp_mutex); 463 } 464 } 465 } 466 467 468 /* 469 * Close global pipes 470 */ 471 void 472 keyspan_close_dev_pipes(keyspan_state_t *ksp) 473 { 474 USB_DPRINTF_L4(DPRINT_CLOSE, ksp->ks_lh, "keyspan_close_dev_pipes"); 475 476 keyspan_close_one_pipe(&ksp->ks_statin_pipe); 477 keyspan_close_one_pipe(&ksp->ks_ctrlout_pipe); 478 } 479 480 481 /* 482 * Open bulk data IN and data OUT pipes for one port. 483 * The status and control pipes are opened in attach because they are global. 484 */ 485 int 486 keyspan_open_port_pipes(keyspan_port_t *kp) 487 { 488 keyspan_state_t *ksp = kp->kp_ksp; 489 int rval; 490 491 USB_DPRINTF_L4(DPRINT_OPEN, kp->kp_lh, "keyspan_open_port_pipes"); 492 493 rval = keyspan_open_one_pipe(ksp, &kp->kp_datain_pipe); 494 if (rval != USB_SUCCESS) { 495 496 goto fail; 497 } 498 499 rval = keyspan_open_one_pipe(ksp, &kp->kp_dataout_pipe); 500 if (rval != USB_SUCCESS) { 501 502 goto fail; 503 } 504 505 return (rval); 506 507 fail: 508 USB_DPRINTF_L2(DPRINT_OPEN, kp->kp_lh, 509 "keyspan_open_port_pipes: failed %d", rval); 510 keyspan_close_port_pipes(kp); 511 512 return (rval); 513 } 514 515 void 516 keyspan_close_pipes(keyspan_state_t *ksp) 517 { 518 USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_close_pipes"); 519 520 /* close all ports' pipes first, and then device ctrl/status pipes. */ 521 keyspan_close_open_pipes(ksp); 522 keyspan_close_dev_pipes(ksp); 523 524 } 525 526 527 /* 528 * bulk out common callback 529 */ 530 /*ARGSUSED*/ 531 void 532 keyspan_bulkout_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 533 { 534 keyspan_port_t *kp = (keyspan_port_t *)req->bulk_client_private; 535 keyspan_pipe_t *bulkout = &kp->kp_dataout_pipe; 536 mblk_t *data = req->bulk_data; 537 int data_len; 538 539 data_len = (data) ? MBLKL(data) : 0; 540 541 USB_DPRINTF_L4(DPRINT_OUT_PIPE, bulkout->pipe_lh, 542 "keyspan_bulkout_cb: len=%d cr=%d cb_flags=%x", 543 data_len, req->bulk_completion_reason, req->bulk_cb_flags); 544 545 if (req->bulk_completion_reason && (data_len > 0)) { 546 547 /* 548 * Data wasn't transfered successfully. 549 * Put data back on the queue. 550 */ 551 keyspan_put_head(&kp->kp_tx_mp, data, kp); 552 553 /* don't release mem in usb_free_bulk_req */ 554 req->bulk_data = NULL; 555 } 556 557 usb_free_bulk_req(req); 558 559 /* if more data available, kick off another transmit */ 560 mutex_enter(&kp->kp_mutex); 561 if (kp->kp_tx_mp == NULL) { 562 563 /* no more data, notify waiters */ 564 cv_broadcast(&kp->kp_tx_cv); 565 mutex_exit(&kp->kp_mutex); 566 567 /* tx callback for this port */ 568 kp->kp_cb.cb_tx(kp->kp_cb.cb_arg); 569 } else { 570 keyspan_tx_start(kp, NULL); 571 mutex_exit(&kp->kp_mutex); 572 } 573 } 574 575 576 /* For incoming data only. Parse a status byte and return the err code */ 577 void 578 keyspan_parse_status(uchar_t *status, uchar_t *err) 579 { 580 if (*status & RXERROR_BREAK) { 581 /* 582 * Parity and Framing errors only count if they 583 * occur exclusive of a break being received. 584 */ 585 *status &= (uint8_t)(RXERROR_OVERRUN | RXERROR_BREAK); 586 } 587 *err |= (*status & RXERROR_OVERRUN) ? DS_OVERRUN_ERR : 0; 588 *err |= (*status & RXERROR_PARITY) ? DS_PARITY_ERR : 0; 589 *err |= (*status & RXERROR_FRAMING) ? DS_FRAMING_ERR : 0; 590 *err |= (*status & RXERROR_BREAK) ? DS_BREAK_ERR : 0; 591 } 592 593 594 /* 595 * pipe callbacks 596 * -------------- 597 * 598 * bulk in common callback for usa19hs model 599 */ 600 /*ARGSUSED*/ 601 int 602 keyspan_bulkin_cb_usa19hs(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 603 { 604 keyspan_port_t *kp = (keyspan_port_t *)req->bulk_client_private; 605 keyspan_pipe_t *bulkin = &kp->kp_datain_pipe; 606 mblk_t *data = req->bulk_data; 607 uint_t cr = req->bulk_completion_reason; 608 int data_len; 609 610 ASSERT(mutex_owned(&kp->kp_mutex)); 611 612 data_len = (data) ? MBLKL(data) : 0; 613 614 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, 615 "keyspan_bulkin_cb_usa19hs: len=%d" 616 " cr=%d flags=%x baud=%x", 617 data_len, cr, req->bulk_cb_flags, kp->kp_baud); 618 619 /* put data on the read queue */ 620 if ((data_len > 0) && (kp->kp_state != KEYSPAN_PORT_CLOSED) && 621 (cr == USB_CR_OK)) { 622 uchar_t status = data->b_rptr[0]; 623 uchar_t err = 0; 624 mblk_t *mp; 625 /* 626 * According to Keyspan spec, if 0x80 bit is clear, there is 627 * only one status byte at the head of the data buf; if 0x80 bit 628 * set, then data buf contains alternate status and data bytes; 629 * In the first case, only OVERRUN err can exist; In the second 630 * case, there are four kinds of err bits may appear in status. 631 */ 632 633 /* if 0x80 bit AND overrun bit are clear, just send up data */ 634 if (!(status & 0x80) && !(status & RXERROR_OVERRUN)) { 635 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, 636 "keyspan_bulkin_cb_usa19hs: len=%d", 637 data_len); 638 639 /* Get rid of the first status byte and send up data */ 640 data->b_rptr++; 641 data_len--; 642 if (data_len > 0) { 643 keyspan_put_tail(&kp->kp_rx_mp, data); 644 645 /* 646 * the data will not be freed and 647 * will be sent up later. 648 */ 649 req->bulk_data = NULL; 650 } 651 } else if (!(status & 0x80)) { 652 /* If 0x80 bit is clear and overrun bit is set */ 653 USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh, 654 "keyspan_bulkin_cb_usa19hs: usb xfer is OK," 655 " but there is overrun err in serial xfer"); 656 657 keyspan_parse_status(&status, &err); 658 mutex_exit(&kp->kp_mutex); 659 if ((mp = allocb(2, BPRI_HI)) == NULL) { 660 USB_DPRINTF_L2(DPRINT_IN_PIPE, kp->kp_lh, 661 "keyspan_bulkin_cb_usa19hs: allocb failed"); 662 mutex_enter(&kp->kp_mutex); 663 664 return (0); 665 } 666 DB_TYPE(mp) = M_BREAK; 667 *mp->b_wptr++ = err; 668 *mp->b_wptr++ = status; 669 mutex_enter(&kp->kp_mutex); 670 671 /* Add to the received list; Send up the err code. */ 672 keyspan_put_tail(&kp->kp_rx_mp, mp); 673 674 /* 675 * Don't send up the first byte because 676 * it is a status byte. 677 */ 678 data->b_rptr++; 679 data_len--; 680 if (data_len > 0) { 681 keyspan_put_tail(&kp->kp_rx_mp, data); 682 683 /* 684 * the data will not be freed and 685 * will be sent up later. 686 */ 687 req->bulk_data = NULL; 688 } 689 } else { /* 0x80 bit set, there are some errs in the data */ 690 USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh, 691 "keyspan_bulkin_cb_usa19hs: usb xfer is OK," 692 " but there are errs in serial xfer"); 693 /* 694 * Usually, there are at least two bytes, 695 * one status and one data. 696 */ 697 if (data_len > 1) { 698 int i = 0; 699 int j = 1; 700 /* 701 * In this case, there might be multi status 702 * bytes. Parse each status byte and move the 703 * data bytes together. 704 */ 705 for (j = 1; j < data_len; j += 2) { 706 status = data->b_rptr[j-1]; 707 keyspan_parse_status(&status, &err); 708 709 /* move the data togeter */ 710 data->b_rptr[i] = data->b_rptr[j]; 711 i++; 712 } 713 data->b_wptr = data->b_rptr + i; 714 } else { /* There are only one byte in incoming buf */ 715 keyspan_parse_status(&status, &err); 716 } 717 mutex_exit(&kp->kp_mutex); 718 if ((mp = allocb(2, BPRI_HI)) == NULL) { 719 USB_DPRINTF_L2(DPRINT_IN_PIPE, kp->kp_lh, 720 "keyspan_bulkin_cb_usa19hs: allocb failed"); 721 mutex_enter(&kp->kp_mutex); 722 723 return (0); 724 } 725 DB_TYPE(mp) = M_BREAK; 726 *mp->b_wptr++ = err; 727 if (data_len > 2) { 728 /* 729 * There are multiple status bytes in this case. 730 * Use err as status character since err is got 731 * by or in all status bytes. 732 */ 733 *mp->b_wptr++ = err; 734 } else { 735 *mp->b_wptr++ = status; 736 } 737 mutex_enter(&kp->kp_mutex); 738 739 /* Add to the received list; Send up the err code. */ 740 keyspan_put_tail(&kp->kp_rx_mp, mp); 741 742 if (data_len > 1) { 743 data_len = data->b_wptr - data->b_rptr; 744 keyspan_put_tail(&kp->kp_rx_mp, data); 745 /* 746 * The data will not be freed and 747 * will be sent up later. 748 */ 749 req->bulk_data = NULL; 750 } 751 } 752 } else { /* usb error happened, so don't send up data */ 753 data_len = 0; 754 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, 755 "keyspan_bulkin_cb_usa19hs: error happened, len=%d, " 756 "cr=0x%x, cb_flags=0x%x", data_len, cr, req->bulk_cb_flags); 757 } 758 if (kp->kp_state != KEYSPAN_PORT_OPEN) { 759 kp->kp_no_more_reads = B_TRUE; 760 } 761 762 return (data_len); 763 } 764 765 766 /* 767 * pipe callbacks 768 * -------------- 769 * 770 * bulk in common callback for usa49 model 771 */ 772 /*ARGSUSED*/ 773 int 774 keyspan_bulkin_cb_usa49(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 775 { 776 keyspan_port_t *kp = (keyspan_port_t *)req->bulk_client_private; 777 keyspan_pipe_t *bulkin = &kp->kp_datain_pipe; 778 mblk_t *data = req->bulk_data; 779 uint_t cr = req->bulk_completion_reason; 780 int data_len; 781 782 ASSERT(mutex_owned(&kp->kp_mutex)); 783 784 data_len = (data) ? MBLKL(data) : 0; 785 786 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, 787 "keyspan_bulkin_cb_usa49: len=%d" 788 " cr=%d flags=%x", data_len, cr, req->bulk_cb_flags); 789 790 /* put data on the read queue */ 791 if ((data_len > 0) && (kp->kp_state != KEYSPAN_PORT_CLOSED) && 792 (cr == USB_CR_OK)) { 793 uchar_t status = data->b_rptr[0]; 794 uchar_t err = 0; 795 mblk_t *mp; 796 /* 797 * According to Keyspan spec, if 0x80 bit is clear, there is 798 * only one status byte at the head of the data buf; if 0x80 bit 799 * set, then data buf contains alternate status and data bytes; 800 * In the first case, only OVERRUN err can exist; In the second 801 * case, there are four kinds of err bits may appear in status. 802 */ 803 804 /* if 0x80 bit AND overrun bit are clear, just send up data */ 805 if (!(status & 0x80) && !(status & RXERROR_OVERRUN)) { 806 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, 807 "keyspan_bulkin_cb_usa49: len=%d", 808 data_len); 809 810 /* Get rid of the first status byte and send up data */ 811 data->b_rptr++; 812 data_len--; 813 if (data_len > 0) { 814 keyspan_put_tail(&kp->kp_rx_mp, data); 815 816 /* 817 * the data will not be freed and 818 * will be sent up later. 819 */ 820 req->bulk_data = NULL; 821 } 822 } else if (!(status & 0x80)) { 823 /* If 0x80 bit is clear and overrun bit is set */ 824 USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh, 825 "keyspan_bulkin_cb_usa49: usb xfer is OK," 826 " but there is overrun err in serial xfer"); 827 828 keyspan_parse_status(&status, &err); 829 mutex_exit(&kp->kp_mutex); 830 if ((mp = allocb(2, BPRI_HI)) == NULL) { 831 USB_DPRINTF_L2(DPRINT_IN_PIPE, kp->kp_lh, 832 "keyspan_bulkin_cb_usa49: allocb failed"); 833 mutex_enter(&kp->kp_mutex); 834 835 return (0); 836 } 837 DB_TYPE(mp) = M_BREAK; 838 *mp->b_wptr++ = err; 839 *mp->b_wptr++ = status; 840 mutex_enter(&kp->kp_mutex); 841 842 /* Add to the received list; Send up the err code. */ 843 keyspan_put_tail(&kp->kp_rx_mp, mp); 844 845 /* 846 * Don't send up the first byte because 847 * it is a status byte. 848 */ 849 data->b_rptr++; 850 data_len--; 851 if (data_len > 0) { 852 keyspan_put_tail(&kp->kp_rx_mp, data); 853 854 /* 855 * the data will not be freed and 856 * will be sent up later. 857 */ 858 req->bulk_data = NULL; 859 } 860 } else { /* 0x80 bit set, there are some errs in the data */ 861 USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh, 862 "keyspan_bulkin_cb_usa49: usb xfer is OK," 863 " but there are errs in serial xfer"); 864 /* 865 * Usually, there are at least two bytes, 866 * one status and one data. 867 */ 868 if (data_len > 1) { 869 int i = 0; 870 int j = 1; 871 /* 872 * In this case, there might be multi status 873 * bytes. Parse each status byte and move the 874 * data bytes together. 875 */ 876 for (j = 1; j < data_len; j += 2) { 877 status = data->b_rptr[j-1]; 878 keyspan_parse_status(&status, &err); 879 880 /* move the data togeter */ 881 data->b_rptr[i] = data->b_rptr[j]; 882 i++; 883 } 884 data->b_wptr = data->b_rptr + i; 885 } else { /* There are only one byte in incoming buf */ 886 keyspan_parse_status(&status, &err); 887 } 888 mutex_exit(&kp->kp_mutex); 889 if ((mp = allocb(2, BPRI_HI)) == NULL) { 890 USB_DPRINTF_L2(DPRINT_IN_PIPE, kp->kp_lh, 891 "keyspan_bulkin_cb_usa49: allocb failed"); 892 mutex_enter(&kp->kp_mutex); 893 894 return (0); 895 } 896 DB_TYPE(mp) = M_BREAK; 897 *mp->b_wptr++ = err; 898 if (data_len > 2) { 899 /* 900 * There are multiple status bytes in this case. 901 * Use err as status character since err is got 902 * by or in all status bytes. 903 */ 904 *mp->b_wptr++ = err; 905 } else { 906 *mp->b_wptr++ = status; 907 } 908 mutex_enter(&kp->kp_mutex); 909 910 /* Add to the received list; Send up the err code. */ 911 keyspan_put_tail(&kp->kp_rx_mp, mp); 912 913 if (data_len > 1) { 914 data_len = data->b_wptr - data->b_rptr; 915 keyspan_put_tail(&kp->kp_rx_mp, data); 916 /* 917 * The data will not be freed and 918 * will be sent up later. 919 */ 920 req->bulk_data = NULL; 921 } 922 } 923 } else { 924 /* usb error happened, so don't send up data */ 925 data_len = 0; 926 USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh, 927 "keyspan_bulkin_cb_usa49: port_state=%d" 928 " b_rptr[0]=%c", kp->kp_state, data->b_rptr[0]); 929 } 930 if (kp->kp_state != KEYSPAN_PORT_OPEN) { 931 kp->kp_no_more_reads = B_TRUE; 932 } 933 934 return (data_len); 935 } 936 937 938 /* 939 * pipe callbacks 940 * -------------- 941 * 942 * bulk in common callback 943 */ 944 /*ARGSUSED*/ 945 void 946 keyspan_bulkin_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 947 { 948 keyspan_port_t *kp = (keyspan_port_t *)req->bulk_client_private; 949 keyspan_state_t *ksp = kp->kp_ksp; 950 int data_len; 951 boolean_t no_more_reads = B_FALSE; 952 953 USB_DPRINTF_L4(DPRINT_IN_PIPE, (&kp->kp_datain_pipe)->pipe_lh, 954 "keyspan_bulkin_cb"); 955 956 mutex_enter(&kp->kp_mutex); 957 958 /* put data on the read queue */ 959 switch (ksp->ks_dev_spec.id_product) { 960 case KEYSPAN_USA19HS_PID: 961 data_len = keyspan_bulkin_cb_usa19hs(pipe, req); 962 963 break; 964 965 966 case KEYSPAN_USA49WLC_PID: 967 data_len = keyspan_bulkin_cb_usa49(pipe, req); 968 969 break; 970 971 default: 972 USB_DPRINTF_L2(DPRINT_IN_PIPE, (&kp->kp_datain_pipe)->pipe_lh, 973 "keyspan_bulkin_cb:" 974 "the device's product id can't be recognized"); 975 mutex_exit(&kp->kp_mutex); 976 977 return; 978 } 979 980 no_more_reads = kp->kp_no_more_reads; 981 982 mutex_exit(&kp->kp_mutex); 983 984 usb_free_bulk_req(req); 985 986 /* kick off another read unless indicated otherwise */ 987 if (!no_more_reads) { 988 (void) keyspan_receive_data(&kp->kp_datain_pipe, 989 kp->kp_read_len, kp); 990 } 991 992 /* setup rx callback for this port */ 993 if (data_len > 0) { 994 kp->kp_cb.cb_rx(kp->kp_cb.cb_arg); 995 } 996 } 997 998 /* 999 * pipe callbacks 1000 * -------------- 1001 * 1002 * bulk in status callback for usa19hs model 1003 */ 1004 /*ARGSUSED*/ 1005 void 1006 keyspan_status_cb_usa19hs(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 1007 { 1008 keyspan_state_t *ksp = (keyspan_state_t *)req->bulk_client_private; 1009 keyspan_pipe_t *bulkin = &ksp->ks_statin_pipe; 1010 mblk_t *data = req->bulk_data; 1011 usb_cr_t cr = req->bulk_completion_reason; 1012 int data_len; 1013 1014 data_len = (data) ? MBLKL(data) : 0; 1015 1016 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, 1017 "keyspan_status_cb_usa19hs: len=%d" 1018 " cr=%d flags=%x", data_len, cr, req->bulk_cb_flags); 1019 1020 /* put data on the read queue */ 1021 if ((data_len == 14) && (cr == USB_CR_OK)) { 1022 keyspan_port_t *kp = &ksp->ks_ports[0]; 1023 keyspan_usa19hs_port_status_msg_t *status_msg = 1024 &(kp->kp_status_msg.usa19hs); 1025 1026 mutex_enter(&kp->kp_mutex); 1027 bcopy(data->b_rptr, status_msg, data_len); 1028 1029 if (status_msg->controlResponse) { 1030 kp->kp_status_flag |= KEYSPAN_PORT_CTRLRESP; 1031 } else { 1032 kp->kp_status_flag &= ~KEYSPAN_PORT_CTRLRESP; 1033 } 1034 1035 if (status_msg->portState & PORTSTATE_ENABLED) { 1036 kp->kp_status_flag |= KEYSPAN_PORT_ENABLE; 1037 } else { 1038 kp->kp_status_flag &= ~KEYSPAN_PORT_ENABLE; 1039 } 1040 1041 if (status_msg->portState & PORTSTATE_TXBREAK) { 1042 kp->kp_status_flag |= KEYSPAN_PORT_TXBREAK; 1043 } else { 1044 kp->kp_status_flag &= ~KEYSPAN_PORT_TXBREAK; 1045 } 1046 1047 if (status_msg->rxBreak) { 1048 kp->kp_status_flag |= KEYSPAN_PORT_RXBREAK; 1049 } else { 1050 kp->kp_status_flag &= ~KEYSPAN_PORT_RXBREAK; 1051 } 1052 1053 if (status_msg->portState & PORTSTATE_LOOPBACK) { 1054 kp->kp_status_flag |= KEYSPAN_PORT_LOOPBACK; 1055 } else { 1056 kp->kp_status_flag &= ~KEYSPAN_PORT_LOOPBACK; 1057 } 1058 1059 /* if msr status changed, then invoke status callback */ 1060 if (status_msg->msr & USA_MSR_dCTS || 1061 status_msg->msr & USA_MSR_dDSR || 1062 status_msg->msr & USA_MSR_dRI || 1063 status_msg->msr & USA_MSR_dDCD) { 1064 1065 mutex_exit(&kp->kp_mutex); 1066 kp->kp_cb.cb_status(kp->kp_cb.cb_arg); 1067 } else { 1068 mutex_exit(&kp->kp_mutex); 1069 } 1070 } else { 1071 1072 USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh, 1073 "keyspan_status_cb_usa19hs: get status failed, cr=%d" 1074 " data_len=%d", cr, data_len); 1075 } 1076 } 1077 1078 1079 /* 1080 * pipe callbacks 1081 * -------------- 1082 * 1083 * bulk in status callback for usa49 model 1084 */ 1085 /*ARGSUSED*/ 1086 void 1087 keyspan_status_cb_usa49(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 1088 { 1089 keyspan_state_t *ksp = (keyspan_state_t *)req->bulk_client_private; 1090 keyspan_pipe_t *bulkin = &ksp->ks_statin_pipe; 1091 mblk_t *data = req->bulk_data; 1092 uint_t cr = req->bulk_completion_reason; 1093 int data_len; 1094 1095 data_len = (data) ? MBLKL(data) : 0; 1096 1097 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, 1098 "keyspan_status_cb_usa49: len=%d" 1099 " cr=%d flags=%x", data_len, cr, req->bulk_cb_flags); 1100 1101 /* put data on the read queue */ 1102 if ((data_len == 11) && (cr == USB_CR_OK)) { 1103 keyspan_usa49_port_status_msg_t status_msg; 1104 keyspan_port_t *cur_kp; 1105 keyspan_usa49_port_status_msg_t *kp_status_msg; 1106 boolean_t need_cb = B_FALSE; 1107 1108 bcopy(data->b_rptr, &status_msg, data_len); 1109 if (status_msg.portNumber >= ksp->ks_dev_spec.port_cnt) { 1110 1111 return; 1112 } 1113 cur_kp = &ksp->ks_ports[status_msg.portNumber]; 1114 kp_status_msg = &(cur_kp->kp_status_msg.usa49); 1115 1116 mutex_enter(&cur_kp->kp_mutex); 1117 1118 /* if msr status changed, then need invoke status callback */ 1119 if (status_msg.cts != kp_status_msg->cts || 1120 status_msg.dsr != kp_status_msg->dsr || 1121 status_msg.ri != kp_status_msg->ri || 1122 status_msg.dcd != kp_status_msg->dcd) { 1123 1124 need_cb = B_TRUE; 1125 } 1126 1127 bcopy(&status_msg, kp_status_msg, data_len); 1128 1129 if (kp_status_msg->controlResponse) { 1130 cur_kp->kp_status_flag |= KEYSPAN_PORT_CTRLRESP; 1131 } else { 1132 cur_kp->kp_status_flag &= ~KEYSPAN_PORT_CTRLRESP; 1133 } 1134 1135 if (!kp_status_msg->rxEnabled) { 1136 cur_kp->kp_status_flag |= KEYSPAN_PORT_RXBREAK; 1137 } else { 1138 cur_kp->kp_status_flag &= ~KEYSPAN_PORT_RXBREAK; 1139 } 1140 1141 mutex_exit(&cur_kp->kp_mutex); 1142 1143 if (need_cb) { 1144 1145 cur_kp->kp_cb.cb_status(cur_kp->kp_cb.cb_arg); 1146 } 1147 } else { 1148 1149 USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh, 1150 "keyspan_status_cb_usa49: get status failed, cr=%d" 1151 " data_len=%d", cr, data_len); 1152 } 1153 } 1154 1155 1156 /* 1157 * pipe callbacks 1158 * -------------- 1159 * 1160 * bulk in callback for status receiving 1161 */ 1162 /*ARGSUSED*/ 1163 void 1164 keyspan_status_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 1165 { 1166 keyspan_state_t *ksp = (keyspan_state_t *)req->bulk_client_private; 1167 usb_cr_t cr = req->bulk_completion_reason; 1168 1169 USB_DPRINTF_L4(DPRINT_IN_PIPE, (&ksp->ks_statin_pipe)->pipe_lh, 1170 "keyspan_status_cb"); 1171 1172 /* put data on the read queue */ 1173 switch (ksp->ks_dev_spec.id_product) { 1174 case KEYSPAN_USA19HS_PID: 1175 keyspan_status_cb_usa19hs(pipe, req); 1176 1177 break; 1178 1179 1180 case KEYSPAN_USA49WLC_PID: 1181 keyspan_status_cb_usa49(pipe, req); 1182 1183 break; 1184 1185 default: 1186 USB_DPRINTF_L2(DPRINT_IN_PIPE, 1187 (&ksp->ks_statin_pipe)->pipe_lh, "keyspan_status_cb:" 1188 "the device's product id can't be recognized"); 1189 1190 return; 1191 } 1192 1193 usb_free_bulk_req(req); 1194 1195 /* kick off another read to receive status */ 1196 if ((cr != USB_CR_FLUSHED) && (cr != USB_CR_DEV_NOT_RESP) && 1197 keyspan_dev_is_online(ksp)) { 1198 if (keyspan_receive_status(ksp) != USB_SUCCESS) { 1199 USB_DPRINTF_L2(DPRINT_IN_PIPE, 1200 (&ksp->ks_statin_pipe)->pipe_lh, 1201 "keyspan_status_cb:" 1202 "receive status can't be restarted."); 1203 } 1204 } else { 1205 USB_DPRINTF_L2(DPRINT_IN_PIPE, 1206 (&ksp->ks_statin_pipe)->pipe_lh, "keyspan_status_cb:" 1207 "get status failed: cr=%d", cr); 1208 } 1209 } 1210 1211 /* 1212 * Submit data read request (asynchronous). If this function returns 1213 * USB_SUCCESS, pipe is acquired and request is sent, otherwise req is free. 1214 */ 1215 int 1216 keyspan_receive_data(keyspan_pipe_t *bulkin, int len, void *cb_arg) 1217 { 1218 keyspan_state_t *ksp = bulkin->pipe_ksp; 1219 usb_bulk_req_t *br; 1220 int rval; 1221 1222 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, "keyspan_receive_data:" 1223 "len=%d", len); 1224 1225 ASSERT(!mutex_owned(&bulkin->pipe_mutex)); 1226 1227 br = usb_alloc_bulk_req(ksp->ks_dip, len, USB_FLAGS_SLEEP); 1228 br->bulk_len = len; 1229 1230 /* No timeout, just wait for data */ 1231 br->bulk_timeout = 0; 1232 br->bulk_client_private = cb_arg; 1233 br->bulk_attributes = USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING; 1234 br->bulk_cb = keyspan_bulkin_cb; 1235 br->bulk_exc_cb = keyspan_bulkin_cb; 1236 1237 rval = usb_pipe_bulk_xfer(bulkin->pipe_handle, br, 0); 1238 if (rval != USB_SUCCESS) { 1239 usb_free_bulk_req(br); 1240 } 1241 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, 1242 "keyspan_receive_data: rval = %d", rval); 1243 return (rval); 1244 } 1245 1246 /* 1247 * submit device status read request (asynchronous). 1248 */ 1249 int 1250 keyspan_receive_status(keyspan_state_t *ksp) 1251 { 1252 keyspan_pipe_t *bulkin = &ksp->ks_statin_pipe; 1253 usb_bulk_req_t *br; 1254 int rval; 1255 1256 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, 1257 "keyspan_receive_status"); 1258 1259 ASSERT(!mutex_owned(&bulkin->pipe_mutex)); 1260 1261 br = usb_alloc_bulk_req(ksp->ks_dip, 32, USB_FLAGS_SLEEP); 1262 br->bulk_len = KEYSPAN_STATIN_MAX_LEN; 1263 1264 /* No timeout, just wait for data */ 1265 br->bulk_timeout = 0; 1266 br->bulk_client_private = (void *)ksp; 1267 br->bulk_attributes = USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING; 1268 br->bulk_cb = keyspan_status_cb; 1269 br->bulk_exc_cb = keyspan_status_cb; 1270 1271 rval = usb_pipe_bulk_xfer(bulkin->pipe_handle, br, 0); 1272 if (rval != USB_SUCCESS) { 1273 usb_free_bulk_req(br); 1274 } 1275 USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, 1276 "keyspan_receive_status: rval = %d", rval); 1277 return (rval); 1278 } 1279 1280 /* 1281 * submit data for transfer (asynchronous) 1282 * 1283 * if data was sent successfully, 'mpp' will be nulled to indicate 1284 * that mblk is consumed by USBA and no longer belongs to the caller. 1285 * 1286 * if this function returns USB_SUCCESS, pipe is acquired and request 1287 * is sent, otherwise pipe is free. 1288 */ 1289 int 1290 keyspan_send_data(keyspan_pipe_t *bulkout, mblk_t **mpp, void *cb_arg) 1291 { 1292 keyspan_state_t *ksp = bulkout->pipe_ksp; 1293 usb_bulk_req_t *br; 1294 int rval; 1295 1296 ASSERT(!mutex_owned(&bulkout->pipe_mutex)); 1297 USB_DPRINTF_L4(DPRINT_OUT_PIPE, bulkout->pipe_lh, 1298 "keyspan_send_data"); 1299 1300 br = usb_alloc_bulk_req(ksp->ks_dip, 0, USB_FLAGS_SLEEP); 1301 br->bulk_len = MBLKL(*mpp); 1302 br->bulk_data = *mpp; 1303 br->bulk_timeout = KEYSPAN_BULK_TIMEOUT; 1304 br->bulk_client_private = cb_arg; 1305 br->bulk_attributes = USB_ATTRS_AUTOCLEARING; 1306 br->bulk_cb = keyspan_bulkout_cb; 1307 br->bulk_exc_cb = keyspan_bulkout_cb; 1308 1309 USB_DPRINTF_L3(DPRINT_OUT_PIPE, bulkout->pipe_lh, "keyspan_send_data:" 1310 "bulk_len = %d", br->bulk_len); 1311 1312 rval = usb_pipe_bulk_xfer(bulkout->pipe_handle, br, 0); 1313 if (rval == USB_SUCCESS) { 1314 1315 /* data consumed. The mem will be released in bulkout_cb */ 1316 *mpp = NULL; 1317 } else { 1318 1319 /* 1320 * Don't free it in usb_free_bulk_req because it will 1321 * be linked in keyspan_put_head 1322 */ 1323 br->bulk_data = NULL; 1324 1325 usb_free_bulk_req(br); 1326 } 1327 USB_DPRINTF_L4(DPRINT_OUT_PIPE, bulkout->pipe_lh, 1328 "keyspan_send_data: rval = %d", rval); 1329 1330 return (rval); 1331 } 1332