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

📄 ipaq.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,		      ipaq_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);		goto error;	}	/*	 * Send out control message observed in win98 sniffs. Not sure what	 * it does, but from empirical observations, it seems that the device	 * will start the chat sequence once one of these messages gets	 * through. Since this has a reasonably high failure rate, we retry	 * several times.	 */	while (retries--) {		result = usb_control_msg(serial->dev,				usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,				0x1, 0, NULL, 0, 100);		if (result == 0) {			return 0;		}	}	err("%s - failed doing control urb, error %d", __FUNCTION__, result);	goto error;enomem:	result = -ENOMEM;	err("%s - Out of memory", __FUNCTION__);error:	ipaq_destroy_lists(port);	kfree(priv);	return result;}static void ipaq_close(struct usb_serial_port *port, struct file *filp){	struct ipaq_private	*priv = usb_get_serial_port_data(port);	dbg("%s - port %d", __FUNCTION__, port->number);			 	/*	 * shut down bulk read and write	 */	usb_kill_urb(port->write_urb);	usb_kill_urb(port->read_urb);	ipaq_destroy_lists(port);	kfree(priv);	usb_set_serial_port_data(port, 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 pt_regs *regs){	struct usb_serial_port	*port = (struct usb_serial_port *)urb->context;	struct tty_struct	*tty;	unsigned char		*data = urb->transfer_buffer;	int			i, result;	dbg("%s - port %d", __FUNCTION__, port->number);	if (urb->status) {		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);		return;	}	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);	tty = port->tty;	if (tty && 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  */	usb_fill_bulk_urb(port->read_urb, port->serial->dev, 		      usb_rcvbulkpipe(port->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, GFP_ATOMIC);	if (result)		err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);	return;}static int ipaq_write(struct usb_serial_port *port, 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);	while (count > 0) {		transfer_size = min(count, PACKET_SIZE);		if (ipaq_write_bulk(port, 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, const unsigned char *buf,			   int count){	struct ipaq_private	*priv = usb_get_serial_port_data(port);	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;	}	memcpy(pkt->data, buf, count);	usb_serial_debug_data(debug, &port->dev, __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, GFP_ATOMIC);		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 = usb_get_serial_port_data(port);	struct usb_serial	*serial = port->serial;	int			count, room;	struct ipaq_packet	*pkt, *tmp;	struct urb		*urb = port->write_urb;	room = URBDATA_SIZE;	list_for_each_entry_safe(pkt, tmp, &priv->queue, list) {		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_move(&pkt->list, &priv->freelist);			priv->free_len += PACKET_SIZE;		}		if (room == 0) {			break;		}	}	count = URBDATA_SIZE - room;	usb_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 pt_regs *regs){	struct usb_serial_port	*port = (struct usb_serial_port *)urb->context;	struct ipaq_private	*priv = usb_get_serial_port_data(port);	unsigned long		flags;	int			result;	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, GFP_ATOMIC);		if (result) {			err("%s - failed submitting write urb, error %d", __FUNCTION__, result);		}	} else {		priv->active = 0;		spin_unlock_irqrestore(&write_list_lock, flags);	}	schedule_work(&port->work);}static int ipaq_write_room(struct usb_serial_port *port){	struct ipaq_private	*priv = usb_get_serial_port_data(port);	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 = usb_get_serial_port_data(port);	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 = usb_get_serial_port_data(port);	struct ipaq_packet	*pkt, *tmp;	list_for_each_entry_safe(pkt, tmp, &priv->queue, list) {		kfree(pkt->data);		kfree(pkt);	}	list_for_each_entry_safe(pkt, tmp, &priv->freelist, list) {		kfree(pkt->data);		kfree(pkt);	}}static int ipaq_startup(struct usb_serial *serial){	dbg("%s", __FUNCTION__);	if (serial->dev->actconfig->desc.bConfigurationValue != 1) {		err("active config #%d != 1 ??",			serial->dev->actconfig->desc.bConfigurationValue);		return -ENODEV;	}	return usb_reset_configuration (serial->dev);}static void ipaq_shutdown(struct usb_serial *serial){	dbg("%s", __FUNCTION__);}static int __init ipaq_init(void){	int retval;	spin_lock_init(&write_list_lock);	retval = usb_serial_register(&ipaq_device);	if (retval) 		goto failed_usb_serial_register;	info(DRIVER_DESC " " DRIVER_VERSION);	if (vendor) {		ipaq_id_table[0].idVendor = vendor;		ipaq_id_table[0].idProduct = product;	}	retval = usb_register(&ipaq_driver);	if (retval)		goto failed_usb_register;		  	return 0;failed_usb_register:	usb_serial_deregister(&ipaq_device);failed_usb_serial_register:	return retval;}static void __exit ipaq_exit(void){	usb_deregister(&ipaq_driver);	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_param(debug, bool, S_IRUGO | S_IWUSR);MODULE_PARM_DESC(debug, "Debug enabled or not");module_param(vendor, ushort, 0);MODULE_PARM_DESC(vendor, "User specified USB idVendor");module_param(product, ushort, 0);MODULE_PARM_DESC(product, "User specified USB idProduct");

⌨️ 快捷键说明

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