static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); void *sent; BT_DBG("%s status 0x%x", hdev->name, status); sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); if (!sent) return; if (!status) { __u8 param = *((__u8 *) sent); clear_bit(HCI_PSCAN, &hdev->flags); clear_bit(HCI_ISCAN, &hdev->flags); if (param & SCAN_INQUIRY) set_bit(HCI_ISCAN, &hdev->flags); if (param & SCAN_PAGE) set_bit(HCI_PSCAN, &hdev->flags); } hci_req_complete(hdev, status); }
/* Command Complete OGF LINK_CTL */ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) { __u8 status; struct hci_conn *pend; BT_DBG("%s ocf 0x%x", hdev->name, ocf); switch (ocf) { case OCF_INQUIRY_CANCEL: case OCF_EXIT_PERIODIC_INQ: status = *((__u8 *) skb->data); if (status) { BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status); } else { clear_bit(HCI_INQUIRY, &hdev->flags); hci_req_complete(hdev, status); } hci_dev_lock(hdev); pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); if (pend) hci_acl_connect(pend); hci_dev_unlock(hdev); break; default: BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf); break; } }
static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); BT_DBG("%s status 0x%x", hdev->name, status); hci_req_complete(hdev, status); }
static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); BT_DBG("%s status 0x%x", hdev->name, status); hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); }
static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); BT_DBG("%s status 0x%x", hdev->name, status); hci_req_complete(hdev, HCI_OP_RESET, status); }
/* Inquiry Complete */ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); BT_DBG("%s status %d", hdev->name, status); clear_bit(HCI_INQUIRY, &hdev->flags); hci_req_complete(hdev, status); }
static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) { BT_DBG("%s status 0x%x", hdev->name, status); if (status) { hci_req_complete(hdev, status); hci_conn_check_pending(hdev); } else set_bit(HCI_INQUIRY, &hdev->flags); }
static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_rp_read_bd_addr *rp = (void *) skb->data; BT_DBG("%s status 0x%x", hdev->name, rp->status); if (!rp->status) bacpy(&hdev->bdaddr, &rp->bdaddr); hci_req_complete(hdev, rp->status); }
static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status) { BT_DBG("%s ocf 0x%x", hdev->name, ocf); switch (ocf) { case OCF_CREATE_CONN: hci_cs_create_conn(hdev, status); break; case OCF_ADD_SCO: if (status) { struct hci_conn *acl, *sco; struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO); __u16 handle; if (!cp) break; handle = __le16_to_cpu(cp->handle); BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status); hci_dev_lock(hdev); acl = hci_conn_hash_lookup_handle(hdev, handle); if (acl && (sco = acl->link)) { sco->state = BT_CLOSED; hci_proto_connect_cfm(sco, status); hci_conn_del(sco); } hci_dev_unlock(hdev); } break; case OCF_INQUIRY: if (status) { BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status); hci_req_complete(hdev, status); } else { set_bit(HCI_INQUIRY, &hdev->flags); } break; default: BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d", hdev->name, ocf, status); break; } }
static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); BT_DBG("%s status 0x%x", hdev->name, status); if (status) return; clear_bit(HCI_INQUIRY, &hdev->flags); hci_req_complete(hdev, status); hci_conn_check_pending(hdev); }
static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); void *sent; BT_DBG("%s status 0x%x", hdev->name, status); sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); if (!sent) return; if (!status) hdev->link_policy = get_unaligned_le16(sent); hci_req_complete(hdev, status); }
/* Inquiry Complete */ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); struct hci_conn *pend; BT_DBG("%s status %d", hdev->name, status); clear_bit(HCI_INQUIRY, &hdev->flags); hci_req_complete(hdev, status); hci_dev_lock(hdev); pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); if (pend) hci_acl_connect(pend); hci_dev_unlock(hdev); }
static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); void *sent; BT_DBG("%s status 0x%x", hdev->name, status); sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); if (!sent) return; if (!status) { __u8 param = *((__u8 *) sent); if (param) set_bit(HCI_ENCRYPT, &hdev->flags); else clear_bit(HCI_ENCRYPT, &hdev->flags); } hci_req_complete(hdev, status); }
static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); void *sent; BT_DBG("%s status 0x%x", hdev->name, status); sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); if (!sent) return; if (!status) { __u8 param = *((__u8 *) sent); if (param == AUTH_ENABLED) set_bit(HCI_AUTH, &hdev->flags); else clear_bit(HCI_AUTH, &hdev->flags); } hci_req_complete(hdev, status); }
//BT_TIK 2011.09.23 SH Start : QoS patch from IL static inline void hci_flowspec_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_flowspec_complete *ev = (void *) skb->data; struct hci_conn *conn; BT_DBG("%s status %d", hdev->name, ev->status); if (!ev->status) { hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (conn) { /* conn->qos_info.delay_variation = le32_to_cpu(ev->qos.delay_variation); conn->qos_info.latency = le32_to_cpu(ev->qos.latency); conn->qos_info.peak_bandwidth = le32_to_cpu(ev->qos.peak_bandwidth); conn->qos_info.service_type = ev->qos.service_type; conn->qos_info.token_rate = le32_to_cpu(ev->qos.token_rate); */ conn->flowspec.bucket_size = le32_to_cpu(ev->flowspec.bucket_size); conn->flowspec.flowdir = ev->flowspec.flowdir; conn->flowspec.latency = le32_to_cpu(ev->flowspec.latency); conn->flowspec.peak_bandwidth = le32_to_cpu(ev->flowspec.peak_bandwidth); conn->flowspec.service_type = ev->flowspec.service_type; conn->flowspec.token_rate = le32_to_cpu(ev->flowspec.token_rate); } hci_dev_unlock(hdev); } //BT_TIK 2011.09.23 SH : Removed HCI_OP_SET_FLOW_SPEC because kernel version of // GT-P1010 is different from one of patch from IL //hci_req_complete(hdev, HCI_OP_SET_FLOW_SPEC, ev->status); hci_req_complete(hdev, ev->status); }
/* Command Complete OGF LINK_CTL */ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) { __u8 status; BT_DBG("%s ocf 0x%x", hdev->name, ocf); switch (ocf) { case OCF_INQUIRY_CANCEL: status = *((__u8 *) skb->data); if (status) { BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status); } else { clear_bit(HCI_INQUIRY, &hdev->flags); hci_req_complete(hdev, status); } break; default: BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf); break; } }
/* Command Complete OGF HOST_CTL */ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) { __u8 status, param; void *sent; BT_DBG("%s ocf 0x%x", hdev->name, ocf); switch (ocf) { case OCF_RESET: status = *((__u8 *) skb->data); hci_req_complete(hdev, status); break; case OCF_SET_EVENT_FLT: status = *((__u8 *) skb->data); if (status) { BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status); } else { BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name); } break; case OCF_WRITE_AUTH_ENABLE: sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE); if (!sent) break; status = *((__u8 *) skb->data); param = *((__u8 *) sent); if (!status) { if (param == AUTH_ENABLED) set_bit(HCI_AUTH, &hdev->flags); else clear_bit(HCI_AUTH, &hdev->flags); } hci_req_complete(hdev, status); break; case OCF_WRITE_ENCRYPT_MODE: sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE); if (!sent) break; status = *((__u8 *) skb->data); param = *((__u8 *) sent); if (!status) { if (param) set_bit(HCI_ENCRYPT, &hdev->flags); else clear_bit(HCI_ENCRYPT, &hdev->flags); } hci_req_complete(hdev, status); break; case OCF_WRITE_CA_TIMEOUT: status = *((__u8 *) skb->data); if (status) { BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status); } else { BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name); } break; case OCF_WRITE_PG_TIMEOUT: status = *((__u8 *) skb->data); if (status) { BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status); } else { BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name); } break; case OCF_WRITE_SCAN_ENABLE: sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE); if (!sent) break; status = *((__u8 *) skb->data); param = *((__u8 *) sent); BT_DBG("param 0x%x", param); if (!status) { clear_bit(HCI_PSCAN, &hdev->flags); clear_bit(HCI_ISCAN, &hdev->flags); if (param & SCAN_INQUIRY) set_bit(HCI_ISCAN, &hdev->flags); if (param & SCAN_PAGE) set_bit(HCI_PSCAN, &hdev->flags); } hci_req_complete(hdev, status); break; case OCF_HOST_BUFFER_SIZE: status = *((__u8 *) skb->data); if (status) { BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status); hci_req_complete(hdev, status); } break; default: BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf); break; }; }
/* Command Complete OGF INFO_PARAM */ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) { read_local_features_rp *lf; read_buffer_size_rp *bs; read_bd_addr_rp *ba; BT_DBG("%s ocf 0x%x", hdev->name, ocf); switch (ocf) { case OCF_READ_LOCAL_FEATURES: lf = (read_local_features_rp *) skb->data; if (lf->status) { BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status); break; } memcpy(hdev->features, lf->features, sizeof(hdev->features)); /* Adjust default settings according to features * supported by device. */ if (hdev->features[0] & LMP_3SLOT) hdev->pkt_type |= (HCI_DM3 | HCI_DH3); if (hdev->features[0] & LMP_5SLOT) hdev->pkt_type |= (HCI_DM5 | HCI_DH5); if (hdev->features[1] & LMP_HV2) hdev->pkt_type |= (HCI_HV2); if (hdev->features[1] & LMP_HV3) hdev->pkt_type |= (HCI_HV3); BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]); break; case OCF_READ_BUFFER_SIZE: bs = (read_buffer_size_rp *) skb->data; if (bs->status) { BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status); hci_req_complete(hdev, bs->status); break; } hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu); hdev->sco_mtu = bs->sco_mtu ? bs->sco_mtu : 64; hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt); hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt); BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name, hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts); break; case OCF_READ_BD_ADDR: ba = (read_bd_addr_rp *) skb->data; if (!ba->status) { bacpy(&hdev->bdaddr, &ba->bdaddr); } else { BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status); } hci_req_complete(hdev, ba->status); break; default: BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf); break; }; }
/* Command Complete OGF INFO_PARAM */ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) { struct hci_rp_read_loc_version *lv; struct hci_rp_read_local_features *lf; struct hci_rp_read_buffer_size *bs; struct hci_rp_read_bd_addr *ba; BT_DBG("%s ocf 0x%x", hdev->name, ocf); switch (ocf) { case OCF_READ_LOCAL_VERSION: lv = (struct hci_rp_read_loc_version *) skb->data; if (lv->status) { BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status); break; } hdev->hci_ver = lv->hci_ver; hdev->hci_rev = btohs(lv->hci_rev); hdev->manufacturer = btohs(lv->manufacturer); BT_DBG("%s: manufacturer %d hci_ver %d hci_rev %d", hdev->name, hdev->manufacturer, hdev->hci_ver, hdev->hci_rev); break; case OCF_READ_LOCAL_FEATURES: lf = (struct hci_rp_read_local_features *) skb->data; if (lf->status) { BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status); break; } memcpy(hdev->features, lf->features, sizeof(hdev->features)); /* Adjust default settings according to features * supported by device. */ if (hdev->features[0] & LMP_3SLOT) hdev->pkt_type |= (HCI_DM3 | HCI_DH3); if (hdev->features[0] & LMP_5SLOT) hdev->pkt_type |= (HCI_DM5 | HCI_DH5); if (hdev->features[1] & LMP_HV2) hdev->pkt_type |= (HCI_HV2); if (hdev->features[1] & LMP_HV3) hdev->pkt_type |= (HCI_HV3); BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]); break; case OCF_READ_BUFFER_SIZE: bs = (struct hci_rp_read_buffer_size *) skb->data; if (bs->status) { BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status); hci_req_complete(hdev, bs->status); break; } hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu); hdev->sco_mtu = bs->sco_mtu; hdev->acl_pkts = __le16_to_cpu(bs->acl_max_pkt); hdev->sco_pkts = __le16_to_cpu(bs->sco_max_pkt); if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { hdev->sco_mtu = 64; hdev->sco_pkts = 8; } hdev->acl_cnt = hdev->acl_pkts; hdev->sco_cnt = hdev->sco_pkts; BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name, hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts); break; case OCF_READ_BD_ADDR: ba = (struct hci_rp_read_bd_addr *) skb->data; if (!ba->status) { bacpy(&hdev->bdaddr, &ba->bdaddr); } else { BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status); } hci_req_complete(hdev, ba->status); break; default: BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf); break; } }
/* Command Complete OGF HOST_CTL */ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) { __u8 status, param; __u16 setting; struct hci_rp_read_voice_setting *vs; void *sent; BT_DBG("%s ocf 0x%x", hdev->name, ocf); switch (ocf) { case OCF_RESET: status = *((__u8 *) skb->data); hci_req_complete(hdev, status); break; case OCF_SET_EVENT_FLT: status = *((__u8 *) skb->data); if (status) { BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status); } else { BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name); } break; case OCF_WRITE_AUTH_ENABLE: sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE); if (!sent) break; status = *((__u8 *) skb->data); param = *((__u8 *) sent); if (!status) { if (param == AUTH_ENABLED) set_bit(HCI_AUTH, &hdev->flags); else clear_bit(HCI_AUTH, &hdev->flags); } hci_req_complete(hdev, status); break; case OCF_WRITE_ENCRYPT_MODE: sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE); if (!sent) break; status = *((__u8 *) skb->data); param = *((__u8 *) sent); if (!status) { if (param) set_bit(HCI_ENCRYPT, &hdev->flags); else clear_bit(HCI_ENCRYPT, &hdev->flags); } hci_req_complete(hdev, status); break; case OCF_WRITE_CA_TIMEOUT: status = *((__u8 *) skb->data); if (status) { BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status); } else { BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name); } break; case OCF_WRITE_PG_TIMEOUT: status = *((__u8 *) skb->data); if (status) { BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status); } else { BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name); } break; case OCF_WRITE_SCAN_ENABLE: sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE); if (!sent) break; status = *((__u8 *) skb->data); param = *((__u8 *) sent); BT_DBG("param 0x%x", param); if (!status) { clear_bit(HCI_PSCAN, &hdev->flags); clear_bit(HCI_ISCAN, &hdev->flags); if (param & SCAN_INQUIRY) set_bit(HCI_ISCAN, &hdev->flags); if (param & SCAN_PAGE) set_bit(HCI_PSCAN, &hdev->flags); } hci_req_complete(hdev, status); break; case OCF_READ_VOICE_SETTING: vs = (struct hci_rp_read_voice_setting *) skb->data; if (vs->status) { BT_DBG("%s READ_VOICE_SETTING failed %d", hdev->name, vs->status); break; } setting = __le16_to_cpu(vs->voice_setting); if (hdev->voice_setting != setting ) { hdev->voice_setting = setting; BT_DBG("%s: voice setting 0x%04x", hdev->name, setting); if (hdev->notify) { tasklet_disable(&hdev->tx_task); hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); tasklet_enable(&hdev->tx_task); } } break; case OCF_WRITE_VOICE_SETTING: sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING); if (!sent) break; status = *((__u8 *) skb->data); setting = __le16_to_cpu(get_unaligned((__le16 *) sent)); if (!status && hdev->voice_setting != setting) { hdev->voice_setting = setting; BT_DBG("%s: voice setting 0x%04x", hdev->name, setting); if (hdev->notify) { tasklet_disable(&hdev->tx_task); hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); tasklet_enable(&hdev->tx_task); } } hci_req_complete(hdev, status); break; case OCF_HOST_BUFFER_SIZE: status = *((__u8 *) skb->data); if (status) { BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status); hci_req_complete(hdev, status); } break; default: BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf); break; } }