1 /* $NetBSD: btuart.c,v 1.13 2007/11/11 12:59:04 plunky Exp $ */ 2 /* 3 * Copyright (c) 2006, 2007 KIYOHARA Takashi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: btuart.c,v 1.13 2007/11/11 12:59:04 plunky Exp $"); 30 31 #include <sys/types.h> 32 #include <sys/param.h> 33 #include <sys/device.h> 34 #include <sys/errno.h> 35 36 #include <sys/conf.h> 37 #include <sys/fcntl.h> 38 #include <sys/kauth.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/mbuf.h> 42 #include <sys/proc.h> 43 #include <sys/syslimits.h> 44 #include <sys/systm.h> 45 #include <sys/tty.h> 46 47 #include <sys/bus.h> 48 #include <sys/intr.h> 49 50 #include <netbt/bluetooth.h> 51 #include <netbt/hci.h> 52 53 #include <dev/bluetooth/btuart.h> 54 #include <dev/firmload.h> 55 56 #include "ioconf.h" 57 58 #ifdef BTUART_DEBUG 59 int btuart_debug = 1; 60 #endif 61 62 struct btuart_softc; 63 struct bth4hci { 64 int type; 65 int init_baud; 66 #define FLOW_CTL 1 67 int flags; 68 int (*init)(struct btuart_softc *); 69 }; 70 71 struct btuart_softc { 72 device_t sc_dev; 73 74 struct tty *sc_tp; 75 struct hci_unit sc_unit; /* Bluetooth HCI Unit */ 76 77 struct bth4hci sc_bth4hci; 78 int sc_baud; 79 80 int sc_state; /* receive state */ 81 #define BTUART_RECV_PKT_TYPE 0 /* packet type */ 82 #define BTUART_RECV_ACL_HDR 1 /* acl header */ 83 #define BTUART_RECV_SCO_HDR 2 /* sco header */ 84 #define BTUART_RECV_EVENT_HDR 3 /* event header */ 85 #define BTUART_RECV_ACL_DATA 4 /* acl packet data */ 86 #define BTUART_RECV_SCO_DATA 5 /* sco packet data */ 87 #define BTUART_RECV_EVENT_DATA 6 /* event packet data */ 88 int sc_want; /* how much we want */ 89 struct mbuf *sc_rxp; /* incoming packet */ 90 struct mbuf *sc_txp; /* outgoing packet */ 91 92 void (*sc_input_acl)(struct hci_unit *, struct mbuf *); 93 void (*sc_input_sco)(struct hci_unit *, struct mbuf *); 94 void (*sc_input_event)(struct hci_unit *, struct mbuf *); 95 }; 96 97 void btuartattach(int); 98 static int btuart_match(device_t, struct cfdata *, void *); 99 static void btuart_attach(device_t, device_t, void *); 100 static int btuart_detach(device_t, int); 101 102 static int bth4_waitresp(struct btuart_softc *, struct mbuf **, uint16_t); 103 static int bth4_firmload(struct btuart_softc *, char *, 104 int (*)(struct btuart_softc *, int, char *)); 105 static int init_ericsson(struct btuart_softc *); 106 static int init_digi(struct btuart_softc *); 107 static int init_texas(struct btuart_softc *); 108 static int init_csr(struct btuart_softc *); 109 static int init_swave(struct btuart_softc *); 110 static int init_st(struct btuart_softc *); 111 static int firmload_stlc2500(struct btuart_softc *, int, char *); 112 static int init_stlc2500(struct btuart_softc *); 113 static int init_bcm2035(struct btuart_softc *); 114 static int bth4init(struct btuart_softc *); 115 static void bth4init_input(struct hci_unit *, struct mbuf *); 116 117 static int bth4open(dev_t, struct tty *); 118 static int bth4close(struct tty *, int); 119 static int bth4ioctl(struct tty *, u_long, void *, int, struct lwp *); 120 static int bth4input(int, struct tty *); 121 static int bth4start(struct tty *); 122 123 static int bth4_enable(device_t); 124 static void bth4_disable(device_t); 125 static void bth4_start(device_t); 126 127 /* 128 * It doesn't need to be exported, as only btuartattach() uses it, 129 * but there's no "official" way to make it static. 130 */ 131 CFATTACH_DECL_NEW(btuart, sizeof(struct btuart_softc), 132 btuart_match, btuart_attach, btuart_detach, NULL); 133 134 static struct linesw bth4_disc = { 135 .l_name = "btuart", 136 .l_open = bth4open, 137 .l_close = bth4close, 138 .l_read = ttyerrio, 139 .l_write = ttyerrio, 140 .l_ioctl = bth4ioctl, 141 .l_rint = bth4input, 142 .l_start = bth4start, 143 .l_modem = ttymodem, 144 .l_poll = ttyerrpoll 145 }; 146 147 static struct bth4hci bth4hci[] = { 148 { BTUART_HCITYPE_ANY, B0, FLOW_CTL, NULL }, 149 { BTUART_HCITYPE_ERICSSON, B57600, FLOW_CTL, init_ericsson }, 150 { BTUART_HCITYPE_DIGI, B9600, FLOW_CTL, init_digi }, 151 { BTUART_HCITYPE_TEXAS, B115200, FLOW_CTL, init_texas }, 152 /* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */ 153 { BTUART_HCITYPE_CSR, B115200, FLOW_CTL, init_csr }, 154 /* Silicon Wave kits */ 155 { BTUART_HCITYPE_SWAVE, B115200, FLOW_CTL, init_swave }, 156 /* ST Microelectronics minikits based on STLC2410/STLC2415 */ 157 { BTUART_HCITYPE_ST, B57600, FLOW_CTL, init_st }, 158 /* ST Microelectronics minikits based on STLC2500 */ 159 { BTUART_HCITYPE_STLC2500, B115200, FLOW_CTL, init_stlc2500 }, 160 /* AmbiCom BT2000C Bluetooth PC/CF Card */ 161 { BTUART_HCITYPE_BT2000C, B57600, FLOW_CTL, init_csr }, 162 /* Broadcom BCM2035 */ 163 { BTUART_HCITYPE_BCM2035, B115200, 0, init_bcm2035 }, 164 165 { -1, B0, 0, NULL } 166 }; 167 168 169 /* ARGSUSED */ 170 void 171 btuartattach(int num __unused) 172 { 173 int error; 174 175 error = ttyldisc_attach(&bth4_disc); 176 if (error) { 177 aprint_error("%s: unable to register line discipline, " 178 "error = %d\n", btuart_cd.cd_name, error); 179 return; 180 } 181 182 error = config_cfattach_attach(btuart_cd.cd_name, &btuart_ca); 183 if (error) { 184 aprint_error("%s: unable to register cfattach, error = %d\n", 185 btuart_cd.cd_name, error); 186 config_cfdriver_detach(&btuart_cd); 187 (void) ttyldisc_detach(&bth4_disc); 188 } 189 } 190 191 /* 192 * Autoconf match routine. 193 * 194 * XXX: unused: config_attach_pseudo(9) does not call ca_match. 195 */ 196 /* ARGSUSED */ 197 static int 198 btuart_match(device_t self __unused, 199 struct cfdata *cfdata __unused, void *arg __unused) 200 { 201 202 /* pseudo-device; always present */ 203 return 1; 204 } 205 206 /* 207 * Autoconf attach routine. Called by config_attach_pseudo(9) when we 208 * open the line discipline. 209 */ 210 /* ARGSUSED */ 211 static void 212 btuart_attach(device_t parent __unused, 213 device_t self, void *aux __unused) 214 { 215 struct btuart_softc *sc = device_private(self); 216 int i; 217 218 sc->sc_dev = self; 219 220 aprint_normal("\n"); 221 aprint_naive("\n"); 222 223 sc->sc_input_acl = bth4init_input; 224 sc->sc_input_sco = bth4init_input; 225 sc->sc_input_event = bth4init_input; 226 227 /* Copy default type */ 228 for (i = 0; bth4hci[i].type != BTUART_HCITYPE_ANY; i++); 229 memcpy(&sc->sc_bth4hci, &bth4hci[i], sizeof(struct bth4hci)); 230 231 /* Attach Bluetooth unit */ 232 sc->sc_unit.hci_dev = self; 233 sc->sc_unit.hci_enable = bth4_enable; 234 sc->sc_unit.hci_disable = bth4_disable; 235 sc->sc_unit.hci_start_cmd = bth4_start; 236 sc->sc_unit.hci_start_acl = bth4_start; 237 sc->sc_unit.hci_start_sco = bth4_start; 238 sc->sc_unit.hci_ipl = makeiplcookie(IPL_TTY); 239 hci_attach(&sc->sc_unit); 240 } 241 242 /* 243 * Autoconf detach routine. Called when we close the line discipline. 244 */ 245 static int 246 btuart_detach(device_t self, int flags __unused) 247 { 248 struct btuart_softc *sc = device_private(self); 249 250 hci_detach(&sc->sc_unit); 251 252 return 0; 253 } 254 255 256 static int 257 bth4_waitresp(struct btuart_softc *sc, struct mbuf **mp, uint16_t opcode) 258 { 259 struct hci_unit *unit = &sc->sc_unit; 260 hci_event_hdr_t *e; 261 int status = 0, rv; 262 263 *mp = NULL; 264 while (1 /* CONSTCOND */) { 265 if ((rv = 266 tsleep(&unit->hci_eventq, PCATCH, "bth4init", 0)) != 0) 267 return rv; 268 269 MBUFQ_DEQUEUE(&unit->hci_eventq, *mp); 270 unit->hci_eventqlen--; 271 KASSERT(*mp != NULL); 272 273 e = mtod(*mp, hci_event_hdr_t *); 274 if (e->event == HCI_EVENT_COMMAND_COMPL) { 275 hci_command_compl_ep *ep; 276 277 ep = (hci_command_compl_ep *)(e + 1); 278 if (ep->opcode == opcode) { 279 status = *(char *)(ep + 1); 280 break; 281 } 282 } else if (e->event == HCI_EVENT_COMMAND_STATUS) { 283 hci_command_status_ep *ep; 284 285 ep = (hci_command_status_ep *)(e + 1); 286 if (ep->opcode == opcode) { 287 status = ep->status; 288 break; 289 } 290 } else if (e->event == HCI_EVENT_VENDOR) 291 break; 292 } 293 294 return status; 295 } 296 297 static int 298 bth4_firmload(struct btuart_softc *sc, char *filename, 299 int (*func_firmload)(struct btuart_softc *, int, char *)) 300 { 301 const cfdriver_t cd = device_cfdriver(sc->sc_dev); 302 firmware_handle_t fh = NULL; 303 int error, size; 304 char *buf; 305 306 if ((error = firmware_open(cd->cd_name, filename, &fh)) != 0) { 307 aprint_error_dev(sc->sc_dev, "firmware_open failed\n"); 308 return error; 309 } 310 size = firmware_get_size(fh); 311 if ((buf = firmware_malloc(size)) != NULL) { 312 aprint_error_dev(sc->sc_dev, "firmware_malloc failed\n"); 313 firmware_close(fh); 314 return ENOMEM; 315 } 316 317 if ((error = firmware_read(fh, 0, buf, size)) != 0) 318 aprint_error_dev(sc->sc_dev, "firmware_read failed\n"); 319 if (error == 0) 320 error = (*func_firmload)(sc, size, buf); 321 322 firmware_close(fh); 323 firmware_free(buf, size); 324 325 return error; 326 } 327 328 /* 329 * LSI initialize functions. 330 */ 331 static int 332 init_ericsson(struct btuart_softc *sc) 333 { 334 struct mbuf *m; 335 struct hci_unit *unit = &sc->sc_unit; 336 hci_cmd_hdr_t *p; 337 int i, error = 0; 338 const uint16_t opcode = htole16(HCI_CMD_ERICSSON_SET_UART_BAUD_RATE); 339 static struct { 340 int baud; 341 uint8_t param; 342 } ericsson_baudtbl[] = { 343 { B460800, 0x00 }, 344 { B230400, 0x01 }, 345 { B115200, 0x02 }, 346 { B57600, 0x03 }, 347 { B28800, 0x04 }, 348 { B14400, 0x05 }, 349 { B7200, 0x06 }, 350 #if defined(B3600) 351 { B3600, 0x07 }, 352 #endif 353 { B1800, 0x08 }, 354 #if defined(B900) 355 { B900, 0x09 }, 356 #endif 357 #if defined(B153600) 358 { B153600, 0x10 }, 359 #endif 360 { B76800, 0x11 }, 361 { B38400, 0x12 }, 362 { B19200, 0x13 }, 363 { B9600, 0x14 }, 364 { B4800, 0x15 }, 365 { B2400, 0x16 }, 366 { B1200, 0x17 }, 367 { B600, 0x18 }, 368 { B300, 0x19 }, 369 { B921600, 0x20 }, 370 { B0, 0xff } 371 }; 372 373 for (i = 0; ericsson_baudtbl[i].baud != sc->sc_baud; i++) 374 if (ericsson_baudtbl[i].baud == B0) 375 return EINVAL; 376 377 m = m_gethdr(M_WAIT, MT_DATA); 378 p = mtod(m, hci_cmd_hdr_t *); 379 p->type = HCI_CMD_PKT; 380 p->opcode = opcode; 381 p->length = sizeof(ericsson_baudtbl[0].param); 382 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 383 m_copyback(m, sizeof(hci_cmd_hdr_t), p->length, 384 &ericsson_baudtbl[i].param); 385 386 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 387 bth4_start(sc->sc_dev); 388 389 #if 0 390 error = bth4_waitresp(sc, &m, opcode); 391 if (m != NULL) { 392 if (error != 0) { 393 aprint_error_dev(sc->sc_dev, 394 "EricssonSetUARTBaudRate failed: Status 0x%02x\n", 395 error); 396 error = EFAULT; 397 } 398 m_freem(m); 399 } 400 #else 401 /* 402 * XXXX: We cannot correctly receive this response perhaps. Wait 403 * until the transmission of the data of 5 bytes * 10 bit is completed. 404 * 1000000usec * 10bit * 5byte / baud 405 */ 406 delay(50000000 / sc->sc_bth4hci.init_baud); 407 #endif 408 return error; 409 } 410 411 static int 412 init_digi(struct btuart_softc *sc) 413 { 414 struct mbuf *m; 415 struct hci_unit *unit = &sc->sc_unit; 416 hci_cmd_hdr_t *p; 417 uint8_t param; 418 419 /* XXXX */ 420 switch (sc->sc_baud) { 421 case B57600: 422 param = 0x08; 423 break; 424 425 case B115200: 426 param = 0x09; 427 break; 428 429 default: 430 return EINVAL; 431 } 432 433 m = m_gethdr(M_WAIT, MT_DATA); 434 p = mtod(m, hci_cmd_hdr_t *); 435 p->type = HCI_CMD_PKT; 436 #define HCI_CMD_DIGIANSWER_SET_UART_BAUD_RATE 0xfc07 /* XXXX */ 437 p->opcode = htole16(HCI_CMD_DIGIANSWER_SET_UART_BAUD_RATE); 438 p->length = sizeof(param); 439 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 440 m_copyback(m, sizeof(hci_cmd_hdr_t), p->length, ¶m); 441 442 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 443 bth4_start(sc->sc_dev); 444 445 /* 446 * XXXX 447 * Wait until the transmission of the data of 5 bytes * 10 bit is 448 * completed. 449 * 1000000usec * 10bit * 5byte / baud 450 */ 451 delay(50000000 / sc->sc_bth4hci.init_baud); 452 return 0; 453 } 454 455 static int 456 init_texas(struct btuart_softc *sc) 457 { 458 459 /* XXXX: Should we obtain the version of LMP? */ 460 return 0; 461 } 462 463 static int 464 init_csr(struct btuart_softc *sc) 465 { 466 struct mbuf *m; 467 struct hci_unit *unit = &sc->sc_unit; 468 hci_cmd_hdr_t *p; 469 int error; 470 const uint16_t opcode = htole16(HCI_CMD_CSR_EXTN); 471 struct { 472 uint8_t last :1; 473 uint8_t first :1; 474 #define CSR_BCCMD_CHANID_BCCMD 2 475 #define CSR_BCCMD_CHANID_HQ 3 476 #define CSR_BCCMD_CHANID_DEVMGRLIB 4 477 #define CSR_BCCMD_CHANID_L2CAPLIB 8 478 #define CSR_BCCMD_CHANID_RFCOMMLIB 9 479 #define CSR_BCCMD_CHANID_SDPLIB 10 480 #define CSR_BCCMD_CHANID_DFU 12 481 #define CSR_BCCMD_CHANID_VM 13 482 #define CSR_BCCMD_CHANID_LMDEBUG 20 483 uint8_t chanid :6; 484 485 struct { 486 #define CSR_BCCMD_MESSAGE_TYPE_GETREQ 0x0000 487 #define CSR_BCCMD_MESSAGE_TYPE_GETRESP 0x0001 488 #define CSR_BCCMD_MESSAGE_TYPE_SETREQ 0x0002 489 uint16_t type; 490 uint16_t length; 491 uint16_t seqno; 492 #define CSR_BCCMD_MESSAGE_VARID_CONFIG_UART 0x6802 493 #define CSR_BCCMD_MESSAGE_VARID_CONFIG_UART_STOPB 0x2000 494 #define CSR_BCCMD_MESSAGE_VARID_CONFIG_UART_PARENB 0x4000 495 #define CSR_BCCMD_MESSAGE_VARID_CONFIG_UART_PARODD 0x8000 496 uint16_t varid; 497 #define CSR_BCCMD_MESSAGE_STATUS_OK 0x0000 498 #define CSR_BCCMD_MESSAGE_STATUS_NO_SUCH_VARID 0x0001 499 #define CSR_BCCMD_MESSAGE_STATUS_TOO_BIG 0x0002 500 #define CSR_BCCMD_MESSAGE_STATUS_NO_VALUE 0x0003 501 #define CSR_BCCMD_MESSAGE_STATUS_BAD_REQ 0x0004 502 #define CSR_BCCMD_MESSAGE_STATUS_NO_ACCESS 0x0005 503 #define CSR_BCCMD_MESSAGE_STATUS_READ_ONLY 0x0006 504 #define CSR_BCCMD_MESSAGE_STATUS_WRITE_ONLY 0x0007 505 #define CSR_BCCMD_MESSAGE_STATUS_ERROR 0x0008 506 #define CSR_BCCMD_MESSAGE_STATUS_PERMISION_DENIED 0x0009 507 uint16_t status; 508 uint16_t payload[4]; 509 } message; 510 } bccmd; 511 512 m = m_gethdr(M_WAIT, MT_DATA); 513 p = mtod(m, hci_cmd_hdr_t *); 514 p->type = HCI_CMD_PKT; 515 p->opcode = opcode; 516 p->length = sizeof(bccmd); 517 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 518 519 /* setup BCSP command packet */ 520 bccmd.last = 1; 521 bccmd.first = 1; 522 bccmd.chanid = CSR_BCCMD_CHANID_BCCMD; 523 bccmd.message.type = htole16(CSR_BCCMD_MESSAGE_TYPE_SETREQ); 524 bccmd.message.length = htole16(sizeof(bccmd.message) >> 1); 525 bccmd.message.seqno = htole16(0); 526 bccmd.message.varid = htole16(CSR_BCCMD_MESSAGE_VARID_CONFIG_UART); 527 bccmd.message.status = htole16(CSR_BCCMD_MESSAGE_STATUS_OK); 528 memset(bccmd.message.payload, 0, sizeof(bccmd.message.payload)); 529 530 /* Value = (baud rate / 244.140625) | no parity | 1 stop bit. */ 531 bccmd.message.payload[0] = htole16((sc->sc_baud * 64 + 7812) / 15625); 532 533 m_copyback(m, sizeof(hci_cmd_hdr_t), p->length, &bccmd); 534 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 535 bth4_start(sc->sc_dev); 536 537 error = bth4_waitresp(sc, &m, opcode); 538 if (m != NULL) { 539 /* 540 * XXXX: 541 * We will have to check the HCI_EVENT_VENDOR packet. For 542 * instance, it might be a different HCI_EVENT_VENDOR packet. 543 */ 544 if (error != 0) { 545 aprint_error_dev(sc->sc_dev, 546 "CSR set UART speed failed: Status 0x%02x\n", 547 error); 548 error = EFAULT; 549 } 550 m_freem(m); 551 } 552 553 return error; 554 } 555 556 static int 557 init_swave(struct btuart_softc *sc) 558 { 559 struct mbuf *m; 560 struct hci_unit *unit = &sc->sc_unit; 561 hci_cmd_hdr_t *p; 562 hci_event_hdr_t *e; 563 int i, error; 564 #define HCI_CMD_SWAVE_SET_UART_BAUD_RATE 0xfc0b /* XXXX */ 565 const uint16_t opcode = htole16(HCI_CMD_SWAVE_SET_UART_BAUD_RATE); 566 char param[6], *resp; 567 static struct { /* XXXX */ 568 int baud; 569 uint8_t param; 570 } swave_baudtbl[] = { 571 { B19200, 0x03 }, 572 { B38400, 0x02 }, 573 { B57600, 0x01 }, 574 { B115200, 0x00 }, 575 { B0, 0xff } 576 }; 577 578 for (i = 0; swave_baudtbl[i].baud != sc->sc_baud; i++) 579 if (swave_baudtbl[i].baud == B0) 580 return EINVAL; 581 582 m = m_gethdr(M_WAIT, MT_DATA); 583 /* first send 'param access set' command. */ 584 p = mtod(m, hci_cmd_hdr_t *); 585 p->type = HCI_CMD_PKT; 586 p->opcode = opcode; 587 p->length = sizeof(param); 588 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 589 590 /* XXXX */ 591 param[0] = 0x01; /* param sub command */ 592 param[1] = 0x11; /* HCI Tranport Params */ 593 param[2] = 0x03; /* length of the parameter following */ 594 param[3] = 0x01; /* HCI Transport flow control enable */ 595 param[4] = 0x01; /* HCI Transport Type = UART */ 596 param[5] = swave_baudtbl[i].param; 597 m_copyback(m, sizeof(hci_cmd_hdr_t), p->length, ¶m); 598 599 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 600 bth4_start(sc->sc_dev); 601 602 while(1 /* CONSTCOND */) { 603 error = bth4_waitresp(sc, &m, opcode); 604 if (error != 0) { 605 if (m != NULL) 606 m_freem(m); 607 aprint_error_dev(sc->sc_dev, 608 "swave set baud rate command failed: error 0x%02x\n", 609 error); 610 return error; 611 } 612 if (m != NULL) { 613 e = mtod(m, hci_event_hdr_t *); 614 resp = (char *)(e + 1); 615 if (e->length == 7 && *resp == 0xb && 616 memcmp(resp + 1, param, sizeof(param)) == 0) 617 break; 618 m_freem(m); 619 } 620 } 621 622 /* send 'reset' command consecutively. */ 623 p = mtod(m, hci_cmd_hdr_t *); 624 p->type = HCI_CMD_PKT; 625 p->opcode = htole16(HCI_CMD_RESET); 626 p->length = 0; 627 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 628 629 /* 630 * XXXX 631 * Wait until the transmission of the data of 4 bytes * 10 bit is 632 * completed. 633 * 1000000usec * 10bit * 4byte / baud 634 */ 635 delay(40000000 / sc->sc_bth4hci.init_baud); 636 return 0; 637 } 638 639 static int 640 init_st(struct btuart_softc *sc) 641 { 642 struct mbuf *m; 643 struct hci_unit *unit = &sc->sc_unit; 644 hci_cmd_hdr_t *p; 645 int i; 646 static struct { /* XXXX */ 647 int baud; 648 uint8_t param; 649 } st_baudtbl[] = { 650 { B9600, 0x09 }, 651 { B19200, 0x0b }, 652 { B38400, 0x0d }, 653 { B57600, 0x0e }, 654 { B115200, 0x10 }, 655 { B230400, 0x12 }, 656 { B460800, 0x13 }, 657 { B921600, 0x14 }, 658 { B0, 0xff } 659 }; 660 661 for (i = 0; st_baudtbl[i].baud != sc->sc_baud; i++) 662 if (st_baudtbl[i].baud == B0) 663 return EINVAL; 664 665 m = m_gethdr(M_WAIT, MT_DATA); 666 p = mtod(m, hci_cmd_hdr_t *); 667 p->type = HCI_CMD_PKT; 668 #define HCI_CMD_ST_SET_UART_BAUD_RATE 0xfc46 /* XXXX */ 669 p->opcode = htole16(HCI_CMD_ST_SET_UART_BAUD_RATE); 670 p->length = sizeof(st_baudtbl[0].param); 671 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 672 m_copyback(m, sizeof(hci_cmd_hdr_t), p->length, &st_baudtbl[i].param); 673 674 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 675 bth4_start(sc->sc_dev); 676 677 /* 678 * XXXX 679 * Wait until the transmission of the data of 5 bytes * 10 bit is 680 * completed. 681 * 1000000usec * 10bit * 5byte / baud 682 */ 683 delay(50000000 / sc->sc_bth4hci.init_baud); 684 return 0; 685 } 686 687 static int 688 firmload_stlc2500(struct btuart_softc *sc, int size, char *buf) 689 { 690 struct hci_unit *unit = &sc->sc_unit; 691 struct mbuf *m; 692 hci_cmd_hdr_t *p; 693 int error, offset, n; 694 uint16_t opcode = htole16(0xfc2e); /* XXXX */ 695 uint8_t seq; 696 697 m = m_gethdr(M_WAIT, MT_DATA); 698 seq = 0; 699 offset = 0; 700 error = 0; 701 while (offset < size) { 702 n = size - offset < 254 ? size - offset : 254; 703 704 p = mtod(m, hci_cmd_hdr_t *); 705 p->type = HCI_CMD_PKT; 706 p->opcode = opcode; 707 p->length = n; 708 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 709 *(char *)(p + 1) = seq; 710 m_copyback(m, 711 sizeof(hci_cmd_hdr_t) + 1, p->length, buf + offset); 712 713 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 714 bth4_start(sc->sc_dev); 715 716 error = bth4_waitresp(sc, &m, opcode); 717 if (m != NULL) { 718 if (error != 0) { 719 aprint_error_dev(sc->sc_dev, 720 "stlc2500 firmware load failed: Status 0x%02x\n", 721 error); 722 error = EFAULT; 723 break; 724 } 725 } 726 727 seq++; 728 offset += n; 729 } 730 m_freem(m); 731 732 return error; 733 } 734 735 static int 736 init_stlc2500(struct btuart_softc *sc) 737 { 738 struct mbuf *m; 739 struct hci_unit *unit = &sc->sc_unit; 740 hci_cmd_hdr_t *p; 741 hci_event_hdr_t *e; 742 hci_read_local_ver_rp *lv; 743 int error, revision, i; 744 uint16_t opcode; 745 char filename[NAME_MAX], param[8]; 746 static const char filenametmpl[] = "STLC2500_R%d_%02d%s"; 747 const char *suffix[] = { ".ptc", ".ssf", NULL }; 748 749 m = m_gethdr(M_WAIT, MT_DATA); 750 p = mtod(m, hci_cmd_hdr_t *); 751 opcode = htole16(HCI_CMD_READ_LOCAL_VER); 752 p->type = HCI_CMD_PKT; 753 p->opcode = opcode; 754 p->length = 0; 755 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 756 757 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 758 bth4_start(sc->sc_dev); 759 760 error = bth4_waitresp(sc, &m, opcode); 761 if (m != NULL) { 762 if (error != 0) { 763 aprint_error_dev(sc->sc_dev, 764 "HCI_Read_Local_Version_Information failed:" 765 " Status 0x%02x\n", error); 766 error = EFAULT; 767 m_freem(m); 768 } 769 } 770 if (error != 0) 771 return error; 772 773 e = mtod(m, hci_event_hdr_t *); 774 lv = (hci_read_local_ver_rp *)(e + 1); 775 revision = le16toh(lv->hci_revision); 776 opcode = htole16(HCI_CMD_RESET); 777 for (i = 0; suffix[i] != NULL; i++) { 778 /* send firmware */ 779 snprintf(filename, sizeof(filename), filenametmpl, 780 (uint8_t)(revision >> 8), (uint8_t)revision, suffix[i]); 781 bth4_firmload(sc, filename, firmload_stlc2500); 782 783 p = mtod(m, hci_cmd_hdr_t *); 784 p->type = HCI_CMD_PKT; 785 p->opcode = opcode; 786 p->length = 0; 787 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 788 789 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 790 bth4_start(sc->sc_dev); 791 792 error = bth4_waitresp(sc, &m, opcode); 793 if (m != NULL) { 794 if (error != 0) { 795 aprint_error_dev(sc->sc_dev, 796 "HCI_Reset (%d) failed: Status 0x%02x\n", 797 i, error); 798 error = EFAULT; 799 m_freem(m); 800 } 801 } 802 if (error != 0) 803 return error; 804 } 805 806 /* XXXX: We will obtain the character string. But I don't know... */ 807 p = mtod(m, hci_cmd_hdr_t *); 808 opcode = htole16(0xfc0f); /* XXXXX ?? */ 809 p->type = HCI_CMD_PKT; 810 p->opcode = opcode; 811 p->length = 0; 812 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 813 814 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 815 bth4_start(sc->sc_dev); 816 817 error = bth4_waitresp(sc, &m, opcode); 818 if (m != NULL) { 819 if (error != 0) { 820 aprint_error_dev(sc->sc_dev, 821 "failed: opcode 0xfc0f Status 0x%02x\n", error); 822 error = EFAULT; 823 m_freem(m); 824 } 825 } 826 if (error != 0) 827 return error; 828 /* 829 * XXXX: 830 * We do not know the beginning point of this character string. 831 * Because it doesn't know the event of this packet. 832 * 833 * aprint_error_dev(sc->sc_dev, "%s\n", ???); 834 */ 835 836 p = mtod(m, hci_cmd_hdr_t *); 837 opcode = htole16(0xfc22); /* XXXXX ?? */ 838 p->type = HCI_CMD_PKT; 839 p->opcode = opcode; 840 p->length = sizeof(param); 841 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 842 843 /* XXXX */ 844 param[0] = 0xfe; 845 param[1] = 0x06; 846 param[2] = 0xba; 847 param[3] = 0xab; 848 param[4] = 0x00; 849 param[5] = 0xe1; 850 param[6] = 0x80; 851 param[7] = 0x00; 852 m_copyback(m, sizeof(hci_cmd_hdr_t), p->length, param); 853 854 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 855 bth4_start(sc->sc_dev); 856 857 error = bth4_waitresp(sc, &m, opcode); 858 if (m != NULL) { 859 if (error != 0) { 860 aprint_error_dev(sc->sc_dev, 861 "failed: opcode 0xfc0f Status 0x%02x\n", error); 862 error = EFAULT; 863 m_freem(m); 864 } 865 } 866 if (error != 0) 867 return error; 868 869 opcode = htole16(HCI_CMD_RESET); 870 p = mtod(m, hci_cmd_hdr_t *); 871 p->type = HCI_CMD_PKT; 872 p->opcode = opcode; 873 p->length = 0; 874 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 875 876 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 877 bth4_start(sc->sc_dev); 878 879 error = bth4_waitresp(sc, &m, opcode); 880 if (m != NULL) { 881 if (error != 0) { 882 aprint_error_dev(sc->sc_dev, 883 "HCI_Reset failed: Status 0x%02x\n", error); 884 error = EFAULT; 885 m_freem(m); 886 } 887 } 888 889 return error; 890 } 891 892 static int 893 init_bcm2035(struct btuart_softc *sc) 894 { 895 struct mbuf *m; 896 struct hci_unit *unit = &sc->sc_unit; 897 hci_cmd_hdr_t *p; 898 int i, error; 899 #define HCI_CMD_BCM2035_SET_UART_BAUD_RATE 0xfc18 /* XXXX */ 900 const uint16_t opcode = htole16(HCI_CMD_BCM2035_SET_UART_BAUD_RATE); 901 static struct { /* XXXX */ 902 int baud; 903 uint16_t param; 904 } bcm2035_baudtbl[] = { 905 { B57600, 0xe600 }, 906 { B230400, 0xfa22 }, 907 { B460800, 0xfd11 }, 908 { B921600, 0xff65 }, 909 { B0, 0xffff } 910 }; 911 912 for (i = 0; bcm2035_baudtbl[i].baud != sc->sc_baud; i++) 913 if (bcm2035_baudtbl[i].baud == -1) 914 return EINVAL; 915 916 m = m_gethdr(M_WAIT, MT_DATA); 917 918 /* 919 * XXXX: Should we send some commands? 920 * HCI_CMD_RESET and HCI_CMD_READ_LOCAL_VER and 921 * HCI_CMD_READ_LOCAL_COMMANDS 922 */ 923 924 p = mtod(m, hci_cmd_hdr_t *); 925 p->type = HCI_CMD_PKT; 926 p->opcode = opcode; 927 p->length = sizeof(bcm2035_baudtbl[0].param); 928 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 929 m_copyback(m, sizeof(hci_cmd_hdr_t), p->length, 930 &bcm2035_baudtbl[i].param); 931 932 MBUFQ_ENQUEUE(&unit->hci_cmdq, m); 933 bth4_start(sc->sc_dev); 934 935 error = bth4_waitresp(sc, &m, opcode); 936 if (m != NULL) { 937 if (error != 0) { 938 aprint_error_dev(sc->sc_dev, 939 "bcm2035 set baud rate failed: Status 0x%02x\n", 940 error); 941 error = EFAULT; 942 } 943 m_freem(m); 944 } 945 946 return error; 947 } 948 949 static int 950 bth4init(struct btuart_softc *sc) 951 { 952 struct tty *tp = sc->sc_tp; 953 struct termios t; 954 int error = 0, s; 955 956 sc->sc_baud = tp->t_ospeed; 957 t.c_cflag = tp->t_cflag; 958 t.c_ispeed = 0; 959 t.c_ospeed = tp->t_ospeed; 960 if ((tp->t_cflag & CRTSCTS) && !(sc->sc_bth4hci.flags & FLOW_CTL)) 961 t.c_cflag &= ~CRTSCTS; 962 if (sc->sc_bth4hci.init_baud != 0 && 963 tp->t_ospeed != sc->sc_bth4hci.init_baud) 964 t.c_ospeed = sc->sc_bth4hci.init_baud; 965 if (t.c_ospeed != tp->t_ospeed || t.c_cflag != tp->t_cflag) 966 error = (*tp->t_param)(tp, &t); 967 968 if (error == 0 && sc->sc_bth4hci.init != NULL) 969 error = (*sc->sc_bth4hci.init)(sc); 970 971 s = splserial(); 972 sc->sc_input_acl = hci_input_acl; 973 sc->sc_input_sco = hci_input_sco; 974 sc->sc_input_event = hci_input_event; 975 splx(s); 976 977 if (sc->sc_bth4hci.init_baud != 0 && 978 sc->sc_bth4hci.init_baud != sc->sc_baud) { 979 t.c_ospeed = sc->sc_baud; 980 t.c_cflag = tp->t_cflag; 981 error = (*tp->t_param)(tp, &t); 982 } 983 984 return error; 985 } 986 987 static void 988 bth4init_input(struct hci_unit *unit, struct mbuf *m) 989 { 990 int i; 991 uint8_t *rptr = mtod(m, uint8_t *); 992 const char *pktstr = NULL; 993 994 switch (*rptr) { 995 case HCI_ACL_DATA_PKT: 996 pktstr = "acl data"; 997 break; 998 999 case HCI_SCO_DATA_PKT: 1000 pktstr = "sco data"; 1001 break; 1002 1003 case HCI_EVENT_PKT: 1004 break; 1005 1006 default: 1007 pktstr = "unknown"; 1008 break; 1009 } 1010 if (pktstr != NULL) 1011 aprint_error_dev(unit->hci_dev, 1012 "%s packet was received in initialization phase\n", pktstr); 1013 if ( 1014 #ifdef BTUART_DEBUG 1015 btuart_debug || 1016 #endif 1017 pktstr != NULL) { 1018 aprint_error_dev(unit->hci_dev, "%s:", __FUNCTION__); 1019 for (i = 0; i < m->m_len; i++) 1020 aprint_error(" %02x", *(rptr + i)); 1021 aprint_error("\n"); 1022 } 1023 1024 if (*rptr == HCI_EVENT_PKT) 1025 if (unit->hci_eventqlen <= hci_eventq_max) { 1026 unit->hci_eventqlen++; 1027 MBUFQ_ENQUEUE(&unit->hci_eventq, m); 1028 m = NULL; 1029 wakeup(&unit->hci_eventq); 1030 } 1031 1032 if (m != NULL) 1033 m_freem(m); 1034 } 1035 1036 1037 /* 1038 * Line discipline functions. 1039 */ 1040 /* ARGSUSED */ 1041 static int 1042 bth4open(dev_t device __unused, struct tty *tp) 1043 { 1044 struct btuart_softc *sc; 1045 struct cfdata *cfdata; 1046 struct lwp *l = curlwp; /* XXX */ 1047 int error, unit, s; 1048 static char name[] = "btuart"; 1049 1050 if ((error = kauth_authorize_device_tty(l->l_cred, 1051 KAUTH_GENERIC_ISSUSER, tp)) != 0) 1052 return error; 1053 1054 s = spltty(); 1055 1056 if (tp->t_linesw == &bth4_disc) { 1057 sc = (struct btuart_softc *)tp->t_sc; 1058 if (sc != NULL) { 1059 splx(s); 1060 return EBUSY; 1061 } 1062 } 1063 1064 KASSERT(tp->t_oproc != NULL); 1065 1066 cfdata = malloc(sizeof(struct cfdata), M_DEVBUF, M_WAITOK); 1067 for (unit = 0; unit < btuart_cd.cd_ndevs; unit++) 1068 if (btuart_cd.cd_devs[unit] == NULL) 1069 break; 1070 cfdata->cf_name = name; 1071 cfdata->cf_atname = name; 1072 cfdata->cf_unit = unit; 1073 cfdata->cf_fstate = FSTATE_STAR; 1074 1075 aprint_normal("%s%d at tty major %d minor %d", 1076 name, unit, major(tp->t_dev), minor(tp->t_dev)); 1077 sc = (struct btuart_softc *)config_attach_pseudo(cfdata); 1078 if (sc == NULL) { 1079 splx(s); 1080 return EIO; 1081 } 1082 mutex_spin_enter(&tty_lock); 1083 tp->t_sc = sc; 1084 sc->sc_tp = tp; 1085 ttyflush(tp, FREAD | FWRITE); 1086 mutex_spin_exit(&tty_lock); 1087 1088 splx(s); 1089 1090 return 0; 1091 } 1092 1093 /* ARGSUSED */ 1094 static int 1095 bth4close(struct tty *tp, int flag __unused) 1096 { 1097 struct btuart_softc *sc; 1098 struct cfdata *cfdata; 1099 int s, baud; 1100 1101 sc = tp->t_sc; 1102 1103 /* reset to initial speed */ 1104 if (sc->sc_bth4hci.init != NULL) { 1105 baud = sc->sc_baud; 1106 sc->sc_baud = sc->sc_bth4hci.init_baud; 1107 sc->sc_bth4hci.init_baud = baud; 1108 s = splserial(); 1109 sc->sc_input_acl = bth4init_input; 1110 sc->sc_input_sco = bth4init_input; 1111 sc->sc_input_event = bth4init_input; 1112 splx(s); 1113 if ((*sc->sc_bth4hci.init)(sc) != 0) 1114 aprint_error_dev(sc->sc_dev, "reset speed fail\n"); 1115 } 1116 1117 s = spltty(); 1118 mutex_spin_enter(&tty_lock); 1119 ttyflush(tp, FREAD | FWRITE); 1120 mutex_spin_exit(&tty_lock); /* XXX */ 1121 ttyldisc_release(tp->t_linesw); 1122 tp->t_linesw = ttyldisc_default(); 1123 if (sc != NULL) { 1124 tp->t_sc = NULL; 1125 if (sc->sc_tp == tp) { 1126 cfdata = device_cfdata(sc->sc_dev); 1127 config_detach(sc->sc_dev, 0); 1128 free(cfdata, M_DEVBUF); 1129 } 1130 1131 } 1132 splx(s); 1133 return 0; 1134 } 1135 1136 /* ARGSUSED */ 1137 static int 1138 bth4ioctl(struct tty *tp, u_long cmd, void *data, 1139 int flag __unused, struct lwp *l __unused) 1140 { 1141 struct btuart_softc *sc = (struct btuart_softc *)tp->t_sc; 1142 int error, i; 1143 1144 if (sc == NULL || tp != sc->sc_tp) 1145 return EPASSTHROUGH; 1146 1147 error = 0; 1148 switch (cmd) { 1149 case BTUART_HCITYPE: 1150 for (i = 0; bth4hci[i].type != -1; i++) 1151 if (bth4hci[i].type == *(uint32_t *)data) 1152 break; 1153 if (bth4hci[i].type != -1) 1154 memcpy(&sc->sc_bth4hci, &bth4hci[i], 1155 sizeof(struct bth4hci)); 1156 else 1157 error = EINVAL; 1158 break; 1159 1160 case BTUART_INITSPEED: 1161 sc->sc_bth4hci.init_baud = *(uint32_t *)data; 1162 break; 1163 1164 case BTUART_START: 1165 error = bth4init(sc); 1166 break; 1167 1168 default: 1169 error = EPASSTHROUGH; 1170 break; 1171 } 1172 1173 return error; 1174 } 1175 1176 static int 1177 bth4input(int c, struct tty *tp) 1178 { 1179 struct btuart_softc *sc = (struct btuart_softc *)tp->t_sc; 1180 struct mbuf *m = sc->sc_rxp; 1181 int space = 0; 1182 1183 c &= TTY_CHARMASK; 1184 1185 /* If we already started a packet, find the trailing end of it. */ 1186 if (m) { 1187 while (m->m_next) 1188 m = m->m_next; 1189 1190 space = M_TRAILINGSPACE(m); 1191 } 1192 1193 if (space == 0) { 1194 if (m == NULL) { 1195 /* new packet */ 1196 MGETHDR(m, M_DONTWAIT, MT_DATA); 1197 if (m == NULL) { 1198 aprint_error_dev(sc->sc_dev, 1199 "out of memory\n"); 1200 ++sc->sc_unit.hci_stats.err_rx; 1201 return 0; /* (lost sync) */ 1202 } 1203 1204 sc->sc_rxp = m; 1205 m->m_pkthdr.len = m->m_len = 0; 1206 space = MHLEN; 1207 1208 sc->sc_state = BTUART_RECV_PKT_TYPE; 1209 sc->sc_want = 1; 1210 } else { 1211 /* extend mbuf */ 1212 MGET(m->m_next, M_DONTWAIT, MT_DATA); 1213 if (m->m_next == NULL) { 1214 aprint_error_dev(sc->sc_dev, 1215 "out of memory\n"); 1216 ++sc->sc_unit.hci_stats.err_rx; 1217 return 0; /* (lost sync) */ 1218 } 1219 1220 m = m->m_next; 1221 m->m_len = 0; 1222 space = MLEN; 1223 1224 if (sc->sc_want > MINCLSIZE) { 1225 MCLGET(m, M_DONTWAIT); 1226 if (m->m_flags & M_EXT) 1227 space = MCLBYTES; 1228 } 1229 } 1230 } 1231 1232 mtod(m, uint8_t *)[m->m_len++] = c; 1233 sc->sc_rxp->m_pkthdr.len++; 1234 sc->sc_unit.hci_stats.byte_rx++; 1235 1236 sc->sc_want--; 1237 if (sc->sc_want > 0) 1238 return 0; /* want more */ 1239 1240 switch (sc->sc_state) { 1241 case BTUART_RECV_PKT_TYPE: /* Got packet type */ 1242 1243 switch (c) { 1244 case HCI_ACL_DATA_PKT: 1245 sc->sc_state = BTUART_RECV_ACL_HDR; 1246 sc->sc_want = sizeof(hci_acldata_hdr_t) - 1; 1247 break; 1248 1249 case HCI_SCO_DATA_PKT: 1250 sc->sc_state = BTUART_RECV_SCO_HDR; 1251 sc->sc_want = sizeof(hci_scodata_hdr_t) - 1; 1252 break; 1253 1254 case HCI_EVENT_PKT: 1255 sc->sc_state = BTUART_RECV_EVENT_HDR; 1256 sc->sc_want = sizeof(hci_event_hdr_t) - 1; 1257 break; 1258 1259 default: 1260 aprint_error_dev(sc->sc_dev, 1261 "Unknown packet type=%#x!\n", c); 1262 sc->sc_unit.hci_stats.err_rx++; 1263 m_freem(sc->sc_rxp); 1264 sc->sc_rxp = NULL; 1265 return 0; /* (lost sync) */ 1266 } 1267 1268 break; 1269 1270 /* 1271 * we assume (correctly of course :) that the packet headers all fit 1272 * into a single pkthdr mbuf 1273 */ 1274 case BTUART_RECV_ACL_HDR: /* Got ACL Header */ 1275 sc->sc_state = BTUART_RECV_ACL_DATA; 1276 sc->sc_want = mtod(m, hci_acldata_hdr_t *)->length; 1277 sc->sc_want = le16toh(sc->sc_want); 1278 break; 1279 1280 case BTUART_RECV_SCO_HDR: /* Got SCO Header */ 1281 sc->sc_state = BTUART_RECV_SCO_DATA; 1282 sc->sc_want = mtod(m, hci_scodata_hdr_t *)->length; 1283 break; 1284 1285 case BTUART_RECV_EVENT_HDR: /* Got Event Header */ 1286 sc->sc_state = BTUART_RECV_EVENT_DATA; 1287 sc->sc_want = mtod(m, hci_event_hdr_t *)->length; 1288 break; 1289 1290 case BTUART_RECV_ACL_DATA: /* ACL Packet Complete */ 1291 (*sc->sc_input_acl)(&sc->sc_unit, sc->sc_rxp); 1292 sc->sc_unit.hci_stats.acl_rx++; 1293 sc->sc_rxp = m = NULL; 1294 break; 1295 1296 case BTUART_RECV_SCO_DATA: /* SCO Packet Complete */ 1297 (*sc->sc_input_sco)(&sc->sc_unit, sc->sc_rxp); 1298 sc->sc_unit.hci_stats.sco_rx++; 1299 sc->sc_rxp = m = NULL; 1300 break; 1301 1302 case BTUART_RECV_EVENT_DATA: /* Event Packet Complete */ 1303 sc->sc_unit.hci_stats.evt_rx++; 1304 (*sc->sc_input_event)(&sc->sc_unit, sc->sc_rxp); 1305 sc->sc_rxp = m = NULL; 1306 break; 1307 1308 default: 1309 panic("%s: invalid state %d!\n", 1310 device_xname(sc->sc_dev), sc->sc_state); 1311 } 1312 1313 return 0; 1314 } 1315 1316 static int 1317 bth4start(struct tty *tp) 1318 { 1319 struct btuart_softc *sc = (struct btuart_softc *)tp->t_sc; 1320 struct mbuf *m; 1321 int count, rlen; 1322 uint8_t *rptr; 1323 1324 m = sc->sc_txp; 1325 if (m == NULL) { 1326 sc->sc_unit.hci_flags &= ~BTF_XMIT; 1327 bth4_start(sc->sc_dev); 1328 return 0; 1329 } 1330 1331 count = 0; 1332 rlen = 0; 1333 rptr = mtod(m, uint8_t *); 1334 1335 for(;;) { 1336 if (rlen >= m->m_len) { 1337 m = m->m_next; 1338 if (m == NULL) { 1339 m = sc->sc_txp; 1340 sc->sc_txp = NULL; 1341 1342 if (M_GETCTX(m, void *) == NULL) 1343 m_freem(m); 1344 else 1345 hci_complete_sco(&sc->sc_unit, m); 1346 1347 break; 1348 } 1349 1350 rlen = 0; 1351 rptr = mtod(m, uint8_t *); 1352 continue; 1353 } 1354 1355 if (putc(*rptr++, &tp->t_outq) < 0) { 1356 m_adj(m, rlen); 1357 break; 1358 } 1359 rlen++; 1360 count++; 1361 } 1362 1363 sc->sc_unit.hci_stats.byte_tx += count; 1364 1365 if (tp->t_outq.c_cc != 0) 1366 (*tp->t_oproc)(tp); 1367 1368 return 0; 1369 } 1370 1371 1372 /* 1373 * HCI UART (H4) functions. 1374 */ 1375 static int 1376 bth4_enable(device_t self) 1377 { 1378 struct btuart_softc *sc = device_private(self); 1379 struct hci_unit *unit = &sc->sc_unit; 1380 1381 if (unit->hci_flags & BTF_RUNNING) 1382 return 0; 1383 1384 unit->hci_flags |= BTF_RUNNING; 1385 unit->hci_flags &= ~BTF_XMIT; 1386 1387 return 0; 1388 } 1389 1390 static void 1391 bth4_disable(device_t self) 1392 { 1393 struct btuart_softc *sc = device_private(self); 1394 struct hci_unit *unit = &sc->sc_unit; 1395 1396 if ((unit->hci_flags & BTF_RUNNING) == 0) 1397 return; 1398 1399 if (sc->sc_rxp) { 1400 m_freem(sc->sc_rxp); 1401 sc->sc_rxp = NULL; 1402 } 1403 1404 if (sc->sc_txp) { 1405 m_freem(sc->sc_txp); 1406 sc->sc_txp = NULL; 1407 } 1408 1409 unit->hci_flags &= ~BTF_RUNNING; 1410 } 1411 1412 static void 1413 bth4_start(device_t self) 1414 { 1415 struct btuart_softc *sc = device_private(self); 1416 struct hci_unit *unit = &sc->sc_unit; 1417 struct mbuf *m; 1418 1419 KASSERT((unit->hci_flags & BTF_XMIT) == 0); 1420 KASSERT(sc->sc_txp == NULL); 1421 1422 if (MBUFQ_FIRST(&unit->hci_cmdq)) { 1423 MBUFQ_DEQUEUE(&unit->hci_cmdq, m); 1424 unit->hci_stats.cmd_tx++; 1425 M_SETCTX(m, NULL); 1426 goto start; 1427 } 1428 1429 if (MBUFQ_FIRST(&unit->hci_scotxq)) { 1430 MBUFQ_DEQUEUE(&unit->hci_scotxq, m); 1431 unit->hci_stats.sco_tx++; 1432 goto start; 1433 } 1434 1435 if (MBUFQ_FIRST(&unit->hci_acltxq)) { 1436 MBUFQ_DEQUEUE(&unit->hci_acltxq, m); 1437 unit->hci_stats.acl_tx++; 1438 M_SETCTX(m, NULL); 1439 goto start; 1440 } 1441 1442 /* Nothing to send */ 1443 return; 1444 1445 start: 1446 sc->sc_txp = m; 1447 unit->hci_flags |= BTF_XMIT; 1448 bth4start(sc->sc_tp); 1449 } 1450