Lines Matching refs:hci

8 #include <ddk/protocol/bt-hci.h>
11 #include <zircon/device/bt-hci.h>
81 static void queue_acl_read_requests_locked(hci_t* hci) {
83 while ((node = list_remove_head(&hci->free_acl_read_reqs)) != NULL) {
85 usb_request_queue(&hci->usb, req);
89 static void queue_interrupt_requests_locked(hci_t* hci) {
91 while ((node = list_remove_head(&hci->free_event_reqs)) != NULL) {
93 usb_request_queue(&hci->usb, req);
97 static void channel_cleanup_locked(hci_t* hci, zx_handle_t* channel) {
103 zx_object_signal(hci->channels_changed_evt, 0, ZX_EVENT_SIGNALED);
106 static void snoop_channel_write_locked(hci_t* hci, uint8_t flags, uint8_t* bytes, size_t length) {
107 if (hci->snoop_channel == ZX_HANDLE_INVALID)
114 zx_status_t status = zx_channel_write(hci->snoop_channel, 0, snoop_buffer, length + 1, NULL, 0);
117 channel_cleanup_locked(hci, &hci->snoop_channel);
122 hci_t* hci = (hci_t*)cookie;
123 mtx_lock(&hci->mutex);
127 if (hci->cmd_channel == ZX_HANDLE_INVALID && hci->snoop_channel == ZX_HANDLE_INVALID)
132 zx_status_t status = usb_req_mmap(&hci->usb, req, (void*)&buffer);
141 if (hci->event_buffer_offset == 0 && length >= 2) {
143 if (hci->cmd_channel != ZX_HANDLE_INVALID) {
144 zx_status_t status = zx_channel_write(hci->cmd_channel, 0, buffer, length, NULL, 0);
149 snoop_channel_write_locked(hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_EVT, true), buffer, length);
154 // complicated case - need to accumulate into hci->event_buffer
156 if (hci->event_buffer_offset + length > sizeof(hci->event_buffer)) {
161 memcpy(&hci->event_buffer[hci->event_buffer_offset], buffer, length);
162 if (hci->event_buffer_offset == 0) {
163 hci->event_buffer_packet_length = packet_size;
165 packet_size = hci->event_buffer_packet_length;
167 hci->event_buffer_offset += length;
170 if (packet_size <= hci->event_buffer_offset) {
171 zx_status_t status = zx_channel_write(hci->cmd_channel, 0, hci->event_buffer,
177 snoop_channel_write_locked(hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_EVT, true), hci->event_buffer, packet_size);
179 uint32_t remaining = hci->event_buffer_offset - packet_size;
180 memmove(hci->event_buffer, hci->event_buffer + packet_size, remaining);
181 hci->event_buffer_offset = 0;
182 hci->event_buffer_packet_length = 0;
187 list_add_head(&hci->free_event_reqs, &req->node);
188 queue_interrupt_requests_locked(hci);
190 mtx_unlock(&hci->mutex);
194 hci_t* hci = (hci_t*)cookie;
196 mtx_lock(&hci->mutex);
200 zx_status_t status = usb_req_mmap(&hci->usb, req, &buffer);
203 mtx_unlock(&hci->mutex);
210 status = zx_channel_write(hci->acl_channel, 0, buffer, req->response.actual, NULL, 0);
217 hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_ACL, true), buffer, req->response.actual);
220 list_add_head(&hci->free_acl_read_reqs, &req->node);
221 queue_acl_read_requests_locked(hci);
223 mtx_unlock(&hci->mutex);
227 hci_t* hci = (hci_t*)cookie;
230 mtx_lock(&hci->mutex);
231 list_add_tail(&hci->free_acl_write_reqs, &req->node);
233 if (hci->snoop_channel) {
235 zx_status_t status = usb_req_mmap(&hci->usb, req, &buffer);
238 mtx_unlock(&hci->mutex);
243 hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_ACL, false), buffer, req->response.actual);
246 mtx_unlock(&hci->mutex);
249 static void hci_build_read_wait_items_locked(hci_t* hci) {
250 zx_wait_item_t* items = hci->read_wait_items;
251 memset(items, 0, sizeof(hci->read_wait_items));
254 if (hci->cmd_channel != ZX_HANDLE_INVALID) {
255 items[count].handle = hci->cmd_channel;
260 if (hci->acl_channel != ZX_HANDLE_INVALID) {
261 items[count].handle = hci->acl_channel;
266 items[count].handle = hci->channels_changed_evt;
270 hci->read_wait_item_count = count;
272 zx_object_signal(hci->channels_changed_evt, ZX_EVENT_SIGNALED, 0);
275 static void hci_build_read_wait_items(hci_t* hci) {
276 mtx_lock(&hci->mutex);
277 hci_build_read_wait_items_locked(hci);
278 mtx_unlock(&hci->mutex);
283 static void hci_handle_cmd_read_events(hci_t* hci, zx_wait_item_t* cmd_item) {
295 status = usb_control(&hci->usb, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE,
302 mtx_lock(&hci->mutex);
303 snoop_channel_write_locked(hci, bt_hci_snoop_flags(BT_HCI_SNOOP_TYPE_CMD, false), buf, length);
304 mtx_unlock(&hci->mutex);
310 mtx_lock(&hci->mutex);
311 channel_cleanup_locked(hci, &hci->cmd_channel);
312 mtx_unlock(&hci->mutex);
315 static void hci_handle_acl_read_events(hci_t* hci, zx_wait_item_t* acl_item) {
317 mtx_lock(&hci->mutex);
318 list_node_t* node = list_peek_head(&hci->free_acl_write_reqs);
319 mtx_unlock(&hci->mutex);
335 mtx_lock(&hci->mutex);
336 node = list_remove_head(&hci->free_acl_write_reqs);
337 mtx_unlock(&hci->mutex);
345 usb_req_copy_to(&hci->usb, req, buf, length, 0);
347 usb_request_queue(&hci->usb, req);
353 mtx_lock(&hci->mutex);
354 channel_cleanup_locked(hci, &hci->acl_channel);
355 mtx_unlock(&hci->mutex);
358 static bool hci_has_read_channels_locked(hci_t* hci) {
360 return hci->read_wait_item_count > 1;
364 hci_t* hci = (hci_t*)arg;
366 mtx_lock(&hci->mutex);
368 if (!hci_has_read_channels_locked(hci)) {
370 hci->read_thread_running = false;
371 mtx_unlock(&hci->mutex);
375 mtx_unlock(&hci->mutex);
379 hci->read_wait_items, hci->read_wait_item_count, ZX_TIME_INFINITE);
383 mtx_lock(&hci->mutex);
384 channel_cleanup_locked(hci, &hci->cmd_channel);
385 channel_cleanup_locked(hci, &hci->acl_channel);
386 mtx_unlock(&hci->mutex);
390 for (unsigned i = 0; i < hci->read_wait_item_count; ++i) {
391 mtx_lock(&hci->mutex);
392 zx_wait_item_t item = hci->read_wait_items[i];
393 mtx_unlock(&hci->mutex);
395 if (item.handle == hci->cmd_channel) {
396 hci_handle_cmd_read_events(hci, &item);
397 } else if (item.handle == hci->acl_channel) {
398 hci_handle_acl_read_events(hci, &item);
403 status = zx_object_wait_one(hci->channels_changed_evt, ZX_EVENT_SIGNALED, 0u, NULL);
405 hci_build_read_wait_items(hci);
406 if (!hci_has_read_channels_locked(hci)) {
413 mtx_lock(&hci->mutex);
414 hci->read_thread_running = false;
415 mtx_unlock(&hci->mutex);
419 static zx_status_t hci_open_channel(hci_t* hci, zx_handle_t* in_channel, zx_handle_t* out_channel) {
421 mtx_lock(&hci->mutex);
438 if (!hci->read_thread_running) {
439 hci_build_read_wait_items_locked(hci);
441 thrd_create_with_name(&read_thread, hci_read_thread, hci, "bt_usb_read_thread");
442 hci->read_thread_running = true;
446 zx_object_signal(hci->channels_changed_evt, 0, ZX_EVENT_SIGNALED);
450 mtx_unlock(&hci->mutex);
455 hci_t* hci = ctx;
458 mtx_lock(&hci->mutex);
460 channel_cleanup_locked(hci, &hci->cmd_channel);
461 channel_cleanup_locked(hci, &hci->acl_channel);
462 channel_cleanup_locked(hci, &hci->snoop_channel);
464 mtx_unlock(&hci->mutex);
466 device_remove(hci->zxdev);
470 hci_t* hci = ctx;
472 mtx_lock(&hci->mutex);
475 while ((req = list_remove_head_type(&hci->free_event_reqs, usb_request_t, node)) != NULL) {
476 usb_req_release(&hci->usb, req);
478 while ((req = list_remove_head_type(&hci->free_acl_read_reqs, usb_request_t, node)) != NULL) {
479 usb_req_release(&hci->usb, req);
481 while ((req = list_remove_head_type(&hci->free_acl_write_reqs, usb_request_t, node)) != NULL) {
482 usb_req_release(&hci->usb, req);
485 mtx_unlock(&hci->mutex);
487 free(hci);
491 hci_t* hci = ctx;
492 return hci_open_channel(hci, &hci->cmd_channel, out_channel);
496 hci_t* hci = ctx;
497 return hci_open_channel(hci, &hci->acl_channel, out_channel);
501 hci_t* hci = ctx;
503 if (hci->snoop_watch == ZX_HANDLE_INVALID) {
504 zx_status_t status = zx_port_create(0, &hci->snoop_watch);
515 zx_status_t status = zx_port_wait(hci->snoop_watch, 0, &packet);
520 hci->snoop_channel = ZX_HANDLE_INVALID;
523 zx_status_t ret = hci_open_channel(hci, &hci->snoop_channel, out_channel);
526 zx_object_wait_async(hci->snoop_channel, hci->snoop_watch, 0, sigs,
539 hci_t* hci = ctx;
542 return device_get_protocol(hci->usb_zxdev, proto_id, protocol);
610 hci_t* hci = calloc(1, sizeof(hci_t));
611 if (!hci) {
616 list_initialize(&hci->free_event_reqs);
617 list_initialize(&hci->free_acl_read_reqs);
618 list_initialize(&hci->free_acl_write_reqs);
620 zx_event_create(0, &hci->channels_changed_evt);
622 mtx_init(&hci->mutex, mtx_plain);
624 hci->usb_zxdev = device;
625 memcpy(&hci->usb, &usb, sizeof(hci->usb));
634 req->cookie = hci;
635 list_add_head(&hci->free_event_reqs, &req->node);
644 req->cookie = hci;
645 list_add_head(&hci->free_acl_read_reqs, &req->node);
654 req->cookie = hci;
655 list_add_head(&hci->free_acl_write_reqs, &req->node);
658 mtx_lock(&hci->mutex);
659 queue_interrupt_requests_locked(hci);
660 queue_acl_read_requests_locked(hci);
661 mtx_unlock(&hci->mutex);
676 .ctx = hci,
683 status = device_add(device, &args, &hci->zxdev);
690 hci_release(hci);