diff options
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/Kconfig | 6 | ||||
-rw-r--r-- | drivers/usb/serial/aircable.c | 7 | ||||
-rw-r--r-- | drivers/usb/serial/airprime.c | 1 | ||||
-rw-r--r-- | drivers/usb/serial/ark3116.c | 3 | ||||
-rw-r--r-- | drivers/usb/serial/cp2101.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 29 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.h | 1 | ||||
-rw-r--r-- | drivers/usb/serial/generic.c | 7 | ||||
-rw-r--r-- | drivers/usb/serial/io_edgeport.c | 139 | ||||
-rw-r--r-- | drivers/usb/serial/io_edgeport.h | 6 | ||||
-rw-r--r-- | drivers/usb/serial/ipaq.c | 1 | ||||
-rw-r--r-- | drivers/usb/serial/kl5kusb105.c | 28 | ||||
-rw-r--r-- | drivers/usb/serial/mct_u232.c | 12 | ||||
-rw-r--r-- | drivers/usb/serial/mos7720.c | 34 | ||||
-rw-r--r-- | drivers/usb/serial/mos7840.c | 233 | ||||
-rw-r--r-- | drivers/usb/serial/omninet.c | 40 | ||||
-rw-r--r-- | drivers/usb/serial/option.c | 23 | ||||
-rw-r--r-- | drivers/usb/serial/sierra.c | 25 | ||||
-rw-r--r-- | drivers/usb/serial/visor.c | 22 | ||||
-rw-r--r-- | drivers/usb/serial/whiteheat.c | 8 | ||||
-rw-r--r-- | drivers/usb/serial/whiteheat.h | 4 |
21 files changed, 374 insertions, 257 deletions
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 2f4d303ee36..ba5d1dc0303 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -423,11 +423,11 @@ config USB_SERIAL_MCT_U232 module will be called mct_u232. config USB_SERIAL_MOS7720 - tristate "USB Moschip 7720 Single Port Serial Driver" + tristate "USB Moschip 7720 Serial Driver" depends on USB_SERIAL ---help--- - Say Y here if you want to use a USB Serial single port adapter from - Moschip Semiconductor Tech. + Say Y here if you want to use USB Serial single and double + port adapters from Moschip Semiconductor Tech. To compile this driver as a module, choose M here: the module will be called mos7720. diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 11dad42c3c6..b675735bfbe 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c @@ -209,6 +209,7 @@ static void aircable_send(struct usb_serial_port *port) int count, result; struct aircable_private *priv = usb_get_serial_port_data(port); unsigned char* buf; + u16 *dbuf; dbg("%s - port %d", __FUNCTION__, port->number); if (port->write_urb_busy) return; @@ -226,8 +227,8 @@ static void aircable_send(struct usb_serial_port *port) buf[0] = TX_HEADER_0; buf[1] = TX_HEADER_1; - buf[2] = (unsigned char)count; - buf[3] = (unsigned char)(count >> 8); + dbuf = (u16 *)&buf[2]; + *dbuf = cpu_to_le16((u16)count); serial_buf_get(priv->tx_buf,buf + HCI_HEADER_LENGTH, MAX_HCI_FRAMESIZE); memcpy(port->write_urb->transfer_buffer, buf, @@ -434,7 +435,7 @@ static void aircable_write_bulk_callback(struct urb *urb) __FUNCTION__, urb->status); port->write_urb->transfer_buffer_length = 1; port->write_urb->dev = port->serial->dev; - result = usb_submit_urb(port->write_urb, GFP_KERNEL); + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n", diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 7538c64a509..39a49836259 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -18,7 +18,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ - { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */ { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ { }, }; diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index edd685791a6..ea2175bb227 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -341,7 +341,7 @@ static int ark3116_open(struct usb_serial_port *port, struct file *filp) result = usb_serial_generic_open(port, filp); if (result) - return result; + goto err_out; /* open */ ARK3116_RCV(serial, 111, 0xFE, 0xC0, 0x0000, 0x0003, 0x02, buf); @@ -372,6 +372,7 @@ static int ark3116_open(struct usb_serial_port *port, struct file *filp) if (port->tty) ark3116_set_termios(port, &tmp_termios); +err_out: kfree(buf); return result; diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index d7d0ba986a8..e831cb7f64f 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -58,9 +58,11 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ + { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ + { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1633a0fd48e..95a1805b064 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -342,6 +342,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_USBX_707_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) }, @@ -879,6 +880,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) break; case FT232BM: /* FT232BM chip */ case FT2232C: /* FT2232C chip */ + case FT232RL: if (baud <= 3000000) { div_value = ftdi_232bm_baud_to_divisor(baud); } else { @@ -1021,9 +1023,12 @@ static void ftdi_determine_type(struct usb_serial_port *port) /* (It might be a BM because of the iSerialNumber bug, * but it will still work as an AM device.) */ priv->chip_type = FT8U232AM; - } else { + } else if (version < 0x600) { /* Assume its an FT232BM (or FT245BM) */ priv->chip_type = FT232BM; + } else { + /* Assume its an FT232R */ + priv->chip_type = FT232RL; } info("Detected %s", ftdi_chip_name[priv->chip_type]); } @@ -1429,6 +1434,7 @@ static int ftdi_write (struct usb_serial_port *port, dbg("%s - write limit hit\n", __FUNCTION__); return 0; } + priv->tx_outstanding_urbs++; spin_unlock_irqrestore(&priv->tx_lock, flags); data_offset = priv->write_offset; @@ -1446,14 +1452,15 @@ static int ftdi_write (struct usb_serial_port *port, buffer = kmalloc (transfer_size, GFP_ATOMIC); if (!buffer) { err("%s ran out of kernel memory for urb ...", __FUNCTION__); - return -ENOMEM; + count = -ENOMEM; + goto error_no_buffer; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { err("%s - no more free urbs", __FUNCTION__); - kfree (buffer); - return -ENOMEM; + count = -ENOMEM; + goto error_no_urb; } /* Copy data */ @@ -1495,10 +1502,9 @@ static int ftdi_write (struct usb_serial_port *port, if (status) { err("%s - failed submitting write urb, error %d", __FUNCTION__, status); count = status; - kfree (buffer); + goto error; } else { spin_lock_irqsave(&priv->tx_lock, flags); - ++priv->tx_outstanding_urbs; priv->tx_outstanding_bytes += count; priv->tx_bytes += count; spin_unlock_irqrestore(&priv->tx_lock, flags); @@ -1506,10 +1512,19 @@ static int ftdi_write (struct usb_serial_port *port, /* we are done with this urb, so let the host driver * really free it when it is finished with it */ - usb_free_urb (urb); + usb_free_urb(urb); dbg("%s write returning: %d", __FUNCTION__, count); return count; +error: + usb_free_urb(urb); +error_no_urb: + kfree (buffer); +error_no_buffer: + spin_lock_irqsave(&priv->tx_lock, flags); + priv->tx_outstanding_urbs--; + spin_unlock_irqrestore(&priv->tx_lock, flags); + return count; } /* ftdi_write */ diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 513cfe1b768..77ad0a09b38 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -31,6 +31,7 @@ #define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ +#define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 */ /* www.canusb.com Lawicel CANUSB device */ diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 53baeec8f26..4f8282ad772 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -20,13 +20,14 @@ #include <linux/usb/serial.h> #include <asm/uaccess.h> -static int generic_probe(struct usb_interface *interface, - const struct usb_device_id *id); - static int debug; #ifdef CONFIG_USB_SERIAL_GENERIC + +static int generic_probe(struct usb_interface *interface, + const struct usb_device_id *id); + static __u16 vendor = 0x05f9; static __u16 product = 0xffff; diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 6a26a2e683a..18f74ac7656 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -111,7 +111,7 @@ struct edgeport_port { struct TxFifo txfifo; /* transmit fifo -- size will be maxTxCredits */ struct urb *write_urb; /* write URB for this port */ - char write_in_progress; /* TRUE while a write URB is outstanding */ + bool write_in_progress; /* 'true' while a write URB is outstanding */ spinlock_t ep_lock; __u8 shadowLCR; /* last LCR value received */ @@ -123,11 +123,11 @@ struct edgeport_port { __u8 validDataMask; __u32 baudRate; - char open; - char openPending; - char commandPending; - char closePending; - char chaseResponsePending; + bool open; + bool openPending; + bool commandPending; + bool closePending; + bool chaseResponsePending; wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */ @@ -156,7 +156,7 @@ struct edgeport_serial { __u8 bulk_in_endpoint; /* the bulk in endpoint handle */ unsigned char * bulk_in_buffer; /* the buffer we use for the bulk in endpoint */ struct urb * read_urb; /* our bulk read urb */ - int read_in_progress; + bool read_in_progress; spinlock_t es_lock; __u8 bulk_out_endpoint; /* the bulk out endpoint handle */ @@ -212,7 +212,7 @@ static int debug; static int low_latency = 1; /* tty low latency flag, on by default */ -static int CmdUrbs = 0; /* Number of outstanding Command Write Urbs */ +static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */ /* local function prototypes */ @@ -631,14 +631,14 @@ static void edge_interrupt_callback (struct urb *urb) if (edge_serial->rxBytesAvail > 0 && !edge_serial->read_in_progress) { dbg("%s - posting a read", __FUNCTION__); - edge_serial->read_in_progress = TRUE; + edge_serial->read_in_progress = true; /* we have pending bytes on the bulk in pipe, send a request */ edge_serial->read_urb->dev = edge_serial->serial->dev; result = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); if (result) { dev_err(&edge_serial->serial->dev->dev, "%s - usb_submit_urb(read bulk) failed with result = %d\n", __FUNCTION__, result); - edge_serial->read_in_progress = FALSE; + edge_serial->read_in_progress = false; } } spin_unlock(&edge_serial->es_lock); @@ -695,13 +695,13 @@ static void edge_bulk_in_callback (struct urb *urb) if (urb->status) { dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); - edge_serial->read_in_progress = FALSE; + edge_serial->read_in_progress = false; return; } if (urb->actual_length == 0) { dbg("%s - read bulk callback with no data", __FUNCTION__); - edge_serial->read_in_progress = FALSE; + edge_serial->read_in_progress = false; return; } @@ -725,10 +725,10 @@ static void edge_bulk_in_callback (struct urb *urb) status = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); if (status) { dev_err(&urb->dev->dev, "%s - usb_submit_urb(read bulk) failed, status = %d\n", __FUNCTION__, status); - edge_serial->read_in_progress = FALSE; + edge_serial->read_in_progress = false; } } else { - edge_serial->read_in_progress = FALSE; + edge_serial->read_in_progress = false; } spin_unlock(&edge_serial->es_lock); @@ -759,7 +759,7 @@ static void edge_bulk_out_data_callback (struct urb *urb) } // Release the Write URB - edge_port->write_in_progress = FALSE; + edge_port->write_in_progress = false; // Check if more data needs to be sent send_more_port_data((struct edgeport_serial *)(usb_get_serial_data(edge_port->port->serial)), edge_port); @@ -779,8 +779,8 @@ static void edge_bulk_out_cmd_callback (struct urb *urb) dbg("%s", __FUNCTION__); - CmdUrbs--; - dbg("%s - FREE URB %p (outstanding %d)", __FUNCTION__, urb, CmdUrbs); + atomic_dec(&CmdUrbs); + dbg("%s - FREE URB %p (outstanding %d)", __FUNCTION__, urb, atomic_read(&CmdUrbs)); /* clean up the transfer buffer */ @@ -802,7 +802,7 @@ static void edge_bulk_out_cmd_callback (struct urb *urb) tty_wakeup(tty); /* we have completed the command */ - edge_port->commandPending = FALSE; + edge_port->commandPending = false; wake_up(&edge_port->wait_command); } @@ -868,7 +868,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) port0->bulk_in_buffer, edge_serial->read_urb->transfer_buffer_length, edge_bulk_in_callback, edge_serial); - edge_serial->read_in_progress = FALSE; + edge_serial->read_in_progress = false; /* start interrupt read for this edgeport * this interrupt will continue as long as the edgeport is connected */ @@ -890,26 +890,26 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) /* initialize our port settings */ edge_port->txCredits = 0; /* Can't send any data yet */ edge_port->shadowMCR = MCR_MASTER_IE; /* Must always set this bit to enable ints! */ - edge_port->chaseResponsePending = FALSE; + edge_port->chaseResponsePending = false; /* send a open port command */ - edge_port->openPending = TRUE; - edge_port->open = FALSE; + edge_port->openPending = true; + edge_port->open = false; response = send_iosp_ext_cmd (edge_port, IOSP_CMD_OPEN_PORT, 0); if (response < 0) { dev_err(&port->dev, "%s - error sending open port command\n", __FUNCTION__); - edge_port->openPending = FALSE; + edge_port->openPending = false; return -ENODEV; } /* now wait for the port to be completely opened */ - wait_event_timeout(edge_port->wait_open, (edge_port->openPending != TRUE), OPEN_TIMEOUT); + wait_event_timeout(edge_port->wait_open, !edge_port->openPending, OPEN_TIMEOUT); - if (edge_port->open == FALSE) { + if (!edge_port->open) { /* open timed out */ dbg("%s - open timedout", __FUNCTION__); - edge_port->openPending = FALSE; + edge_port->openPending = false; return -ENODEV; } @@ -928,7 +928,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) /* Allocate a URB for the write */ edge_port->write_urb = usb_alloc_urb (0, GFP_KERNEL); - edge_port->write_in_progress = FALSE; + edge_port->write_in_progress = false; if (!edge_port->write_urb) { dbg("%s - no memory", __FUNCTION__); @@ -966,7 +966,7 @@ static void block_until_chase_response(struct edgeport_port *edge_port) lastCredits = edge_port->txCredits; // Did we get our Chase response - if (edge_port->chaseResponsePending == FALSE) { + if (!edge_port->chaseResponsePending) { dbg("%s - Got Chase Response", __FUNCTION__); // did we get all of our credit back? @@ -985,7 +985,7 @@ static void block_until_chase_response(struct edgeport_port *edge_port) // No activity.. count down. loop--; if (loop == 0) { - edge_port->chaseResponsePending = FALSE; + edge_port->chaseResponsePending = false; dbg("%s - Chase TIMEOUT", __FUNCTION__); return; } @@ -1068,13 +1068,13 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) // block until tx is empty block_until_tx_empty(edge_port); - edge_port->closePending = TRUE; + edge_port->closePending = true; if ((!edge_serial->is_epic) || ((edge_serial->is_epic) && (edge_serial->epic_descriptor.Supports.IOSPChase))) { /* flush and chase */ - edge_port->chaseResponsePending = TRUE; + edge_port->chaseResponsePending = true; dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); @@ -1082,7 +1082,7 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) // block until chase finished block_until_chase_response(edge_port); } else { - edge_port->chaseResponsePending = FALSE; + edge_port->chaseResponsePending = false; } } @@ -1094,10 +1094,10 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); } - //port->close = TRUE; - edge_port->closePending = FALSE; - edge_port->open = FALSE; - edge_port->openPending = FALSE; + //port->close = true; + edge_port->closePending = false; + edge_port->open = false; + edge_port->openPending = false; usb_kill_urb(edge_port->write_urb); @@ -1247,7 +1247,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge } // lock this write - edge_port->write_in_progress = TRUE; + edge_port->write_in_progress = true; // get a pointer to the write_urb urb = edge_port->write_urb; @@ -1261,7 +1261,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge buffer = kmalloc (count+2, GFP_ATOMIC); if (buffer == NULL) { dev_err(&edge_port->port->dev, "%s - no more kernel memory...\n", __FUNCTION__); - edge_port->write_in_progress = FALSE; + edge_port->write_in_progress = false; goto exit_send; } buffer[0] = IOSP_BUILD_DATA_HDR1 (edge_port->port->number - edge_port->port->serial->minor, count); @@ -1301,7 +1301,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge if (status) { /* something went wrong */ dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n", __FUNCTION__, status); - edge_port->write_in_progress = FALSE; + edge_port->write_in_progress = false; /* revert the credits as something bad happened. */ edge_port->txCredits += count; @@ -1332,7 +1332,7 @@ static int edge_write_room (struct usb_serial_port *port) if (edge_port == NULL) return -ENODEV; - if (edge_port->closePending == TRUE) + if (edge_port->closePending) return -ENODEV; dbg("%s - port %d", __FUNCTION__, port->number); @@ -1371,7 +1371,7 @@ static int edge_chars_in_buffer (struct usb_serial_port *port) if (edge_port == NULL) return -ENODEV; - if (edge_port->closePending == TRUE) + if (edge_port->closePending) return -ENODEV; if (!edge_port->open) { @@ -1762,7 +1762,7 @@ static void edge_break (struct usb_serial_port *port, int break_state) ((edge_serial->is_epic) && (edge_serial->epic_descriptor.Supports.IOSPChase))) { /* flush and chase */ - edge_port->chaseResponsePending = TRUE; + edge_port->chaseResponsePending = true; dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); @@ -1770,7 +1770,7 @@ static void edge_break (struct usb_serial_port *port, int break_state) // block until chase finished block_until_chase_response(edge_port); } else { - edge_port->chaseResponsePending = FALSE; + edge_port->chaseResponsePending = false; } } @@ -1952,13 +1952,13 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2 // Also, we currently clear flag and close the port regardless of content of above's Byte3. // We could choose to do something else when Byte3 says Timeout on Chase from Edgeport, // like wait longer in block_until_chase_response, but for now we don't. - edge_port->chaseResponsePending = FALSE; + edge_port->chaseResponsePending = false; wake_up (&edge_port->wait_chase); return; case IOSP_EXT_STATUS_RX_CHECK_RSP: dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __FUNCTION__, edge_serial->rxPort, byte3 ); - //Port->RxCheckRsp = TRUE; + //Port->RxCheckRsp = true; return; } } @@ -1974,8 +1974,8 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2 change_port_settings (edge_port, edge_port->port->tty->termios); /* we have completed the open */ - edge_port->openPending = FALSE; - edge_port->open = TRUE; + edge_port->openPending = false; + edge_port->open = true; wake_up(&edge_port->wait_open); return; } @@ -1983,7 +1983,7 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2 // If port is closed, silently discard all rcvd status. We can // have cases where buffered status is received AFTER the close // port command is sent to the Edgeport. - if ((!edge_port->open ) || (edge_port->closePending)) { + if (!edge_port->open || edge_port->closePending) { return; } @@ -1991,14 +1991,14 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2 // Not currently sent by Edgeport case IOSP_STATUS_LSR: dbg("%s - Port %u LSR Status = %02x", __FUNCTION__, edge_serial->rxPort, byte2); - handle_new_lsr (edge_port, FALSE, byte2, 0); + handle_new_lsr(edge_port, false, byte2, 0); break; case IOSP_STATUS_LSR_DATA: dbg("%s - Port %u LSR Status = %02x, Data = %02x", __FUNCTION__, edge_serial->rxPort, byte2, byte3); // byte2 is LSR Register // byte3 is broken data byte - handle_new_lsr (edge_port, TRUE, byte2, byte3); + handle_new_lsr(edge_port, true, byte2, byte3); break; // // case IOSP_EXT_4_STATUS: @@ -2317,14 +2317,14 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer if (!urb) return -ENOMEM; - CmdUrbs++; - dbg("%s - ALLOCATE URB %p (outstanding %d)", __FUNCTION__, urb, CmdUrbs); + atomic_inc(&CmdUrbs); + dbg("%s - ALLOCATE URB %p (outstanding %d)", __FUNCTION__, urb, atomic_read(&CmdUrbs)); usb_fill_bulk_urb (urb, edge_serial->serial->dev, usb_sndbulkpipe(edge_serial->serial->dev, edge_serial->bulk_out_endpoint), buffer, length, edge_bulk_out_cmd_callback, edge_port); - edge_port->commandPending = TRUE; + edge_port->commandPending = true; status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { @@ -2332,16 +2332,16 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write command) failed, status = %d\n", __FUNCTION__, status); usb_kill_urb(urb); usb_free_urb(urb); - CmdUrbs--; + atomic_dec(&CmdUrbs); return status; } // wait for command to finish timeout = COMMAND_TIMEOUT; #if 0 - wait_event (&edge_port->wait_command, (edge_port->commandPending == FALSE)); + wait_event (&edge_port->wait_command, !edge_port->commandPending); - if (edge_port->commandPending == TRUE) { + if (edge_port->commandPending) { /* command timed out */ dbg("%s - command timed out", __FUNCTION__); status = -EINVAL; @@ -2524,8 +2524,8 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi dbg("%s - port %d", __FUNCTION__, edge_port->port->number); - if ((!edge_port->open) && - (!edge_port->openPending)) { + if (!edge_port->open && + !edge_port->openPending) { dbg("%s - port not opened", __FUNCTION__); return; } @@ -2836,9 +2836,9 @@ static int edge_startup (struct usb_serial *serial) struct usb_device *dev; int i, j; int response; - int interrupt_in_found; - int bulk_in_found; - int bulk_out_found; + bool interrupt_in_found; + bool bulk_in_found; + bool bulk_out_found; static __u32 descriptor[3] = { EDGE_COMPATIBILITY_MASK0, EDGE_COMPATIBILITY_MASK1, EDGE_COMPATIBILITY_MASK2 }; @@ -2936,14 +2936,14 @@ static int edge_startup (struct usb_serial *serial) if (edge_serial->is_epic) { /* EPIC thing, set up our interrupt polling now and our read urb, so * that the device knows it really is connected. */ - interrupt_in_found = bulk_in_found = bulk_out_found = FALSE; + interrupt_in_found = bulk_in_found = bulk_out_found = false; for (i = 0; i < serial->interface->altsetting[0].desc.bNumEndpoints; ++i) { struct usb_endpoint_descriptor *endpoint; int buffer_size; endpoint = &serial->interface->altsetting[0].endpoint[i].desc; buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - if ((!interrupt_in_found) && + if (!interrupt_in_found && (usb_endpoint_is_int_in(endpoint))) { /* we found a interrupt in endpoint */ dbg("found interrupt in"); @@ -2972,10 +2972,10 @@ static int edge_startup (struct usb_serial *serial) edge_serial, endpoint->bInterval); - interrupt_in_found = TRUE; + interrupt_in_found = true; } - if ((!bulk_in_found) && + if (!bulk_in_found && (usb_endpoint_is_bulk_in(endpoint))) { /* we found a bulk in endpoint */ dbg("found bulk in"); @@ -3001,19 +3001,19 @@ static int edge_startup (struct usb_serial *serial) endpoint->wMaxPacketSize, edge_bulk_in_callback, edge_serial); - bulk_in_found = TRUE; + bulk_in_found = true; } - if ((!bulk_out_found) && + if (!bulk_out_found && (usb_endpoint_is_bulk_out(endpoint))) { /* we found a bulk out endpoint */ dbg("found bulk out"); edge_serial->bulk_out_endpoint = endpoint->bEndpointAddress; - bulk_out_found = TRUE; + bulk_out_found = true; } } - if ((!interrupt_in_found) || (!bulk_in_found) || (!bulk_out_found)) { + if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) { err ("Error - the proper endpoints were not found!"); return -ENODEV; } @@ -3083,6 +3083,7 @@ static int __init edgeport_init(void) retval = usb_register(&io_driver); if (retval) goto failed_usb_register; + atomic_set(&CmdUrbs, 0); info(DRIVER_DESC " " DRIVER_VERSION); return 0; diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h index 29a913a6dac..cb201c1f67f 100644 --- a/drivers/usb/serial/io_edgeport.h +++ b/drivers/usb/serial/io_edgeport.h @@ -19,12 +19,6 @@ #define MAX_RS232_PORTS 8 /* Max # of RS-232 ports per device */ /* typedefs that the insideout headers need */ -#ifndef TRUE - #define TRUE (1) -#endif -#ifndef FALSE - #define FALSE (0) -#endif #ifndef LOW8 #define LOW8(a) ((unsigned char)(a & 0xff)) #endif diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index d16e2e1764a..4df0ec74e0b 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -255,6 +255,7 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */ { USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */ { USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */ + { USB_DEVICE(0x04DD, 0x9151) }, /* SHARP S01SH USB Modem */ { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index b2097c45a23..7b085f334ce 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -238,7 +238,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, if (rc < 0) err("Reading line status failed (error = %d)", rc); else { - status = status_buf[0] + (status_buf[1]<<8); + status = le16_to_cpu(*(u16 *)status_buf); info("%s - read status %x %x", __FUNCTION__, status_buf[0], status_buf[1]); @@ -257,7 +257,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, static int klsi_105_startup (struct usb_serial *serial) { struct klsi_105_private *priv; - int i; + int i, j; /* check if we support the product id (see keyspan.c) * FIXME @@ -265,12 +265,12 @@ static int klsi_105_startup (struct usb_serial *serial) /* allocate the private data structure */ for (i=0; i<serial->num_ports; i++) { - int j; priv = kmalloc(sizeof(struct klsi_105_private), GFP_KERNEL); if (!priv) { dbg("%skmalloc for klsi_105_private failed.", __FUNCTION__); - return -ENOMEM; + i--; + goto err_cleanup; } /* set initial values for control structures */ priv->cfg.pktlen = 5; @@ -292,15 +292,14 @@ static int klsi_105_startup (struct usb_serial *serial) priv->write_urb_pool[j] = urb; if (urb == NULL) { err("No more urbs???"); - continue; + goto err_cleanup; } - urb->transfer_buffer = NULL; urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (!urb->transfer_buffer) { err("%s - out of memory for urb buffers.", __FUNCTION__); - continue; + goto err_cleanup; } } @@ -308,7 +307,20 @@ static int klsi_105_startup (struct usb_serial *serial) init_waitqueue_head(&serial->port[i]->write_wait); } - return (0); + return 0; + +err_cleanup: + for (; i >= 0; i--) { + priv = usb_get_serial_port_data(serial->port[i]); + for (j=0; j < NUM_URBS; j++) { + if (priv->write_urb_pool[j]) { + kfree(priv->write_urb_pool[j]->transfer_buffer); + usb_free_urb(priv->write_urb_pool[j]); + } + } + usb_set_serial_port_data(serial->port[i], NULL); + } + return -ENOMEM; } /* klsi_105_startup */ diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 4cd839b1407..3db1adc25f8 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -438,17 +438,21 @@ static int mct_u232_open (struct usb_serial_port *port, struct file *filp) if (retval) { err("usb_submit_urb(read bulk) failed pipe 0x%x err %d", port->read_urb->pipe, retval); - goto exit; + goto error; } port->interrupt_in_urb->dev = port->serial->dev; retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (retval) + if (retval) { + usb_kill_urb(port->read_urb); err(" usb_submit_urb(read int) failed pipe 0x%x err %d", port->interrupt_in_urb->pipe, retval); - -exit: + goto error; + } return 0; + +error: + return retval; } /* mct_u232_open */ diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 19bf403f9db..b563e2ad872 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -103,11 +103,9 @@ static void mos7720_interrupt_callback(struct urb *urb) { int result; int length; - __u32 *data; - unsigned int status; + __u8 *data; __u8 sp1; __u8 sp2; - __u8 st; dbg("%s"," : Entering\n"); @@ -141,18 +139,19 @@ static void mos7720_interrupt_callback(struct urb *urb) * Byte 2 IIR Port 2 (port.number is 1) * Byte 3 -------------- * Byte 4 FIFO status for both */ - if (length && length > 4) { + + /* the above description is inverted + * oneukum 2007-03-14 */ + + if (unlikely(length != 4)) { dbg("Wrong data !!!"); return; } - status = *data; - - sp1 = (status & 0xff000000)>>24; - sp2 = (status & 0x00ff0000)>>16; - st = status & 0x000000ff; + sp1 = data[3]; + sp2 = data[2]; - if ((sp1 & 0x01) || (sp2 & 0x01)) { + if ((sp1 | sp2) & 0x01) { /* No Interrupt Pending in both the ports */ dbg("No Interrupt !!!"); } else { @@ -333,6 +332,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) int response; int port_number; char data; + int allocated_urbs = 0; int j; serial = port->serial; @@ -353,7 +353,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) /* Initialising the write urb pool */ for (j = 0; j < NUM_URBS; ++j) { - urb = usb_alloc_urb(0,GFP_ATOMIC); + urb = usb_alloc_urb(0,GFP_KERNEL); mos7720_port->write_urb_pool[j] = urb; if (urb == NULL) { @@ -365,10 +365,16 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) GFP_KERNEL); if (!urb->transfer_buffer) { err("%s-out of memory for urb buffers.", __FUNCTION__); + usb_free_urb(mos7720_port->write_urb_pool[j]); + mos7720_port->write_urb_pool[j] = NULL; continue; } + allocated_urbs++; } + if (!allocated_urbs) + return -ENOMEM; + /* Initialize MCS7720 -- Write Init values to corresponding Registers * * Register Index @@ -526,7 +532,7 @@ static int mos7720_chars_in_buffer(struct usb_serial_port *port) } for (i = 0; i < NUM_URBS; ++i) { - if (mos7720_port->write_urb_pool[i]->status == -EINPROGRESS) + if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status == -EINPROGRESS) chars += URB_TRANSFER_BUFFER_SIZE; } dbg("%s - returns %d", __FUNCTION__, chars); @@ -629,7 +635,7 @@ static int mos7720_write_room(struct usb_serial_port *port) } for (i = 0; i < NUM_URBS; ++i) { - if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) + if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) room += URB_TRANSFER_BUFFER_SIZE; } @@ -664,7 +670,7 @@ static int mos7720_write(struct usb_serial_port *port, urb = NULL; for (i = 0; i < NUM_URBS; ++i) { - if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) { + if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) { urb = mos7720_port->write_urb_pool[i]; dbg("URB:%d",i); break; diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index c6cca859af4..2366e7b63ec 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -176,9 +176,12 @@ struct moschip_port { int port_num; /*Actual port number in the device(1,2,etc) */ struct urb *write_urb; /* write URB for this port */ struct urb *read_urb; /* read URB for this port */ + struct urb *int_urb; __u8 shadowLCR; /* last LCR value received */ __u8 shadowMCR; /* last MCR value received */ char open; + char open_ports; + char zombie; wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ int delta_msr_cond; @@ -191,17 +194,17 @@ struct moschip_port { __u8 DcrRegOffset; //for processing control URBS in interrupt context struct urb *control_urb; + struct usb_ctrlrequest *dr; char *ctrl_buf; int MsrLsr; + spinlock_t pool_lock; struct urb *write_urb_pool[NUM_URBS]; + char busy[NUM_URBS]; }; static int debug; -static int mos7840_num_ports; //this says the number of ports in the device -static int mos7840_num_open_ports; - /* * mos7840_set_reg_sync @@ -254,7 +257,7 @@ static int mos7840_set_uart_reg(struct usb_serial_port *port, __u16 reg, struct usb_device *dev = port->serial->dev; val = val & 0x00ff; // For the UART control registers, the application number need to be Or'ed - if (mos7840_num_ports == 4) { + if (port->serial->num_ports == 4) { val |= (((__u16) port->number - (__u16) (port->serial->minor)) + 1) << 8; @@ -294,7 +297,7 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg, //dbg("application number is %4x \n",(((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); /*Wval is same as application number */ - if (mos7840_num_ports == 4) { + if (port->serial->num_ports == 4) { Wval = (((__u16) port->number - (__u16) (port->serial->minor)) + 1) << 8; @@ -352,7 +355,7 @@ static inline struct moschip_port *mos7840_get_port_private(struct return (struct moschip_port *)usb_get_serial_port_data(port); } -static int mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) +static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) { struct moschip_port *mos7840_port; struct async_icount *icount; @@ -366,22 +369,24 @@ static int mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) /* update input line counters */ if (new_msr & MOS_MSR_DELTA_CTS) { icount->cts++; + smp_wmb(); } if (new_msr & MOS_MSR_DELTA_DSR) { icount->dsr++; + smp_wmb(); } if (new_msr & MOS_MSR_DELTA_CD) { icount->dcd++; + smp_wmb(); } if (new_msr & MOS_MSR_DELTA_RI) { icount->rng++; + smp_wmb(); } } - - return 0; } -static int mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) +static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) { struct async_icount *icount; @@ -400,18 +405,20 @@ static int mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) icount = &port->icount; if (new_lsr & SERIAL_LSR_BI) { icount->brk++; + smp_wmb(); } if (new_lsr & SERIAL_LSR_OE) { icount->overrun++; + smp_wmb(); } if (new_lsr & SERIAL_LSR_PE) { icount->parity++; + smp_wmb(); } if (new_lsr & SERIAL_LSR_FE) { icount->frame++; + smp_wmb(); } - - return 0; } /************************************************************************/ @@ -426,12 +433,15 @@ static void mos7840_control_callback(struct urb *urb) unsigned char *data; struct moschip_port *mos7840_port; __u8 regval = 0x0; + int result = 0; if (!urb) { dbg("%s", "Invalid Pointer !!!!:\n"); return; } + mos7840_port = (struct moschip_port *)urb->context; + switch (urb->status) { case 0: /* success */ @@ -449,8 +459,6 @@ static void mos7840_control_callback(struct urb *urb) goto exit; } - mos7840_port = (struct moschip_port *)urb->context; - dbg("%s urb buffer size is %d\n", __FUNCTION__, urb->actual_length); dbg("%s mos7840_port->MsrLsr is %d port %d\n", __FUNCTION__, mos7840_port->MsrLsr, mos7840_port->port_num); @@ -462,21 +470,26 @@ static void mos7840_control_callback(struct urb *urb) else if (mos7840_port->MsrLsr == 1) mos7840_handle_new_lsr(mos7840_port, regval); - exit: - return; +exit: + spin_lock(&mos7840_port->pool_lock); + if (!mos7840_port->zombie) + result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC); + spin_unlock(&mos7840_port->pool_lock); + if (result) { + dev_err(&urb->dev->dev, + "%s - Error %d submitting interrupt urb\n", + __FUNCTION__, result); + } } static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, __u16 * val) { struct usb_device *dev = mcs->port->serial->dev; - struct usb_ctrlrequest *dr = NULL; - unsigned char *buffer = NULL; - int ret = 0; - buffer = (__u8 *) mcs->ctrl_buf; + struct usb_ctrlrequest *dr = mcs->dr; + unsigned char *buffer = mcs->ctrl_buf; + int ret; -// dr=(struct usb_ctrlrequest *)(buffer); - dr = (void *)(buffer + 2); dr->bRequestType = MCS_RD_RTYPE; dr->bRequest = MCS_RDREQ; dr->wValue = cpu_to_le16(Wval); //0; @@ -506,8 +519,8 @@ static void mos7840_interrupt_callback(struct urb *urb) __u16 Data; unsigned char *data; __u8 sp[5], st; - int i; - __u16 wval; + int i, rv = 0; + __u16 wval, wreg = 0; dbg("%s", " : Entering\n"); if (!urb) { @@ -569,31 +582,34 @@ static void mos7840_interrupt_callback(struct urb *urb) dbg("Serial Port %d: Receiver status error or ", i); dbg("address bit detected in 9-bit mode\n"); mos7840_port->MsrLsr = 1; - mos7840_get_reg(mos7840_port, wval, - LINE_STATUS_REGISTER, - &Data); + wreg = LINE_STATUS_REGISTER; break; case SERIAL_IIR_MS: dbg("Serial Port %d: Modem status change\n", i); mos7840_port->MsrLsr = 0; - mos7840_get_reg(mos7840_port, wval, - MODEM_STATUS_REGISTER, - &Data); + wreg = MODEM_STATUS_REGISTER; break; } + spin_lock(&mos7840_port->pool_lock); + if (!mos7840_port->zombie) { + rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); + } else { + spin_unlock(&mos7840_port->pool_lock); + return; + } + spin_unlock(&mos7840_port->pool_lock); } } } - exit: + if (!(rv < 0)) /* the completion handler for the control urb will resubmit */ + return; +exit: result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { dev_err(&urb->dev->dev, "%s - Error %d submitting interrupt urb\n", __FUNCTION__, result); } - - return; - } static int mos7840_port_paranoia_check(struct usb_serial_port *port, @@ -634,7 +650,8 @@ static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port, if (!port || mos7840_port_paranoia_check(port, function) || mos7840_serial_paranoia_check(port->serial, function)) { - /* then say that we don't have a valid usb_serial thing, which will * end up genrating -ENODEV return values */ + /* then say that we don't have a valid usb_serial thing, which will + * end up genrating -ENODEV return values */ return NULL; } @@ -699,6 +716,7 @@ static void mos7840_bulk_in_callback(struct urb *urb) tty_flip_buffer_push(tty); } mos7840_port->icount.rx += urb->actual_length; + smp_wmb(); dbg("mos7840_port->icount.rx is %d:\n", mos7840_port->icount.rx); } @@ -708,15 +726,14 @@ static void mos7840_bulk_in_callback(struct urb *urb) return; } - if (mos7840_port->read_urb->status != -EINPROGRESS) { - mos7840_port->read_urb->dev = serial->dev; - status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); + mos7840_port->read_urb->dev = serial->dev; - if (status) { - dbg(" usb_submit_urb(read bulk) failed, status = %d", - status); - } + status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); + + if (status) { + dbg(" usb_submit_urb(read bulk) failed, status = %d", + status); } } @@ -730,17 +747,28 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) { struct moschip_port *mos7840_port; struct tty_struct *tty; + int i; + if (!urb) { dbg("%s", "Invalid Pointer !!!!:\n"); return; } + mos7840_port = (struct moschip_port *)urb->context; + spin_lock(&mos7840_port->pool_lock); + for (i = 0; i < NUM_URBS; i++) { + if (urb == mos7840_port->write_urb_pool[i]) { + mos7840_port->busy[i] = 0; + break; + } + } + spin_unlock(&mos7840_port->pool_lock); + if (urb->status) { dbg("nonzero write bulk status received:%d\n", urb->status); return; } - mos7840_port = (struct moschip_port *)urb->context; if (!mos7840_port) { dbg("%s", "NULL mos7840_port pointer \n"); return; @@ -792,13 +820,13 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) __u16 Data; int status; struct moschip_port *mos7840_port; + struct moschip_port *port0; if (mos7840_port_paranoia_check(port, __FUNCTION__)) { dbg("%s", "Port Paranoia failed \n"); return -ENODEV; } - mos7840_num_open_ports++; serial = port->serial; if (mos7840_serial_paranoia_check(serial, __FUNCTION__)) { @@ -807,16 +835,18 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) } mos7840_port = mos7840_get_port_private(port); + port0 = mos7840_get_port_private(serial->port[0]); - if (mos7840_port == NULL) + if (mos7840_port == NULL || port0 == NULL) return -ENODEV; usb_clear_halt(serial->dev, port->write_urb->pipe); usb_clear_halt(serial->dev, port->read_urb->pipe); + port0->open_ports++; /* Initialising the write urb pool */ for (j = 0; j < NUM_URBS; ++j) { - urb = usb_alloc_urb(0, GFP_ATOMIC); + urb = usb_alloc_urb(0, GFP_KERNEL); mos7840_port->write_urb_pool[j] = urb; if (urb == NULL) { @@ -824,10 +854,10 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) continue; } - urb->transfer_buffer = NULL; - urb->transfer_buffer = - kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); + urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (!urb->transfer_buffer) { + usb_free_urb(urb); + mos7840_port->write_urb_pool[j] = NULL; err("%s-out of memory for urb buffers.", __FUNCTION__); continue; } @@ -879,9 +909,7 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) } Data |= 0x08; //Driver done bit Data |= 0x20; //rx_disable - status = 0; - status = - mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data); + status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data); if (status < 0) { dbg("writing Controlreg failed\n"); return -1; @@ -893,7 +921,6 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) //////////////////////////////////// Data = 0x00; - status = 0; status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); if (status < 0) { dbg("disableing interrupts failed\n"); @@ -901,7 +928,6 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) } // Set FIFO_CONTROL_REGISTER to the default value Data = 0x00; - status = 0; status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); if (status < 0) { dbg("Writing FIFO_CONTROL_REGISTER failed\n"); @@ -909,7 +935,6 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) } Data = 0xcf; - status = 0; status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); if (status < 0) { dbg("Writing FIFO_CONTROL_REGISTER failed\n"); @@ -917,22 +942,18 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) } Data = 0x03; - status = 0; status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); mos7840_port->shadowLCR = Data; Data = 0x0b; - status = 0; status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); mos7840_port->shadowMCR = Data; Data = 0x00; - status = 0; status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); mos7840_port->shadowLCR = Data; Data |= SERIAL_LCR_DLAB; //data latch enable in LCR 0x80 - status = 0; status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); Data = 0x0c; @@ -999,7 +1020,7 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp) /* Check to see if we've set up our endpoint info yet * * (can't set it up in mos7840_startup as the structures * * were not set up at that time.) */ - if (mos7840_num_open_ports == 1) { + if (port0->open_ports == 1) { if (serial->port[0]->interrupt_in_buffer == NULL) { /* set up interrupt urb */ @@ -1097,6 +1118,7 @@ static int mos7840_chars_in_buffer(struct usb_serial_port *port) { int i; int chars = 0; + unsigned long flags; struct moschip_port *mos7840_port; dbg("%s \n", " mos7840_chars_in_buffer:entering ..........."); @@ -1112,13 +1134,15 @@ static int mos7840_chars_in_buffer(struct usb_serial_port *port) return -1; } + spin_lock_irqsave(&mos7840_port->pool_lock,flags); for (i = 0; i < NUM_URBS; ++i) { - if (mos7840_port->write_urb_pool[i]->status == -EINPROGRESS) { + if (mos7840_port->busy[i]) { chars += URB_TRANSFER_BUFFER_SIZE; } } + spin_unlock_irqrestore(&mos7840_port->pool_lock,flags); dbg("%s - returns %d", __FUNCTION__, chars); - return (chars); + return chars; } @@ -1172,6 +1196,7 @@ static void mos7840_close(struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial; struct moschip_port *mos7840_port; + struct moschip_port *port0; int j; __u16 Data; @@ -1189,10 +1214,10 @@ static void mos7840_close(struct usb_serial_port *port, struct file *filp) } mos7840_port = mos7840_get_port_private(port); + port0 = mos7840_get_port_private(serial->port[0]); - if (mos7840_port == NULL) { + if (mos7840_port == NULL || port0 == NULL) return; - } for (j = 0; j < NUM_URBS; ++j) usb_kill_urb(mos7840_port->write_urb_pool[j]); @@ -1234,12 +1259,13 @@ static void mos7840_close(struct usb_serial_port *port, struct file *filp) } // if(mos7840_port->ctrl_buf != NULL) // kfree(mos7840_port->ctrl_buf); - mos7840_num_open_ports--; + port0->open_ports--; dbg("mos7840_num_open_ports in close%d:in port%d\n", - mos7840_num_open_ports, port->number); - if (mos7840_num_open_ports == 0) { + port0->open_ports, port->number); + if (port0->open_ports == 0) { if (serial->port[0]->interrupt_in_urb) { dbg("%s", "Shutdown interrupt_in_urb\n"); + usb_kill_urb(serial->port[0]->interrupt_in_urb); } } @@ -1368,6 +1394,7 @@ static int mos7840_write_room(struct usb_serial_port *port) { int i; int room = 0; + unsigned long flags; struct moschip_port *mos7840_port; dbg("%s \n", " mos7840_write_room:entering ..........."); @@ -1384,14 +1411,17 @@ static int mos7840_write_room(struct usb_serial_port *port) return -1; } + spin_lock_irqsave(&mos7840_port->pool_lock, flags); for (i = 0; i < NUM_URBS; ++i) { - if (mos7840_port->write_urb_pool[i]->status != -EINPROGRESS) { + if (!mos7840_port->busy[i]) { room += URB_TRANSFER_BUFFER_SIZE; } } + spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); + room = (room == 0) ? 0 : room - URB_TRANSFER_BUFFER_SIZE + 1; dbg("%s - returns %d", __FUNCTION__, room); - return (room); + return room; } @@ -1410,6 +1440,7 @@ static int mos7840_write(struct usb_serial_port *port, int i; int bytes_sent = 0; int transfer_size; + unsigned long flags; struct moschip_port *mos7840_port; struct usb_serial *serial; @@ -1476,13 +1507,16 @@ static int mos7840_write(struct usb_serial_port *port, /* try to find a free urb in the list */ urb = NULL; + spin_lock_irqsave(&mos7840_port->pool_lock, flags); for (i = 0; i < NUM_URBS; ++i) { - if (mos7840_port->write_urb_pool[i]->status != -EINPROGRESS) { + if (!mos7840_port->busy[i]) { + mos7840_port->busy[i] = 1; urb = mos7840_port->write_urb_pool[i]; dbg("\nURB:%d", i); break; } } + spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); if (urb == NULL) { dbg("%s - no more free urbs", __FUNCTION__); @@ -1518,6 +1552,7 @@ static int mos7840_write(struct usb_serial_port *port, status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { + mos7840_port->busy[i] = 0; err("%s - usb_submit_urb(write bulk) failed with status = %d", __FUNCTION__, status); bytes_sent = status; @@ -1525,6 +1560,7 @@ static int mos7840_write(struct usb_serial_port *port, } bytes_sent = transfer_size; mos7840_port->icount.tx += transfer_size; + smp_wmb(); dbg("mos7840_port->icount.tx is %d:\n", mos7840_port->icount.tx); exit: @@ -2490,6 +2526,7 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, if (signal_pending(current)) return -ERESTARTSYS; cnow = mos7840_port->icount; + smp_rmb(); if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) return -EIO; /* no change => error */ @@ -2506,6 +2543,7 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, case TIOCGICOUNT: cnow = mos7840_port->icount; + smp_rmb(); icount.cts = cnow.cts; icount.dsr = cnow.dsr; icount.rng = cnow.rng; @@ -2535,19 +2573,18 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, static int mos7840_calc_num_ports(struct usb_serial *serial) { + int mos7840_num_ports = 0; dbg("numberofendpoints: %d \n", (int)serial->interface->cur_altsetting->desc.bNumEndpoints); dbg("numberofendpoints: %d \n", (int)serial->interface->altsetting->desc.bNumEndpoints); if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) { - mos7840_num_ports = 2; - serial->type->num_ports = 2; + mos7840_num_ports = serial->num_ports = 2; } else if (serial->interface->cur_altsetting->desc.bNumEndpoints == 9) { - mos7840_num_ports = 4; - serial->type->num_bulk_in = 4; - serial->type->num_bulk_out = 4; - serial->type->num_ports = 4; + serial->num_bulk_in = 4; + serial->num_bulk_out = 4; + mos7840_num_ports = serial->num_ports = 4; } return mos7840_num_ports; @@ -2583,7 +2620,9 @@ static int mos7840_startup(struct usb_serial *serial) mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); if (mos7840_port == NULL) { err("%s - Out of memory", __FUNCTION__); - return -ENOMEM; + status = -ENOMEM; + i--; /* don't follow NULL pointer cleaning up */ + goto error; } /* Initialize all port interrupt end point to port 0 int endpoint * @@ -2591,6 +2630,7 @@ static int mos7840_startup(struct usb_serial *serial) mos7840_port->port = serial->port[i]; mos7840_set_port_private(serial->port[i], mos7840_port); + spin_lock_init(&mos7840_port->pool_lock); mos7840_port->port_num = ((serial->port[i]->number - (serial->port[i]->serial->minor)) + @@ -2601,22 +2641,22 @@ static int mos7840_startup(struct usb_serial *serial) mos7840_port->ControlRegOffset = 0x1; mos7840_port->DcrRegOffset = 0x4; } else if ((mos7840_port->port_num == 2) - && (mos7840_num_ports == 4)) { + && (serial->num_ports == 4)) { mos7840_port->SpRegOffset = 0x8; mos7840_port->ControlRegOffset = 0x9; mos7840_port->DcrRegOffset = 0x16; } else if ((mos7840_port->port_num == 2) - && (mos7840_num_ports == 2)) { + && (serial->num_ports == 2)) { mos7840_port->SpRegOffset = 0xa; mos7840_port->ControlRegOffset = 0xb; mos7840_port->DcrRegOffset = 0x19; } else if ((mos7840_port->port_num == 3) - && (mos7840_num_ports == 4)) { + && (serial->num_ports == 4)) { mos7840_port->SpRegOffset = 0xa; mos7840_port->ControlRegOffset = 0xb; mos7840_port->DcrRegOffset = 0x19; } else if ((mos7840_port->port_num == 4) - && (mos7840_num_ports == 4)) { + && (serial->num_ports == 4)) { mos7840_port->SpRegOffset = 0xc; mos7840_port->ControlRegOffset = 0xd; mos7840_port->DcrRegOffset = 0x1c; @@ -2701,21 +2741,19 @@ static int mos7840_startup(struct usb_serial *serial) dbg("CLK_START_VALUE_REGISTER Writing success status%d\n", status); Data = 0x20; - status = 0; status = mos7840_set_reg_sync(serial->port[i], CLK_MULTI_REGISTER, Data); if (status < 0) { dbg("Writing CLK_MULTI_REGISTER failed status-0x%x\n", status); - break; + goto error; } else dbg("CLK_MULTI_REGISTER Writing success status%d\n", status); //write value 0x0 to scratchpad register Data = 0x00; - status = 0; status = mos7840_set_uart_reg(serial->port[i], SCRATCH_PAD_REGISTER, Data); @@ -2729,7 +2767,7 @@ static int mos7840_startup(struct usb_serial *serial) //Zero Length flag register if ((mos7840_port->port_num != 1) - && (mos7840_num_ports == 2)) { + && (serial->num_ports == 2)) { Data = 0xff; status = 0; @@ -2770,14 +2808,17 @@ static int mos7840_startup(struct usb_serial *serial) i + 1, status); } - mos7840_port->control_urb = usb_alloc_urb(0, GFP_ATOMIC); + mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL); - + mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || !mos7840_port->dr) { + status = -ENOMEM; + goto error; + } } //Zero Length flag enable Data = 0x0f; - status = 0; status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); if (status < 0) { dbg("Writing ZLP_REG5 failed status-0x%x\n", status); @@ -2789,6 +2830,17 @@ static int mos7840_startup(struct usb_serial *serial) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ); return 0; +error: + for (/* nothing */; i >= 0; i--) { + mos7840_port = mos7840_get_port_private(serial->port[i]); + + kfree(mos7840_port->dr); + kfree(mos7840_port->ctrl_buf); + usb_free_urb(mos7840_port->control_urb); + kfree(mos7840_port); + serial->port[i] = NULL; + } + return status; } /**************************************************************************** @@ -2799,6 +2851,7 @@ static int mos7840_startup(struct usb_serial *serial) static void mos7840_shutdown(struct usb_serial *serial) { int i; + unsigned long flags; struct moschip_port *mos7840_port; dbg("%s \n", " shutdown :entering.........."); @@ -2814,8 +2867,12 @@ static void mos7840_shutdown(struct usb_serial *serial) for (i = 0; i < serial->num_ports; ++i) { mos7840_port = mos7840_get_port_private(serial->port[i]); - kfree(mos7840_port->ctrl_buf); + spin_lock_irqsave(&mos7840_port->pool_lock, flags); + mos7840_port->zombie = 1; + spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); usb_kill_urb(mos7840_port->control_urb); + kfree(mos7840_port->ctrl_buf); + kfree(mos7840_port->dr); kfree(mos7840_port); mos7840_set_port_private(serial->port[i], NULL); } diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 0216ac12a27..4adfab988e8 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -69,6 +69,7 @@ static void omninet_write_bulk_callback (struct urb *urb); static int omninet_write (struct usb_serial_port *port, const unsigned char *buf, int count); static int omninet_write_room (struct usb_serial_port *port); static void omninet_shutdown (struct usb_serial *serial); +static int omninet_attach (struct usb_serial *serial); static struct usb_device_id id_table [] = { { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, @@ -99,6 +100,7 @@ static struct usb_serial_driver zyxel_omninet_device = { .num_bulk_in = 1, .num_bulk_out = 2, .num_ports = 1, + .attach = omninet_attach, .open = omninet_open, .close = omninet_close, .write = omninet_write, @@ -145,22 +147,30 @@ struct omninet_data __u8 od_outseq; // Sequence number for bulk_out URBs }; +static int omninet_attach (struct usb_serial *serial) +{ + struct omninet_data *od; + struct usb_serial_port *port = serial->port[0]; + + od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); + if( !od ) { + err("%s- kmalloc(%Zd) failed.", __FUNCTION__, sizeof(struct omninet_data)); + return -ENOMEM; + } + usb_set_serial_port_data(port, od); + return 0; +} + static int omninet_open (struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; struct usb_serial_port *wport; - struct omninet_data *od; + struct omninet_data *od = usb_get_serial_port_data(port); int result = 0; dbg("%s - port %d", __FUNCTION__, port->number); od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); - if( !od ) { - err("%s- kmalloc(%Zd) failed.", __FUNCTION__, sizeof(struct omninet_data)); - return -ENOMEM; - } - - usb_set_serial_port_data(port, od); wport = serial->port[1]; wport->tty = port->tty; @@ -170,24 +180,17 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, omninet_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_KERNEL); - if (result) + if (result) { err("%s - failed submitting read urb, error %d", __FUNCTION__, result); + } return result; } static void omninet_close (struct usb_serial_port *port, struct file * filp) { - struct usb_serial *serial = port->serial; - struct usb_serial_port *wport; - dbg("%s - port %d", __FUNCTION__, port->number); - - wport = serial->port[1]; - usb_kill_urb(wport->write_urb); usb_kill_urb(port->read_urb); - - kfree(usb_get_serial_port_data(port)); } @@ -326,7 +329,12 @@ static void omninet_write_bulk_callback (struct urb *urb) static void omninet_shutdown (struct usb_serial *serial) { + struct usb_serial_port *wport = serial->port[1]; + struct usb_serial_port *port = serial->port[0]; dbg ("%s", __FUNCTION__); + + usb_kill_urb(wport->write_urb); + kfree(usb_get_serial_port_data(port)); } diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e178e6f4031..8c3f55b080b 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -113,6 +113,12 @@ static int option_send_setup(struct usb_serial_port *port); #define ANYDATA_VENDOR_ID 0x16d5 #define ANYDATA_PRODUCT_ID 0x6501 +#define BANDRICH_VENDOR_ID 0x1A8D +#define BANDRICH_PRODUCT_C100_1 0x1002 +#define BANDRICH_PRODUCT_C100_2 0x1003 + +#define DELL_VENDOR_ID 0x413C + static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -165,6 +171,9 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, + { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, + { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); @@ -591,12 +600,6 @@ static int option_open(struct usb_serial_port *port, struct file *filp) return (0); } -static inline void stop_urb(struct urb *urb) -{ - if (urb && urb->status == -EINPROGRESS) - usb_kill_urb(urb); -} - static void option_close(struct usb_serial_port *port, struct file *filp) { int i; @@ -614,9 +617,9 @@ static void option_close(struct usb_serial_port *port, struct file *filp) /* Stop reading/writing urbs */ for (i = 0; i < N_IN_URB; i++) - stop_urb(portdata->in_urbs[i]); + usb_kill_urb(portdata->in_urbs[i]); for (i = 0; i < N_OUT_URB; i++) - stop_urb(portdata->out_urbs[i]); + usb_kill_urb(portdata->out_urbs[i]); } port->tty = NULL; } @@ -747,9 +750,9 @@ static void option_shutdown(struct usb_serial *serial) port = serial->port[i]; portdata = usb_get_serial_port_data(port); for (j = 0; j < N_IN_URB; j++) - stop_urb(portdata->in_urbs[j]); + usb_kill_urb(portdata->in_urbs[j]); for (j = 0; j < N_OUT_URB; j++) - stop_urb(portdata->out_urbs[j]); + usb_kill_urb(portdata->out_urbs[j]); } /* Now free them */ diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index ecedd833818..644607de4c1 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -456,12 +456,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) return (0); } -static inline void stop_urb(struct urb *urb) -{ - if (urb && urb->status == -EINPROGRESS) - usb_kill_urb(urb); -} - static void sierra_close(struct usb_serial_port *port, struct file *filp) { int i; @@ -479,9 +473,9 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp) /* Stop reading/writing urbs */ for (i = 0; i < N_IN_URB; i++) - stop_urb(portdata->in_urbs[i]); + usb_unlink_urb(portdata->in_urbs[i]); for (i = 0; i < N_OUT_URB; i++) - stop_urb(portdata->out_urbs[i]); + usb_unlink_urb(portdata->out_urbs[i]); } port->tty = NULL; } @@ -583,17 +577,26 @@ static void sierra_shutdown(struct usb_serial *serial) /* Stop reading/writing urbs */ for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; + if (!port) + continue; portdata = usb_get_serial_port_data(port); + if (!portdata) + continue; + for (j = 0; j < N_IN_URB; j++) - stop_urb(portdata->in_urbs[j]); + usb_unlink_urb(portdata->in_urbs[j]); for (j = 0; j < N_OUT_URB; j++) - stop_urb(portdata->out_urbs[j]); + usb_unlink_urb(portdata->out_urbs[j]); } /* Now free them */ for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; + if (!port) + continue; portdata = usb_get_serial_port_data(port); + if (!portdata) + continue; for (j = 0; j < N_IN_URB; j++) { if (portdata->in_urbs[j]) { @@ -612,6 +615,8 @@ static void sierra_shutdown(struct usb_serial *serial) /* Now free per port private data */ for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; + if (!port) + continue; kfree(usb_get_serial_port_data(port)); } } diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 2f59ff226e2..ffbe601cde2 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -384,19 +384,21 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf, dbg("%s - write limit hit\n", __FUNCTION__); return 0; } + priv->outstanding_urbs++; spin_unlock_irqrestore(&priv->lock, flags); buffer = kmalloc (count, GFP_ATOMIC); if (!buffer) { dev_err(&port->dev, "out of memory\n"); - return -ENOMEM; + count = -ENOMEM; + goto error_no_buffer; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { dev_err(&port->dev, "no more free urbs\n"); - kfree (buffer); - return -ENOMEM; + count = -ENOMEM; + goto error_no_urb; } memcpy (buffer, buf, count); @@ -415,19 +417,27 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf, dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __FUNCTION__, status); count = status; - kfree (buffer); + goto error; } else { spin_lock_irqsave(&priv->lock, flags); - ++priv->outstanding_urbs; priv->bytes_out += count; spin_unlock_irqrestore(&priv->lock, flags); } /* we are done with this urb, so let the host driver * really free it when it is finished with it */ - usb_free_urb (urb); + usb_free_urb(urb); return count; +error: + usb_free_urb(urb); +error_no_urb: + kfree(buffer); +error_no_buffer: + spin_lock_irqsave(&priv->lock, flags); + --priv->outstanding_urbs; + spin_unlock_irqrestore(&priv->lock, flags); + return count; } diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index bf16e9e1d84..27c5f8f9a2d 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -1109,7 +1109,7 @@ static int firm_send_command (struct usb_serial_port *port, __u8 command, __u8 * command_port = port->serial->port[COMMAND_PORT]; command_info = usb_get_serial_port_data(command_port); spin_lock_irqsave(&command_info->lock, flags); - command_info->command_finished = FALSE; + command_info->command_finished = false; transfer_buffer = (__u8 *)command_port->write_urb->transfer_buffer; transfer_buffer[0] = command; @@ -1124,12 +1124,12 @@ static int firm_send_command (struct usb_serial_port *port, __u8 command, __u8 * spin_unlock_irqrestore(&command_info->lock, flags); /* wait for the command to complete */ - wait_event_interruptible_timeout(command_info->wait_command, - (command_info->command_finished != FALSE), COMMAND_TIMEOUT); + wait_event_interruptible_timeout(command_info->wait_command, + (bool)command_info->command_finished, COMMAND_TIMEOUT); spin_lock_irqsave(&command_info->lock, flags); - if (command_info->command_finished == FALSE) { + if (command_info->command_finished == false) { dbg("%s - command timed out.", __FUNCTION__); retval = -ETIMEDOUT; goto exit; diff --git a/drivers/usb/serial/whiteheat.h b/drivers/usb/serial/whiteheat.h index d714eff58dc..f1607970566 100644 --- a/drivers/usb/serial/whiteheat.h +++ b/drivers/usb/serial/whiteheat.h @@ -20,10 +20,6 @@ #define __LINUX_USB_SERIAL_WHITEHEAT_H -#define FALSE 0 -#define TRUE 1 - - /* WhiteHEAT commands */ #define WHITEHEAT_OPEN 1 /* open the port */ #define WHITEHEAT_CLOSE 2 /* close the port */ |