aboutsummaryrefslogtreecommitdiff
path: root/drivers/nfc/st21nfca
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/nfc/st21nfca')
-rw-r--r--drivers/nfc/st21nfca/i2c.c34
-rw-r--r--drivers/nfc/st21nfca/st21nfca.c59
-rw-r--r--drivers/nfc/st21nfca/st21nfca.h21
-rw-r--r--drivers/nfc/st21nfca/st21nfca_dep.c59
4 files changed, 72 insertions, 101 deletions
diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c
index ff31939978ae..0ea756b77519 100644
--- a/drivers/nfc/st21nfca/i2c.c
+++ b/drivers/nfc/st21nfca/i2c.c
@@ -271,6 +271,7 @@ static int st21nfca_hci_i2c_write(void *phy_id, struct sk_buff *skb)
static int get_frame_size(u8 *buf, int buflen)
{
int len = 0;
+
if (buf[len + 1] == ST21NFCA_SOF_EOF)
return 0;
@@ -311,6 +312,7 @@ static int check_crc(u8 *buf, int buflen)
static int st21nfca_hci_i2c_repack(struct sk_buff *skb)
{
int i, j, r, size;
+
if (skb->len < 1 || (skb->len > 1 && skb->data[1] != 0))
return -EBADMSG;
@@ -525,24 +527,19 @@ static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client)
}
/* GPIO request and configuration */
- r = devm_gpio_request(&client->dev, gpio, "clf_enable");
+ r = devm_gpio_request_one(&client->dev, gpio, GPIOF_OUT_INIT_HIGH,
+ "clf_enable");
if (r) {
nfc_err(&client->dev, "Failed to request enable pin\n");
return -ENODEV;
}
- r = gpio_direction_output(gpio, 1);
- if (r) {
- nfc_err(&client->dev, "Failed to set enable pin direction as output\n");
- return -ENODEV;
- }
phy->gpio_ena = gpio;
/* IRQ */
r = irq_of_parse_and_map(pp, 0);
if (r < 0) {
- nfc_err(&client->dev,
- "Unable to get irq, error: %d\n", r);
+ nfc_err(&client->dev, "Unable to get irq, error: %d\n", r);
return r;
}
@@ -576,32 +573,20 @@ static int st21nfca_hci_i2c_request_resources(struct i2c_client *client)
phy->gpio_ena = pdata->gpio_ena;
phy->irq_polarity = pdata->irq_polarity;
- r = devm_gpio_request(&client->dev, phy->gpio_irq, "wake_up");
+ r = devm_gpio_request_one(&client->dev, phy->gpio_irq, GPIOF_IN,
+ "wake_up");
if (r) {
pr_err("%s : gpio_request failed\n", __FILE__);
return -ENODEV;
}
- r = gpio_direction_input(phy->gpio_irq);
- if (r) {
- pr_err("%s : gpio_direction_input failed\n", __FILE__);
- return -ENODEV;
- }
-
if (phy->gpio_ena > 0) {
- r = devm_gpio_request(&client->dev,
- phy->gpio_ena, "clf_enable");
+ r = devm_gpio_request_one(&client->dev, phy->gpio_ena,
+ GPIOF_OUT_INIT_HIGH, "clf_enable");
if (r) {
pr_err("%s : ena gpio_request failed\n", __FILE__);
return -ENODEV;
}
- r = gpio_direction_output(phy->gpio_ena, 1);
-
- if (r) {
- pr_err("%s : ena gpio_direction_output failed\n",
- __FILE__);
- return -ENODEV;
- }
}
/* IRQ */
@@ -711,7 +696,6 @@ static struct i2c_driver st21nfca_hci_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = ST21NFCA_HCI_I2C_DRIVER_NAME,
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(of_st21nfca_i2c_match),
},
.probe = st21nfca_hci_i2c_probe,
diff --git a/drivers/nfc/st21nfca/st21nfca.c b/drivers/nfc/st21nfca/st21nfca.c
index a902b0551c86..a89e56c2c749 100644
--- a/drivers/nfc/st21nfca/st21nfca.c
+++ b/drivers/nfc/st21nfca/st21nfca.c
@@ -34,7 +34,7 @@
#define ST21NFCA_RF_READER_CMD_PRESENCE_CHECK 0x30
#define ST21NFCA_RF_READER_ISO15693_GATE 0x12
-#define ST21NFCA_RF_READER_ISO15693_INVENTORY 0x01
+#define ST21NFCA_RF_READER_ISO15693_INVENTORY 0x01
/*
* Reader gate for communication with contact-less cards using Type A
@@ -45,21 +45,42 @@
#define ST21NFCA_RF_READER_14443_3_A_ATQA 0x03
#define ST21NFCA_RF_READER_14443_3_A_SAK 0x04
+#define ST21NFCA_RF_READER_F_DATARATE 0x01
+#define ST21NFCA_RF_READER_F_DATARATE_106 0x01
+#define ST21NFCA_RF_READER_F_DATARATE_212 0x02
+#define ST21NFCA_RF_READER_F_DATARATE_424 0x04
+#define ST21NFCA_RF_READER_F_POL_REQ 0x02
+#define ST21NFCA_RF_READER_F_POL_REQ_DEFAULT 0xffff0000
+#define ST21NFCA_RF_READER_F_NFCID2 0x03
+#define ST21NFCA_RF_READER_F_NFCID1 0x04
+
+#define ST21NFCA_RF_CARD_F_MODE 0x01
+#define ST21NFCA_RF_CARD_F_NFCID2_LIST 0x04
+#define ST21NFCA_RF_CARD_F_NFCID1 0x05
+#define ST21NFCA_RF_CARD_F_SENS_RES 0x06
+#define ST21NFCA_RF_CARD_F_SEL_RES 0x07
+#define ST21NFCA_RF_CARD_F_DATARATE 0x08
+#define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01
+
#define ST21NFCA_DEVICE_MGNT_GATE 0x01
#define ST21NFCA_DEVICE_MGNT_PIPE 0x02
-#define ST21NFCA_DM_GETINFO 0x13
-#define ST21NFCA_DM_GETINFO_PIPE_LIST 0x02
-#define ST21NFCA_DM_GETINFO_PIPE_INFO 0x01
-#define ST21NFCA_DM_PIPE_CREATED 0x02
-#define ST21NFCA_DM_PIPE_OPEN 0x04
-#define ST21NFCA_DM_RF_ACTIVE 0x80
-#define ST21NFCA_DM_DISCONNECT 0x30
+#define ST21NFCA_DM_GETINFO 0x13
+#define ST21NFCA_DM_GETINFO_PIPE_LIST 0x02
+#define ST21NFCA_DM_GETINFO_PIPE_INFO 0x01
+#define ST21NFCA_DM_PIPE_CREATED 0x02
+#define ST21NFCA_DM_PIPE_OPEN 0x04
+#define ST21NFCA_DM_RF_ACTIVE 0x80
+#define ST21NFCA_DM_DISCONNECT 0x30
#define ST21NFCA_DM_IS_PIPE_OPEN(p) \
((p & 0x0f) == (ST21NFCA_DM_PIPE_CREATED | ST21NFCA_DM_PIPE_OPEN))
-#define ST21NFCA_NFC_MODE 0x03 /* NFC_MODE parameter*/
+#define ST21NFCA_NFC_MODE 0x03 /* NFC_MODE parameter*/
+#define ST21NFCA_EVT_FIELD_ON 0x11
+#define ST21NFCA_EVT_CARD_DEACTIVATED 0x12
+#define ST21NFCA_EVT_CARD_ACTIVATED 0x13
+#define ST21NFCA_EVT_FIELD_OFF 0x14
static DECLARE_BITMAP(dev_mask, ST21NFCA_NUM_DEVICES);
@@ -355,8 +376,8 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
if (r < 0)
return r;
- pol_req =
- be32_to_cpu(ST21NFCA_RF_READER_F_POL_REQ_DEFAULT);
+ pol_req = be32_to_cpu((__force __be32)
+ ST21NFCA_RF_READER_F_POL_REQ_DEFAULT);
r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
ST21NFCA_RF_READER_F_POL_REQ,
(u8 *) &pol_req, 4);
@@ -790,6 +811,7 @@ static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev,
struct nfc_target *target)
{
u8 fwi = 0x11;
+
switch (target->hci_reader_gate) {
case NFC_HCI_RF_READER_A_GATE:
case NFC_HCI_RF_READER_B_GATE:
@@ -839,20 +861,16 @@ static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 gate,
if (gate == ST21NFCA_RF_CARD_F_GATE) {
r = st21nfca_tm_event_send_data(hdev, skb, gate);
if (r < 0)
- goto exit;
+ return r;
return 0;
- } else {
- info->dep_info.curr_nfc_dep_pni = 0;
- return 1;
}
- break;
+ info->dep_info.curr_nfc_dep_pni = 0;
+ return 1;
default:
return 1;
}
kfree_skb(skb);
return 0;
-exit:
- return r;
}
static struct nfc_hci_ops st21nfca_hci_ops = {
@@ -904,8 +922,11 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
* persistent info to discriminate 2 identical chips
*/
dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES);
+
if (dev_num >= ST21NFCA_NUM_DEVICES)
- goto err_alloc_hdev;
+ return -ENODEV;
+
+ set_bit(dev_num, dev_mask);
scnprintf(init_data.session_id, sizeof(init_data.session_id), "%s%2x",
"ST21AH", dev_num);
diff --git a/drivers/nfc/st21nfca/st21nfca.h b/drivers/nfc/st21nfca/st21nfca.h
index 96fe5a62dc0d..a0b77f1ba6d9 100644
--- a/drivers/nfc/st21nfca/st21nfca.h
+++ b/drivers/nfc/st21nfca/st21nfca.h
@@ -82,30 +82,9 @@ struct st21nfca_hci_info {
#define ST21NFCA_WR_XCHG_DATA 0x10
#define ST21NFCA_RF_READER_F_GATE 0x14
-#define ST21NFCA_RF_READER_F_DATARATE 0x01
-#define ST21NFCA_RF_READER_F_DATARATE_106 0x01
-#define ST21NFCA_RF_READER_F_DATARATE_212 0x02
-#define ST21NFCA_RF_READER_F_DATARATE_424 0x04
-#define ST21NFCA_RF_READER_F_POL_REQ 0x02
-#define ST21NFCA_RF_READER_F_POL_REQ_DEFAULT 0xffff0000
-#define ST21NFCA_RF_READER_F_NFCID2 0x03
-#define ST21NFCA_RF_READER_F_NFCID1 0x04
-#define ST21NFCA_RF_READER_F_SENS_RES 0x05
#define ST21NFCA_RF_CARD_F_GATE 0x24
-#define ST21NFCA_RF_CARD_F_MODE 0x01
-#define ST21NFCA_RF_CARD_F_NFCID2_LIST 0x04
-#define ST21NFCA_RF_CARD_F_NFCID1 0x05
-#define ST21NFCA_RF_CARD_F_SENS_RES 0x06
-#define ST21NFCA_RF_CARD_F_SEL_RES 0x07
-#define ST21NFCA_RF_CARD_F_DATARATE 0x08
-#define ST21NFCA_RF_CARD_F_DATARATE_106 0x00
-#define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01
#define ST21NFCA_EVT_SEND_DATA 0x10
-#define ST21NFCA_EVT_FIELD_ON 0x11
-#define ST21NFCA_EVT_CARD_DEACTIVATED 0x12
-#define ST21NFCA_EVT_CARD_ACTIVATED 0x13
-#define ST21NFCA_EVT_FIELD_OFF 0x14
#endif /* __LOCAL_ST21NFCA_H_ */
diff --git a/drivers/nfc/st21nfca/st21nfca_dep.c b/drivers/nfc/st21nfca/st21nfca_dep.c
index b2d9957b57f8..bfb6df56c505 100644
--- a/drivers/nfc/st21nfca/st21nfca_dep.c
+++ b/drivers/nfc/st21nfca/st21nfca_dep.c
@@ -121,6 +121,7 @@ static void st21nfca_tx_work(struct work_struct *work)
struct nfc_dev *dev;
struct sk_buff *skb;
+
if (info) {
dev = info->hdev->ndev;
skb = info->dep_info.tx_pending;
@@ -128,9 +129,8 @@ static void st21nfca_tx_work(struct work_struct *work)
device_lock(&dev->dev);
nfc_hci_send_cmd_async(info->hdev, ST21NFCA_RF_READER_F_GATE,
- ST21NFCA_WR_XCHG_DATA,
- skb->data, skb->len,
- info->async_cb, info);
+ ST21NFCA_WR_XCHG_DATA, skb->data, skb->len,
+ info->async_cb, info);
device_unlock(&dev->dev);
kfree_skb(skb);
}
@@ -185,8 +185,10 @@ static int st21nfca_tm_send_atr_res(struct nfc_hci_dev *hdev,
info->dep_info.curr_nfc_dep_pni = 0;
- return nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
+ r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
+ kfree_skb(skb);
+ return r;
}
static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
@@ -197,10 +199,6 @@ static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
int r;
skb_trim(skb, skb->len - 1);
- if (IS_ERR(skb)) {
- r = PTR_ERR(skb);
- goto exit;
- }
if (!skb->len) {
r = -EIO;
@@ -214,6 +212,11 @@ static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
atr_req = (struct st21nfca_atr_req *)skb->data;
+ if (atr_req->length < sizeof(struct st21nfca_atr_req)) {
+ r = -EPROTO;
+ goto exit;
+ }
+
r = st21nfca_tm_send_atr_res(hdev, atr_req);
if (r)
goto exit;
@@ -237,7 +240,6 @@ static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
struct st21nfca_psl_res *psl_res;
struct sk_buff *skb;
u8 bitrate[2] = {0, 0};
-
int r;
skb = alloc_skb(sizeof(struct st21nfca_psl_res), GFP_KERNEL);
@@ -254,6 +256,8 @@ static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
+ if (r < 0)
+ goto error;
/*
* ST21NFCA only support P2P passive.
@@ -269,8 +273,11 @@ static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
}
/* Send an event to change bitrate change event to card f */
- return nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
+ r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
ST21NFCA_EVT_CARD_F_BITRATE, bitrate, 2);
+error:
+ kfree_skb(skb);
+ return r;
}
static int st21nfca_tm_recv_psl_req(struct nfc_hci_dev *hdev,
@@ -280,11 +287,6 @@ static int st21nfca_tm_recv_psl_req(struct nfc_hci_dev *hdev,
int r;
skb_trim(skb, skb->len - 1);
- if (IS_ERR(skb)) {
- r = PTR_ERR(skb);
- skb = NULL;
- goto exit;
- }
if (!skb->len) {
r = -EIO;
@@ -314,7 +316,7 @@ int st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb)
*skb_push(skb, 1) = skb->len;
r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
- ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
+ ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
kfree_skb(skb);
return r;
@@ -330,11 +332,6 @@ static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev,
struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
skb_trim(skb, skb->len - 1);
- if (IS_ERR(skb)) {
- r = PTR_ERR(skb);
- skb = NULL;
- goto exit;
- }
size = 4;
@@ -368,12 +365,6 @@ static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev,
break;
}
- if (IS_ERR(skb)) {
- r = PTR_ERR(skb);
- skb = NULL;
- goto exit;
- }
-
skb_pull(skb, size);
return nfc_tm_data_received(hdev->ndev, skb);
@@ -437,8 +428,6 @@ static void st21nfca_im_send_psl_req(struct nfc_hci_dev *hdev, u8 did, u8 bsi,
*skb_push(skb, 1) = info->dep_info.to | 0x10;
st21nfca_im_send_pdu(info, skb);
-
- kfree_skb(skb);
}
#define ST21NFCA_CB_TYPE_READER_F 1
@@ -452,7 +441,7 @@ static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
if (err != 0)
return;
- if (IS_ERR(skb))
+ if (!skb)
return;
switch (info->async_cb_type) {
@@ -484,8 +473,7 @@ static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
ST21NFCA_PP2LRI(atr_res->ppi));
break;
default:
- if (err == 0)
- kfree_skb(skb);
+ kfree_skb(skb);
break;
}
}
@@ -522,7 +510,7 @@ int st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len)
memset(atr_req->nfcid3, 0, NFC_NFCID3_MAXSIZE);
target = hdev->ndev->targets;
- if (target->sensf_res)
+ if (target->sensf_res_len > 0)
memcpy(atr_req->nfcid3, target->sensf_res,
target->sensf_res_len);
else
@@ -565,7 +553,7 @@ static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
if (err != 0)
return;
- if (IS_ERR(skb))
+ if (!skb)
return;
switch (info->async_cb_type) {
@@ -615,8 +603,7 @@ static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
}
exit:
- if (err == 0)
- kfree_skb(skb);
+ kfree_skb(skb);
}
int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb)