⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hci_usb.c

📁 S3CEB2410开发板中蓝牙设备开发.如果有对arm920T板子上开发蓝牙技术感兴趣
💻 C
📖 第 1 页 / 共 2 页
字号:
		}		/* Allocate skb */		if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {			ERR("Can't allocate mem for new packet");			return;		}		skb->dev = (void *) &husb->hdev;		skb->pkt_type = HCI_EVENT_PKT;		husb->intr_skb = skb;		husb->intr_count = len;	} else {		/* Continuation */		if (count > husb->intr_count) {			ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);			kfree_skb(skb);			husb->intr_skb = NULL;			husb->intr_count = 0;			return;		}	}	memcpy(skb_put(skb, count), data, count);	husb->intr_count -= count;	DMP(data, count);	if (!husb->intr_count) {		/* Got complete frame */		husb->hdev.stat.byte_rx += skb->len;		hci_recv_frame(skb);		husb->intr_skb = NULL;	}}static void hci_usb_bulk_read(struct urb *urb){	struct hci_usb *husb = (struct hci_usb *) urb->context;	unsigned char *data = urb->transfer_buffer;	int count = urb->actual_length, status;	struct sk_buff *skb;	hci_acl_hdr *ah;	register __u16 dlen;	if (!husb)		return;	DBG("%s status %d, count %d, flags %x", husb->hdev.name, urb->status, count, urb->transfer_flags);	if (urb->status) {		/* Do not re-submit URB on critical errors */		switch (urb->status) {			case -ENOENT:				return;			default:				goto resubmit;		};	}	if (!count)		goto resubmit;	DMP(data, count);	ah = (hci_acl_hdr *) data;	dlen = le16_to_cpu(ah->dlen);	/* Verify frame len and completeness */	if ((count - HCI_ACL_HDR_SIZE) != dlen) {		ERR("%s corrupted ACL packet: count %d, plen %d", husb->hdev.name, count, dlen);		goto resubmit;	}	/* Allocate packet */	if (!(skb = bluez_skb_alloc(count, GFP_ATOMIC))) {		ERR("Can't allocate mem for new packet");		goto resubmit;	}	memcpy(skb_put(skb, count), data, count);	skb->dev = (void *) &husb->hdev;	skb->pkt_type = HCI_ACLDATA_PKT;	husb->hdev.stat.byte_rx += skb->len;	hci_recv_frame(skb);resubmit:	husb->read_urb->dev = husb->udev;	if ((status = usb_submit_urb(husb->read_urb)))		DBG("%s read URB submit failed %d", husb->hdev.name, status);	DBG("%s read URB re-submited", husb->hdev.name);}static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb){	struct urb *urb = husb->ctrl_urb;	devrequest *dr  = &husb->dev_req;	int pipe, status;	DBG("%s len %d", husb->hdev.name, skb->len);	pipe = usb_sndctrlpipe(husb->udev, 0);	dr->requesttype = HCI_CTRL_REQ;	dr->request = 0;	dr->index   = 0;	dr->value   = 0;	dr->length  = cpu_to_le16(skb->len);	FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len,	                 hci_usb_ctrl, skb);	if ((status = usb_submit_urb(urb))) {		DBG("%s control URB submit failed %d", husb->hdev.name, status);		return status;	}	return 0;}static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb){	struct urb *urb = husb->write_urb;	int pipe, status;	DBG("%s len %d", husb->hdev.name, skb->len);	pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep_addr);	FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,	              hci_usb_bulk_write, skb);	urb->transfer_flags |= USB_QUEUE_BULK;	if ((status = usb_submit_urb(urb))) {		DBG("%s write URB submit failed %d", husb->hdev.name, status);		return status;	}	return 0;}static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id){	struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;	struct usb_interface_descriptor *uif;	struct usb_endpoint_descriptor *ep;	struct hci_usb *husb;	struct hci_dev *hdev;	int i, size, pipe;	__u8 * buf;	DBG("udev %p ifnum %d", udev, ifnum);	/* Check device signature */	if ((udev->descriptor.bDeviceClass    != HCI_DEV_CLASS)   ||	    (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||	    (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )		return NULL;	MOD_INC_USE_COUNT;	uif = &udev->actconfig->interface[ifnum].altsetting[0];	if (uif->bNumEndpoints != 3) {		DBG("Wrong number of endpoints %d", uif->bNumEndpoints);		MOD_DEC_USE_COUNT;		return NULL;	}	bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;	/* Find endpoints that we need */	for ( i = 0; i < uif->bNumEndpoints; ++i) {		ep = &uif->endpoint[i];		switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {			case USB_ENDPOINT_XFER_BULK:				if (ep->bEndpointAddress & USB_DIR_IN)					bulk_in_ep  = ep;				else					bulk_out_ep = ep;				break;			case USB_ENDPOINT_XFER_INT:				intr_in_ep = ep;				break;		};	}	if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {		DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);		MOD_DEC_USE_COUNT;		return NULL;	}	if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {		ERR("Can't allocate: control structure");		MOD_DEC_USE_COUNT;		return NULL;	}	memset(husb, 0, sizeof(struct hci_usb));	husb->udev = udev;	husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;	if (!(husb->ctrl_urb = usb_alloc_urb(0))) {		ERR("Can't allocate: control URB");		goto probe_error;	}	if (!(husb->write_urb = usb_alloc_urb(0))) {		ERR("Can't allocate: write URB");		goto probe_error;	}	if (!(husb->read_urb = usb_alloc_urb(0))) {		ERR("Can't allocate: read URB");		goto probe_error;	}	ep = bulk_in_ep;	pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);	size = HCI_MAX_FRAME_SIZE;	if (!(buf = kmalloc(size, GFP_KERNEL))) {		ERR("Can't allocate: read buffer");		goto probe_error;	}	FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);	husb->read_urb->transfer_flags |= USB_QUEUE_BULK;	ep = intr_in_ep;	pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);	size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));	if (!(husb->intr_urb = usb_alloc_urb(0))) {		ERR("Can't allocate: interrupt URB");		goto probe_error;	}	if (!(buf = kmalloc(size, GFP_KERNEL))) {		ERR("Can't allocate: interrupt buffer");		goto probe_error;	}	FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);	skb_queue_head_init(&husb->tx_ctrl_q);	skb_queue_head_init(&husb->tx_write_q);	/* Initialize and register HCI device */	hdev = &husb->hdev;	hdev->type = HCI_USB;	hdev->driver_data = husb;	hdev->open  = hci_usb_open;	hdev->close = hci_usb_close;	hdev->flush = hci_usb_flush;	hdev->send	= hci_usb_send_frame;	if (hci_register_dev(hdev) < 0) {		ERR("Can't register HCI device %s", hdev->name);		goto probe_error;	}	return husb;probe_error:	hci_usb_free_bufs(husb);	kfree(husb);	MOD_DEC_USE_COUNT;	return NULL;}static void hci_usb_disconnect(struct usb_device *udev, void *ptr){	struct hci_usb *husb = (struct hci_usb *) ptr;	struct hci_dev *hdev = &husb->hdev;	if (!husb)		return;	DBG("%s", hdev->name);	hci_usb_close(hdev);	if (hci_unregister_dev(hdev) < 0) {		ERR("Can't unregister HCI device %s", hdev->name);	}	hci_usb_free_bufs(husb);	kfree(husb);	MOD_DEC_USE_COUNT;}static struct usb_driver hci_usb_driver ={	name:           "hci_usb",	probe:          hci_usb_probe,	disconnect:     hci_usb_disconnect,	id_table:       usb_bluetooth_ids,};int hci_usb_init(void){	int err;	INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  		VERSION);	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");	if ((err = usb_register(&hci_usb_driver)) < 0)		ERR("Failed to register HCI USB driver");	return err;}void hci_usb_cleanup(void){	usb_deregister(&hci_usb_driver);}module_init(hci_usb_init);module_exit(hci_usb_cleanup);MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");MODULE_DESCRIPTION("BlueZ HCI USB driver ver " VERSION);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -