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

📄 ti_usb_3410_5052.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	size = sizeof(struct ti_port_status);	data = kmalloc(size, GFP_KERNEL);	if (!data) {		dev_err(&port->dev, "%s - out of memory\n", __FUNCTION__);		return -ENOMEM;	}	status = ti_command_in_sync(tdev, TI_GET_PORT_STATUS,		(__u8)(TI_UART1_PORT+port_number), 0, (__u8 *)data, size);	if (status) {		dev_err(&port->dev, "%s - get port status command failed, %d\n", __FUNCTION__, status);		goto free_data;	}	dbg("%s - lsr 0x%02X", __FUNCTION__, data->bLSR);	tport->tp_lsr = data->bLSR;free_data:	kfree(data);	return status;}static int ti_get_serial_info(struct ti_port *tport,	struct serial_struct __user *ret_arg){	struct usb_serial_port *port = tport->tp_port;	struct serial_struct ret_serial;	if (!ret_arg)		return -EFAULT;	memset(&ret_serial, 0, sizeof(ret_serial));	ret_serial.type = PORT_16550A;	ret_serial.line = port->serial->minor;	ret_serial.port = port->number - port->serial->minor;	ret_serial.flags = tport->tp_flags;	ret_serial.xmit_fifo_size = TI_WRITE_BUF_SIZE;	ret_serial.baud_base = tport->tp_tdev->td_is_3410 ? 921600 : 460800;	ret_serial.closing_wait = tport->tp_closing_wait;	if (copy_to_user(ret_arg, &ret_serial, sizeof(*ret_arg)))		return -EFAULT;	return 0;}static int ti_set_serial_info(struct ti_port *tport,	struct serial_struct __user *new_arg){	struct usb_serial_port *port = tport->tp_port;	struct serial_struct new_serial;	if (copy_from_user(&new_serial, new_arg, sizeof(new_serial)))		return -EFAULT;	tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;	if (port->tty)		port->tty->low_latency =			(tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;	tport->tp_closing_wait = new_serial.closing_wait;	return 0;}static void ti_handle_new_msr(struct ti_port *tport, __u8 msr){	struct async_icount *icount;	struct tty_struct *tty;	unsigned long flags;	dbg("%s - msr 0x%02X", __FUNCTION__, msr);	if (msr & TI_MSR_DELTA_MASK) {		spin_lock_irqsave(&tport->tp_lock, flags);		icount = &tport->tp_icount;		if (msr & TI_MSR_DELTA_CTS)			icount->cts++;		if (msr & TI_MSR_DELTA_DSR)			icount->dsr++;		if (msr & TI_MSR_DELTA_CD)			icount->dcd++;		if (msr & TI_MSR_DELTA_RI)			icount->rng++;		wake_up_interruptible(&tport->tp_msr_wait);		spin_unlock_irqrestore(&tport->tp_lock, flags);	}	tport->tp_msr = msr & TI_MSR_MASK;	/* handle CTS flow control */	tty = tport->tp_port->tty;	if (tty && C_CRTSCTS(tty)) {		if (msr & TI_MSR_CTS) {			tty->hw_stopped = 0;			tty_wakeup(tty);		} else {			tty->hw_stopped = 1;		}	}}static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush){	struct ti_device *tdev = tport->tp_tdev;	struct usb_serial_port *port = tport->tp_port;	wait_queue_t wait;	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&tport->tp_lock, flags);	/* wait for data to drain from the buffer */	tdev->td_urb_error = 0;	init_waitqueue_entry(&wait, current);	add_wait_queue(&tport->tp_write_wait, &wait);	for (;;) {		set_current_state(TASK_INTERRUPTIBLE);		if (ti_buf_data_avail(tport->tp_write_buf) == 0		|| timeout == 0 || signal_pending(current)		|| tdev->td_urb_error		|| !usb_get_intfdata(port->serial->interface))  /* disconnect */			break;		spin_unlock_irqrestore(&tport->tp_lock, flags);		timeout = schedule_timeout(timeout);		spin_lock_irqsave(&tport->tp_lock, flags);	}	set_current_state(TASK_RUNNING);	remove_wait_queue(&tport->tp_write_wait, &wait);	/* flush any remaining data in the buffer */	if (flush)		ti_buf_clear(tport->tp_write_buf);	spin_unlock_irqrestore(&tport->tp_lock, flags);	/* wait for data to drain from the device */	/* wait for empty tx register, plus 20 ms */	timeout += jiffies;	tport->tp_lsr &= ~TI_LSR_TX_EMPTY;	while ((long)(jiffies - timeout) < 0 && !signal_pending(current)	&& !(tport->tp_lsr&TI_LSR_TX_EMPTY) && !tdev->td_urb_error	&& usb_get_intfdata(port->serial->interface)) {  /* not disconnected */		if (ti_get_lsr(tport))			break;		msleep_interruptible(20);	}}static void ti_stop_read(struct ti_port *tport, struct tty_struct *tty){	unsigned long flags;	spin_lock_irqsave(&tport->tp_lock, flags);	if (tport->tp_read_urb_state == TI_READ_URB_RUNNING)		tport->tp_read_urb_state = TI_READ_URB_STOPPING;	spin_unlock_irqrestore(&tport->tp_lock, flags);}static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty){	struct urb *urb;	int status = 0;	unsigned long flags;	spin_lock_irqsave(&tport->tp_lock, flags);	if (tport->tp_read_urb_state == TI_READ_URB_STOPPED) {		urb = tport->tp_port->read_urb;		urb->complete = ti_bulk_in_callback;		urb->context = tport;		urb->dev = tport->tp_port->serial->dev;		status = usb_submit_urb(urb, GFP_KERNEL);	}	tport->tp_read_urb_state = TI_READ_URB_RUNNING;	spin_unlock_irqrestore(&tport->tp_lock, flags);	return status;}static int ti_command_out_sync(struct ti_device *tdev, __u8 command,	__u16 moduleid, __u16 value, __u8 *data, int size){	int status;	status = usb_control_msg(tdev->td_serial->dev,		usb_sndctrlpipe(tdev->td_serial->dev, 0), command,		(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT),		value, moduleid, data, size, 1000);	if (status == size)		status = 0;	if (status > 0)		status = -ECOMM;	return status;}static int ti_command_in_sync(struct ti_device *tdev, __u8 command,	__u16 moduleid, __u16 value, __u8 *data, int size){	int status;	status = usb_control_msg(tdev->td_serial->dev,		usb_rcvctrlpipe(tdev->td_serial->dev, 0), command,		(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN),		value, moduleid, data, size, 1000);	if (status == size)		status = 0;	if (status > 0)		status = -ECOMM;	return status;}static int ti_write_byte(struct ti_device *tdev, unsigned long addr,	__u8 mask, __u8 byte){	int status;	unsigned int size;	struct ti_write_data_bytes *data;	struct device *dev = &tdev->td_serial->dev->dev;	dbg("%s - addr 0x%08lX, mask 0x%02X, byte 0x%02X", __FUNCTION__, addr, mask, byte);	size = sizeof(struct ti_write_data_bytes) + 2;	data = kmalloc(size, GFP_KERNEL);	if (!data) {		dev_err(dev, "%s - out of memory\n", __FUNCTION__);		return -ENOMEM;	}	data->bAddrType = TI_RW_DATA_ADDR_XDATA;	data->bDataType = TI_RW_DATA_BYTE;	data->bDataCounter = 1;	data->wBaseAddrHi = cpu_to_be16(addr>>16);	data->wBaseAddrLo = cpu_to_be16(addr);	data->bData[0] = mask;	data->bData[1] = byte;	status = ti_command_out_sync(tdev, TI_WRITE_DATA, TI_RAM_PORT, 0,		(__u8 *)data, size);	if (status < 0)		dev_err(dev, "%s - failed, %d\n", __FUNCTION__, status);	kfree(data);	return status;}static int ti_download_firmware(struct ti_device *tdev,	unsigned char *firmware, unsigned int firmware_size){	int status = 0;	int buffer_size;	int pos;	int len;	int done;	__u8 cs = 0;	__u8 *buffer;	struct usb_device *dev = tdev->td_serial->dev;	struct ti_firmware_header *header;	unsigned int pipe = usb_sndbulkpipe(dev,		tdev->td_serial->port[0]->bulk_out_endpointAddress);	buffer_size = TI_FIRMWARE_BUF_SIZE + sizeof(struct ti_firmware_header);	buffer = kmalloc(buffer_size, GFP_KERNEL);	if (!buffer) {		dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);		return -ENOMEM;	}	memcpy(buffer, firmware, firmware_size);	memset(buffer+firmware_size, 0xff, buffer_size-firmware_size);	for(pos = sizeof(struct ti_firmware_header); pos < buffer_size; pos++)		cs = (__u8)(cs + buffer[pos]);	header = (struct ti_firmware_header *)buffer;	header->wLength = cpu_to_le16((__u16)(buffer_size - sizeof(struct ti_firmware_header)));	header->bCheckSum = cs;	dbg("%s - downloading firmware", __FUNCTION__);	for (pos = 0; pos < buffer_size; pos += done) {		len = min(buffer_size - pos, TI_DOWNLOAD_MAX_PACKET_SIZE);		status = usb_bulk_msg(dev, pipe, buffer+pos, len, &done, 1000);		if (status)			break;	}	kfree(buffer);	if (status) {		dev_err(&dev->dev, "%s - error downloading firmware, %d\n", __FUNCTION__, status);		return status;	}	dbg("%s - download successful", __FUNCTION__);	return 0;}/* Circular Buffer Functions *//* * ti_buf_alloc * * Allocate a circular buffer and all associated memory. */static struct circ_buf *ti_buf_alloc(void){	struct circ_buf *cb;	cb = (struct circ_buf *)kmalloc(sizeof(struct circ_buf), GFP_KERNEL);	if (cb == NULL)		return NULL;	cb->buf = kmalloc(TI_WRITE_BUF_SIZE, GFP_KERNEL);	if (cb->buf == NULL) {		kfree(cb);		return NULL;	}	ti_buf_clear(cb);	return cb;}/* * ti_buf_free * * Free the buffer and all associated memory. */static void ti_buf_free(struct circ_buf *cb){	kfree(cb->buf);	kfree(cb);}/* * ti_buf_clear * * Clear out all data in the circular buffer. */static void ti_buf_clear(struct circ_buf *cb){	cb->head = cb->tail = 0;}/* * ti_buf_data_avail * * Return the number of bytes of data available in the circular * buffer. */static int ti_buf_data_avail(struct circ_buf *cb){	return CIRC_CNT(cb->head,cb->tail,TI_WRITE_BUF_SIZE);}/* * ti_buf_space_avail * * Return the number of bytes of space available in the circular * buffer. */static int ti_buf_space_avail(struct circ_buf *cb){	return CIRC_SPACE(cb->head,cb->tail,TI_WRITE_BUF_SIZE);}/* * ti_buf_put * * Copy data data from a user buffer and put it into the circular buffer. * Restrict to the amount of space available. * * Return the number of bytes copied. */static int ti_buf_put(struct circ_buf *cb, const char *buf, int count){	int c, ret = 0;	while (1) {		c = CIRC_SPACE_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE);		if (count < c)			c = count;		if (c <= 0)			break;		memcpy(cb->buf + cb->head, buf, c);		cb->head = (cb->head + c) & (TI_WRITE_BUF_SIZE-1);		buf += c;		count -= c;		ret += c;	}	return ret;}/* * ti_buf_get * * Get data from the circular buffer and copy to the given buffer. * Restrict to the amount of data available. * * Return the number of bytes copied. */static int ti_buf_get(struct circ_buf *cb, char *buf, int count){	int c, ret = 0;	while (1) {		c = CIRC_CNT_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE);		if (count < c)			c = count;		if (c <= 0)			break;		memcpy(buf, cb->buf + cb->tail, c);		cb->tail = (cb->tail + c) & (TI_WRITE_BUF_SIZE-1);		buf += c;		count -= c;		ret += c;	}	return ret;}

⌨️ 快捷键说明

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