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

📄 usbserial.c

📁 基于S3CEB2410平台LINUX操作系统下 USB驱动源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	int result = 0;	if (port_paranoia_check (port, __FUNCTION__))		return -ENODEV;	/* only increment our usage count, if this device is _really_ a generic device */	if_generic_do(MOD_INC_USE_COUNT);	dbg(__FUNCTION__ " - port %d", port->number);	down (&port->sem);		++port->open_count;		if (!port->active) {		port->active = 1;		/* force low_latency on so that our tty_push actually forces the data through, 		   otherwise it is scheduled, and with high data rates (like with OHCI) data		   can get lost. */		port->tty->low_latency = 1;				/* if we have a bulk interrupt, start reading from it */		if (serial->num_bulk_in) {			/* Start reading from the device */			FILL_BULK_URB(port->read_urb, serial->dev, 				      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),				      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,				      ((serial->type->read_bulk_callback) ?				       serial->type->read_bulk_callback :				       generic_read_bulk_callback), 				      port);			result = usb_submit_urb(port->read_urb);			if (result)				err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);		}	}		up (&port->sem);		return result;}static void generic_close (struct usb_serial_port *port, struct file * filp){	struct usb_serial *serial = port->serial;	dbg(__FUNCTION__ " - port %d", port->number);	down (&port->sem);	--port->open_count;	if (port->open_count <= 0) {		if (serial->dev) {			/* shutdown any bulk reads that might be going on */			if (serial->num_bulk_out)				usb_unlink_urb (port->write_urb);			if (serial->num_bulk_in)				usb_unlink_urb (port->read_urb);		}				port->active = 0;		port->open_count = 0;	}	up (&port->sem);	/* only decrement our usage count, if this device is _really_ a generic device */	if_generic_do(MOD_DEC_USE_COUNT);}static int generic_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count){	struct usb_serial *serial = port->serial;	int result;	dbg(__FUNCTION__ " - port %d", port->number);	if (count == 0) {		dbg(__FUNCTION__ " - write request of 0 bytes");		return (0);	}	/* only do something if we have a bulk out endpoint */	if (serial->num_bulk_out) {		if (port->write_urb->status == -EINPROGRESS) {			dbg (__FUNCTION__ " - already writing");			return (0);		}		count = (count > port->bulk_out_size) ? port->bulk_out_size : count;		if (from_user) {			if (copy_from_user(port->write_urb->transfer_buffer, buf, count))				return -EFAULT;		}		else {			memcpy (port->write_urb->transfer_buffer, buf, count);		}  		usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);		/* set up our urb */		FILL_BULK_URB(port->write_urb, serial->dev, 			      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),			      port->write_urb->transfer_buffer, count,			      ((serial->type->write_bulk_callback) ? 			       serial->type->write_bulk_callback : 			       generic_write_bulk_callback), 			      port);		/* send the data out the bulk port */		result = usb_submit_urb(port->write_urb);		if (result)			err(__FUNCTION__ " - failed submitting write urb, error %d", result);		else			result = count;		return result;	}		/* no bulk out, so return 0 bytes written */	return (0);} static int generic_write_room (struct usb_serial_port *port){	struct usb_serial *serial = port->serial;	int room = 0;	dbg(__FUNCTION__ " - port %d", port->number);		if (serial->num_bulk_out) {		if (port->write_urb->status != -EINPROGRESS)			room = port->bulk_out_size;	}		dbg(__FUNCTION__ " - returns %d", room);	return (room);}static int generic_chars_in_buffer (struct usb_serial_port *port){	struct usb_serial *serial = port->serial;	int chars = 0;	dbg(__FUNCTION__ " - port %d", port->number);		if (serial->num_bulk_out) {		if (port->write_urb->status == -EINPROGRESS)			chars = port->write_urb->transfer_buffer_length;	}	dbg (__FUNCTION__ " - returns %d", chars);	return (chars);}static void generic_read_bulk_callback (struct urb *urb){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);	struct tty_struct *tty;	unsigned char *data = urb->transfer_buffer;	int i;	int result;	dbg(__FUNCTION__ " - port %d", port->number);		if (!serial) {		dbg(__FUNCTION__ " - bad serial pointer, exiting");		return;	}	if (urb->status) {		dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);		return;	}	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);	tty = port->tty;	if (urb->actual_length) {		for (i = 0; i < urb->actual_length ; ++i) {			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {				tty_flip_buffer_push(tty);			}			/* this doesn't actually push the data through unless tty->low_latency is set */			tty_insert_flip_char(tty, data[i], 0);		}	  	tty_flip_buffer_push(tty);	}	/* Continue trying to always read  */	FILL_BULK_URB(port->read_urb, serial->dev, 		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,		      ((serial->type->read_bulk_callback) ?		       serial->type->read_bulk_callback :		       generic_read_bulk_callback), 		      port);	result = usb_submit_urb(port->read_urb);	if (result)		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);}static void generic_write_bulk_callback (struct urb *urb){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);	dbg(__FUNCTION__ " - port %d", port->number);		if (!serial) {		dbg(__FUNCTION__ " - bad serial pointer, exiting");		return;	}	if (urb->status) {		dbg(__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);		return;	}	queue_task(&port->tqueue, &tq_immediate);	mark_bh(IMMEDIATE_BH);		return;}static void generic_shutdown (struct usb_serial *serial){	int i;	dbg (__FUNCTION__);	/* stop reads and writes on all ports */	for (i=0; i < serial->num_ports; ++i) {		while (serial->port[i].open_count > 0) {			generic_close (&serial->port[i], NULL);		}	}}static void port_softint(void *private){	struct usb_serial_port *port = (struct usb_serial_port *)private;	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);	struct tty_struct *tty;	dbg(__FUNCTION__ " - port %d", port->number);		if (!serial) {		return;	} 		tty = port->tty;	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {		dbg(__FUNCTION__ " - write wakeup call.");		(tty->ldisc.write_wakeup)(tty);	}	wake_up_interruptible(&tty->write_wait);}static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum,			       const struct usb_device_id *id){	struct usb_serial *serial = NULL;	struct usb_serial_port *port;	struct usb_interface *interface;	struct usb_interface_descriptor *iface_desc;	struct usb_endpoint_descriptor *endpoint;	struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];	struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];	struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];	struct usb_serial_device_type *type = NULL;	struct list_head *tmp;	int found;	int minor;	int buffer_size;	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;	int num_ports;	int max_endpoints;	const struct usb_device_id *id_pattern = NULL;		/* loop through our list of known serial converters, and see if this	   device matches. */	found = 0;	interface = &dev->actconfig->interface[ifnum];	list_for_each (tmp, &usb_serial_driver_list) {		type = list_entry(tmp, struct usb_serial_device_type, driver_list);		id_pattern = usb_match_id(dev, interface, type->id_table);		if (id_pattern != NULL) {			dbg("descriptor matches");			found = 1;			break;		}	}	if (!found) {		/* no match */		dbg("none matched");		return(NULL);	}		/* descriptor matches, let's find the endpoints needed */	interrupt_pipe = bulk_in_pipe = bulk_out_pipe = HAS_NOT;				/* check out the endpoints */	iface_desc = &interface->altsetting[0];	for (i = 0; i < iface_desc->bNumEndpoints; ++i) {		endpoint = &iface_desc->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;		}	}	#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)	/* BEGIN HORRIBLE HACK FOR PL2303 */ 	/* this is needed due to the looney way its endpoints are set up */	if (ifnum == 1) {		if (((dev->descriptor.idVendor == PL2303_VENDOR_ID) &&		     (dev->descriptor.idProduct == PL2303_PRODUCT_ID)) ||		    ((dev->descriptor.idVendor == ATEN_VENDOR_ID) &&		     (dev->descriptor.idProduct == ATEN_PRODUCT_ID))) {			/* check out the endpoints of the other interface*/			interface = &dev->actconfig->interface[ifnum ^ 1];			iface_desc = &interface->altsetting[0];			for (i = 0; i < iface_desc->bNumEndpoints; ++i) {				endpoint = &iface_desc->endpoint[i];				if ((endpoint->bEndpointAddress & 0x80) &&				    ((endpoint->bmAttributes & 3) == 0x03)) {					/* we found a interrupt in endpoint */					dbg("found interrupt in for Prolific device on separate interface");					interrupt_pipe = HAS;					interrupt_in_endpoint[num_interrupt_in] = endpoint;					++num_interrupt_in;				}			}		}	}	/* END HORRIBLE HACK FOR PL2303 */#endif		/* 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))) {

⌨️ 快捷键说明

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