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

📄 ipaq.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
	port->private = NULL;	/* Uncomment the following line if you want to see some statistics in your syslog */	/* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */}static void ipaq_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, result;	if (port_paranoia_check(port, __FUNCTION__))		return;	dbg("%s - port %d", __FUNCTION__, port->number);	if (!serial) {		dbg("%s - bad serial pointer, exiting", __FUNCTION__);		return;	}	if (urb->status) {		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, 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);		bytes_in += urb->actual_length;	}	/* 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,		      ipaq_read_bulk_callback, port);	result = usb_submit_urb(port->read_urb);	if (result)		err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);	return;}static int ipaq_write(struct usb_serial_port *port, int from_user, const unsigned char *buf,		       int count){	const unsigned char	*current_position = buf;	int			bytes_sent = 0;	int			transfer_size;	dbg("%s - port %d", __FUNCTION__, port->number);	usb_serial_debug_data(__FILE__, __FUNCTION__, count, buf);		while (count > 0) {		transfer_size = min(count, PACKET_SIZE);		if (ipaq_write_bulk(port, from_user, current_position, transfer_size)) {			break;		}		current_position += transfer_size;		bytes_sent += transfer_size;		count -= transfer_size;		bytes_out += transfer_size;	}	return bytes_sent;} static int ipaq_write_bulk(struct usb_serial_port *port, int from_user, const unsigned char *buf,			   int count){	struct ipaq_private	*priv = port->private;	struct ipaq_packet	*pkt = NULL;	int			result = 0;	unsigned long		flags;	if (priv->free_len <= 0) {		dbg("%s - we're stuffed", __FUNCTION__);		return -EAGAIN;	}	spin_lock_irqsave(&write_list_lock, flags);	if (!list_empty(&priv->freelist)) {		pkt = list_entry(priv->freelist.next, struct ipaq_packet, list);		list_del(&pkt->list);		priv->free_len -= PACKET_SIZE;	}	spin_unlock_irqrestore(&write_list_lock, flags);	if (pkt == NULL) {		dbg("%s - we're stuffed", __FUNCTION__);		return -EAGAIN;	}	if (from_user) {		if (copy_from_user(pkt->data, buf, count))			return -EFAULT;	} else {		memcpy(pkt->data, buf, count);	}	usb_serial_debug_data(__FILE__, __FUNCTION__, count, pkt->data);	pkt->len = count;	pkt->written = 0;	spin_lock_irqsave(&write_list_lock, flags);	list_add_tail(&pkt->list, &priv->queue);	priv->queue_len += count;	if (priv->active == 0) {		priv->active = 1;		ipaq_write_gather(port);		spin_unlock_irqrestore(&write_list_lock, flags);		result = usb_submit_urb(port->write_urb);		if (result) {			err("%s - failed submitting write urb, error %d", __FUNCTION__, result);		}	} else {		spin_unlock_irqrestore(&write_list_lock, flags);	}	return result;}static void ipaq_write_gather(struct usb_serial_port *port){	struct ipaq_private	*priv = (struct ipaq_private *)port->private;	struct usb_serial	*serial = port->serial;	int			count, room;	struct ipaq_packet	*pkt;	struct urb		*urb = port->write_urb;	struct list_head	*tmp;	if (urb->status == -EINPROGRESS) {		/* Should never happen */		err("%s - flushing while urb is active !", __FUNCTION__);		return;	}	room = URBDATA_SIZE;	for (tmp = priv->queue.next; tmp != &priv->queue;) {		pkt = list_entry(tmp, struct ipaq_packet, list);		tmp = tmp->next;		count = min(room, (int)(pkt->len - pkt->written));		memcpy(urb->transfer_buffer + (URBDATA_SIZE - room),		       pkt->data + pkt->written, count);		room -= count;		pkt->written += count;		priv->queue_len -= count;		if (pkt->written == pkt->len) {			list_del(&pkt->list);			list_add(&pkt->list, &priv->freelist);			priv->free_len += PACKET_SIZE;		}		if (room == 0) {			break;		}	}	count = URBDATA_SIZE - room;	FILL_BULK_URB(port->write_urb, serial->dev, 		      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),		      port->write_urb->transfer_buffer, count, ipaq_write_bulk_callback,		      port);	return;}static void ipaq_write_bulk_callback(struct urb *urb){	struct usb_serial_port	*port = (struct usb_serial_port *)urb->context;	struct ipaq_private	*priv = (struct ipaq_private *)port->private;	unsigned long		flags;	int			result;	if (port_paranoia_check (port, __FUNCTION__)) {		return;	}		dbg("%s - port %d", __FUNCTION__, port->number);		if (urb->status) {		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);	}	spin_lock_irqsave(&write_list_lock, flags);	if (!list_empty(&priv->queue)) {		ipaq_write_gather(port);		spin_unlock_irqrestore(&write_list_lock, flags);		result = usb_submit_urb(port->write_urb);		if (result) {			err("%s - failed submitting write urb, error %d", __FUNCTION__, result);		}	} else {		priv->active = 0;		spin_unlock_irqrestore(&write_list_lock, flags);	}	queue_task(&port->tqueue, &tq_immediate);	mark_bh(IMMEDIATE_BH);		return;}static int ipaq_write_room(struct usb_serial_port *port){	struct ipaq_private	*priv = (struct ipaq_private *)port->private;	dbg("%s - freelen %d", __FUNCTION__, priv->free_len);	return priv->free_len;}static int ipaq_chars_in_buffer(struct usb_serial_port *port){	struct ipaq_private	*priv = (struct ipaq_private *)port->private;	dbg("%s - queuelen %d", __FUNCTION__, priv->queue_len);	return priv->queue_len;}static void ipaq_destroy_lists(struct usb_serial_port *port){	struct ipaq_private	*priv = (struct ipaq_private *)port->private;	struct list_head	*tmp;	struct ipaq_packet	*pkt;	for (tmp = priv->queue.next; tmp != &priv->queue;) {		pkt = list_entry(tmp, struct ipaq_packet, list);		tmp = tmp->next;		kfree(pkt->data);		kfree(pkt);	}	for (tmp = priv->freelist.next; tmp != &priv->freelist;) {		pkt = list_entry(tmp, struct ipaq_packet, list);		tmp = tmp->next;		kfree(pkt->data);		kfree(pkt);	}	return;}static int ipaq_startup(struct usb_serial *serial){	dbg("%s", __FUNCTION__);	usb_set_configuration(serial->dev, 1);	return 0;}static void ipaq_shutdown(struct usb_serial *serial){	dbg("%s", __FUNCTION__);}static int __init ipaq_init(void){	spin_lock_init(&write_list_lock);	info(DRIVER_DESC " " DRIVER_VERSION);	if (vendor) {		ipaq_id_table[0].idVendor = vendor;		ipaq_id_table[0].idProduct = product;	}	usb_serial_register(&ipaq_device);	return 0;}static void __exit ipaq_exit(void){	usb_serial_deregister(&ipaq_device);}module_init(ipaq_init);module_exit(ipaq_exit);MODULE_AUTHOR( DRIVER_AUTHOR );MODULE_DESCRIPTION( DRIVER_DESC );MODULE_LICENSE("GPL");MODULE_PARM(debug, "i");MODULE_PARM_DESC(debug, "Debug enabled or not");MODULE_PARM(vendor, "h");MODULE_PARM_DESC(vendor, "User specified USB idVendor");MODULE_PARM(product, "h");MODULE_PARM_DESC(product, "User specified USB idProduct");

⌨️ 快捷键说明

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