# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.623 -> 1.624 # drivers/usb/serial/ipaq.c 1.6 -> 1.7 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/08/29 greg@kroah.com 1.624 # USB: ipaq update due to usbserial core changes. # -------------------------------------------- # diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c --- a/drivers/usb/serial/ipaq.c Thu Aug 29 13:54:41 2002 +++ b/drivers/usb/serial/ipaq.c Thu Aug 29 13:54:41 2002 @@ -38,18 +38,15 @@ #include #include -#include -#include #include -#include #include #include -#include #include #include #include #include #include +#include #include #ifdef CONFIG_USB_SERIAL_DEBUG @@ -99,24 +96,22 @@ /* All of the device info needed for the Compaq iPAQ */ struct usb_serial_device_type ipaq_device = { - name: "Compaq iPAQ", - id_table: ipaq_id_table, - needs_interrupt_in: DONT_CARE, - needs_bulk_in: MUST_HAVE, - needs_bulk_out: MUST_HAVE, - num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: ipaq_open, - close: ipaq_close, - startup: ipaq_startup, - shutdown: ipaq_shutdown, - 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, + .owner = THIS_MODULE, + .name = "Compaq iPAQ", + .id_table = ipaq_id_table, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = ipaq_open, + .close = ipaq_close, + .startup = ipaq_startup, + .shutdown = ipaq_shutdown, + .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; @@ -137,121 +132,101 @@ dbg("%s - port %d", __FUNCTION__, port->number); - down(&port->sem); - - ++port->open_count; - MOD_INC_USE_COUNT; - - if (!port->active) { - port->active = 1; - bytes_in = 0; - bytes_out = 0; - priv = (struct ipaq_private *)kmalloc(sizeof(struct ipaq_private), GFP_KERNEL); - if (priv == NULL) { - err("%s - Out of memory", __FUNCTION__); - result = -ENOMEM; - goto error; - } - port->private = (void *)priv; - priv->active = 0; - priv->queue_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; - } - - /* - * Force low latency on. This will immediately push data to the line - * discipline instead of queueing. - */ - - port->tty->low_latency = 1; - port->tty->raw = 1; - port->tty->real_raw = 1; - - /* - * Lose the small buffers usbserial provides. Make larger ones. - */ - - kfree(port->bulk_in_buffer); - kfree(port->bulk_out_buffer); - port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); - if (port->bulk_in_buffer == NULL) { + bytes_in = 0; + bytes_out = 0; + priv = (struct ipaq_private *)kmalloc(sizeof(struct ipaq_private), GFP_KERNEL); + if (priv == NULL) { + err("%s - Out of memory", __FUNCTION__); + return -ENOMEM; + } + port->private = (void *)priv; + priv->active = 0; + priv->queue_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; } - port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); - if (port->bulk_out_buffer == NULL) { - kfree(port->bulk_in_buffer); + pkt->data = kmalloc(PACKET_SIZE, GFP_KERNEL); + if (pkt->data == NULL) { + kfree(pkt); 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; - - /* Start reading from the device */ - 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 submitting read urb, error %d", __FUNCTION__, result); - goto cleanup; - } - - /* - * 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, HZ / 10 + 1); - if (result == 0) { - break; - } - } - if (result < 0) { - err("%s - failed doing control urb, error %d", __FUNCTION__, result); - goto cleanup; + pkt->len = 0; + pkt->written = 0; + INIT_LIST_HEAD(&pkt->list); + list_add(&pkt->list, &priv->freelist); + priv->free_len += PACKET_SIZE; + } + + /* + * Force low latency on. This will immediately push data to the line + * discipline instead of queueing. + */ + + port->tty->low_latency = 1; + port->tty->raw = 1; + port->tty->real_raw = 1; + + /* + * Lose the small buffers usbserial provides. Make larger ones. + */ + + kfree(port->bulk_in_buffer); + kfree(port->bulk_out_buffer); + 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) { + kfree(port->bulk_in_buffer); + 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; + + /* Start reading from the device */ + 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 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, HZ / 10 + 1); + if (result == 0) { + return 0; } } + err("%s - failed doing control urb, error %d", __FUNCTION__, result); + goto error; - up(&port->sem); - return 0; - enomem: - err("%s - Out of memory", __FUNCTION__); result = -ENOMEM; -cleanup: + err("%s - Out of memory", __FUNCTION__); +error: ipaq_destroy_lists(port); kfree(priv); -error: - port->private = NULL; - port->open_count = 0; - port->active = 0; - up(&port->sem); - MOD_DEC_USE_COUNT; return result; } @@ -270,32 +245,19 @@ serial = get_usb_serial(port, __FUNCTION__); if (!serial) return; - - down (&port->sem); - - --port->open_count; - if (port->open_count <= 0) { + /* + * shut down bulk read and write + */ - /* - * shut down bulk read and write - */ - - usb_unlink_urb(port->write_urb); - usb_unlink_urb(port->read_urb); - ipaq_destroy_lists(port); - kfree(priv); - port->private = NULL; - port->active = 0; - port->open_count = 0; - - } - up (&port->sem); + usb_unlink_urb(port->write_urb); + usb_unlink_urb(port->read_urb); + ipaq_destroy_lists(port); + kfree(priv); + 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); */ - - MOD_DEC_USE_COUNT; } static void ipaq_read_bulk_callback(struct urb *urb) @@ -399,7 +361,8 @@ } if (from_user) { - copy_from_user(pkt->data, buf, count); + if (copy_from_user(pkt->data, buf, count)) + return -EFAULT; } else { memcpy(pkt->data, buf, count); } @@ -548,16 +511,7 @@ static void ipaq_shutdown(struct usb_serial *serial) { - int i; - dbg("%s", __FUNCTION__); - - /* stop reads and writes on all ports */ - for (i=0; i < serial->num_ports; ++i) { - while (serial->port[i].open_count > 0) { - ipaq_close(&serial->port[i], NULL); - } - } } static int __init ipaq_init(void)