diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c index ec50027b0d8ba327b5b125249e1fdc142426b7e9..d5784a47fc1309387d4862f65840f3b4765f065b 100644 --- a/drivers/nfc/fdp/fdp.c +++ b/drivers/nfc/fdp/fdp.c @@ -726,7 +726,7 @@ static struct nci_driver_ops fdp_prop_ops[] = { }, }; -struct nci_ops nci_ops = { +static struct nci_ops nci_ops = { .open = fdp_nci_open, .close = fdp_nci_close, .send = fdp_nci_send, diff --git a/drivers/nfc/microread/i2c.c b/drivers/nfc/microread/i2c.c index b668b7b9a61e7ea097addd0263c3aa3531e6a0cd..1806d20a5e298784b03d637a30c218e1d02f6569 100644 --- a/drivers/nfc/microread/i2c.c +++ b/drivers/nfc/microread/i2c.c @@ -294,7 +294,7 @@ static int microread_i2c_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id microread_i2c_id[] = { +static const struct i2c_device_id microread_i2c_id[] = { { MICROREAD_I2C_DRIVER_NAME, 0}, { } }; diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c index ffec103702f14c1db74092f511661869d463fba6..0f22379887ca8cb86c43d87b2880a7b9b0bf3791 100644 --- a/drivers/nfc/nfcmrvl/i2c.c +++ b/drivers/nfc/nfcmrvl/i2c.c @@ -266,7 +266,7 @@ static const struct of_device_id of_nfcmrvl_i2c_match[] = { }; MODULE_DEVICE_TABLE(of, of_nfcmrvl_i2c_match); -static struct i2c_device_id nfcmrvl_i2c_id_table[] = { +static const struct i2c_device_id nfcmrvl_i2c_id_table[] = { { "nfcmrvl_i2c", 0 }, {} }; diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c index 198585bbc7711275d53a656aaf2eca12563db8e2..ba695e392c3b7b1c4d85c9e877d1234c23502caf 100644 --- a/drivers/nfc/nxp-nci/i2c.c +++ b/drivers/nfc/nxp-nci/i2c.c @@ -393,7 +393,7 @@ static int nxp_nci_i2c_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id nxp_nci_i2c_id_table[] = { +static const struct i2c_device_id nxp_nci_i2c_id_table[] = { {"nxp-nci_i2c", 0}, {} }; diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c index 8f60ce039b0d43191cf9921877564aa920a5abfd..4389eb4c8d0b3cbead89b907986a6a90b17cc1cf 100644 --- a/drivers/nfc/pn533/i2c.c +++ b/drivers/nfc/pn533/i2c.c @@ -264,7 +264,7 @@ static const struct of_device_id of_pn533_i2c_match[] = { }; MODULE_DEVICE_TABLE(of, of_pn533_i2c_match); -static struct i2c_device_id pn533_i2c_id_table[] = { +static const struct i2c_device_id pn533_i2c_id_table[] = { { PN533_I2C_DRIVER_NAME, 0 }, {} }; diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index 4b14740edb672c734239eb4c26282c036009d415..d0207f8e68b7c8760d3f93c8d54a5295ae65f432 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c @@ -54,7 +54,7 @@ #define PN544_HCI_I2C_LLC_MAX_SIZE (PN544_HCI_I2C_LLC_LEN_CRC + 1 + \ PN544_HCI_I2C_LLC_MAX_PAYLOAD) -static struct i2c_device_id pn544_hci_i2c_id_table[] = { +static const struct i2c_device_id pn544_hci_i2c_id_table[] = { {"pn544", 0}, {} }; diff --git a/drivers/nfc/s3fwrn5/firmware.c b/drivers/nfc/s3fwrn5/firmware.c index 38548bd970cd2aa738a916ab198ee3456b0e9cfe..b7828fb252f272da04e4845211d88a8d37764eb0 100644 --- a/drivers/nfc/s3fwrn5/firmware.c +++ b/drivers/nfc/s3fwrn5/firmware.c @@ -336,7 +336,7 @@ static int s3fwrn5_fw_get_base_addr( struct s3fwrn5_fw_cmd_get_bootinfo_rsp *bootinfo, u32 *base_addr) { int i; - struct { + static const struct { u8 version[4]; u32 base_addr; } match[] = { diff --git a/drivers/nfc/s3fwrn5/i2c.c b/drivers/nfc/s3fwrn5/i2c.c index 3f09d7fd2285f3e727e9ea448fed49b72fcadaa5..4da409e77a72e32bc3442bf36c2a70c5f22db0d6 100644 --- a/drivers/nfc/s3fwrn5/i2c.c +++ b/drivers/nfc/s3fwrn5/i2c.c @@ -276,7 +276,7 @@ static int s3fwrn5_i2c_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id s3fwrn5_i2c_id_table[] = { +static const struct i2c_device_id s3fwrn5_i2c_id_table[] = { {S3FWRN5_I2C_DRIVER_NAME, 0}, {} }; diff --git a/drivers/nfc/st-nci/i2c.c b/drivers/nfc/st-nci/i2c.c index 515f08d037fb40c0656dd07808c67e6ffffc1f0e..f9525ef87d57a7b163051c0305400cfa0b3e0088 100644 --- a/drivers/nfc/st-nci/i2c.c +++ b/drivers/nfc/st-nci/i2c.c @@ -279,7 +279,7 @@ static int st_nci_i2c_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id st_nci_i2c_id_table[] = { +static const struct i2c_device_id st_nci_i2c_id_table[] = { {ST_NCI_DRIVER_NAME, 0}, {} }; diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index cd1f7bfa75ebe3a75f5577d33cc162fdfacfa8c1..1b347096422ff2d4c9d0933682c79ef89fe86d01 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c @@ -589,7 +589,7 @@ static int st21nfca_hci_i2c_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id st21nfca_hci_i2c_id_table[] = { +static const struct i2c_device_id st21nfca_hci_i2c_id_table[] = { {ST21NFCA_HCI_DRIVER_NAME, 0}, {} }; diff --git a/include/uapi/linux/nfc.h b/include/uapi/linux/nfc.h index 399f39ff8048da02844b0fa81a918714d043cdf5..f6e3c8c9c7449ad6b98623d034128e03a3c9e651 100644 --- a/include/uapi/linux/nfc.h +++ b/include/uapi/linux/nfc.h @@ -89,6 +89,7 @@ * @NFC_CMD_ACTIVATE_TARGET: Request NFC controller to reactivate target. * @NFC_CMD_VENDOR: Vendor specific command, to be implemented directly * from the driver in order to support hardware specific operations. + * @NFC_CMD_DEACTIVATE_TARGET: Request NFC controller to deactivate target. */ enum nfc_commands { NFC_CMD_UNSPEC, @@ -121,6 +122,7 @@ enum nfc_commands { NFC_CMD_SE_IO, NFC_CMD_ACTIVATE_TARGET, NFC_CMD_VENDOR, + NFC_CMD_DEACTIVATE_TARGET, /* private: internal use only */ __NFC_CMD_AFTER_LAST }; diff --git a/net/nfc/core.c b/net/nfc/core.c index e5e23c2cbe74417359ca20d56c4d8289df25caa8..947a470f929d601b384caf9e00940a6b08d27343 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -1015,9 +1015,9 @@ static void nfc_check_pres_work(struct work_struct *work) device_unlock(&dev->dev); } -static void nfc_check_pres_timeout(unsigned long data) +static void nfc_check_pres_timeout(struct timer_list *t) { - struct nfc_dev *dev = (struct nfc_dev *)data; + struct nfc_dev *dev = from_timer(dev, t, check_pres_timer); schedule_work(&dev->check_pres_work); } @@ -1094,9 +1094,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, dev->targets_generation = 1; if (ops->check_presence) { - setup_timer(&dev->check_pres_timer, nfc_check_pres_timeout, - (unsigned long)dev); - + timer_setup(&dev->check_pres_timer, nfc_check_pres_timeout, 0); INIT_WORK(&dev->check_pres_work, nfc_check_pres_work); } @@ -1105,7 +1103,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, err_free_dev: kfree(dev); - return ERR_PTR(rc); + return NULL; } EXPORT_SYMBOL(nfc_allocate_device); diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c index de6dd37d04c7065b9eb9f5186f735136048be335..ec0a8998e52dc0f3c6124039aaeee4b0ca5eaeb2 100644 --- a/net/nfc/digital_core.c +++ b/net/nfc/digital_core.c @@ -650,6 +650,7 @@ static void digital_deactivate_target(struct nfc_dev *nfc_dev, return; } + digital_abort_cmd(ddev); ddev->curr_protocol = 0; } diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c index a8a6e7814e0918916553232a469db99735d6869c..ac8030c4bcf8638f7b77873f21285c88795a62f4 100644 --- a/net/nfc/hci/core.c +++ b/net/nfc/hci/core.c @@ -428,9 +428,9 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, nfc_hci_driver_failure(hdev, r); } -static void nfc_hci_cmd_timeout(unsigned long data) +static void nfc_hci_cmd_timeout(struct timer_list *t) { - struct nfc_hci_dev *hdev = (struct nfc_hci_dev *)data; + struct nfc_hci_dev *hdev = from_timer(hdev, t, cmd_timer); schedule_work(&hdev->msg_tx_work); } @@ -1004,8 +1004,7 @@ int nfc_hci_register_device(struct nfc_hci_dev *hdev) INIT_WORK(&hdev->msg_tx_work, nfc_hci_msg_tx_work); - setup_timer(&hdev->cmd_timer, nfc_hci_cmd_timeout, - (unsigned long)hdev); + timer_setup(&hdev->cmd_timer, nfc_hci_cmd_timeout, 0); skb_queue_head_init(&hdev->rx_hcp_frags); diff --git a/net/nfc/hci/llc_shdlc.c b/net/nfc/hci/llc_shdlc.c index 58df37eae1e89cb6b7da4d4ed7d7cd7e5c2ba1e5..fe988936ad923ae7fac6355a3204ad9c127704d4 100644 --- a/net/nfc/hci/llc_shdlc.c +++ b/net/nfc/hci/llc_shdlc.c @@ -580,27 +580,27 @@ static void llc_shdlc_handle_send_queue(struct llc_shdlc *shdlc) } } -static void llc_shdlc_connect_timeout(unsigned long data) +static void llc_shdlc_connect_timeout(struct timer_list *t) { - struct llc_shdlc *shdlc = (struct llc_shdlc *)data; + struct llc_shdlc *shdlc = from_timer(shdlc, t, connect_timer); pr_debug("\n"); schedule_work(&shdlc->sm_work); } -static void llc_shdlc_t1_timeout(unsigned long data) +static void llc_shdlc_t1_timeout(struct timer_list *t) { - struct llc_shdlc *shdlc = (struct llc_shdlc *)data; + struct llc_shdlc *shdlc = from_timer(shdlc, t, t1_timer); pr_debug("SoftIRQ: need to send ack\n"); schedule_work(&shdlc->sm_work); } -static void llc_shdlc_t2_timeout(unsigned long data) +static void llc_shdlc_t2_timeout(struct timer_list *t) { - struct llc_shdlc *shdlc = (struct llc_shdlc *)data; + struct llc_shdlc *shdlc = from_timer(shdlc, t, t2_timer); pr_debug("SoftIRQ: need to retransmit\n"); @@ -763,14 +763,9 @@ static void *llc_shdlc_init(struct nfc_hci_dev *hdev, xmit_to_drv_t xmit_to_drv, mutex_init(&shdlc->state_mutex); shdlc->state = SHDLC_DISCONNECTED; - setup_timer(&shdlc->connect_timer, llc_shdlc_connect_timeout, - (unsigned long)shdlc); - - setup_timer(&shdlc->t1_timer, llc_shdlc_t1_timeout, - (unsigned long)shdlc); - - setup_timer(&shdlc->t2_timer, llc_shdlc_t2_timeout, - (unsigned long)shdlc); + timer_setup(&shdlc->connect_timer, llc_shdlc_connect_timeout, 0); + timer_setup(&shdlc->t1_timer, llc_shdlc_t1_timeout, 0); + timer_setup(&shdlc->t2_timer, llc_shdlc_t2_timeout, 0); shdlc->w = SHDLC_MAX_WINDOW; shdlc->srej_support = SHDLC_SREJ_SUPPORT; diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index 7988185072e5f308528b9a7b1093d6e419428ec8..ef4026a23e802eba74c3269617b8aeb4f68e97ca 100644 --- a/net/nfc/llcp_core.c +++ b/net/nfc/llcp_core.c @@ -242,9 +242,9 @@ static void nfc_llcp_timeout_work(struct work_struct *work) nfc_dep_link_down(local->dev); } -static void nfc_llcp_symm_timer(unsigned long data) +static void nfc_llcp_symm_timer(struct timer_list *t) { - struct nfc_llcp_local *local = (struct nfc_llcp_local *) data; + struct nfc_llcp_local *local = from_timer(local, t, link_timer); pr_err("SYMM timeout\n"); @@ -285,9 +285,9 @@ static void nfc_llcp_sdreq_timeout_work(struct work_struct *work) nfc_genl_llc_send_sdres(local->dev, &nl_sdres_list); } -static void nfc_llcp_sdreq_timer(unsigned long data) +static void nfc_llcp_sdreq_timer(struct timer_list *t) { - struct nfc_llcp_local *local = (struct nfc_llcp_local *) data; + struct nfc_llcp_local *local = from_timer(local, t, sdreq_timer); schedule_work(&local->sdreq_timeout_work); } @@ -1573,8 +1573,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) INIT_LIST_HEAD(&local->list); kref_init(&local->ref); mutex_init(&local->sdp_lock); - setup_timer(&local->link_timer, nfc_llcp_symm_timer, - (unsigned long)local); + timer_setup(&local->link_timer, nfc_llcp_symm_timer, 0); skb_queue_head_init(&local->tx_queue); INIT_WORK(&local->tx_work, nfc_llcp_tx_work); @@ -1600,8 +1599,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) mutex_init(&local->sdreq_lock); INIT_HLIST_HEAD(&local->pending_sdreqs); - setup_timer(&local->sdreq_timer, nfc_llcp_sdreq_timer, - (unsigned long)local); + timer_setup(&local->sdreq_timer, nfc_llcp_sdreq_timer, 0); INIT_WORK(&local->sdreq_timeout_work, nfc_llcp_sdreq_timeout_work); list_add(&local->list, &llcp_devices); diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index b251fb936a27a9632c55d5aa91c1dbd2fa543ffa..f6359c277212518d7725b0b91978500b244f4da8 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -928,6 +928,30 @@ static int nfc_genl_activate_target(struct sk_buff *skb, struct genl_info *info) return rc; } +static int nfc_genl_deactivate_target(struct sk_buff *skb, + struct genl_info *info) +{ + struct nfc_dev *dev; + u32 device_idx, target_idx; + int rc; + + if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) + return -EINVAL; + + device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); + + dev = nfc_get_device(device_idx); + if (!dev) + return -ENODEV; + + target_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]); + + rc = nfc_deactivate_target(dev, target_idx, NFC_TARGET_MODE_SLEEP); + + nfc_put_device(dev); + return rc; +} + static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info) { struct nfc_dev *dev; @@ -1751,6 +1775,11 @@ static const struct genl_ops nfc_genl_ops[] = { .doit = nfc_genl_vendor_cmd, .policy = nfc_genl_policy, }, + { + .cmd = NFC_CMD_DEACTIVATE_TARGET, + .doit = nfc_genl_deactivate_target, + .policy = nfc_genl_policy, + }, }; static struct genl_family nfc_genl_family __ro_after_init = {