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

📄 bluetty.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		goto exit;	}	if (!count) {		dbg("%s - zero length read bulk", __FUNCTION__);		goto exit;	}#ifdef DEBUG	if (count) {		printk (KERN_DEBUG __FILE__ ": %s- length = %d, data = ", __FUNCTION__, count);		for (i = 0; i < count; ++i) {			printk ("%.2x ", data[i]);		}		printk ("\n");	}#endif#ifdef BTBUGGYHARDWARE	if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00)	    && (data[2] == 0x00) && (data[3] == 0x00)) {		urb->actual_length = 0;		usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, 			      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),			      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 			      bluetooth_read_bulk_callback, bluetooth);		result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);		if (result)			err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);		return;	}#endif	/* We add  a packet type identifier to the beginning of each	   HCI frame.  This makes the data in the tty look like a	   serial USB devices.  Each HCI frame can be broken across	   multiple URBs so we buffer them until we have a full hci	   packet */		if (!bluetooth->bulk_packet_pos) {		bluetooth->bulk_buffer[0] = ACL_PKT;		bluetooth->bulk_packet_pos++;	}	if (bluetooth->bulk_packet_pos + count > ACL_BUFFER_SIZE) {		err("%s - exceeded ACL_BUFFER_SIZE", __FUNCTION__);		bluetooth->bulk_packet_pos = 0;		goto exit;	}	memcpy (&bluetooth->bulk_buffer[bluetooth->bulk_packet_pos],		urb->transfer_buffer, count);	bluetooth->bulk_packet_pos += count;	urb->actual_length = 0;	if (bluetooth->bulk_packet_pos >= ACL_HDR_SIZE) {		packet_size = CHAR2INT16(bluetooth->bulk_buffer[4],bluetooth->bulk_buffer[3]);	} else {		goto exit;	}	if (packet_size + ACL_HDR_SIZE < bluetooth->bulk_packet_pos) {		err("%s - packet was too long", __FUNCTION__);		bluetooth->bulk_packet_pos = 0;		goto exit;	}	if (packet_size + ACL_HDR_SIZE == bluetooth->bulk_packet_pos) {		for (i = 0; i < bluetooth->bulk_packet_pos; ++i) {			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */			if (bluetooth->tty->flip.count >= TTY_FLIPBUF_SIZE) {				tty_flip_buffer_push(bluetooth->tty);			}			tty_insert_flip_char(bluetooth->tty, bluetooth->bulk_buffer[i], 0);		}		tty_flip_buffer_push(bluetooth->tty);		bluetooth->bulk_packet_pos = 0;	}	exit:	if (!bluetooth || !bluetooth->open_count)		return;	usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, 		      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),		      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 		      bluetooth_read_bulk_callback, bluetooth);	result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);	if (result)		err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);	return;}static void bluetooth_write_bulk_callback (struct urb *urb, struct pt_regs *regs){	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);	dbg("%s", __FUNCTION__);	/* free up the transfer buffer, as usb_free_urb() does not do this */	kfree(urb->transfer_buffer);	if (!bluetooth) {		dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__);		return;	}	if (urb->status) {		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);		return;	}	/* wake up our little function to let the tty layer know that something happened */	schedule_work(&bluetooth->work);}static void bluetooth_softint(void *private){	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)private, __FUNCTION__);	dbg("%s", __FUNCTION__);	if (!bluetooth)		return;	tty_wakeup(bluetooth->tty);}static int usb_bluetooth_probe (struct usb_interface *intf, 				const struct usb_device_id *id){	struct usb_device *dev = interface_to_usbdev (intf);	struct usb_bluetooth *bluetooth = NULL;	struct usb_host_interface *interface;	struct usb_endpoint_descriptor *endpoint;	struct usb_endpoint_descriptor *interrupt_in_endpoint[8];	struct usb_endpoint_descriptor *bulk_in_endpoint[8];	struct usb_endpoint_descriptor *bulk_out_endpoint[8];	int control_out_endpoint;	int minor;	int buffer_size;	int i;	int num_interrupt_in = 0;	int num_bulk_in = 0;	int num_bulk_out = 0;	interface = intf->cur_altsetting;	control_out_endpoint = interface->desc.bInterfaceNumber;	/* find the endpoints that we need */	for (i = 0; i < interface->desc.bNumEndpoints; ++i) {		endpoint = &interface->endpoint[i].desc;		if ((endpoint->bEndpointAddress & 0x80) &&		    ((endpoint->bmAttributes & 3) == 0x02)) {			/* we found a bulk in endpoint */			dbg("found bulk in");			bulk_in_endpoint[num_bulk_in] = endpoint;			++num_bulk_in;		}		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&		    ((endpoint->bmAttributes & 3) == 0x02)) {			/* we found a bulk out endpoint */			dbg("found bulk out");			bulk_out_endpoint[num_bulk_out] = endpoint;			++num_bulk_out;		}		if ((endpoint->bEndpointAddress & 0x80) &&		    ((endpoint->bmAttributes & 3) == 0x03)) {			/* we found a interrupt in endpoint */			dbg("found interrupt in");			interrupt_in_endpoint[num_interrupt_in] = endpoint;			++num_interrupt_in;		}	}	/* according to the spec, we can only have 1 bulk_in, 1 bulk_out, and 1 interrupt_in endpoints */	if ((num_bulk_in != 1) ||	    (num_bulk_out != 1) ||	    (num_interrupt_in != 1)) {		dbg ("%s - improper number of endpoints. Bluetooth driver not bound.", __FUNCTION__);		return -EIO;	}	info("USB Bluetooth converter detected");	for (minor = 0; minor < BLUETOOTH_TTY_MINORS && bluetooth_table[minor]; ++minor)		;	if (bluetooth_table[minor]) {		err("No more free Bluetooth devices");		return -ENODEV;	}	if (!(bluetooth = kmalloc(sizeof(struct usb_bluetooth), GFP_KERNEL))) {		err("Out of memory");		return -ENOMEM;	}	memset(bluetooth, 0, sizeof(struct usb_bluetooth));	bluetooth->magic = USB_BLUETOOTH_MAGIC;	bluetooth->dev = dev;	bluetooth->minor = minor;	INIT_WORK(&bluetooth->work, bluetooth_softint, bluetooth);	init_MUTEX(&bluetooth->lock);	/* record the interface number for the control out */	bluetooth->control_out_bInterfaceNum = control_out_endpoint;		/* create our control out urb pool */ 	for (i = 0; i < NUM_CONTROL_URBS; ++i) {		struct urb  *urb = usb_alloc_urb(0, GFP_KERNEL);		if (urb == NULL) {			err("No free urbs available");			goto probe_error;		}		urb->transfer_buffer = NULL;		bluetooth->control_urb_pool[i] = urb;	}	/* set up the endpoint information */	endpoint = bulk_in_endpoint[0];	bluetooth->read_urb = usb_alloc_urb (0, GFP_KERNEL);	if (!bluetooth->read_urb) {		err("No free urbs available");		goto probe_error;	}	bluetooth->bulk_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);	bluetooth->bulk_in_endpointAddress = endpoint->bEndpointAddress;	bluetooth->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);	if (!bluetooth->bulk_in_buffer) {		err("Couldn't allocate bulk_in_buffer");		goto probe_error;	}	usb_fill_bulk_urb(bluetooth->read_urb, dev, usb_rcvbulkpipe(dev, endpoint->bEndpointAddress),		      bluetooth->bulk_in_buffer, buffer_size, bluetooth_read_bulk_callback, bluetooth);	endpoint = bulk_out_endpoint[0];	bluetooth->bulk_out_endpointAddress = endpoint->bEndpointAddress;	bluetooth->bulk_out_buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2;	endpoint = interrupt_in_endpoint[0];	bluetooth->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);	if (!bluetooth->interrupt_in_urb) {		err("No free urbs available");		goto probe_error;	}	bluetooth->interrupt_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);	bluetooth->interrupt_in_endpointAddress = endpoint->bEndpointAddress;	bluetooth->interrupt_in_interval = endpoint->bInterval;	bluetooth->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);	if (!bluetooth->interrupt_in_buffer) {		err("Couldn't allocate interrupt_in_buffer");		goto probe_error;	}	usb_fill_int_urb(bluetooth->interrupt_in_urb, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),		     bluetooth->interrupt_in_buffer, buffer_size, bluetooth_int_callback,		     bluetooth, endpoint->bInterval);	/* initialize the devfs nodes for this device and let the user know what bluetooths we are bound to */	tty_register_device (bluetooth_tty_driver, minor, &intf->dev);	info("Bluetooth converter now attached to ttyUB%d (or usb/ttub/%d for devfs)", minor, minor);	bluetooth_table[minor] = bluetooth;	/* success */	usb_set_intfdata (intf, bluetooth);	return 0;probe_error:	if (bluetooth->read_urb)		usb_free_urb (bluetooth->read_urb);	if (bluetooth->bulk_in_buffer)		kfree (bluetooth->bulk_in_buffer);	if (bluetooth->interrupt_in_urb)		usb_free_urb (bluetooth->interrupt_in_urb);	if (bluetooth->interrupt_in_buffer)		kfree (bluetooth->interrupt_in_buffer);	for (i = 0; i < NUM_CONTROL_URBS; ++i) 		if (bluetooth->control_urb_pool[i]) {			if (bluetooth->control_urb_pool[i]->transfer_buffer)				kfree (bluetooth->control_urb_pool[i]->transfer_buffer);			usb_free_urb (bluetooth->control_urb_pool[i]);		}	bluetooth_table[minor] = NULL;	/* free up any memory that we allocated */	kfree (bluetooth);	return -EIO;}static void usb_bluetooth_disconnect(struct usb_interface *intf){	struct usb_bluetooth *bluetooth = usb_get_intfdata (intf);	int i;	usb_set_intfdata (intf, NULL);	if (bluetooth) {		if ((bluetooth->open_count) && (bluetooth->tty))			tty_hangup(bluetooth->tty);		bluetooth->open_count = 0;		if (bluetooth->read_urb) {			usb_kill_urb (bluetooth->read_urb);			usb_free_urb (bluetooth->read_urb);		}		if (bluetooth->bulk_in_buffer)			kfree (bluetooth->bulk_in_buffer);		if (bluetooth->interrupt_in_urb) {			usb_kill_urb (bluetooth->interrupt_in_urb);			usb_free_urb (bluetooth->interrupt_in_urb);		}		if (bluetooth->interrupt_in_buffer)			kfree (bluetooth->interrupt_in_buffer);		tty_unregister_device (bluetooth_tty_driver, bluetooth->minor);		for (i = 0; i < NUM_CONTROL_URBS; ++i) {			if (bluetooth->control_urb_pool[i]) {				usb_kill_urb (bluetooth->control_urb_pool[i]);				if (bluetooth->control_urb_pool[i]->transfer_buffer)					kfree (bluetooth->control_urb_pool[i]->transfer_buffer);				usb_free_urb (bluetooth->control_urb_pool[i]);			}		}				info("Bluetooth converter now disconnected from ttyUB%d", bluetooth->minor);		bluetooth_table[bluetooth->minor] = NULL;		/* free up any memory that we allocated */		kfree (bluetooth);	} else {		info("device disconnected");	}}static struct tty_operations bluetooth_ops = {	.open =			bluetooth_open,	.close =		bluetooth_close,	.write =		bluetooth_write,	.write_room =		bluetooth_write_room,	.ioctl =		bluetooth_ioctl,	.set_termios =		bluetooth_set_termios,	.throttle =		bluetooth_throttle,	.unthrottle =		bluetooth_unthrottle,	.chars_in_buffer =	bluetooth_chars_in_buffer,};static int usb_bluetooth_init(void){	int i;	int result;	/* Initialize our global data */	for (i = 0; i < BLUETOOTH_TTY_MINORS; ++i) {		bluetooth_table[i] = NULL;	}	info ("USB Bluetooth support registered");	bluetooth_tty_driver = alloc_tty_driver(BLUETOOTH_TTY_MINORS);	if (!bluetooth_tty_driver)		return -ENOMEM;	bluetooth_tty_driver->owner = THIS_MODULE;	bluetooth_tty_driver->driver_name = "usb-bluetooth";	bluetooth_tty_driver->name = "ttyUB";	bluetooth_tty_driver->devfs_name = "usb/ttub/";	bluetooth_tty_driver->major = BLUETOOTH_TTY_MAJOR;	bluetooth_tty_driver->minor_start = 0;	bluetooth_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;	bluetooth_tty_driver->subtype = SERIAL_TYPE_NORMAL;	bluetooth_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;	bluetooth_tty_driver->init_termios = tty_std_termios;	bluetooth_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;	tty_set_operations(bluetooth_tty_driver, &bluetooth_ops);	if (tty_register_driver (bluetooth_tty_driver)) {		err("%s - failed to register tty driver", __FUNCTION__);		put_tty_driver(bluetooth_tty_driver);		return -1;	}	/* register the USB driver */	result = usb_register(&usb_bluetooth_driver);	if (result < 0) {		tty_unregister_driver(bluetooth_tty_driver);		put_tty_driver(bluetooth_tty_driver);		err("usb_register failed for the USB bluetooth driver. Error number %d", result);		return -1;	}	info(DRIVER_DESC " " DRIVER_VERSION);	return 0;}static void usb_bluetooth_exit(void){	usb_deregister(&usb_bluetooth_driver);	tty_unregister_driver(bluetooth_tty_driver);	put_tty_driver(bluetooth_tty_driver);}module_init(usb_bluetooth_init);module_exit(usb_bluetooth_exit);/* Module information */MODULE_AUTHOR( DRIVER_AUTHOR );MODULE_DESCRIPTION( DRIVER_DESC );MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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