diff options
Diffstat (limited to 'drivers/usb/serial/mos7720.c')
| -rw-r--r-- | drivers/usb/serial/mos7720.c | 85 |
1 files changed, 51 insertions, 34 deletions
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index cc0e54345df9..84657e07dc5d 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -40,7 +40,7 @@ #define DRIVER_DESC "Moschip USB Serial Driver" /* default urb timeout */ -#define MOS_WDR_TIMEOUT (HZ * 5) +#define MOS_WDR_TIMEOUT 5000 #define MOS_MAX_PORT 0x02 #define MOS_WRITE 0x0E @@ -90,6 +90,7 @@ struct urbtracker { struct list_head urblist_entry; struct kref ref_count; struct urb *urb; + struct usb_ctrlrequest *setup; }; enum mos7715_pp_modes { @@ -227,11 +228,22 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, __u8 requesttype = (__u8)0xc0; __u16 index = get_reg_index(reg); __u16 value = get_reg_value(reg, serial_portnum); - int status = usb_control_msg(usbdev, pipe, request, requesttype, value, - index, data, 1, MOS_WDR_TIMEOUT); - if (status < 0) + u8 *buf; + int status; + + buf = kmalloc(1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + status = usb_control_msg(usbdev, pipe, request, requesttype, value, + index, buf, 1, MOS_WDR_TIMEOUT); + if (status == 1) + *data = *buf; + else if (status < 0) dev_err(&usbdev->dev, "mos7720: usb_control_msg() failed: %d", status); + kfree(buf); + return status; } @@ -260,6 +272,7 @@ static void destroy_urbtracker(struct kref *kref) struct mos7715_parport *mos_parport = urbtrack->mos_parport; usb_free_urb(urbtrack->urb); + kfree(urbtrack->setup); kfree(urbtrack); kref_put(&mos_parport->ref_count, destroy_mos_parport); } @@ -344,7 +357,6 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, struct urbtracker *urbtrack; int ret_val; unsigned long flags; - struct usb_ctrlrequest setup; struct usb_serial *serial = mos_parport->serial; struct usb_device *usbdev = serial->dev; @@ -362,14 +374,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, kfree(urbtrack); return -ENOMEM; } - setup.bRequestType = (__u8)0x40; - setup.bRequest = (__u8)0x0e; - setup.wValue = get_reg_value(reg, dummy); - setup.wIndex = get_reg_index(reg); - setup.wLength = 0; + urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_ATOMIC); + if (!urbtrack->setup) { + usb_free_urb(urbtrack->urb); + kfree(urbtrack); + return -ENOMEM; + } + urbtrack->setup->bRequestType = (__u8)0x40; + urbtrack->setup->bRequest = (__u8)0x0e; + urbtrack->setup->wValue = cpu_to_le16(get_reg_value(reg, dummy)); + urbtrack->setup->wIndex = cpu_to_le16(get_reg_index(reg)); + urbtrack->setup->wLength = 0; usb_fill_control_urb(urbtrack->urb, usbdev, usb_sndctrlpipe(usbdev, 0), - (unsigned char *)&setup, + (unsigned char *)urbtrack->setup, NULL, 0, async_complete, urbtrack); kref_init(&urbtrack->ref_count); INIT_LIST_HEAD(&urbtrack->urblist_entry); @@ -1036,7 +1054,7 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) * * 0x08 : SP1/2 Control Reg */ - port_number = port->number - port->serial->minor; + port_number = port->port_number; read_mos_reg(serial, port_number, LSR, &data); dev_dbg(&port->dev, "SS::%p LSR:%x\n", mos7720_port, data); @@ -1055,7 +1073,7 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) write_mos_reg(serial, port_number, SP_CONTROL_REG, 0x00); read_mos_reg(serial, dummy, SP_CONTROL_REG, &data); - data = data | (port->number - port->serial->minor + 1); + data = data | (port->port_number + 1); write_mos_reg(serial, dummy, SP_CONTROL_REG, data); mos7720_port->shadowLCR = 0x83; write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); @@ -1136,8 +1154,8 @@ static void mos7720_close(struct usb_serial_port *port) usb_kill_urb(port->write_urb); usb_kill_urb(port->read_urb); - write_mos_reg(serial, port->number - port->serial->minor, MCR, 0x00); - write_mos_reg(serial, port->number - port->serial->minor, IER, 0x00); + write_mos_reg(serial, port->port_number, MCR, 0x00); + write_mos_reg(serial, port->port_number, IER, 0x00); mos7720_port->open = 0; } @@ -1161,8 +1179,7 @@ static void mos7720_break(struct tty_struct *tty, int break_state) data = mos7720_port->shadowLCR & ~UART_LCR_SBC; mos7720_port->shadowLCR = data; - write_mos_reg(serial, port->number - port->serial->minor, - LCR, mos7720_port->shadowLCR); + write_mos_reg(serial, port->port_number, LCR, mos7720_port->shadowLCR); } /* @@ -1293,8 +1310,8 @@ static void mos7720_throttle(struct tty_struct *tty) /* if we are implementing RTS/CTS, toggle that line */ if (tty->termios.c_cflag & CRTSCTS) { mos7720_port->shadowMCR &= ~UART_MCR_RTS; - write_mos_reg(port->serial, port->number - port->serial->minor, - MCR, mos7720_port->shadowMCR); + write_mos_reg(port->serial, port->port_number, MCR, + mos7720_port->shadowMCR); if (status != 0) return; } @@ -1325,8 +1342,8 @@ static void mos7720_unthrottle(struct tty_struct *tty) /* if we are implementing RTS/CTS, toggle that line */ if (tty->termios.c_cflag & CRTSCTS) { mos7720_port->shadowMCR |= UART_MCR_RTS; - write_mos_reg(port->serial, port->number - port->serial->minor, - MCR, mos7720_port->shadowMCR); + write_mos_reg(port->serial, port->port_number, MCR, + mos7720_port->shadowMCR); if (status != 0) return; } @@ -1350,7 +1367,7 @@ static int set_higher_rates(struct moschip_port *mos7720_port, * Init Sequence for higher rates ***********************************************/ dev_dbg(&port->dev, "Sending Setting Commands ..........\n"); - port_number = port->number - port->serial->minor; + port_number = port->port_number; write_mos_reg(serial, port_number, IER, 0x00); write_mos_reg(serial, port_number, FCR, 0x00); @@ -1476,7 +1493,7 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, port = mos7720_port->port; serial = port->serial; - number = port->number - port->serial->minor; + number = port->port_number; dev_dbg(&port->dev, "%s - baud = %d\n", __func__, baudrate); /* Calculate the Divisor */ @@ -1527,7 +1544,7 @@ static void change_port_settings(struct tty_struct *tty, port = mos7720_port->port; serial = port->serial; - port_number = port->number - port->serial->minor; + port_number = port->port_number; if (!mos7720_port->open) { dev_dbg(&port->dev, "%s - port not opened\n", __func__); @@ -1618,7 +1635,7 @@ static void change_port_settings(struct tty_struct *tty, mos7720_port->shadowMCR |= (UART_MCR_XONANY); /* To set hardware flow control to the specified * * serial port, in SP1/2_CONTROL_REG */ - if (port->number) + if (port_number) write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01); else write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02); @@ -1720,7 +1737,7 @@ static int get_lsr_info(struct tty_struct *tty, struct usb_serial_port *port = tty->driver_data; unsigned int result = 0; unsigned char data = 0; - int port_number = port->number - port->serial->minor; + int port_number = port->port_number; int count; count = mos7720_chars_in_buffer(tty); @@ -1782,8 +1799,8 @@ static int mos7720_tiocmset(struct tty_struct *tty, mcr &= ~UART_MCR_LOOP; mos7720_port->shadowMCR = mcr; - write_mos_reg(port->serial, port->number - port->serial->minor, - MCR, mos7720_port->shadowMCR); + write_mos_reg(port->serial, port->port_number, MCR, + mos7720_port->shadowMCR); return 0; } @@ -1827,8 +1844,8 @@ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, } mos7720_port->shadowMCR = mcr; - write_mos_reg(port->serial, port->number - port->serial->minor, - MCR, mos7720_port->shadowMCR); + write_mos_reg(port->serial, port->port_number, MCR, + mos7720_port->shadowMCR); return 0; } @@ -1844,8 +1861,8 @@ static int get_serial_info(struct moschip_port *mos7720_port, memset(&tmp, 0, sizeof(tmp)); tmp.type = PORT_16550A; - tmp.line = mos7720_port->port->serial->minor; - tmp.port = mos7720_port->port->number; + tmp.line = mos7720_port->port->minor; + tmp.port = mos7720_port->port->port_number; tmp.irq = 0; tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; @@ -1927,7 +1944,7 @@ static int mos7720_startup(struct usb_serial *serial) /* setting configuration feature to one */ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); + (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000); /* start the interrupt urb */ ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); @@ -1970,7 +1987,7 @@ static void mos7720_release(struct usb_serial *serial) /* wait for synchronous usb calls to return */ if (mos_parport->msg_pending) wait_for_completion_timeout(&mos_parport->syncmsg_compl, - MOS_WDR_TIMEOUT); + msecs_to_jiffies(MOS_WDR_TIMEOUT)); parport_remove_port(mos_parport->pp); usb_set_serial_data(serial, NULL); |
