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