diff -Nruw iuu_phoenix-0.9/V2.6/iuu_phoenix.c iuu_phoenix-0.9-Fix/V2.6/iuu_phoenix.c --- iuu_phoenix-0.9/V2.6/iuu_phoenix.c 2008-01-18 22:30:42.000000000 +0100 +++ iuu_phoenix-0.9-Fix/V2.6/iuu_phoenix.c 2009-08-16 17:17:21.000000000 +0200 @@ -3,7 +3,6 @@ * * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com) * - * * Original code taken from iuutool ( Copyright (C) 2006 Juan Carlos BorrĂ¡s ) * * This program is free software; you can redistribute it and/or modify @@ -14,7 +13,6 @@ * And tested with help of WB Electronics * */ - #include #include #include @@ -42,14 +40,13 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.8" +#define DRIVER_VERSION "v0.9-Fix" #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" static struct usb_device_id id_table[] = { {USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)}, {} /* Terminating entry */ }; - MODULE_DEVICE_TABLE(usb, id_table); static struct usb_driver iuu_driver = { @@ -60,78 +57,16 @@ .no_dynamic_id = 1, }; -/* base functions */ -static int iuu_startup(struct usb_serial *serial); -static void iuu_shutdown(struct usb_serial *serial); - -static int iuu_open(struct usb_serial_port *port, struct file *filp); -static void iuu_close(struct usb_serial_port *port, struct file *filp); - -static int iuu_uart_flush(struct usb_serial_port *port); - -/* non interrupt context functions */ - -static int read_immediate(struct usb_serial_port *port, u8 * buf, u8 count); -static int iuu_uart_baud(struct usb_serial_port *port, u32 baud, - u32 *actual, u8 parity); -static int bulk_immediate(struct usb_serial_port *port, u8 * buf, u8 count); - -static int iuu_tiocmset(struct usb_serial_port *port, struct file *file, - unsigned int set, unsigned int clear); -static int iuu_tiocmget(struct usb_serial_port *port, struct file *file); - -static int iuu_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, - unsigned long arg); -static void iuu_set_termios(struct usb_serial_port *port, struct ktermios *old_termios); - -static int iuu_uart_write(struct usb_serial_port *port, - const u8 * buf, int count); - -static int iuu_uart_on(struct usb_serial_port *port); -static int iuu_uart_off(struct usb_serial_port *port); - -/* polled functions (interrupt context) */ - - -static void iuu_uart_read_callback(struct urb *urb); -static int iuu_read_buf(struct usb_serial_port *port, int len); -static void read_buf_callback(struct urb *urb); - -static int iuu_bulk_write(struct usb_serial_port *port); +/* turbo parameter */ +static int boost = 100; +static int clockmode = 1; +static int cdmode = 1; +static int iuu_cardin ; +static int iuu_cardout ; +static int xmas ; -static void iuu_rxcmd(struct urb *urb); static void read_rxcmd_callback(struct urb *urb); -static int iuu_status(struct usb_serial_port *port); -static void iuu_status_callback(struct urb *urb); -static void iuu_update_status_callback(struct urb *urb); - -static int iuu_reset(struct usb_serial_port *port, u8 wt); - -/* structures definitions */ - -static struct usb_serial_driver iuu_device = { - .driver = { - .owner = THIS_MODULE, - .name = "IUU Phoenix", - }, - .id_table = id_table, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = 1, - .num_bulk_out = 1, - .num_ports = 1, - .open = iuu_open, - .close = iuu_close, - .write = iuu_uart_write, - .read_bulk_callback = iuu_uart_read_callback, - .tiocmget = iuu_tiocmget, - .tiocmset = iuu_tiocmset, - .ioctl = iuu_ioctl, - .set_termios = iuu_set_termios, - .attach = iuu_startup, - .shutdown = iuu_shutdown, -}; - struct iuu_private { spinlock_t lock; /* store irq state */ wait_queue_head_t delta_msr_wait; @@ -142,7 +77,7 @@ u8 reset; /* if 1 reset is needed */ int poll; /* number of poll */ u8 *writebuf; /* buffer for writing to device */ - u8 writelen; /* num of byte to write to device */ + int writelen; /* num of byte to write to device */ u8 *buf; /* used for initialize speed */ u8 *dbgbuf; /* debug buffer */ u8 len; @@ -165,27 +100,18 @@ priv->writebuf = kzalloc(256, GFP_KERNEL); if (!priv->buf || !priv->dbgbuf || !priv->writebuf) { iuu_free_buf(priv); - dbg("%s problem allocation buffer", __FUNCTION__); + dbg("%s problem allocation buffer", __func__); return -ENOMEM; } - dbg("%s - Privates buffers allocation success", __FUNCTION__); + dbg("%s - Privates buffers allocation success", __func__); return 0; } -/* turbo parameter */ - -static int boost = 100; -static int clockmode = 1; -static int cdmode = 1; -static int iuu_cardin ; -static int iuu_cardout ; -static int xmas ; - static int iuu_startup(struct usb_serial *serial) { struct iuu_private *priv; priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); - dbg("%s- priv allocation success", __FUNCTION__); + dbg("%s- priv allocation success", __func__); if (!priv) return -ENOMEM; if (iuu_alloc_buf(priv)) { @@ -199,7 +125,6 @@ } /* Shutdown function */ - static void iuu_shutdown(struct usb_serial *serial) { struct usb_serial_port *port = serial->port[0]; @@ -207,40 +132,40 @@ if (!port) return; - dbg("%s", __FUNCTION__); + dbg("%s", __func__); if (priv) { iuu_free_buf(priv); - dbg("%s - I will free all", __FUNCTION__); + dbg("%s - I will free all", __func__); usb_set_serial_port_data(port, NULL); - dbg("%s - priv is not anymore in port structure", __FUNCTION__); + dbg("%s - priv is not anymore in port structure", __func__); kfree(priv); - dbg("%s priv is now kfree", __FUNCTION__); + dbg("%s priv is now kfree", __func__); } } - -static int -iuu_tiocmset(struct usb_serial_port *port, struct file *file, unsigned int set, - unsigned int clear) +static int iuu_tiocmset(struct tty_struct *tty, struct file *file, + unsigned int set, unsigned int clear) { + struct usb_serial_port *port = tty->driver_data; struct iuu_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - tty = port->tty; + unsigned long flags; - dbg("%s (%d) msg : SET = 0x%04x, CLEAR = 0x%04x ", __FUNCTION__, + /* FIXME: locking on tiomstatus */ + dbg("%s (%d) msg : SET = 0x%04x, CLEAR = 0x%04x ", __func__, port->number, set, clear); + + spin_lock_irqsave(&priv->lock, flags); if (set & TIOCM_RTS) priv->tiostatus = TIOCM_RTS; if (!(set & TIOCM_RTS) && priv->tiostatus == TIOCM_RTS) { - dbg("%s TIOCMSET RESET called !!!", __FUNCTION__); + dbg("%s TIOCMSET RESET called !!!", __func__); priv->reset = 1; - return 0; } - + spin_unlock_irqrestore(&priv->lock, flags); return 0; } @@ -249,47 +174,28 @@ * When no card , the reader respond with TIOCM_CD * This is known as CD autodetect mechanism */ - -static int iuu_tiocmget(struct usb_serial_port *port, struct file *file) +static int iuu_tiocmget(struct tty_struct *tty, struct file *file) { + struct usb_serial_port *port = tty->driver_data; struct iuu_private *priv = usb_get_serial_port_data(port); - dbg("%s (%d) ", __FUNCTION__, port->number); - return priv->tiostatus ; -} - -static void -iuu_set_termios(struct usb_serial_port *port, struct ktermios *old_termios){ - unsigned int cflag = port->tty->termios->c_cflag; - int status; - u32 actual; - dbg("%s (%d) ", __FUNCTION__, port->number); - if (cflag & PARODD) { - status = iuu_uart_baud(port, - (clockmode==2)?16457:9600 * boost / 100, - &actual, IUU_PARITY_ODD | IUU_TWO_STOP_BITS); - port->tty->termios->c_cflag &= CSTOPB ; - dbg("%s (%d) ODD", __FUNCTION__, port->number); - return; - } + unsigned long flags; + int rc; - if (cflag & PARENB) { - status = iuu_uart_baud(port, - (clockmode==2)?16457:9600 * boost / 100, - &actual, IUU_PARITY_EVEN | IUU_ONE_STOP_BIT); - port->tty->termios->c_cflag &= ~CSTOPB ; - dbg("%s (%d) EVEN", __FUNCTION__, port->number); - } + spin_lock_irqsave(&priv->lock, flags); + rc = priv->tiostatus; + spin_unlock_irqrestore(&priv->lock, flags); + return rc; } -static int -iuu_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, - unsigned long arg) +static int iuu_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) { + struct usb_serial_port *port = tty->driver_data; int mask; - dbg("%s (%d) cmd = 0x%04x", __FUNCTION__, port->number, cmd); + dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); switch (cmd) { @@ -303,7 +209,7 @@ case TCGETS: if (get_user(mask, (unsigned long *)arg)) return -EFAULT; - dbg("%s TIOCGSERIAL", __FUNCTION__); + dbg("%s TIOCGSERIAL", __func__); mask = CLOCAL | CREAD | CS8 | B9600 | TIOCM_CTS | CSTOPB | PARODD ; put_user(mask, &arg) ; return 0; @@ -312,7 +218,7 @@ case TIOCSSERIAL: if (get_user(mask, (unsigned long *)arg)) return -EFAULT; - dbg("%s (%d) msg = %04x", __FUNCTION__, port->number, mask); + dbg("%s (%d) msg = %04x", __func__, port->number, mask); return (0); case TIOCMIWAIT: @@ -321,18 +227,42 @@ case TCSBRK: return 0; default: - dbg("%s not supported = 0x%04x", __FUNCTION__, cmd); + dbg("%s not supported = 0x%04x", __func__, cmd); } return -ENOIOCTLCMD; } +static void iuu_rxcmd(struct urb *urb) +{ + struct usb_serial_port *port = urb->context; + int result; + int status = urb->status; + + dbg("%s - enter", __func__); + + if (status) { + dbg("%s - status = %d", __func__, status); + /* error stop all */ + return; + } + + + memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1); + usb_fill_bulk_urb(port->write_urb, port->serial->dev, + usb_sndbulkpipe(port->serial->dev, + port->bulk_out_endpointAddress), + port->write_urb->transfer_buffer, 1, + read_rxcmd_callback, port); + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); +} + static int iuu_reset(struct usb_serial_port *port, u8 wt) { struct iuu_private *priv = usb_get_serial_port_data(port); int result; char *buf_ptr = port->write_urb->transfer_buffer ; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); /* Prepare the reset sequence */ @@ -353,60 +283,29 @@ return result; } -static int iuu_status(struct usb_serial_port *port) -{ - int result; - - dbg("%s - enter", __FUNCTION__); - - memset(port->write_urb->transfer_buffer, IUU_GET_STATE_REGISTER, 1); - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, 1, - iuu_status_callback, port); - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - return result; - -} - -static void iuu_status_callback(struct urb *urb) -{ - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; - int result; - dbg("%s - enter", __FUNCTION__); - - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); - usb_fill_bulk_urb(port->read_urb, port->serial->dev, - usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, 256, - iuu_update_status_callback, port); - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); -} - /* Status Function * Return value is * 0x00 = no card * 0x01 = smartcard * 0x02 = sim card */ - static void iuu_update_status_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct iuu_private *priv = usb_get_serial_port_data(port); u8 *st; - dbg("%s - enter", __FUNCTION__); + int status = urb->status; - if (urb->status) { - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + dbg("%s - enter", __func__); + + if (status) { + dbg("%s - status = %d", __func__, status); /* error stop all */ return; } st = urb->transfer_buffer; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); if (urb->actual_length == 1) { switch (st[0]) { case 0x1: @@ -422,13 +321,45 @@ iuu_rxcmd(urb); } +static void iuu_status_callback(struct urb *urb) +{ + struct usb_serial_port *port = urb->context; + int result; + int status = urb->status; + + dbg("%s - status = %d", __func__, status); + usb_fill_bulk_urb(port->read_urb, port->serial->dev, + usb_rcvbulkpipe(port->serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, 256, + iuu_update_status_callback, port); + result = usb_submit_urb(port->read_urb, GFP_ATOMIC); +} + +static int iuu_status(struct usb_serial_port *port) +{ + int result; + + dbg("%s - enter", __func__); + + memset(port->write_urb->transfer_buffer, IUU_GET_STATE_REGISTER, 1); + usb_fill_bulk_urb(port->write_urb, port->serial->dev, + usb_sndbulkpipe(port->serial->dev, + port->bulk_out_endpointAddress), + port->write_urb->transfer_buffer, 1, + iuu_status_callback, port); + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); + return result; + +} + static int bulk_immediate(struct usb_serial_port *port, u8 * buf, u8 count) { int status; struct usb_serial *serial = port->serial; int actual = 0; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); /* send the data out the bulk port */ @@ -438,11 +369,10 @@ port->bulk_out_endpointAddress), buf, count, &actual, HZ * 1); - if (status != IUU_OPERATION_OK) { - dbg("%s - error = %2x", __FUNCTION__, status); - } else { - dbg("%s - write OK !", __FUNCTION__); - } + if (status != IUU_OPERATION_OK) + dbg("%s - error = %2x", __func__, status); + else + dbg("%s - write OK !", __func__); return status; } @@ -452,7 +382,7 @@ struct usb_serial *serial = port->serial; int actual = 0; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); /* send the data out the bulk port */ @@ -463,17 +393,16 @@ count, &actual, HZ * 1); if (status != IUU_OPERATION_OK) { - dbg("%s - error = %2x", __FUNCTION__, status); + dbg("%s - error = %2x", __func__, status); } else { - dbg("%s - read OK !", __FUNCTION__); + dbg("%s - read OK !", __func__); } return status; } -int -iuu_led(struct usb_serial_port *port, unsigned int R, unsigned int G, - unsigned int B, u8 f) +static int iuu_led(struct usb_serial_port *port, unsigned int R, + unsigned int G, unsigned int B, u8 f) { int status; u8 *buf; @@ -481,7 +410,7 @@ if (!buf) return -ENOMEM ; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); buf[0] = IUU_SET_LED; buf[1] = R & 0xFF; @@ -494,14 +423,15 @@ status = bulk_immediate(port, buf, 8); kfree(buf); if (status != IUU_OPERATION_OK) - dbg("%s - led error status = %2x", __FUNCTION__, status); + dbg("%s - led error status = %2x", __func__, status); else - dbg("%s - led OK !", __FUNCTION__); + dbg("%s - led OK !", __func__); return IUU_OPERATION_OK; } static void iuu_rgbf_fill_buffer( u8 *buf , u8 r1, u8 r2, u8 g1, u8 g2, u8 b1, - u8 b2, u8 freq ) { + u8 b2, u8 freq ) +{ *buf++ = IUU_SET_LED ; *buf++ = r1; *buf++ = r2; @@ -512,8 +442,9 @@ *buf = freq ; } -static void iuu_led_activity_on ( struct urb *urb ) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; +static void iuu_led_activity_on(struct urb *urb) +{ + struct usb_serial_port *port = urb->context; int result; char *buf_ptr = port->write_urb->transfer_buffer ; *buf_ptr++ = IUU_SET_LED ; @@ -532,8 +463,9 @@ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); } -static void iuu_led_activity_off ( struct urb *urb ) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; +static void iuu_led_activity_off(struct urb *urb) +{ + struct usb_serial_port *port = urb->context; int result ; char *buf_ptr = port->write_urb->transfer_buffer ; if ( xmas == 1 ) { @@ -571,7 +503,7 @@ unsigned int P2 = 0; int frq = (int)dwFrq; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); if (frq == 0) { priv->buf[Count++] = IUU_UART_WRITE_I2C; @@ -581,7 +513,7 @@ status = bulk_immediate(port, (u8 *) priv->buf, Count); if (status != 0) { - dbg("%s - write error ", __FUNCTION__); + dbg("%s - write error ", __func__); return status; } } else if (frq == 3579000) { @@ -605,10 +537,10 @@ unsigned int check; unsigned int check2; char found = 0x00; - unsigned int lQ = 2; unsigned int lP = 2055; unsigned int lDiv = 4; + for (lQ = 2; lQ <= 47 && !found; lQ++) for (lP = 2055; lP >= 8 && !found; lP--) for (lDiv = 4; lDiv <= 127 && !found; lDiv++) { @@ -661,8 +593,8 @@ priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ priv->buf[Count++] = FrqGenAdr << 1; priv->buf[Count++] = 0x40; - priv->buf[Count++] = (0xC0 | ((PUMP & 0x07) << 2)) - | (PBmsb & 0x03); /* Adr = 0x40 */ + priv->buf[Count++] = (0xC0 | ((PUMP & 0x07) << 2)) | + (PBmsb & 0x03); /* Adr = 0x40 */ priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ priv->buf[Count++] = FrqGenAdr << 1; priv->buf[Count++] = 0x41; @@ -690,7 +622,7 @@ status = bulk_immediate(port, (u8 *) priv->buf, Count); if (status != IUU_OPERATION_OK) - dbg("%s - write error ", __FUNCTION__); + dbg("%s - write error ", __func__); return status; } @@ -701,78 +633,154 @@ u8 rxcmd = IUU_UART_RX; struct iuu_private *priv = usb_get_serial_port_data(port); - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); - if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) { + if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) return -EIO; - } for (i = 0; i < 2; i++) { status = bulk_immediate(port, &rxcmd, 1); if (status != IUU_OPERATION_OK) { - dbg("%s - uart_flush_write error", __FUNCTION__); + dbg("%s - uart_flush_write error", __func__); return status; } status = read_immediate(port, &priv->len, 1); if (status != IUU_OPERATION_OK) { - dbg("%s - uart_flush_read error", __FUNCTION__); + dbg("%s - uart_flush_read error", __func__); return status; } if (priv->len > 0) { - dbg("%s - uart_flush datalen is : %i ", __FUNCTION__, + dbg("%s - uart_flush datalen is : %i ", __func__, priv->len); status = read_immediate(port, priv->buf, priv->len); if (status != IUU_OPERATION_OK) { - dbg("%s - uart_flush_read error", __FUNCTION__); + dbg("%s - uart_flush_read error", __func__); return status; } } } - dbg("%s - uart_flush_read OK!", __FUNCTION__); + dbg("%s - uart_flush_read OK!", __func__); iuu_led(port, 0, 0xF000, 0, 0xFF); return status; } +static void read_buf_callback(struct urb *urb) +{ + struct usb_serial_port *port = urb->context; + unsigned char *data = urb->transfer_buffer; + struct tty_struct *tty; + int status = urb->status; + + if (status) { + dbg("%s - status = %d", __func__, status); + if (status == -EPROTO) { + /* reschedule needed */ + } + return; + } + + dbg("%s - %i chars to write", __func__, urb->actual_length); + tty = tty_port_tty_get(&port->port); + if ( data == NULL ) + dbg("%s - data is NULL !!!", __func__ ); + if (tty && urb->actual_length && data ) { + tty_insert_flip_string(tty, data, urb->actual_length); + tty_flip_buffer_push(tty); + } + tty_kref_put(tty); + iuu_led_activity_on(urb); +} + +static int iuu_bulk_write(struct usb_serial_port *port) +{ + struct iuu_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + int result; + int i; + u8 buf_len ; + char *buf_ptr = port->write_urb->transfer_buffer ; + dbg("%s - enter", __func__); + spin_lock_irqsave(&priv->lock, flags); + + *buf_ptr++ = IUU_UART_ESC ; + *buf_ptr++ = IUU_UART_TX ; + *buf_ptr++ = priv->writelen ; + + memcpy(buf_ptr, priv->writebuf, + priv->writelen); + buf_len = priv->writelen ; + priv->writelen = 0; + spin_unlock_irqrestore(&priv->lock, flags); + if ( debug == 1 ) { + for ( i = 0 ; i dbgbuf + i*2 , + "%02X", priv->writebuf[i]); + } + priv->dbgbuf[buf_len+i*2] = 0 ; + dbg("%s - writing %i chars : %s", __func__, + buf_len, priv->dbgbuf ); + } + usb_fill_bulk_urb(port->write_urb, port->serial->dev, + usb_sndbulkpipe(port->serial->dev, + port->bulk_out_endpointAddress), + port->write_urb->transfer_buffer, buf_len + 3, + iuu_rxcmd, port); + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); + usb_serial_port_softint(port); + return result; +} + +static int iuu_read_buf(struct usb_serial_port *port, int len) +{ + int result; + dbg("%s - enter", __func__); + + usb_fill_bulk_urb(port->read_urb, port->serial->dev, + usb_rcvbulkpipe(port->serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, len, + read_buf_callback, port); + result = usb_submit_urb(port->read_urb, GFP_ATOMIC); + return result; +} + static void iuu_uart_read_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned int flags; - int status; + unsigned long flags; + int status = urb->status; int error = 0; int len = 0 ; unsigned char *data = urb->transfer_buffer ; priv->poll++; - dbg("%s - enter", __FUNCTION__); + dbg("%s - enter", __func__); - if (urb->status) { - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + if (status) { + dbg("%s - status = %d", __func__, status); /* error stop all */ return; } if ( data == NULL ) - dbg("%s - data is NULL !!!", __FUNCTION__ ); + dbg("%s - data is NULL !!!", __func__ ); if ( urb->actual_length == 1 && data != NULL ) len = (int) data[0]; - if (urb->actual_length > 1) { - dbg("%s - urb->actual_length = %i", __FUNCTION__, + dbg("%s - urb->actual_length = %i", __func__, urb->actual_length); error = 1; return ; } - - /* if len > 0 call readbuf */ if (len > 0 && error == 0) { dbg("%s - call read buf - len to read is %i ", - __FUNCTION__, len); + __func__, len); status = iuu_read_buf(port, len); return; } @@ -798,57 +806,16 @@ } spin_unlock_irqrestore(&priv->lock, flags); /* if nothing to write call again rxcmd */ - dbg("%s - rxcmd recall", __FUNCTION__); + dbg("%s - rxcmd recall", __func__); iuu_led_activity_off(urb); - return; -} - -static int iuu_read_buf(struct usb_serial_port *port, int len) -{ - int result; - dbg("%s - enter", __FUNCTION__); - - usb_fill_bulk_urb(port->read_urb, port->serial->dev, - usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, len, - read_buf_callback, port); - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); - return result; -} - -static void read_buf_callback(struct urb *urb) -{ - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; - unsigned char *data = urb->transfer_buffer; - struct tty_struct *tty; - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); - - if (urb->status) { - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); - if (urb->status == -EPROTO) { - /* reschedule needed */ - } - return; - } - - dbg("%s - %i chars to write", __FUNCTION__, urb->actual_length); - tty = port->tty; - if ( data == NULL ) - dbg("%s - data is NULL !!!", __FUNCTION__ ); - if (tty && urb->actual_length && data ) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } - iuu_led_activity_on(urb); } -static int -iuu_uart_write(struct usb_serial_port *port, const u8 * buf, int count) +static int iuu_uart_write(struct tty_struct *tty, struct usb_serial_port *port, + const u8 *buf, int count) { struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned int flags; - dbg("%s - enter", __FUNCTION__); + unsigned long flags; + dbg("%s - enter", __func__); if ( count > 256 ) return -ENOMEM ; @@ -857,85 +824,25 @@ //if (priv->writelen > 0 ) { /* buffer already filled but not commited */ // spin_unlock_irqrestore(&priv->lock, flags); - // return (0); + // return 0; //} /* fill the buffer */ memcpy(priv->writebuf+priv->writelen, buf, count); priv->writelen += (u8) count; spin_unlock_irqrestore(&priv->lock, flags); - return (count); -} - -static int iuu_bulk_write(struct usb_serial_port *port) -{ - struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned int flags; - int result; - int i; - u8 buf_len ; - char *buf_ptr = port->write_urb->transfer_buffer ; - dbg("%s - enter", __FUNCTION__); - spin_lock_irqsave(&priv->lock, flags); - *buf_ptr++ = IUU_UART_ESC ; - *buf_ptr++ = IUU_UART_TX ; - *buf_ptr++ = priv->writelen ; - memcpy(buf_ptr, priv->writebuf, - priv->writelen); - buf_len = priv->writelen ; - priv->writelen = 0; - spin_unlock_irqrestore(&priv->lock, flags); - if ( debug == 1 ) { - for ( i = 0 ; i dbgbuf + i*2 , - "%02X", priv->writebuf[i]); - } - priv->dbgbuf[buf_len+i*2] = 0 ; - dbg("%s - writing %i chars : %s", __FUNCTION__, - buf_len, priv->dbgbuf ); - } - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, buf_len + 3, - iuu_rxcmd, port); - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - usb_serial_port_softint(port); - return result; -} - -static void iuu_rxcmd(struct urb *urb) -{ - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; - int result; - dbg("%s - enter", __FUNCTION__); - - if (urb->status) { - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); - /* error stop all */ - return; - } - - - memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1); - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, 1, - read_rxcmd_callback, port); - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); + return count; } static void read_rxcmd_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct usb_serial_port *port = urb->context; int result; - dbg("%s - enter", __FUNCTION__); + int status = urb->status; - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + dbg("%s - status = %d", __func__, status); - if (urb->status) { - dbg("%s - urb->status = %d", __FUNCTION__, urb->status); + if (status) { /* error stop all */ return; } @@ -946,7 +853,7 @@ port->read_urb->transfer_buffer, 256, iuu_uart_read_callback, port); result = usb_submit_urb(port->read_urb, GFP_ATOMIC); - dbg("%s - submit result = %d", __FUNCTION__, result); + dbg("%s - submit result = %d", __func__, result); return; } @@ -967,13 +874,13 @@ status = bulk_immediate(port, buf, 4); if (status != IUU_OPERATION_OK) { - dbg("%s - uart_on error", __FUNCTION__); + dbg("%s - uart_on error", __func__); goto uart_enable_failed ; } /* iuu_reset() the card after iuu_uart_on() */ status = iuu_uart_flush(port); if (status != IUU_OPERATION_OK) - dbg("%s - uart_flush error", __FUNCTION__); + dbg("%s - uart_flush error", __func__); uart_enable_failed: kfree(buf); return status; @@ -991,16 +898,14 @@ status = bulk_immediate(port, buf, 1); if (status != IUU_OPERATION_OK) - dbg("%s - uart_off error", __FUNCTION__); + dbg("%s - uart_off error", __func__); kfree(buf); return status; } - -static int -iuu_uart_baud(struct usb_serial_port *port, u32 baud, u32 *actual, - u8 parity) +static int iuu_uart_baud(struct usb_serial_port *port, u32 baud, + u32 *actual, u8 parity) { int status; u8 *dataout; @@ -1087,12 +992,86 @@ status = bulk_immediate(port, dataout, DataCount); if (status != IUU_OPERATION_OK) - dbg("%s - uart_off error", __FUNCTION__); + dbg("%s - uart_off error", __func__); kfree(dataout); return status; } -static int iuu_open(struct usb_serial_port *port, struct file *filp) +static void iuu_set_termios(struct tty_struct *tty, struct usb_serial_port *port, + struct ktermios *old_termios) +{ + unsigned int cflag = tty->termios->c_cflag; + int status; + u32 actual; + dbg("%s (%d) ", __func__, port->number); + if (cflag & PARODD) { + status = iuu_uart_baud(port, + (clockmode==2)?16457:9600 * boost / 100, + &actual, IUU_PARITY_ODD | IUU_TWO_STOP_BITS); + tty->termios->c_cflag &= CSTOPB ; + dbg("%s (%d) ODD", __func__, port->number); + return; + } + + if (cflag & PARENB) { + status = iuu_uart_baud(port, + (clockmode==2)?16457:9600 * boost / 100, + &actual, IUU_PARITY_EVEN | IUU_ONE_STOP_BIT); + tty->termios->c_cflag &= ~CSTOPB ; + dbg("%s (%d) EVEN", __func__, port->number); + } + +} + +static int set_control_lines(struct usb_device *dev, u8 value) +{ + return 0; +} + +static void iuu_close(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp) +{ + /* iuu_led (port,255,0,0,0); */ + struct usb_serial *serial; + struct iuu_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + unsigned int c_cflag; + + serial = port->serial; + if (!serial) + return; + + dbg("%s - port %d", __func__, port->number); + + iuu_uart_off(port); + if (serial->dev) { + if (tty) { + c_cflag = tty->termios->c_cflag; + if (c_cflag & HUPCL) { + /* drop DTR and RTS */ + priv = usb_get_serial_port_data(port); + spin_lock_irqsave(&priv->lock, flags); + priv->line_control = 0; + spin_unlock_irqrestore(&priv->lock, flags); + set_control_lines(port->serial->dev, 0); + } + } + /* free writebuf */ + /* shutdown our urbs */ + dbg("%s - shutting down urbs", __func__); + usb_kill_urb(port->write_urb); + usb_kill_urb(port->read_urb); + usb_kill_urb(port->interrupt_in_urb); + msleep(1000); + /* wait one second to free all buffers */ + iuu_led(port, 0, 0, 0xF000, 0xFF); + msleep(1000); + usb_reset_device(port->serial->dev); + } +} + +static int iuu_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; u8 *buf; @@ -1101,7 +1080,7 @@ unsigned long flags; struct iuu_private *priv = usb_get_serial_port_data(port); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __func__, port->number); usb_clear_halt(serial->dev, port->write_urb->pipe); usb_clear_halt(serial->dev, port->read_urb->pipe); @@ -1110,7 +1089,6 @@ return -ENOMEM; /* fixup the endpoint buffer size */ - kfree(port->bulk_out_buffer) ; port->bulk_out_buffer = kmalloc(512, GFP_KERNEL); port->bulk_out_size = 512 ; @@ -1141,23 +1119,23 @@ /* set the termios structure */ spin_lock_irqsave(&priv->lock, flags); - if (!priv->termios_initialized) { - *(port->tty->termios) = tty_std_termios; - port->tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600 + if (tty && !priv->termios_initialized) { + *(tty->termios) = tty_std_termios; + tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600 | TIOCM_CTS | PARENB; - port->tty->termios->c_cflag &= ~(CSIZE|PARODD|CSTOPB); - port->tty->termios->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); - port->tty->termios->c_oflag &= ~OPOST;; - port->tty->termios->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP +// tty->termios->c_ispeed = 9600; +// tty->termios->c_ospeed = 9600; + tty->termios->c_cflag &= ~(CSIZE|PARODD|CSTOPB); + tty->termios->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + tty->termios->c_oflag &= ~OPOST;; + tty->termios->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP |INLCR|IGNCR|ICRNL|IXON); priv->termios_initialized = 1; - port->tty->low_latency = 1; priv->poll = 0; } spin_unlock_irqrestore(&priv->lock, flags); /* initialize writebuf */ - #define FISH(a, b, c, d) do { \ result = usb_control_msg(port->serial->dev, \ usb_rcvctrlpipe(port->serial->dev, 0), \ @@ -1204,7 +1182,6 @@ } /* set the cardin cardout signals */ - switch (cdmode) { case 0: iuu_cardin = 0 ; @@ -1245,7 +1222,7 @@ iuu_uart_flush(port); - dbg("%s - initialization done", __FUNCTION__); + dbg("%s - initialization done", __func__); memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1); usb_fill_bulk_urb(port->write_urb, port->serial->dev, @@ -1257,60 +1234,33 @@ if (result) { dev_err(&port->dev, "%s - failed submitting read urb," - " error %d\n", __FUNCTION__, result); - iuu_close(port, NULL); + " error %d\n", __func__, result); + iuu_close(tty, port, NULL); return -EPROTO; } else { - dbg("%s - rxcmd OK", __FUNCTION__); + dbg("%s - rxcmd OK", __func__); } return result; } -static int set_control_lines(struct usb_device *dev, u8 value) -{ - return 0; -} - -static void iuu_close(struct usb_serial_port *port, struct file *filp) -{ - /* iuu_led (port,255,0,0,0); */ - struct usb_serial *serial; - struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int c_cflag; - - serial = port->serial; - if (!serial) - return; - - dbg("%s - port %d", __FUNCTION__, port->number); - - iuu_uart_off(port); - if (serial->dev) { - if (port->tty) { - c_cflag = port->tty->termios->c_cflag; - if (c_cflag & HUPCL) { - /* drop DTR and RTS */ - priv = usb_get_serial_port_data(port); - spin_lock_irqsave(&priv->lock, flags); - priv->line_control = 0; - spin_unlock_irqrestore(&priv->lock, flags); - set_control_lines(port->serial->dev, 0); - } - } - /* free writebuf */ - /* shutdown our urbs */ - dbg("%s - shutting down urbs", __FUNCTION__); - usb_kill_urb(port->write_urb); - usb_kill_urb(port->read_urb); - usb_kill_urb(port->interrupt_in_urb); - msleep(1000); - /* wait one second to free all buffers */ - iuu_led(port, 0, 0, 0xF000, 0xFF); - msleep(1000); - usb_reset_device(port->serial->dev); - } -} +static struct usb_serial_driver iuu_device = { + .driver = { + .owner = THIS_MODULE, + .name = "iuu_phoenix", + }, + .id_table = id_table, + .num_ports = 1, + .open = iuu_open, + .close = iuu_close, + .write = iuu_uart_write, + .read_bulk_callback = iuu_uart_read_callback, + .tiocmget = iuu_tiocmget, + .tiocmset = iuu_tiocmset, + .ioctl = iuu_ioctl, + .set_termios = iuu_set_termios, + .attach = iuu_startup, + .shutdown = iuu_shutdown, +}; static int __init iuu_init(void) { @@ -1321,7 +1271,8 @@ retval = usb_register(&iuu_driver); if (retval) goto failed_usb_register; - info(DRIVER_DESC " " DRIVER_VERSION); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); return 0; failed_usb_register: usb_serial_deregister(&iuu_device); @@ -1357,4 +1308,5 @@ MODULE_PARM_DESC(clockmode, "1=3Mhz579,2=3Mhz680,3=6Mhz"); module_param(cdmode, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(cdmode, "Card detect mode 0=none, 1=CD, 2=!CD, 3=DSR, 4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING"); +MODULE_PARM_DESC(cdmode, "Card detect mode 0=none, 1=CD, 2=!CD, 3=DSR, " + "4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING"); diff -Nruw iuu_phoenix-0.9/V2.6/Makefile iuu_phoenix-0.9-Fix/V2.6/Makefile --- iuu_phoenix-0.9/V2.6/Makefile 2007-08-04 13:38:09.000000000 +0200 +++ iuu_phoenix-0.9-Fix/V2.6/Makefile 2009-08-16 17:17:06.000000000 +0200 @@ -1,9 +1,11 @@ # USB-Serial Makefile # +ifneq ($(VER),) + VERSION=$(VER) +else VERSION=$(shell uname -r) -#VERSION=2.6.22.1 - +endif obj-m := iuu_phoenix.o