NFC: Add HCI quirks to support driver (non)standard implementations
authorEric Lapuyade <eric.lapuyade@linux.intel.com>
Tue, 18 Dec 2012 13:15:49 +0000 (14:15 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Wed, 9 Jan 2013 23:51:51 +0000 (00:51 +0100)
Some chips diverge from the HCI spec in their implementation of standard
features. This adds a new quirks parameter to
nfc_hci_allocate_device() to let the driver indicate its divergence.

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

index cd8fb16f5416dc9e238833a650cbc19625a8df36..ece8342398525c2cbb5ae6aec16409fe637ccb9f 100644 (file)
@@ -833,7 +833,7 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
                    NFC_PROTO_ISO14443_B_MASK |
                    NFC_PROTO_NFC_DEP_MASK;
 
-       info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data,
+       info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, 0,
                                             protocols, llc_name,
                                             phy_headroom + PN544_CMDS_HEADROOM,
                                             phy_tailroom, phy_payload);
index 834e36481afff556a363f18fb895eff36459c9e4..2ff71750c4280dafda7d3736fb07e094c7eee586 100644 (file)
@@ -82,6 +82,16 @@ typedef int (*xmit) (struct sk_buff *skb, void *cb_data);
 
 #define NFC_HCI_MAX_GATES              256
 
+/*
+ * These values can be specified by a driver to indicate it requires some
+ * adaptation of the HCI standard.
+ *
+ * NFC_HCI_QUIRK_SHORT_CLEAR - send HCI_ADM_CLEAR_ALL_PIPE cmd with no params
+ */
+enum {
+       NFC_HCI_QUIRK_SHORT_CLEAR       = 0,
+};
+
 struct nfc_hci_dev {
        struct nfc_dev *ndev;
 
@@ -131,11 +141,14 @@ struct nfc_hci_dev {
 
        u8 *gb;
        size_t gb_len;
+
+       unsigned long quirks;
 };
 
 /* hci device allocation */
 struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops,
                                            struct nfc_hci_init_data *init_data,
+                                           unsigned long quirks,
                                            u32 protocols,
                                            const char *llc_name,
                                            int tx_headroom,
index 7d99410e6c1a542d91795a40f5e9d8bf9e719c5f..64f922be928127d8837899ae081044b48190447f 100644 (file)
@@ -280,14 +280,19 @@ 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)
 {
        u8 param[2];
+       size_t param_len = 2;
 
        /* TODO: Find out what the identity reference data is
         * and fill param with it. HCI spec 6.1.3.5 */
 
        pr_debug("\n");
 
+       if (test_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &hdev->quirks))
+               param_len = 0;
+
        return nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE,
-                                  NFC_HCI_ADM_CLEAR_ALL_PIPE, param, 2, NULL);
+                                  NFC_HCI_ADM_CLEAR_ALL_PIPE, param, param_len,
+                                  NULL);
 }
 
 int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate)
index d9190da4a403fa36ce5c6ef6dc86b9c9dbb6ecc8..755a6b9774ab911daa887be5dedb74183733d230 100644 (file)
@@ -795,6 +795,7 @@ static struct nfc_ops hci_nfc_ops = {
 
 struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops,
                                            struct nfc_hci_init_data *init_data,
+                                           unsigned long quirks,
                                            u32 protocols,
                                            const char *llc_name,
                                            int tx_headroom,
@@ -838,6 +839,8 @@ struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops,
 
        memset(hdev->gate2pipe, NFC_HCI_INVALID_PIPE, sizeof(hdev->gate2pipe));
 
+       hdev->quirks = quirks;
+
        return hdev;
 }
 EXPORT_SYMBOL(nfc_hci_allocate_device);