diff options
Diffstat (limited to 'net/nfc/hci')
-rw-r--r-- | net/nfc/hci/command.c | 28 | ||||
-rw-r--r-- | net/nfc/hci/core.c | 90 | ||||
-rw-r--r-- | net/nfc/hci/llc.c | 2 | ||||
-rw-r--r-- | net/nfc/hci/llc_shdlc.c | 7 |
4 files changed, 89 insertions, 38 deletions
diff --git a/net/nfc/hci/command.c b/net/nfc/hci/command.c index 71c6a7086b8..7d99410e6c1 100644 --- a/net/nfc/hci/command.c +++ b/net/nfc/hci/command.c @@ -257,16 +257,16 @@ static u8 nfc_hci_create_pipe(struct nfc_hci_dev *hdev, u8 dest_host, *result = nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE, NFC_HCI_ADM_CREATE_PIPE, (u8 *) ¶ms, sizeof(params), &skb); - if (*result == 0) { - resp = (struct hci_create_pipe_resp *)skb->data; - pipe = resp->pipe; - kfree_skb(skb); + if (*result < 0) + return NFC_HCI_INVALID_PIPE; - pr_debug("pipe created=%d\n", pipe); + resp = (struct hci_create_pipe_resp *)skb->data; + pipe = resp->pipe; + kfree_skb(skb); - return pipe; - } else - return NFC_HCI_INVALID_PIPE; + pr_debug("pipe created=%d\n", pipe); + + return pipe; } static int nfc_hci_delete_pipe(struct nfc_hci_dev *hdev, u8 pipe) @@ -279,8 +279,6 @@ static int nfc_hci_delete_pipe(struct nfc_hci_dev *hdev, u8 pipe) static int nfc_hci_clear_all_pipes(struct nfc_hci_dev *hdev) { - int r; - u8 param[2]; /* TODO: Find out what the identity reference data is @@ -288,10 +286,8 @@ static int nfc_hci_clear_all_pipes(struct nfc_hci_dev *hdev) pr_debug("\n"); - r = nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE, - NFC_HCI_ADM_CLEAR_ALL_PIPE, param, 2, NULL); - - return 0; + return nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE, + NFC_HCI_ADM_CLEAR_ALL_PIPE, param, 2, NULL); } int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate) @@ -348,7 +344,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate, return -EADDRINUSE; if (pipe != NFC_HCI_INVALID_PIPE) - goto pipe_is_open; + goto open_pipe; switch (dest_gate) { case NFC_HCI_LINK_MGMT_GATE: @@ -365,6 +361,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate, break; } +open_pipe: r = nfc_hci_open_pipe(hdev, pipe); if (r < 0) { if (pipe_created) @@ -375,7 +372,6 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate, return r; } -pipe_is_open: hdev->gate2pipe[dest_gate] = pipe; return 0; diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c index 5fbb6e40793..7bea574d593 100644 --- a/net/nfc/hci/core.c +++ b/net/nfc/hci/core.c @@ -33,17 +33,20 @@ /* Largest headroom needed for outgoing HCI commands */ #define HCI_CMDS_HEADROOM 1 -static int nfc_hci_result_to_errno(u8 result) +int nfc_hci_result_to_errno(u8 result) { switch (result) { case NFC_HCI_ANY_OK: return 0; + case NFC_HCI_ANY_E_REG_PAR_UNKNOWN: + return -EOPNOTSUPP; case NFC_HCI_ANY_E_TIMEOUT: return -ETIME; default: return -1; } } +EXPORT_SYMBOL(nfc_hci_result_to_errno); static void nfc_hci_msg_tx_work(struct work_struct *work) { @@ -65,8 +68,9 @@ static void nfc_hci_msg_tx_work(struct work_struct *work) -ETIME); kfree(hdev->cmd_pending_msg); hdev->cmd_pending_msg = NULL; - } else + } else { goto exit; + } } next_msg: @@ -166,7 +170,7 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, kfree_skb(skb); } -static u32 nfc_hci_sak_to_protocol(u8 sak) +u32 nfc_hci_sak_to_protocol(u8 sak) { switch (NFC_HCI_TYPE_A_SEL_PROT(sak)) { case NFC_HCI_TYPE_A_SEL_PROT_MIFARE: @@ -181,8 +185,9 @@ static u32 nfc_hci_sak_to_protocol(u8 sak) return 0xffffffff; } } +EXPORT_SYMBOL(nfc_hci_sak_to_protocol); -static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) +int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) { struct nfc_target *targets; struct sk_buff *atqa_skb = NULL; @@ -263,7 +268,9 @@ static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) break; } - targets->hci_reader_gate = gate; + /* if driver set the new gate, we will skip the old one */ + if (targets->hci_reader_gate == 0x00) + targets->hci_reader_gate = gate; r = nfc_targets_found(hdev->ndev, targets, 1); @@ -275,11 +282,18 @@ exit: return r; } +EXPORT_SYMBOL(nfc_hci_target_discovered); void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, struct sk_buff *skb) { int r = 0; + u8 gate = nfc_hci_pipe2gate(hdev, pipe); + + if (gate == 0xff) { + pr_err("Discarded event %x to unopened pipe %x\n", event, pipe); + goto exit; + } switch (event) { case NFC_HCI_EVT_TARGET_DISCOVERED: @@ -303,12 +317,14 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, goto exit; } - r = nfc_hci_target_discovered(hdev, - nfc_hci_pipe2gate(hdev, pipe)); + r = nfc_hci_target_discovered(hdev, gate); break; default: - /* TODO: Unknown events are hardware specific - * pass them to the driver (needs a new hci_ops) */ + if (hdev->ops->event_received) { + hdev->ops->event_received(hdev, gate, event, skb); + return; + } + break; } @@ -410,6 +426,10 @@ static int hci_dev_version(struct nfc_hci_dev *hdev) r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE, NFC_HCI_ID_MGMT_VERSION_SW, &skb); + if (r == -EOPNOTSUPP) { + pr_info("Software/Hardware info not available\n"); + return 0; + } if (r < 0) return r; @@ -527,7 +547,8 @@ static int hci_start_poll(struct nfc_dev *nfc_dev, return hdev->ops->start_poll(hdev, im_protocols, tm_protocols); else return nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, - NFC_HCI_EVT_READER_REQUESTED, NULL, 0); + NFC_HCI_EVT_READER_REQUESTED, + NULL, 0); } static void hci_stop_poll(struct nfc_dev *nfc_dev) @@ -538,6 +559,28 @@ static void hci_stop_poll(struct nfc_dev *nfc_dev) NFC_HCI_EVT_END_OPERATION, NULL, 0); } +static int hci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, + __u8 comm_mode, __u8 *gb, size_t gb_len) +{ + struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); + + if (hdev->ops->dep_link_up) + return hdev->ops->dep_link_up(hdev, target, comm_mode, + gb, gb_len); + + return 0; +} + +static int hci_dep_link_down(struct nfc_dev *nfc_dev) +{ + struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); + + if (hdev->ops->dep_link_down) + return hdev->ops->dep_link_down(hdev); + + return 0; +} + static int hci_activate_target(struct nfc_dev *nfc_dev, struct nfc_target *target, u32 protocol) { @@ -586,8 +629,8 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, switch (target->hci_reader_gate) { case NFC_HCI_RF_READER_A_GATE: case NFC_HCI_RF_READER_B_GATE: - if (hdev->ops->data_exchange) { - r = hdev->ops->data_exchange(hdev, target, skb, cb, + if (hdev->ops->im_transceive) { + r = hdev->ops->im_transceive(hdev, target, skb, cb, cb_context); if (r <= 0) /* handled */ break; @@ -604,14 +647,14 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, skb->len, hci_transceive_cb, hdev); break; default: - if (hdev->ops->data_exchange) { - r = hdev->ops->data_exchange(hdev, target, skb, cb, + if (hdev->ops->im_transceive) { + r = hdev->ops->im_transceive(hdev, target, skb, cb, cb_context); if (r == 1) r = -ENOTSUPP; - } - else + } else { r = -ENOTSUPP; + } break; } @@ -620,6 +663,16 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, return r; } +static int hci_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) +{ + struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); + + if (hdev->ops->tm_send) + return hdev->ops->tm_send(hdev, skb); + else + return -ENOTSUPP; +} + static int hci_check_presence(struct nfc_dev *nfc_dev, struct nfc_target *target) { @@ -723,9 +776,12 @@ static struct nfc_ops hci_nfc_ops = { .dev_down = hci_dev_down, .start_poll = hci_start_poll, .stop_poll = hci_stop_poll, + .dep_link_up = hci_dep_link_up, + .dep_link_down = hci_dep_link_down, .activate_target = hci_activate_target, .deactivate_target = hci_deactivate_target, .im_transceive = hci_transceive, + .tm_send = hci_tm_send, .check_presence = hci_check_presence, }; @@ -848,7 +904,7 @@ void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err) } EXPORT_SYMBOL(nfc_hci_driver_failure); -void inline nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb) +void nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb) { nfc_llc_rcv_from_drv(hdev->llc, skb); } diff --git a/net/nfc/hci/llc.c b/net/nfc/hci/llc.c index ae1205ded87..fe5e966e5b8 100644 --- a/net/nfc/hci/llc.c +++ b/net/nfc/hci/llc.c @@ -72,7 +72,7 @@ int nfc_llc_register(const char *name, struct nfc_llc_ops *ops) llc_engine->ops = ops; INIT_LIST_HEAD(&llc_engine->entry); - list_add_tail (&llc_engine->entry, &llc_engines); + list_add_tail(&llc_engine->entry, &llc_engines); return 0; } diff --git a/net/nfc/hci/llc_shdlc.c b/net/nfc/hci/llc_shdlc.c index 01cbc72943c..27b313befc3 100644 --- a/net/nfc/hci/llc_shdlc.c +++ b/net/nfc/hci/llc_shdlc.c @@ -634,9 +634,9 @@ static void llc_shdlc_sm_work(struct work_struct *work) r = llc_shdlc_connect_initiate(shdlc); else r = -ETIME; - if (r < 0) + if (r < 0) { llc_shdlc_connect_complete(shdlc, r); - else { + } else { mod_timer(&shdlc->connect_timer, jiffies + msecs_to_jiffies(SHDLC_CONNECT_VALUE_MS)); @@ -682,9 +682,8 @@ static void llc_shdlc_sm_work(struct work_struct *work) llc_shdlc_handle_send_queue(shdlc); } - if (shdlc->hard_fault) { + if (shdlc->hard_fault) shdlc->llc_failure(shdlc->hdev, shdlc->hard_fault); - } break; default: break; |