예제 #1
0
파일: core.c 프로젝트: AlexShiLucky/linux
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;
}
예제 #2
0
파일: pn544.c 프로젝트: bjayesh/chandra
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;
}
예제 #3
0
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(&microread_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;
}
예제 #4
0
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;
}