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

📄 ti_usb_3410_5052.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
		dev_err(&port->dev, "%s - out of memory\n", __FUNCTION__);		return;	}	config->wFlags = 0;	/* these flags must be set */	config->wFlags |= TI_UART_ENABLE_MS_INTS;	config->wFlags |= TI_UART_ENABLE_AUTO_START_DMA;	config->bUartMode = (__u8)(tport->tp_uart_mode);	switch (cflag & CSIZE) {		case CS5:			    config->bDataBits = TI_UART_5_DATA_BITS;			    break;		case CS6:			    config->bDataBits = TI_UART_6_DATA_BITS;			    break;		case CS7:			    config->bDataBits = TI_UART_7_DATA_BITS;			    break;		default:		case CS8:			    config->bDataBits = TI_UART_8_DATA_BITS;			    break;	}	if (cflag & PARENB) {		if (cflag & PARODD) {			config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING;			config->bParity = TI_UART_ODD_PARITY;		} else {			config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING;			config->bParity = TI_UART_EVEN_PARITY;		}	} else {		config->wFlags &= ~TI_UART_ENABLE_PARITY_CHECKING;		config->bParity = TI_UART_NO_PARITY; 		}	if (cflag & CSTOPB)		config->bStopBits = TI_UART_2_STOP_BITS;	else		config->bStopBits = TI_UART_1_STOP_BITS;	if (cflag & CRTSCTS) {		/* RTS flow control must be off to drop RTS for baud rate B0 */		if ((cflag & CBAUD) != B0)			config->wFlags |= TI_UART_ENABLE_RTS_IN;		config->wFlags |= TI_UART_ENABLE_CTS_OUT;	} else {		tty->hw_stopped = 0;		ti_restart_read(tport, tty);	}	if (I_IXOFF(tty) || I_IXON(tty)) {		config->cXon  = START_CHAR(tty);		config->cXoff = STOP_CHAR(tty);		if (I_IXOFF(tty))			config->wFlags |= TI_UART_ENABLE_X_IN;		else			ti_restart_read(tport, tty);		if (I_IXON(tty))			config->wFlags |= TI_UART_ENABLE_X_OUT;	}	baud = tty_get_baud_rate(tty);	if (!baud) baud = 9600;	if (tport->tp_tdev->td_is_3410)		config->wBaudRate = (__u16)((923077 + baud/2) / baud);	else		config->wBaudRate = (__u16)((461538 + baud/2) / baud);	dbg("%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d",	__FUNCTION__, baud, config->wBaudRate, config->wFlags, config->bDataBits, config->bParity, config->bStopBits, config->cXon, config->cXoff, config->bUartMode);	cpu_to_be16s(&config->wBaudRate);	cpu_to_be16s(&config->wFlags);	status = ti_command_out_sync(tport->tp_tdev, TI_SET_CONFIG,		(__u8)(TI_UART1_PORT + port_number), 0, (__u8 *)config,		sizeof(*config));	if (status)		dev_err(&port->dev, "%s - cannot set config on port %d, %d\n", __FUNCTION__, port_number, status);	/* SET_CONFIG asserts RTS and DTR, reset them correctly */	mcr = tport->tp_shadow_mcr;	/* if baud rate is B0, clear RTS and DTR */	if ((cflag & CBAUD) == B0)		mcr &= ~(TI_MCR_DTR | TI_MCR_RTS);	status = ti_set_mcr(tport, mcr);	if (status)		dev_err(&port->dev, "%s - cannot set modem control on port %d, %d\n", __FUNCTION__, port_number, status);	kfree(config);}static int ti_tiocmget(struct usb_serial_port *port, struct file *file){	struct ti_port *tport = usb_get_serial_port_data(port);	unsigned int result;	unsigned int msr;	unsigned int mcr;	dbg("%s - port %d", __FUNCTION__, port->number);	if (tport == NULL)		return -ENODEV;	msr = tport->tp_msr;	mcr = tport->tp_shadow_mcr;	result = ((mcr & TI_MCR_DTR) ? TIOCM_DTR : 0)		| ((mcr & TI_MCR_RTS) ? TIOCM_RTS : 0)		| ((mcr & TI_MCR_LOOP) ? TIOCM_LOOP : 0)		| ((msr & TI_MSR_CTS) ? TIOCM_CTS : 0)		| ((msr & TI_MSR_CD) ? TIOCM_CAR : 0)		| ((msr & TI_MSR_RI) ? TIOCM_RI : 0)		| ((msr & TI_MSR_DSR) ? TIOCM_DSR : 0);	dbg("%s - 0x%04X", __FUNCTION__, result);	return result;}static int ti_tiocmset(struct usb_serial_port *port, struct file *file,	unsigned int set, unsigned int clear){	struct ti_port *tport = usb_get_serial_port_data(port);	unsigned int mcr;	dbg("%s - port %d", __FUNCTION__, port->number);	if (tport == NULL)		return -ENODEV;	mcr = tport->tp_shadow_mcr;	if (set & TIOCM_RTS)		mcr |= TI_MCR_RTS;	if (set & TIOCM_DTR)		mcr |= TI_MCR_DTR;	if (set & TIOCM_LOOP)		mcr |= TI_MCR_LOOP;	if (clear & TIOCM_RTS)		mcr &= ~TI_MCR_RTS;	if (clear & TIOCM_DTR)		mcr &= ~TI_MCR_DTR;	if (clear & TIOCM_LOOP)		mcr &= ~TI_MCR_LOOP;	return ti_set_mcr(tport, mcr);}static void ti_break(struct usb_serial_port *port, int break_state){	struct ti_port *tport = usb_get_serial_port_data(port);	int status;	dbg("%s - state = %d", __FUNCTION__, break_state);	if (tport == NULL)		return;	ti_drain(tport, (tport->tp_closing_wait*HZ)/100, 0);	status = ti_write_byte(tport->tp_tdev,		tport->tp_uart_base_addr + TI_UART_OFFSET_LCR,		TI_LCR_BREAK, break_state == -1 ? TI_LCR_BREAK : 0);	if (status)		dbg("%s - error setting break, %d", __FUNCTION__, status);}static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs){	struct ti_device *tdev = (struct ti_device *)urb->context;	struct usb_serial_port *port;	struct usb_serial *serial = tdev->td_serial;	struct ti_port *tport;	struct device *dev = &urb->dev->dev;	unsigned char *data = urb->transfer_buffer;	int length = urb->actual_length;	int port_number;	int function;	int status;	__u8 msr;	dbg("%s", __FUNCTION__);	switch (urb->status) {	case 0:		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);		tdev->td_urb_error = 1;		return;	default:		dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status);		tdev->td_urb_error = 1;		goto exit;	}	if (length != 2) {		dbg("%s - bad packet size, %d", __FUNCTION__, length);		goto exit;	}	if (data[0] == TI_CODE_HARDWARE_ERROR) {		dev_err(dev, "%s - hardware error, %d\n", __FUNCTION__, data[1]);		goto exit;	}	port_number = TI_GET_PORT_FROM_CODE(data[0]);	function = TI_GET_FUNC_FROM_CODE(data[0]);	dbg("%s - port_number %d, function %d, data 0x%02X", __FUNCTION__, port_number, function, data[1]);	if (port_number >= serial->num_ports) {		dev_err(dev, "%s - bad port number, %d\n", __FUNCTION__, port_number);		goto exit;	}	port = serial->port[port_number];	tport = usb_get_serial_port_data(port);	if (!tport)		goto exit;	switch (function) {	case TI_CODE_DATA_ERROR:		dev_err(dev, "%s - DATA ERROR, port %d, data 0x%02X\n", __FUNCTION__, port_number, data[1]);		break;	case TI_CODE_MODEM_STATUS:		msr = data[1];		dbg("%s - port %d, msr 0x%02X", __FUNCTION__, port_number, msr);		ti_handle_new_msr(tport, msr);		break;	default:		dev_err(dev, "%s - unknown interrupt code, 0x%02X\n", __FUNCTION__, data[1]);		break;	}exit:	status = usb_submit_urb(urb, GFP_ATOMIC);	if (status)		dev_err(dev, "%s - resubmit interrupt urb failed, %d\n", __FUNCTION__, status);}static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs){	struct ti_port *tport = (struct ti_port *)urb->context;	struct usb_serial_port *port = tport->tp_port;	struct device *dev = &urb->dev->dev;	int status = 0;	dbg("%s", __FUNCTION__);	switch (urb->status) {	case 0:		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);		tport->tp_tdev->td_urb_error = 1;		wake_up_interruptible(&tport->tp_write_wait);		return;	default:		dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status );		tport->tp_tdev->td_urb_error = 1;		wake_up_interruptible(&tport->tp_write_wait);	}	if (urb->status == -EPIPE)		goto exit;	if (urb->status) {		dev_err(dev, "%s - stopping read!\n", __FUNCTION__);		return;	}	if (port->tty && urb->actual_length) {		usb_serial_debug_data(debug, dev, __FUNCTION__,			urb->actual_length, urb->transfer_buffer);		if (!tport->tp_is_open)			dbg("%s - port closed, dropping data", __FUNCTION__);		else			ti_recv(&urb->dev->dev, port->tty, urb->transfer_buffer,				urb->actual_length);		spin_lock(&tport->tp_lock);		tport->tp_icount.rx += urb->actual_length;		spin_unlock(&tport->tp_lock);	}exit:	/* continue to read unless stopping */	spin_lock(&tport->tp_lock);	if (tport->tp_read_urb_state == TI_READ_URB_RUNNING) {		urb->dev = port->serial->dev;		status = usb_submit_urb(urb, GFP_ATOMIC);	} else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING) {		tport->tp_read_urb_state = TI_READ_URB_STOPPED;	}	spin_unlock(&tport->tp_lock);	if (status)		dev_err(dev, "%s - resubmit read urb failed, %d\n", __FUNCTION__, status);}static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs){	struct ti_port *tport = (struct ti_port *)urb->context;	struct usb_serial_port *port = tport->tp_port;	struct device *dev = &urb->dev->dev;	dbg("%s - port %d", __FUNCTION__, port->number);	tport->tp_write_urb_in_use = 0;	switch (urb->status) {	case 0:		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status);		tport->tp_tdev->td_urb_error = 1;		wake_up_interruptible(&tport->tp_write_wait);		return;	default:		dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status);		tport->tp_tdev->td_urb_error = 1;		wake_up_interruptible(&tport->tp_write_wait);	}	/* send any buffered data */	ti_send(tport);}static void ti_recv(struct device *dev, struct tty_struct *tty,	unsigned char *data, int length){	int cnt;	do {		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {			tty_flip_buffer_push(tty);			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {				dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length);				return;			}		}		cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count);		memcpy(tty->flip.char_buf_ptr, data, cnt);		memset(tty->flip.flag_buf_ptr, 0, cnt);		tty->flip.char_buf_ptr += cnt;		tty->flip.flag_buf_ptr += cnt;		tty->flip.count += cnt;		data += cnt;		length -= cnt;	} while (length > 0);	tty_flip_buffer_push(tty);}static void ti_send(struct ti_port *tport){	int count, result;	struct usb_serial_port *port = tport->tp_port;	struct tty_struct *tty = port->tty;	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&tport->tp_lock, flags);	if (tport->tp_write_urb_in_use) {		spin_unlock_irqrestore(&tport->tp_lock, flags);		return;	}	count = ti_buf_get(tport->tp_write_buf,				port->write_urb->transfer_buffer,				port->bulk_out_size);	if (count == 0) {		spin_unlock_irqrestore(&tport->tp_lock, flags);		return;	}	tport->tp_write_urb_in_use = 1;	spin_unlock_irqrestore(&tport->tp_lock, flags);	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer);	usb_fill_bulk_urb(port->write_urb, port->serial->dev,			   usb_sndbulkpipe(port->serial->dev,					    port->bulk_out_endpointAddress),			   port->write_urb->transfer_buffer, count,			   ti_bulk_out_callback, tport);	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);	if (result) {		dev_err(&port->dev, "%s - submit write urb failed, %d\n", __FUNCTION__, result);		tport->tp_write_urb_in_use = 0; 		/* TODO: reschedule ti_send */	} else {		spin_lock_irqsave(&tport->tp_lock, flags);		tport->tp_icount.tx += count;		spin_unlock_irqrestore(&tport->tp_lock, flags);	}	/* more room in the buffer for new writes, wakeup */	if (tty)		tty_wakeup(tty);	wake_up_interruptible(&tport->tp_write_wait);}static int ti_set_mcr(struct ti_port *tport, unsigned int mcr){	int status;	status = ti_write_byte(tport->tp_tdev,		tport->tp_uart_base_addr + TI_UART_OFFSET_MCR,		TI_MCR_RTS | TI_MCR_DTR | TI_MCR_LOOP, mcr);	if (!status)		tport->tp_shadow_mcr = mcr;	return status;}static int ti_get_lsr(struct ti_port *tport){	int size,status;	struct ti_device *tdev = tport->tp_tdev;	struct usb_serial_port *port = tport->tp_port;	int port_number = port->number - port->serial->minor;	struct ti_port_status *data;	dbg("%s - port %d", __FUNCTION__, port->number);

⌨️ 快捷键说明

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