1 /* $NetBSD: hci_unit.c,v 1.11 2008/04/24 11:38:37 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 2005 Iain Hibbert. 5 * Copyright (c) 2006 Itronix Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of Itronix Inc. may not be used to endorse 17 * or promote products derived from this software without specific 18 * prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: hci_unit.c,v 1.11 2008/04/24 11:38:37 ad Exp $"); 35 36 #include <sys/param.h> 37 #include <sys/conf.h> 38 #include <sys/device.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/mbuf.h> 42 #include <sys/proc.h> 43 #include <sys/queue.h> 44 #include <sys/systm.h> 45 #include <sys/intr.h> 46 #include <sys/socketvar.h> 47 48 #include <netbt/bluetooth.h> 49 #include <netbt/hci.h> 50 51 struct hci_unit_list hci_unit_list = SIMPLEQ_HEAD_INITIALIZER(hci_unit_list); 52 53 MALLOC_DEFINE(M_BLUETOOTH, "Bluetooth", "Bluetooth System Memory"); 54 55 /* 56 * HCI Input Queue max lengths. 57 */ 58 int hci_eventq_max = 20; 59 int hci_aclrxq_max = 50; 60 int hci_scorxq_max = 50; 61 62 /* 63 * This is the default minimum command set supported by older 64 * devices. Anything conforming to 1.2 spec or later will get 65 * updated during init. 66 */ 67 static const uint8_t hci_cmds_v10[HCI_COMMANDS_SIZE] = { 68 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff, 0xff, 69 0xff, 0xff, 0xff, 0x7f, 0x32, 0x03, 0xb8, 0xfe, 70 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 76 }; 77 78 /* 79 * bluetooth unit functions 80 */ 81 static void hci_intr (void *); 82 83 struct hci_unit * 84 hci_attach(const struct hci_if *hci_if, device_t dev, uint16_t flags) 85 { 86 struct hci_unit *unit; 87 88 KASSERT(dev != NULL); 89 KASSERT(hci_if->enable != NULL); 90 KASSERT(hci_if->disable != NULL); 91 KASSERT(hci_if->output_cmd != NULL); 92 KASSERT(hci_if->output_acl != NULL); 93 KASSERT(hci_if->output_sco != NULL); 94 KASSERT(hci_if->get_stats != NULL); 95 96 unit = malloc(sizeof(struct hci_unit), M_BLUETOOTH, M_ZERO | M_WAITOK); 97 KASSERT(unit != NULL); 98 99 unit->hci_dev = dev; 100 unit->hci_if = hci_if; 101 unit->hci_flags = flags; 102 103 mutex_init(&unit->hci_devlock, MUTEX_DRIVER, hci_if->ipl); 104 cv_init(&unit->hci_init, "hci_init"); 105 106 MBUFQ_INIT(&unit->hci_eventq); 107 MBUFQ_INIT(&unit->hci_aclrxq); 108 MBUFQ_INIT(&unit->hci_scorxq); 109 MBUFQ_INIT(&unit->hci_cmdwait); 110 MBUFQ_INIT(&unit->hci_scodone); 111 112 TAILQ_INIT(&unit->hci_links); 113 LIST_INIT(&unit->hci_memos); 114 115 mutex_enter(bt_lock); 116 SIMPLEQ_INSERT_TAIL(&hci_unit_list, unit, hci_next); 117 mutex_exit(bt_lock); 118 119 return unit; 120 } 121 122 void 123 hci_detach(struct hci_unit *unit) 124 { 125 126 mutex_enter(bt_lock); 127 hci_disable(unit); 128 129 SIMPLEQ_REMOVE(&hci_unit_list, unit, hci_unit, hci_next); 130 mutex_exit(bt_lock); 131 132 cv_destroy(&unit->hci_init); 133 mutex_destroy(&unit->hci_devlock); 134 free(unit, M_BLUETOOTH); 135 } 136 137 int 138 hci_enable(struct hci_unit *unit) 139 { 140 int err; 141 142 /* 143 * Bluetooth spec says that a device can accept one 144 * command on power up until they send a Command Status 145 * or Command Complete event with more information, but 146 * it seems that some devices cant and prefer to send a 147 * No-op Command Status packet when they are ready. 148 */ 149 unit->hci_num_cmd_pkts = (unit->hci_flags & BTF_POWER_UP_NOOP) ? 0 : 1; 150 unit->hci_num_acl_pkts = 0; 151 unit->hci_num_sco_pkts = 0; 152 153 /* 154 * only allow the basic packet types until 155 * the features report is in 156 */ 157 unit->hci_acl_mask = HCI_PKT_DM1 | HCI_PKT_DH1; 158 unit->hci_packet_type = unit->hci_acl_mask; 159 160 memcpy(unit->hci_cmds, hci_cmds_v10, HCI_COMMANDS_SIZE); 161 162 unit->hci_rxint = softint_establish(SOFTINT_NET, &hci_intr, unit); 163 if (unit->hci_rxint == NULL) 164 return EIO; 165 166 err = (*unit->hci_if->enable)(unit->hci_dev); 167 if (err) 168 goto bad1; 169 170 unit->hci_flags |= BTF_RUNNING; 171 172 /* 173 * Reset the device, this will trigger initialisation 174 * and wake us up. 175 */ 176 unit->hci_flags |= BTF_INIT; 177 178 err = hci_send_cmd(unit, HCI_CMD_RESET, NULL, 0); 179 if (err) 180 goto bad2; 181 182 while (unit->hci_flags & BTF_INIT) { 183 err = cv_timedwait_sig(&unit->hci_init, bt_lock, 5 * hz); 184 if (err) 185 goto bad2; 186 187 /* XXX 188 * "What If", while we were sleeping, the device 189 * was removed and detached? Ho Hum. 190 */ 191 } 192 193 /* 194 * Attach Bluetooth Device Hub 195 */ 196 unit->hci_bthub = config_found_ia(unit->hci_dev, 197 "btbus", &unit->hci_bdaddr, NULL); 198 199 return 0; 200 201 bad2: 202 (*unit->hci_if->disable)(unit->hci_dev); 203 unit->hci_flags &= ~BTF_RUNNING; 204 bad1: 205 softint_disestablish(unit->hci_rxint); 206 unit->hci_rxint = NULL; 207 208 return err; 209 } 210 211 void 212 hci_disable(struct hci_unit *unit) 213 { 214 struct hci_link *link, *next; 215 struct hci_memo *memo; 216 int acl; 217 218 if (unit->hci_bthub) { 219 config_detach(unit->hci_bthub, DETACH_FORCE); 220 unit->hci_bthub = NULL; 221 } 222 223 if (unit->hci_rxint) { 224 softint_disestablish(unit->hci_rxint); 225 unit->hci_rxint = NULL; 226 } 227 228 (*unit->hci_if->disable)(unit->hci_dev); 229 unit->hci_flags &= ~BTF_RUNNING; 230 231 /* 232 * close down any links, take care to close SCO first since 233 * they may depend on ACL links. 234 */ 235 for (acl = 0 ; acl < 2 ; acl++) { 236 next = TAILQ_FIRST(&unit->hci_links); 237 while ((link = next) != NULL) { 238 next = TAILQ_NEXT(link, hl_next); 239 if (acl || link->hl_type != HCI_LINK_ACL) 240 hci_link_free(link, ECONNABORTED); 241 } 242 } 243 244 while ((memo = LIST_FIRST(&unit->hci_memos)) != NULL) 245 hci_memo_free(memo); 246 247 /* (no need to hold hci_devlock, the driver is disabled) */ 248 249 MBUFQ_DRAIN(&unit->hci_eventq); 250 unit->hci_eventqlen = 0; 251 252 MBUFQ_DRAIN(&unit->hci_aclrxq); 253 unit->hci_aclrxqlen = 0; 254 255 MBUFQ_DRAIN(&unit->hci_scorxq); 256 unit->hci_scorxqlen = 0; 257 258 MBUFQ_DRAIN(&unit->hci_cmdwait); 259 MBUFQ_DRAIN(&unit->hci_scodone); 260 } 261 262 struct hci_unit * 263 hci_unit_lookup(bdaddr_t *addr) 264 { 265 struct hci_unit *unit; 266 267 SIMPLEQ_FOREACH(unit, &hci_unit_list, hci_next) { 268 if ((unit->hci_flags & BTF_UP) == 0) 269 continue; 270 271 if (bdaddr_same(&unit->hci_bdaddr, addr)) 272 break; 273 } 274 275 return unit; 276 } 277 278 /* 279 * update num_cmd_pkts and push on pending commands queue 280 */ 281 void 282 hci_num_cmds(struct hci_unit *unit, uint8_t num) 283 { 284 struct mbuf *m; 285 286 unit->hci_num_cmd_pkts = num; 287 288 while (unit->hci_num_cmd_pkts > 0 && MBUFQ_FIRST(&unit->hci_cmdwait)) { 289 MBUFQ_DEQUEUE(&unit->hci_cmdwait, m); 290 hci_output_cmd(unit, m); 291 } 292 } 293 294 /* 295 * construct and queue a HCI command packet 296 */ 297 int 298 hci_send_cmd(struct hci_unit *unit, uint16_t opcode, void *buf, uint8_t len) 299 { 300 struct mbuf *m; 301 hci_cmd_hdr_t *p; 302 303 KASSERT(unit != NULL); 304 305 m = m_gethdr(M_DONTWAIT, MT_DATA); 306 if (m == NULL) 307 return ENOMEM; 308 309 p = mtod(m, hci_cmd_hdr_t *); 310 p->type = HCI_CMD_PKT; 311 p->opcode = htole16(opcode); 312 p->length = len; 313 m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t); 314 315 if (len) { 316 KASSERT(buf != NULL); 317 318 m_copyback(m, sizeof(hci_cmd_hdr_t), len, buf); 319 if (m->m_pkthdr.len != (sizeof(hci_cmd_hdr_t) + len)) { 320 m_freem(m); 321 return ENOMEM; 322 } 323 } 324 325 DPRINTFN(2, "(%s) opcode (%3.3x|%4.4x)\n", device_xname(unit->hci_dev), 326 HCI_OGF(opcode), HCI_OCF(opcode)); 327 328 /* and send it on */ 329 if (unit->hci_num_cmd_pkts == 0) 330 MBUFQ_ENQUEUE(&unit->hci_cmdwait, m); 331 else 332 hci_output_cmd(unit, m); 333 334 return 0; 335 } 336 337 /* 338 * Incoming packet processing. Since the code is single threaded 339 * in any case (IPL_SOFTNET), we handle it all in one interrupt function 340 * picking our way through more important packets first so that hopefully 341 * we will never get clogged up with bulk data. 342 */ 343 static void 344 hci_intr(void *arg) 345 { 346 struct hci_unit *unit = arg; 347 struct mbuf *m; 348 349 mutex_enter(bt_lock); 350 another: 351 mutex_enter(&unit->hci_devlock); 352 353 if (unit->hci_eventqlen > 0) { 354 MBUFQ_DEQUEUE(&unit->hci_eventq, m); 355 unit->hci_eventqlen--; 356 mutex_exit(&unit->hci_devlock); 357 358 KASSERT(m != NULL); 359 360 DPRINTFN(10, "(%s) recv event, len = %d\n", 361 device_xname(unit->hci_dev), m->m_pkthdr.len); 362 363 m->m_flags |= M_LINK0; /* mark incoming packet */ 364 hci_mtap(m, unit); 365 hci_event(m, unit); 366 367 goto another; 368 } 369 370 if (unit->hci_scorxqlen > 0) { 371 MBUFQ_DEQUEUE(&unit->hci_scorxq, m); 372 unit->hci_scorxqlen--; 373 mutex_exit(&unit->hci_devlock); 374 375 KASSERT(m != NULL); 376 377 DPRINTFN(10, "(%s) recv SCO, len = %d\n", 378 device_xname(unit->hci_dev), m->m_pkthdr.len); 379 380 m->m_flags |= M_LINK0; /* mark incoming packet */ 381 hci_mtap(m, unit); 382 hci_sco_recv(m, unit); 383 384 goto another; 385 } 386 387 if (unit->hci_aclrxqlen > 0) { 388 MBUFQ_DEQUEUE(&unit->hci_aclrxq, m); 389 unit->hci_aclrxqlen--; 390 mutex_exit(&unit->hci_devlock); 391 392 KASSERT(m != NULL); 393 394 DPRINTFN(10, "(%s) recv ACL, len = %d\n", 395 device_xname(unit->hci_dev), m->m_pkthdr.len); 396 397 m->m_flags |= M_LINK0; /* mark incoming packet */ 398 hci_mtap(m, unit); 399 hci_acl_recv(m, unit); 400 401 goto another; 402 } 403 404 MBUFQ_DEQUEUE(&unit->hci_scodone, m); 405 if (m != NULL) { 406 struct hci_link *link; 407 408 mutex_exit(&unit->hci_devlock); 409 410 DPRINTFN(11, "(%s) complete SCO\n", 411 device_xname(unit->hci_dev)); 412 413 TAILQ_FOREACH(link, &unit->hci_links, hl_next) { 414 if (link == M_GETCTX(m, struct hci_link *)) { 415 hci_sco_complete(link, 1); 416 break; 417 } 418 } 419 420 unit->hci_num_sco_pkts++; 421 m_freem(m); 422 423 goto another; 424 } 425 426 mutex_exit(&unit->hci_devlock); 427 mutex_exit(bt_lock); 428 429 DPRINTFN(10, "done\n"); 430 } 431 432 /********************************************************************** 433 * 434 * IO routines 435 * 436 * input & complete routines will be called from device drivers, 437 * possibly in interrupt context. We return success or failure to 438 * enable proper accounting but we own the mbuf. 439 */ 440 441 bool 442 hci_input_event(struct hci_unit *unit, struct mbuf *m) 443 { 444 bool rv; 445 446 mutex_enter(&unit->hci_devlock); 447 448 if (unit->hci_eventqlen > hci_eventq_max || unit->hci_rxint == NULL) { 449 DPRINTF("(%s) dropped event packet.\n", device_xname(unit->hci_dev)); 450 m_freem(m); 451 rv = false; 452 } else { 453 unit->hci_eventqlen++; 454 MBUFQ_ENQUEUE(&unit->hci_eventq, m); 455 softint_schedule(unit->hci_rxint); 456 rv = true; 457 } 458 459 mutex_exit(&unit->hci_devlock); 460 return rv; 461 } 462 463 bool 464 hci_input_acl(struct hci_unit *unit, struct mbuf *m) 465 { 466 bool rv; 467 468 mutex_enter(&unit->hci_devlock); 469 470 if (unit->hci_aclrxqlen > hci_aclrxq_max || unit->hci_rxint == NULL) { 471 DPRINTF("(%s) dropped ACL packet.\n", device_xname(unit->hci_dev)); 472 m_freem(m); 473 rv = false; 474 } else { 475 unit->hci_aclrxqlen++; 476 MBUFQ_ENQUEUE(&unit->hci_aclrxq, m); 477 softint_schedule(unit->hci_rxint); 478 rv = true; 479 } 480 481 mutex_exit(&unit->hci_devlock); 482 return rv; 483 } 484 485 bool 486 hci_input_sco(struct hci_unit *unit, struct mbuf *m) 487 { 488 bool rv; 489 490 mutex_enter(&unit->hci_devlock); 491 492 if (unit->hci_scorxqlen > hci_scorxq_max || unit->hci_rxint == NULL) { 493 DPRINTF("(%s) dropped SCO packet.\n", device_xname(unit->hci_dev)); 494 m_freem(m); 495 rv = false; 496 } else { 497 unit->hci_scorxqlen++; 498 MBUFQ_ENQUEUE(&unit->hci_scorxq, m); 499 softint_schedule(unit->hci_rxint); 500 rv = true; 501 } 502 503 mutex_exit(&unit->hci_devlock); 504 return rv; 505 } 506 507 void 508 hci_output_cmd(struct hci_unit *unit, struct mbuf *m) 509 { 510 void *arg; 511 512 hci_mtap(m, unit); 513 514 DPRINTFN(10, "(%s) num_cmd_pkts=%d\n", device_xname(unit->hci_dev), 515 unit->hci_num_cmd_pkts); 516 517 unit->hci_num_cmd_pkts--; 518 519 /* 520 * If context is set, this was from a HCI raw socket 521 * and a record needs to be dropped from the sockbuf. 522 */ 523 arg = M_GETCTX(m, void *); 524 if (arg != NULL) 525 hci_drop(arg); 526 527 (*unit->hci_if->output_cmd)(unit->hci_dev, m); 528 } 529 530 void 531 hci_output_acl(struct hci_unit *unit, struct mbuf *m) 532 { 533 534 hci_mtap(m, unit); 535 536 DPRINTFN(10, "(%s) num_acl_pkts=%d\n", device_xname(unit->hci_dev), 537 unit->hci_num_acl_pkts); 538 539 unit->hci_num_acl_pkts--; 540 (*unit->hci_if->output_acl)(unit->hci_dev, m); 541 } 542 543 void 544 hci_output_sco(struct hci_unit *unit, struct mbuf *m) 545 { 546 547 hci_mtap(m, unit); 548 549 DPRINTFN(10, "(%s) num_sco_pkts=%d\n", device_xname(unit->hci_dev), 550 unit->hci_num_sco_pkts); 551 552 unit->hci_num_sco_pkts--; 553 (*unit->hci_if->output_sco)(unit->hci_dev, m); 554 } 555 556 bool 557 hci_complete_sco(struct hci_unit *unit, struct mbuf *m) 558 { 559 560 if (unit->hci_rxint == NULL) { 561 DPRINTFN(10, "(%s) complete SCO!\n", device_xname(unit->hci_dev)); 562 m_freem(m); 563 return false; 564 } 565 566 mutex_enter(&unit->hci_devlock); 567 568 MBUFQ_ENQUEUE(&unit->hci_scodone, m); 569 softint_schedule(unit->hci_rxint); 570 571 mutex_exit(&unit->hci_devlock); 572 return true; 573 } 574