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

📄 ftdi_sio.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	ftdi_determine_type (serial->port[0]);	create_sysfs_attrs(serial);	/* Check for device requiring special set up. */	quirk = (struct ftdi_sio_quirk *)usb_get_serial_data(serial);	if (quirk && quirk->setup) {		quirk->setup(serial);	}		return (0);} /* ftdi_sio_attach *//* Setup for the USB-UIRT device, which requires hardwired * baudrate (38400 gets mapped to 312500) *//* Called from usbserial:serial_probe */static void ftdi_USB_UIRT_setup (struct usb_serial *serial){	struct ftdi_private *priv;	dbg("%s",__FUNCTION__);	priv = usb_get_serial_port_data(serial->port[0]);	priv->flags |= ASYNC_SPD_CUST;	priv->custom_divisor = 77;	priv->force_baud = B38400;} /* ftdi_USB_UIRT_setup *//* Setup for the HE-TIRA1 device, which requires hardwired * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled.  */static void ftdi_HE_TIRA1_setup (struct usb_serial *serial){	struct ftdi_private *priv;	dbg("%s",__FUNCTION__);	priv = usb_get_serial_port_data(serial->port[0]);	priv->flags |= ASYNC_SPD_CUST;	priv->custom_divisor = 240;	priv->force_baud = B38400;	priv->force_rtscts = 1;} /* ftdi_HE_TIRA1_setup *//* ftdi_shutdown is called from usbserial:usb_serial_disconnect  *   it is called when the usb device is disconnected * *   usbserial:usb_serial_disconnect *      calls __serial_close for each open of the port *      shutdown is called then (ie ftdi_shutdown) */static void ftdi_shutdown (struct usb_serial *serial){ /* ftdi_shutdown */		struct usb_serial_port *port = serial->port[0];	struct ftdi_private *priv = usb_get_serial_port_data(port);	dbg("%s", __FUNCTION__);	remove_sysfs_attrs(serial);		/* all open ports are closed at this point          *    (by usbserial.c:__serial_close, which calls ftdi_close)  	 */	if (priv) {		usb_set_serial_port_data(port, NULL);		kfree(priv);	}} /* ftdi_shutdown */static int  ftdi_open (struct usb_serial_port *port, struct file *filp){ /* ftdi_open */	struct termios tmp_termios;	struct usb_device *dev = port->serial->dev;	struct ftdi_private *priv = usb_get_serial_port_data(port);	unsigned long flags;		int result = 0;	char buf[1]; /* Needed for the usb_control_msg I think */	dbg("%s", __FUNCTION__);	port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;	/* No error checking for this (will get errors later anyway) */	/* See ftdi_sio.h for description of what is reset */	usb_control_msg(dev, usb_sndctrlpipe(dev, 0),			FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 			FTDI_SIO_RESET_SIO, 			priv->interface, buf, 0, WDR_TIMEOUT);	/* Termios defaults are set by usb_serial_init. We don't change	   port->tty->termios - this would loose speed settings, etc.	   This is same behaviour as serial.c/rs_open() - Kuba */	/* ftdi_set_termios  will send usb control messages */	ftdi_set_termios(port, &tmp_termios);	/* FIXME: Flow control might be enabled, so it should be checked -	   we have no control of defaults! */	/* Turn on RTS and DTR since we are not flow controlling by default */	set_mctrl(port, TIOCM_DTR | TIOCM_RTS);	/* Not throttled */	spin_lock_irqsave(&priv->rx_lock, flags);	priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED);	spin_unlock_irqrestore(&priv->rx_lock, flags);	/* Start reading from the device */	priv->rx_processed = 0;	usb_fill_bulk_urb(port->read_urb, dev,		      usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,		      ftdi_read_bulk_callback, port);	result = usb_submit_urb(port->read_urb, GFP_KERNEL);	if (result)		err("%s - failed submitting read urb, error %d", __FUNCTION__, result);	return result;} /* ftdi_open *//*  * usbserial:__serial_close  only calls ftdi_close if the point is open * *   This only gets called when it is the last close *    *    */static void ftdi_close (struct usb_serial_port *port, struct file *filp){ /* ftdi_close */	unsigned int c_cflag = port->tty->termios->c_cflag;	struct ftdi_private *priv = usb_get_serial_port_data(port);	char buf[1];	dbg("%s", __FUNCTION__);	if (c_cflag & HUPCL){		/* Disable flow control */		if (usb_control_msg(port->serial->dev, 				    usb_sndctrlpipe(port->serial->dev, 0),				    FTDI_SIO_SET_FLOW_CTRL_REQUEST,				    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,				    0, priv->interface, buf, 0,				    WDR_TIMEOUT) < 0) {			err("error from flowcontrol urb");		}	    		/* drop RTS and DTR */		clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);	} /* Note change no line if hupcl is off */	/* cancel any scheduled reading */	cancel_delayed_work(&priv->rx_work);	flush_scheduled_work();		/* shutdown our bulk read */	if (port->read_urb)		usb_kill_urb(port->read_urb);} /* ftdi_close */  /* The SIO requires the first byte to have: *  B0 1 *  B1 0 *  B2..7 length of message excluding byte 0 * * The new devices do not require this byte */static int ftdi_write (struct usb_serial_port *port,			   const unsigned char *buf, int count){ /* ftdi_write */	struct ftdi_private *priv = usb_get_serial_port_data(port);	struct urb *urb;	unsigned char *buffer;	int data_offset ;       /* will be 1 for the SIO and 0 otherwise */	int status;	int transfer_size;	dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count);	if (count == 0) {		dbg("write request of 0 bytes");		return 0;	}		data_offset = priv->write_offset;        dbg("data_offset set to %d",data_offset);	/* Determine total transfer size */	transfer_size = count;	if (data_offset > 0) {		/* Original sio needs control bytes too... */		transfer_size += (data_offset *				((count + (PKTSZ - 1 - data_offset)) /				 (PKTSZ - data_offset)));	}	buffer = kmalloc (transfer_size, GFP_ATOMIC);	if (!buffer) {		err("%s ran out of kernel memory for urb ...", __FUNCTION__);		return -ENOMEM;	}	urb = usb_alloc_urb(0, GFP_ATOMIC);	if (!urb) {		err("%s - no more free urbs", __FUNCTION__);		kfree (buffer);		return -ENOMEM;	}	/* Copy data */	if (data_offset > 0) {		/* Original sio requires control byte at start of each packet. */		int user_pktsz = PKTSZ - data_offset;		int todo = count;		unsigned char *first_byte = buffer;		const unsigned char *current_position = buf;		while (todo > 0) {			if (user_pktsz > todo) {				user_pktsz = todo;			}			/* Write the control byte at the front of the packet*/			*first_byte = 1 | ((user_pktsz) << 2); 			/* Copy data for packet */			memcpy (first_byte + data_offset,				current_position, user_pktsz);			first_byte += user_pktsz + data_offset;			current_position += user_pktsz;			todo -= user_pktsz;		}	} else {		/* No control byte required. */		/* Copy in the data to send */		memcpy (buffer, buf, count);	}	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, buffer);	/* fill the buffer and send it */	usb_fill_bulk_urb(urb, port->serial->dev, 		      usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),		      buffer, transfer_size,		      ftdi_write_bulk_callback, port);	status = usb_submit_urb(urb, GFP_ATOMIC);	if (status) {		err("%s - failed submitting write urb, error %d", __FUNCTION__, status);		count = status;		kfree (buffer);	}	/* we are done with this urb, so let the host driver	 * really free it when it is finished with it */	usb_free_urb (urb);	dbg("%s write returning: %d", __FUNCTION__, count);	return count;} /* ftdi_write *//* This function may get called when the device is closed */static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	/* free up the transfer buffer, as usb_free_urb() does not do this */	kfree (urb->transfer_buffer);	dbg("%s - port %d", __FUNCTION__, port->number);		if (urb->status) {		dbg("nonzero write bulk status received: %d", urb->status);		return;	}	schedule_work(&port->work);} /* ftdi_write_bulk_callback */static int ftdi_write_room( struct usb_serial_port *port ){	dbg("%s - port %d", __FUNCTION__, port->number);	/*	 * We really can take anything the user throws at us	 * but let's pick a nice big number to tell the tty	 * layer that we have lots of free space	 */	return 2048;} /* ftdi_write_room */static int ftdi_chars_in_buffer (struct usb_serial_port *port){ /* ftdi_chars_in_buffer */	dbg("%s - port %d", __FUNCTION__, port->number);	/* 	 * We can't really account for how much data we	 * have sent out, but hasn't made it through to the	 * device, so just tell the tty layer that everything	 * is flushed.	 */	return 0;} /* ftdi_chars_in_buffer */static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs){ /* ftdi_read_bulk_callback */	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct tty_struct *tty;	struct ftdi_private *priv;	if (urb->number_of_packets > 0) {		err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__,		    urb->transfer_buffer_length, urb->actual_length, urb->number_of_packets );		err("%s transfer_flags %x ", __FUNCTION__,urb->transfer_flags );	}	dbg("%s - port %d", __FUNCTION__, port->number);	if (port->open_count <= 0)		return;	tty = port->tty;	if (!tty) {		dbg("%s - bad tty pointer - exiting",__FUNCTION__);		return;	}	priv = usb_get_serial_port_data(port);	if (!priv) {		dbg("%s - bad port private data pointer - exiting", __FUNCTION__);		return;	}	if (urb != port->read_urb) {		err("%s - Not my urb!", __FUNCTION__);	}	if (urb->status) {		/* This will happen at close every time so it is a dbg not an err */		dbg("(this is ok on close) nonzero read bulk status received: %d", urb->status);		return;	}	ftdi_process_read(port);} /* ftdi_read_bulk_callback */static void ftdi_process_read (void *param){ /* ftdi_process_read */	struct usb_serial_port *port = (struct usb_serial_port*)param;	struct urb *urb;	struct tty_struct *tty;	struct ftdi_private *priv;	char error_flag;       	unsigned char *data;	int i;	int result;	int need_flip;	int packet_offset;	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	if (port->open_count <= 0)		return;	tty = port->tty;	if (!tty) {		dbg("%s - bad tty pointer - exiting",__FUNCTION__);		return;	}

⌨️ 快捷键说明

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