static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name) { struct nci_vs_nfcc_info_cmd *cmd; struct sk_buff *skb; unsigned long comp_ret; int rc; nfc_dev_dbg(&drv->pdev->dev, "get_bts_file_name entry"); skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd), GFP_KERNEL); if (!skb) { nfc_dev_err(&drv->pdev->dev, "no memory for nci_vs_nfcc_info_cmd"); return -ENOMEM; } cmd = (struct nci_vs_nfcc_info_cmd *) skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd)); cmd->gid = NCI_VS_NFCC_INFO_CMD_GID; cmd->oid = NCI_VS_NFCC_INFO_CMD_OID; cmd->plen = 0; drv->nfcc_info.plen = 0; rc = nfcwilink_send(drv->ndev, skb); if (rc) return rc; comp_ret = wait_for_completion_timeout(&drv->completed, msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld", comp_ret); if (comp_ret == 0) { nfc_dev_err(&drv->pdev->dev, "timeout on wait_for_completion_timeout"); return -ETIMEDOUT; } nfc_dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d", drv->nfcc_info.plen, drv->nfcc_info.status); if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) { nfc_dev_err(&drv->pdev->dev, "invalid nci_vs_nfcc_info_rsp"); return -EINVAL; } snprintf(file_name, BTS_FILE_NAME_MAX_SIZE, "TINfcInit_%d.%d.%d.%d.bts", drv->nfcc_info.hw_id, drv->nfcc_info.sw_ver_x, drv->nfcc_info.sw_ver_z, drv->nfcc_info.patch_id); nfc_dev_info(&drv->pdev->dev, "nfcwilink FW file name: %s", file_name); return 0; }
static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len) { struct nfcwilink_hdr *hdr = (struct nfcwilink_hdr *)data; struct sk_buff *skb; unsigned long comp_ret; int rc; nfc_dev_dbg(&drv->pdev->dev, "send_bts_cmd entry"); /* verify valid cmd for the NFC channel */ if ((len <= sizeof(struct nfcwilink_hdr)) || (len > BTS_FILE_CMD_MAX_LEN) || (hdr->chnl != NFCWILINK_CHNL) || (hdr->opcode != NFCWILINK_OPCODE)) { nfc_dev_err(&drv->pdev->dev, "ignoring invalid bts cmd, len %d, chnl %d, opcode %d", len, hdr->chnl, hdr->opcode); return 0; } /* remove the ST header */ len -= sizeof(struct nfcwilink_hdr); data += sizeof(struct nfcwilink_hdr); skb = nfcwilink_skb_alloc(len, GFP_KERNEL); if (!skb) { nfc_dev_err(&drv->pdev->dev, "no memory for bts cmd"); return -ENOMEM; } skb->dev = (void *)drv->ndev; memcpy(skb_put(skb, len), data, len); rc = nfcwilink_send(skb); if (rc) return rc; comp_ret = wait_for_completion_timeout(&drv->completed, msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld", comp_ret); if (comp_ret == 0) { nfc_dev_err(&drv->pdev->dev, "timeout on wait_for_completion_timeout"); return -ETIMEDOUT; } return 0; }