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

📄 usb-serial.c

📁 Usb1.1驱动c语言源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	usb_unlink_urb (&serial->write_urb);	usb_unlink_urb (&serial->read_urb);	serial->active = 0;}static void visor_throttle (struct tty_struct * tty){/*	struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; */	dbg("visor_throttle");	/* Change the control signals */	/* FIXME!!! */	return;}static void visor_unthrottle (struct tty_struct * tty){/*	struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; */	dbg("visor_unthrottle");	/* Change the control signals */	/* FIXME!!! */	return;}#endif	/* CONFIG_USB_SERIAL_VISOR*//***************************************************************************** * generic devices specific driver functions *****************************************************************************/static int generic_serial_open (struct tty_struct *tty, struct file *filp){	struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 	dbg("generic_serial_open");	if (!serial->present) {		dbg("no device registered");		return -EINVAL;	}	if (serial->active) {		dbg ("device already open");		return -EINVAL;	}	serial->active = 1; 	/* if we have a bulk interrupt, start reading from it */	if (serial->num_bulk_in) {		/*Start reading from the device*/		if (usb_submit_urb(&serial->read_urb))			dbg("usb_submit_urb(read bulk) failed");	}	return (0);}static void generic_serial_close(struct tty_struct *tty, struct file * filp){	struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 	dbg("generic_serial_close");		/* shutdown any bulk reads that might be going on */	if (serial->num_bulk_out) {		usb_unlink_urb (&serial->write_urb);	}	if (serial->num_bulk_in) {		usb_unlink_urb (&serial->read_urb);	}	serial->active = 0;}static int generic_serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count){	struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 		dbg("generic_serial_write");	if (count == 0) {		dbg("write request of 0 bytes");		return (0);	}	/* only do something if we have a bulk out endpoint */	if (serial->num_bulk_out) {		if (serial->write_urb.status == -EINPROGRESS) {			dbg ("already writing");			return (0);		}		count = (count > serial->bulk_out_size[0]) ? serial->bulk_out_size[0] : count;		if (from_user) {			copy_from_user(serial->write_urb.transfer_buffer, buf, count);		}		else {			memcpy (serial->write_urb.transfer_buffer, buf, count);		}  		/* send the data out the bulk port */		serial->write_urb.transfer_buffer_length = count;		if (usb_submit_urb(&serial->write_urb))			dbg("usb_submit_urb(write bulk) failed");		return (count);	}		/* no bulk out, so return 0 bytes written */	return (0);} static void generic_serial_put_char (struct tty_struct *tty, unsigned char ch){	struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; 		dbg("generic_serial_put_char");		/* if we have a bulk out endpoint, then shove a character out it */	if (serial->num_bulk_out) {		/* send the single character out the bulk port */		memcpy (serial->write_urb.transfer_buffer, &ch, 1);		serial->write_urb.transfer_buffer_length = 1;		if (usb_submit_urb(&serial->write_urb))			dbg("usb_submit_urb(write bulk) failed");	}	return;}static int generic_write_room (struct tty_struct *tty) {	struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; 	int room;	dbg("generic_write_room");		if (serial->num_bulk_out) {		if (serial->write_urb.status == -EINPROGRESS)			room = 0;		else			room = serial->bulk_out_size[0];		dbg("generic_write_room returns %d", room);		return (room);	}		return (0);}static int generic_chars_in_buffer (struct tty_struct *tty) {	struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; 	dbg("generic_chars_in_buffer");		if (serial->num_bulk_out) {		if (serial->write_urb.status == -EINPROGRESS) {			return (serial->bulk_out_size[0]);		}	}	return (0);}static int Get_Free_Serial (void){	int i; 	for (i=0; i < NUM_PORTS; ++i) {		if (!serial_state_table[i].present)			return (i);	}	return (-1);}static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum){	struct usb_serial_state *serial = NULL;	struct usb_interface_descriptor *interface;	struct usb_endpoint_descriptor *endpoint;	struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_ENDPOINTS];	struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_ENDPOINTS];	struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_ENDPOINTS];	struct usb_serial_device_type *type;	int device_num;	int serial_num;	int i;	char interrupt_pipe;	char bulk_in_pipe;	char bulk_out_pipe;	int num_interrupt_in = 0;	int num_bulk_in = 0;	int num_bulk_out = 0;		/* loop through our list of known serial converters, and see if this device matches */	device_num = 0;	while (usb_serial_devices[device_num] != NULL) {		type = usb_serial_devices[device_num];		dbg ("Looking at %s Vendor id=%.4x Product id=%.4x", type->name, *(type->idVendor), *(type->idProduct));		/* look at the device descriptor */		if ((dev->descriptor.idVendor == *(type->idVendor)) &&		    (dev->descriptor.idProduct == *(type->idProduct))) {			dbg("descriptor matches...looking at the endpoints");			/* descriptor matches, let's try to find the endpoints needed */			interrupt_pipe = bulk_in_pipe = bulk_out_pipe = HAS_NOT;						/* check out the endpoints */			interface = &dev->actconfig->interface[ifnum].altsetting[0];			for (i = 0; i < interface->bNumEndpoints; ++i) {				endpoint = &interface->endpoint[i];						if ((endpoint->bEndpointAddress & 0x80) &&				    ((endpoint->bmAttributes & 3) == 0x02)) {					/* we found a bulk in endpoint */					dbg("found bulk in");					bulk_in_pipe = HAS;					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_pipe = HAS;					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_pipe = HAS;					interrupt_in_endpoint[num_interrupt_in] = endpoint;					++num_interrupt_in;				}			}				/* verify that we found all of the endpoints that we need */			if ((interrupt_pipe & type->needs_interrupt_in) &&			    (bulk_in_pipe & type->needs_bulk_in) &&			    (bulk_out_pipe & type->needs_bulk_out)) {				/* found all that we need */				info("%s converter detected", type->name);				if (0>(serial_num = Get_Free_Serial())) {					dbg("Too many devices connected");					return NULL;				}					serial = &serial_state_table[serial_num];			       	memset(serial, 0, sizeof(struct usb_serial_state));			       	serial->dev = dev;				serial->type = type;				serial->number = serial_num;				serial->num_bulk_in = num_bulk_in;				serial->num_bulk_out = num_bulk_out;				serial->num_interrupt_in = num_interrupt_in;				/* if this device type has a startup function, call it */				if (type->startup) {					if (type->startup (serial))						return NULL;				}				/* set up the endpoint information */				for (i = 0; i < num_bulk_in; ++i) {					serial->bulk_in_endpoint[i] = bulk_in_endpoint[i]->bEndpointAddress;					serial->bulk_in_size[i] = bulk_in_endpoint[i]->wMaxPacketSize;					serial->bulk_in_interval[i] = bulk_in_endpoint[i]->bInterval;					serial->bulk_in_pipe[i] = usb_rcvbulkpipe (dev, serial->bulk_in_endpoint[i]);					serial->bulk_in_buffer[i] = kmalloc (serial->bulk_in_size[i], GFP_KERNEL);					if (!serial->bulk_in_buffer[i]) {						err("Couldn't allocate bulk_in_buffer");						goto probe_error;					}				}				if (num_bulk_in)					FILL_BULK_URB(&serial->read_urb, dev, usb_rcvbulkpipe (dev, serial->bulk_in_endpoint[0]),							serial->bulk_in_buffer[0], serial->bulk_in_size[0], serial_read_bulk, serial);				for (i = 0; i < num_bulk_out; ++i) {					serial->bulk_out_endpoint[i] = bulk_out_endpoint[i]->bEndpointAddress;					serial->bulk_out_size[i] = bulk_out_endpoint[i]->wMaxPacketSize;					serial->bulk_out_interval[i] = bulk_out_endpoint[i]->bInterval;					serial->bulk_out_pipe[i] = usb_rcvbulkpipe (dev, serial->bulk_out_endpoint[i]);					serial->bulk_out_buffer[i] = kmalloc (serial->bulk_out_size[i], GFP_KERNEL);					if (!serial->bulk_out_buffer[i]) {						err("Couldn't allocate bulk_out_buffer");						goto probe_error;					}				}				if (num_bulk_out)					FILL_BULK_URB(&serial->write_urb, dev, usb_sndbulkpipe (dev, serial->bulk_in_endpoint[0]),							serial->bulk_in_buffer[0], serial->bulk_in_size[0], serial_write_bulk, serial);				for (i = 0; i < num_interrupt_in; ++i) {					serial->interrupt_in_inuse = 0;					serial->interrupt_in_endpoint[i] = interrupt_in_endpoint[i]->bEndpointAddress;					serial->interrupt_in_size[i] = interrupt_in_endpoint[i]->wMaxPacketSize;					serial->interrupt_in_interval[i] = interrupt_in_endpoint[i]->bInterval;					/* serial->interrupt_in_pipe = usb_rcvbulkpipe (dev, serial->bulk_in_endpoint); */					serial->interrupt_in_buffer[i] = kmalloc (serial->bulk_in_size[i], GFP_KERNEL);					if (!serial->interrupt_in_buffer[i]) {						err("Couldn't allocate interrupt_in_buffer");						goto probe_error;					}				}				#if 0				/* set up an interrupt for out bulk in pipe */				/* ask for a bulk read */				serial->bulk_in_inuse = 1;				serial->bulk_in_transfer = usb_request_bulk (serial->dev, serial->bulk_in_pipe, serial_read_irq, serial->bulk_in_buffer, serial->bulk_in_size, serial);				/* set up our interrupt to be the time for the bulk in read */				ret = usb_request_irq (dev, serial->bulk_in_pipe, usb_serial_irq, serial->bulk_in_interval, serial, &serial->irq_handle);				if (ret) {					info("failed usb_request_irq (0x%x)", ret);					goto probe_error;				}				#endif				serial->present = 1;				MOD_INC_USE_COUNT;				info("%s converter now attached to ttyUSB%d", type->name, serial_num);				return serial;			} else {				info("descriptors matched, but endpoints did not");			}		}		/* look at the next type in our list */		++device_num;	}probe_error:	if (serial) {		for (i = 0; i < num_bulk_in; ++i)			if (serial->bulk_in_buffer[i])				kfree (serial->bulk_in_buffer[i]);		for (i = 0; i < num_bulk_out; ++i)			if (serial->bulk_out_buffer[i])				kfree (serial->bulk_out_buffer[i]);		for (i = 0; i < num_interrupt_in; ++i)			if (serial->interrupt_in_buffer[i])				kfree (serial->interrupt_in_buffer[i]);	}	return NULL;}static void usb_serial_disconnect(struct usb_device *dev, void *ptr){	struct usb_serial_state *serial = (struct usb_serial_state *) ptr;	int i;	if (serial) {		if (!serial->present) {			/* something strange is going on */			dbg("disconnect but not present?");			return;			}		/* need to stop any transfers...*/		usb_unlink_urb (&serial->write_urb);		usb_unlink_urb (&serial->read_urb);		/* free up any memory that we allocated */		for (i = 0; i < serial->num_bulk_in; ++i)			if (serial->bulk_in_buffer[i])				kfree (serial->bulk_in_buffer[i]);		for (i = 0; i < serial->num_bulk_out; ++i)			if (serial->bulk_out_buffer[i])				kfree (serial->bulk_out_buffer[i]);		for (i = 0; i < serial->num_interrupt_in; ++i)			if (serial->interrupt_in_buffer[i])				kfree (serial->interrupt_in_buffer[i]);		serial->present = 0;		serial->active = 0;		info("%s converter now disconnected from ttyUSB%d", serial->type->name, serial->number);	} else {		info("device disconnected");	}		MOD_DEC_USE_COUNT;}static struct tty_driver serial_tty_driver = {	magic:			TTY_DRIVER_MAGIC,	driver_name:		"usb",	name:			"ttyUSB",	major:			SERIAL_MAJOR,	minor_start:		0,	num:			NUM_PORTS,	type:			TTY_DRIVER_TYPE_SERIAL,	subtype:		SERIAL_TYPE_NORMAL,	flags:			TTY_DRIVER_REAL_RAW,	refcount:		&serial_refcount,	table:			serial_tty,	proc_entry:		NULL,	other:			NULL,	termios:		serial_termios,	termios_locked:		serial_termios_locked,		open:			serial_open,	close:			serial_close,	write:			serial_write,	put_char:		serial_put_char,	flush_chars:		NULL,	write_room:		serial_write_room,	ioctl:			NULL,	set_termios:		NULL,	set_ldisc:		NULL, 	throttle:		serial_throttle,	unthrottle:		serial_unthrottle,	stop:			NULL,	start:			NULL,	hangup:			NULL,	break_ctl:		NULL,	wait_until_sent:	NULL,	send_xchar:		NULL,	read_proc:		NULL,	chars_in_buffer:	serial_chars_in_buffer,	flush_buffer:		NULL};int usb_serial_init(void){	int i;	/* Initalize our global data */	for (i = 0; i < NUM_PORTS; ++i) {		memset(&serial_state_table[i], 0x00, sizeof(struct usb_serial_state));	}	/* register the tty driver */	serial_tty_driver.init_termios		= tty_std_termios;	serial_tty_driver.init_termios.c_cflag	= B9600 | CS8 | CREAD | HUPCL | CLOCAL;	if (tty_register_driver (&serial_tty_driver)) {		err("failed to register tty driver");		return -EPERM;	}		/* register the USB driver */	if (usb_register(&usb_serial_driver) < 0) {		tty_unregister_driver(&serial_tty_driver);		return -1;	}	info("support registered");	return 0;}#ifdef MODULEint init_module(void){	return usb_serial_init();}void cleanup_module(void){	tty_unregister_driver(&serial_tty_driver);	usb_deregister(&usb_serial_driver);}#endif

⌨️ 快捷键说明

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