diff options
Diffstat (limited to 'drivers/usb/serial/ipaq.c')
| -rw-r--r-- | drivers/usb/serial/ipaq.c | 357 | 
1 files changed, 10 insertions, 347 deletions
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 3fea9298eb1..28913fa95fb 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -56,7 +56,6 @@  #include <linux/uaccess.h>  #include <linux/usb.h>  #include <linux/usb/serial.h> -#include "ipaq.h"  #define KP_RETRIES	100 @@ -64,7 +63,7 @@   * Version Information   */ -#define DRIVER_VERSION "v0.5" +#define DRIVER_VERSION "v1.0"  #define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>"  #define DRIVER_DESC "USB PocketPC PDA driver" @@ -76,20 +75,8 @@ static int initial_wait;  /* Function prototypes for an ipaq */  static int  ipaq_open(struct tty_struct *tty,  			struct usb_serial_port *port); -static void ipaq_close(struct usb_serial_port *port);  static int  ipaq_calc_num_ports(struct usb_serial *serial);  static int  ipaq_startup(struct usb_serial *serial); -static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, -			const unsigned char *buf, int count); -static int ipaq_write_bulk(struct usb_serial_port *port, -				const unsigned char *buf, int count); -static void ipaq_write_gather(struct usb_serial_port *port); -static void ipaq_read_bulk_callback(struct urb *urb); -static void ipaq_write_bulk_callback(struct urb *urb); -static int ipaq_write_room(struct tty_struct *tty); -static int ipaq_chars_in_buffer(struct tty_struct *tty); -static void ipaq_destroy_lists(struct usb_serial_port *port); -  static struct usb_device_id ipaq_id_table [] = {  	/* The first entry is a placeholder for the insmod-specified device */ @@ -558,7 +545,7 @@ static struct usb_driver ipaq_driver = {  	.probe =	usb_serial_probe,  	.disconnect =	usb_serial_disconnect,  	.id_table =	ipaq_id_table, -	.no_dynamic_id = 	1, +	.no_dynamic_id =	1,  }; @@ -569,91 +556,24 @@ static struct usb_serial_driver ipaq_device = {  		.name =		"ipaq",  	},  	.description =		"PocketPC PDA", -	.usb_driver = 		&ipaq_driver, +	.usb_driver =		&ipaq_driver,  	.id_table =		ipaq_id_table, +	.bulk_in_size =		256, +	.bulk_out_size =	256,  	.open =			ipaq_open, -	.close =		ipaq_close,  	.attach =		ipaq_startup,  	.calc_num_ports =	ipaq_calc_num_ports, -	.write =		ipaq_write, -	.write_room =		ipaq_write_room, -	.chars_in_buffer =	ipaq_chars_in_buffer, -	.read_bulk_callback =	ipaq_read_bulk_callback, -	.write_bulk_callback =	ipaq_write_bulk_callback,  }; -static spinlock_t	write_list_lock; -static int		bytes_in; -static int		bytes_out; -  static int ipaq_open(struct tty_struct *tty,  			struct usb_serial_port *port)  {  	struct usb_serial	*serial = port->serial; -	struct ipaq_private	*priv; -	struct ipaq_packet	*pkt; -	int			i, result = 0; +	int			result = 0;  	int			retries = connect_retries;  	dbg("%s - port %d", __func__, port->number); -	bytes_in = 0; -	bytes_out = 0; -	priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL); -	if (priv == NULL) { -		dev_err(&port->dev, "%s - Out of memory\n", __func__); -		return -ENOMEM; -	} -	usb_set_serial_port_data(port, priv); -	priv->active = 0; -	priv->queue_len = 0; -	priv->free_len = 0; -	INIT_LIST_HEAD(&priv->queue); -	INIT_LIST_HEAD(&priv->freelist); - -	for (i = 0; i < URBDATA_QUEUE_MAX / PACKET_SIZE; i++) { -		pkt = kmalloc(sizeof(struct ipaq_packet), GFP_KERNEL); -		if (pkt == NULL) -			goto enomem; - -		pkt->data = kmalloc(PACKET_SIZE, GFP_KERNEL); -		if (pkt->data == NULL) { -			kfree(pkt); -			goto enomem; -		} -		pkt->len = 0; -		pkt->written = 0; -		INIT_LIST_HEAD(&pkt->list); -		list_add(&pkt->list, &priv->freelist); -		priv->free_len += PACKET_SIZE; -	} - -	/* -	 * Lose the small buffers usbserial provides. Make larger ones. -	 */ - -	kfree(port->bulk_in_buffer); -	kfree(port->bulk_out_buffer); -	/* make sure the generic serial code knows */ -	port->bulk_out_buffer = NULL; - -	port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); -	if (port->bulk_in_buffer == NULL) -		goto enomem; - -	port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); -	if (port->bulk_out_buffer == NULL) { -		/* the buffer is useless, free it */ -		kfree(port->bulk_in_buffer); -		port->bulk_in_buffer = NULL; -		goto enomem; -	} -	port->read_urb->transfer_buffer = port->bulk_in_buffer; -	port->write_urb->transfer_buffer = port->bulk_out_buffer; -	port->read_urb->transfer_buffer_length = URBDATA_SIZE; -	port->bulk_out_size = port->write_urb->transfer_buffer_length -							= URBDATA_SIZE; -  	msleep(1000*initial_wait);  	/* @@ -663,7 +583,6 @@ static int ipaq_open(struct tty_struct *tty,  	 * 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, @@ -673,269 +592,15 @@ static int ipaq_open(struct tty_struct *tty,  		msleep(1000);  	} -  	if (!retries && result) { -		dev_err(&port->dev, "%s - failed doing control urb, error %d\n",			__func__, result); -		goto error; -	} - -	/* Start reading from the device */ -	usb_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, GFP_KERNEL); -	if (result) { -		dev_err(&port->dev, -			"%s - failed submitting read urb, error %d\n", -			__func__, result); -		goto error; -	} - -	return 0; - -enomem: -	result = -ENOMEM; -	dev_err(&port->dev, "%s - Out of memory\n", __func__); -error: -	ipaq_destroy_lists(port); -	kfree(priv); -	return result; -} - - -static void ipaq_close(struct usb_serial_port *port) -{ -	struct ipaq_private	*priv = usb_get_serial_port_data(port); - -	dbg("%s - port %d", __func__, 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 usb_serial_port	*port = urb->context; -	struct tty_struct	*tty; -	unsigned char		*data = urb->transfer_buffer; -	int			result; -	int status = urb->status; - -	dbg("%s - port %d", __func__, port->number); - -	if (status) { -		dbg("%s - nonzero read bulk status received: %d", -		    __func__, status); -		return; -	} - -	usb_serial_debug_data(debug, &port->dev, __func__, -						urb->actual_length, data); - -	tty = tty_port_tty_get(&port->port); -	if (tty && urb->actual_length) { -		tty_insert_flip_string(tty, data, urb->actual_length); -		tty_flip_buffer_push(tty); -		bytes_in += urb->actual_length; -	} -	tty_kref_put(tty); - -	/* 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) -		dev_err(&port->dev, -			"%s - failed resubmitting read urb, error %d\n", -			__func__, result); -	return; -} - -static int ipaq_write(struct tty_struct *tty, 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", __func__, 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; +		dev_err(&port->dev, "%s - failed doing control urb, error %d\n", +							__func__, result); +		return result;  	} -	return bytes_sent; +	return usb_serial_generic_open(tty, port);  } -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", __func__); -		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", __func__); -		return -EAGAIN; -	} - -	memcpy(pkt->data, buf, count); -	usb_serial_debug_data(debug, &port->dev, __func__, 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) -			dev_err(&port->dev, -				"%s - failed submitting write urb, error %d\n", -				__func__, 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 usb_serial_port	*port = urb->context; -	struct ipaq_private	*priv = usb_get_serial_port_data(port); -	unsigned long		flags; -	int			result; -	int status = urb->status; - -	dbg("%s - port %d", __func__, port->number); - -	if (status) { -		dbg("%s - nonzero write bulk status received: %d", -		    __func__, status); -		return; -	} - -	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) -			dev_err(&port->dev, -				"%s - failed submitting write urb, error %d\n", -				__func__, result); -	} else { -		priv->active = 0; -		spin_unlock_irqrestore(&write_list_lock, flags); -	} - -	usb_serial_port_softint(port); -} - -static int ipaq_write_room(struct tty_struct *tty) -{ -	struct usb_serial_port *port = tty->driver_data; -	struct ipaq_private	*priv = usb_get_serial_port_data(port); - -	dbg("%s - freelen %d", __func__, priv->free_len); -	return priv->free_len; -} - -static int ipaq_chars_in_buffer(struct tty_struct *tty) -{ -	struct usb_serial_port *port = tty->driver_data; -	struct ipaq_private	*priv = usb_get_serial_port_data(port); - -	dbg("%s - queuelen %d", __func__, 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_calc_num_ports(struct usb_serial *serial)  {  	/* @@ -994,7 +659,6 @@ static int ipaq_startup(struct usb_serial *serial)  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; @@ -1015,7 +679,6 @@ failed_usb_serial_register:  	return retval;  } -  static void __exit ipaq_exit(void)  {  	usb_deregister(&ipaq_driver);  |