int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, int phy_headroom, int phy_tailroom, int phy_payload, struct nfc_hci_dev **hdev, struct st21nfca_se_status *se_status) { struct st21nfca_hci_info *info; int r = 0; int dev_num; u32 protocols; struct nfc_hci_init_data init_data; unsigned long quirks = 0; info = kzalloc(sizeof(struct st21nfca_hci_info), GFP_KERNEL); if (!info) return -ENOMEM; info->phy_ops = phy_ops; info->phy_id = phy_id; info->state = ST21NFCA_ST_COLD; mutex_init(&info->info_lock); init_data.gate_count = ARRAY_SIZE(st21nfca_gates); memcpy(init_data.gates, st21nfca_gates, sizeof(st21nfca_gates)); /* * Session id must include the driver name + i2c bus addr * persistent info to discriminate 2 identical chips */ dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES); if (dev_num >= ST21NFCA_NUM_DEVICES) { r = -ENODEV; goto err_alloc_hdev; } set_bit(dev_num, dev_mask); scnprintf(init_data.session_id, sizeof(init_data.session_id), "%s%2x", "ST21AH", dev_num); protocols = NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK | NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK; set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks); info->hdev = nfc_hci_allocate_device(&st21nfca_hci_ops, &init_data, quirks, protocols, llc_name, phy_headroom + ST21NFCA_CMDS_HEADROOM, phy_tailroom, phy_payload); if (!info->hdev) { pr_err("Cannot allocate nfc hdev.\n"); r = -ENOMEM; goto err_alloc_hdev; } info->se_status = se_status; nfc_hci_set_clientdata(info->hdev, info); r = nfc_hci_register_device(info->hdev); if (r) goto err_regdev; *hdev = info->hdev; st21nfca_dep_init(info->hdev); st21nfca_se_init(info->hdev); st21nfca_vendor_cmds_init(info->hdev); return 0; err_regdev: nfc_hci_free_device(info->hdev); err_alloc_hdev: kfree(info); return r; }
int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, int phy_headroom, int phy_tailroom, int phy_payload, fw_download_t fw_download, struct nfc_hci_dev **hdev) { struct pn544_hci_info *info; u32 protocols; struct nfc_hci_init_data init_data; int r; info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL); if (!info) { pr_err("Cannot allocate memory for pn544_hci_info.\n"); r = -ENOMEM; goto err_info_alloc; } info->phy_ops = phy_ops; info->phy_id = phy_id; info->fw_download = fw_download; info->state = PN544_ST_COLD; mutex_init(&info->info_lock); init_data.gate_count = ARRAY_SIZE(pn544_gates); memcpy(init_data.gates, pn544_gates, sizeof(pn544_gates)); /* * TODO: Session id must include the driver name + some bus addr * persistent info to discriminate 2 identical chips */ strcpy(init_data.session_id, "ID544HCI"); protocols = NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK | NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_NFC_DEP_MASK; info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, 0, protocols, llc_name, phy_headroom + PN544_CMDS_HEADROOM, phy_tailroom, phy_payload); if (!info->hdev) { pr_err("Cannot allocate nfc hdev.\n"); r = -ENOMEM; goto err_alloc_hdev; } nfc_hci_set_clientdata(info->hdev, info); r = nfc_hci_register_device(info->hdev); if (r) goto err_regdev; *hdev = info->hdev; return 0; err_regdev: nfc_hci_free_device(info->hdev); err_alloc_hdev: kfree(info); err_info_alloc: return r; }
int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, int phy_headroom, int phy_tailroom, int phy_payload, struct nfc_hci_dev **hdev) { struct microread_info *info; unsigned long quirks = 0; u32 protocols; struct nfc_hci_init_data init_data; int r; info = kzalloc(sizeof(struct microread_info), GFP_KERNEL); if (!info) { pr_err("Cannot allocate memory for microread_info.\n"); r = -ENOMEM; goto err_info_alloc; } info->phy_ops = phy_ops; info->phy_id = phy_id; init_data.gate_count = ARRAY_SIZE(microread_gates); memcpy(init_data.gates, microread_gates, sizeof(microread_gates)); strcpy(init_data.session_id, "MICROREA"); set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks); protocols = NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK | NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_NFC_DEP_MASK; info->hdev = nfc_hci_allocate_device(µread_hci_ops, &init_data, quirks, protocols, llc_name, phy_headroom + MICROREAD_CMDS_HEADROOM, phy_tailroom + MICROREAD_CMD_TAILROOM, phy_payload); if (!info->hdev) { pr_err("Cannot allocate nfc hdev.\n"); r = -ENOMEM; goto err_alloc_hdev; } nfc_hci_set_clientdata(info->hdev, info); r = nfc_hci_register_device(info->hdev); if (r) goto err_regdev; *hdev = info->hdev; return 0; err_regdev: nfc_hci_free_device(info->hdev); err_alloc_hdev: kfree(info); err_info_alloc: return r; }
struct nfc_shdlc *nfc_shdlc_allocate(struct nfc_shdlc_ops *ops, struct nfc_hci_init_data *init_data, u32 protocols, int tx_headroom, int tx_tailroom, int max_link_payload, const char *devname) { struct nfc_shdlc *shdlc; int r; char name[32]; if (ops->xmit == NULL) return NULL; shdlc = kzalloc(sizeof(struct nfc_shdlc), GFP_KERNEL); if (shdlc == NULL) return NULL; mutex_init(&shdlc->state_mutex); shdlc->ops = ops; shdlc->state = SHDLC_DISCONNECTED; init_timer(&shdlc->connect_timer); shdlc->connect_timer.data = (unsigned long)shdlc; shdlc->connect_timer.function = nfc_shdlc_connect_timeout; init_timer(&shdlc->t1_timer); shdlc->t1_timer.data = (unsigned long)shdlc; shdlc->t1_timer.function = nfc_shdlc_t1_timeout; init_timer(&shdlc->t2_timer); shdlc->t2_timer.data = (unsigned long)shdlc; shdlc->t2_timer.function = nfc_shdlc_t2_timeout; shdlc->w = SHDLC_MAX_WINDOW; shdlc->srej_support = SHDLC_SREJ_SUPPORT; skb_queue_head_init(&shdlc->rcv_q); skb_queue_head_init(&shdlc->send_q); skb_queue_head_init(&shdlc->ack_pending_q); INIT_WORK(&shdlc->sm_work, nfc_shdlc_sm_work); snprintf(name, sizeof(name), "%s_shdlc_sm_wq", devname); shdlc->sm_wq = alloc_workqueue(name, WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); if (shdlc->sm_wq == NULL) goto err_allocwq; shdlc->client_headroom = tx_headroom; shdlc->client_tailroom = tx_tailroom; shdlc->hdev = nfc_hci_allocate_device(&shdlc_ops, init_data, protocols, tx_headroom + SHDLC_LLC_HEAD_ROOM, tx_tailroom + SHDLC_LLC_TAIL_ROOM, max_link_payload); if (shdlc->hdev == NULL) goto err_allocdev; nfc_hci_set_clientdata(shdlc->hdev, shdlc); r = nfc_hci_register_device(shdlc->hdev); if (r < 0) goto err_regdev; return shdlc; err_regdev: nfc_hci_free_device(shdlc->hdev); err_allocdev: destroy_workqueue(shdlc->sm_wq); err_allocwq: kfree(shdlc); return NULL; }