]> nv-tegra.nvidia Code Review - linux-3.10.git/commitdiff
NFC: Allow HCI driver to pre-open pipes to some gates
authorEric Lapuyade <eric.lapuyade@linux.intel.com>
Tue, 5 Jun 2012 12:42:11 +0000 (14:42 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 9 Jul 2012 20:42:12 +0000 (16:42 -0400)
Some NFC chips will statically create and open pipes for both standard
and proprietary gates. The driver can now pass this information to HCI
such that HCI will not attempt to create and open them, but will instead
directly use the passed pipe ids.

Signed-off-by: Eric Lapuyade <eric.lapuyade@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
drivers/nfc/pn544_hci.c
include/net/nfc/hci.h
net/nfc/hci/command.c
net/nfc/hci/core.c
net/nfc/hci/hci.h

index 69df6fecb84759bb5f5eb72840a41c2087127f30..c67b55e224e0b10fc3eea740ba95968bb639de98 100644 (file)
@@ -108,16 +108,22 @@ enum pn544_state {
 
 #define PN544_NFC_WI_MGMT_GATE                 0xA1
 
-static u8 pn544_custom_gates[] = {
-       PN544_SYS_MGMT_GATE,
-       PN544_SWP_MGMT_GATE,
-       PN544_POLLING_LOOP_MGMT_GATE,
-       PN544_NFC_WI_MGMT_GATE,
-       PN544_RF_READER_F_GATE,
-       PN544_RF_READER_JEWEL_GATE,
-       PN544_RF_READER_ISO15693_GATE,
-       PN544_RF_READER_NFCIP1_INITIATOR_GATE,
-       PN544_RF_READER_NFCIP1_TARGET_GATE
+static struct nfc_hci_gate pn544_gates[] = {
+       {NFC_HCI_ADMIN_GATE, NFC_HCI_INVALID_PIPE},
+       {NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE},
+       {NFC_HCI_ID_MGMT_GATE, NFC_HCI_INVALID_PIPE},
+       {NFC_HCI_LINK_MGMT_GATE, NFC_HCI_INVALID_PIPE},
+       {NFC_HCI_RF_READER_B_GATE, NFC_HCI_INVALID_PIPE},
+       {NFC_HCI_RF_READER_A_GATE, NFC_HCI_INVALID_PIPE},
+       {PN544_SYS_MGMT_GATE, NFC_HCI_INVALID_PIPE},
+       {PN544_SWP_MGMT_GATE, NFC_HCI_INVALID_PIPE},
+       {PN544_POLLING_LOOP_MGMT_GATE, NFC_HCI_INVALID_PIPE},
+       {PN544_NFC_WI_MGMT_GATE, NFC_HCI_INVALID_PIPE},
+       {PN544_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE},
+       {PN544_RF_READER_JEWEL_GATE, NFC_HCI_INVALID_PIPE},
+       {PN544_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE},
+       {PN544_RF_READER_NFCIP1_INITIATOR_GATE, NFC_HCI_INVALID_PIPE},
+       {PN544_RF_READER_NFCIP1_TARGET_GATE, NFC_HCI_INVALID_PIPE}
 };
 
 /* Largest headroom needed for outgoing custom commands */
@@ -849,10 +855,9 @@ static int __devinit pn544_hci_probe(struct i2c_client *client,
                goto err_rti;
        }
 
-       init_data.gate_count = ARRAY_SIZE(pn544_custom_gates);
+       init_data.gate_count = ARRAY_SIZE(pn544_gates);
 
-       memcpy(init_data.gates, pn544_custom_gates,
-              ARRAY_SIZE(pn544_custom_gates));
+       memcpy(init_data.gates, pn544_gates, sizeof(pn544_gates));
 
        /*
         * TODO: Session id must include the driver name + some bus addr
index d25dd9b998773d7157b8619c28e29e7c7e54856c..f5169b04f0829aa10a438fcfb33e336b4cc26f33 100644 (file)
@@ -44,10 +44,20 @@ struct nfc_hci_ops {
                              struct nfc_target *target);
 };
 
-#define NFC_HCI_MAX_CUSTOM_GATES       15
+/* Pipes */
+#define NFC_HCI_INVALID_PIPE   0x80
+#define NFC_HCI_LINK_MGMT_PIPE 0x00
+#define NFC_HCI_ADMIN_PIPE     0x01
+
+struct nfc_hci_gate {
+       u8 gate;
+       u8 pipe;
+};
+
+#define NFC_HCI_MAX_CUSTOM_GATES       50
 struct nfc_hci_init_data {
        u8 gate_count;
-       u8 gates[NFC_HCI_MAX_CUSTOM_GATES];
+       struct nfc_hci_gate gates[NFC_HCI_MAX_CUSTOM_GATES];
        char session_id[9];
 };
 
@@ -182,7 +192,8 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,
 void nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb);
 
 /* connecting to gates and sending hci instructions */
-int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate);
+int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
+                        u8 pipe);
 int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate);
 int nfc_hci_disconnect_all_gates(struct nfc_hci_dev *hdev);
 int nfc_hci_get_param(struct nfc_hci_dev *hdev, u8 gate, u8 idx,
index 12cd6f3f77ec8e088de0b268952ae4ee505a1cbc..46362ef979db1ca88b4ad69d4b6adb7bd440f844 100644 (file)
@@ -299,9 +299,9 @@ int nfc_hci_disconnect_all_gates(struct nfc_hci_dev *hdev)
 }
 EXPORT_SYMBOL(nfc_hci_disconnect_all_gates);
 
-int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate)
+int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate,
+                        u8 pipe)
 {
-       u8 pipe = NFC_HCI_INVALID_PIPE;
        bool pipe_created = false;
        int r;
 
@@ -310,6 +310,9 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate)
        if (hdev->gate2pipe[dest_gate] != NFC_HCI_INVALID_PIPE)
                return -EADDRINUSE;
 
+       if (pipe != NFC_HCI_INVALID_PIPE)
+               goto pipe_is_open;
+
        switch (dest_gate) {
        case NFC_HCI_LINK_MGMT_GATE:
                pipe = NFC_HCI_LINK_MGMT_PIPE;
@@ -335,6 +338,7 @@ 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;
index e6b2df3981b62fd5e88d4e9637c8669bcb153cb4..4ccc518f56ebf8f69b9ac718ada0dd7c16347dc3 100644 (file)
@@ -315,15 +315,15 @@ static void nfc_hci_cmd_timeout(unsigned long data)
 }
 
 static int hci_dev_connect_gates(struct nfc_hci_dev *hdev, u8 gate_count,
-                                u8 gates[])
+                                struct nfc_hci_gate *gates)
 {
        int r;
-       u8 *p = gates;
        while (gate_count--) {
-               r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, *p);
+               r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID,
+                                        gates->gate, gates->pipe);
                if (r < 0)
                        return r;
-               p++;
+               gates++;
        }
 
        return 0;
@@ -333,14 +333,13 @@ static int hci_dev_session_init(struct nfc_hci_dev *hdev)
 {
        struct sk_buff *skb = NULL;
        int r;
-       u8 hci_gates[] = {      /* NFC_HCI_ADMIN_GATE MUST be first */
-               NFC_HCI_ADMIN_GATE, NFC_HCI_LOOPBACK_GATE,
-               NFC_HCI_ID_MGMT_GATE, NFC_HCI_LINK_MGMT_GATE,
-               NFC_HCI_RF_READER_B_GATE, NFC_HCI_RF_READER_A_GATE
-       };
+
+       if (hdev->init_data.gates[0].gate != NFC_HCI_ADMIN_GATE)
+               return -EPROTO;
 
        r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID,
-                                NFC_HCI_ADMIN_GATE);
+                                hdev->init_data.gates[0].gate,
+                                hdev->init_data.gates[0].pipe);
        if (r < 0)
                goto exit;
 
@@ -368,10 +367,6 @@ static int hci_dev_session_init(struct nfc_hci_dev *hdev)
        if (r < 0)
                goto exit;
 
-       r = hci_dev_connect_gates(hdev, sizeof(hci_gates), hci_gates);
-       if (r < 0)
-               goto disconnect_all;
-
        r = hci_dev_connect_gates(hdev, hdev->init_data.gate_count,
                                  hdev->init_data.gates);
        if (r < 0)
index d3cde075ba608208b85c3c1bd6878e2057933c20..fa9a21e922396bd396dc11a3b9dd916282b39ef9 100644 (file)
@@ -132,9 +132,4 @@ void nfc_hci_hcp_message_rx(struct nfc_hci_dev *hdev, u8 pipe, u8 type,
 #define NFC_HCI_ANY_E_REG_ACCESS_DENIED                0x0a
 #define NFC_HCI_ANY_E_PIPE_ACCESS_DENIED       0x0b
 
-/* Pipes */
-#define NFC_HCI_INVALID_PIPE   0x80
-#define NFC_HCI_LINK_MGMT_PIPE 0x00
-#define NFC_HCI_ADMIN_PIPE     0x01
-
 #endif /* __LOCAL_HCI_H */