Because Greg wanted more smaller patches:

This is patch 3 which will apply against 2.4.21-pre5 with the ftdi_sio patch 2 applied. (as an aside patch1 was the reject one with lots of new ioctls).

This patch now allows the device to operate very close to buadrate (I get around baudrate at 921600 with a BM device). Richard Shooter who implemented the read speed change gets 1Mb/s at 1.5MBaud).

John Wilkins fixed Xon/Xoff and added a vid/pid for the videonetworks/homechoice device.

The device driver now has full soft and hard flow control, high speed and seems pretty stable (I test with four different ftdi devices attached through a hub and have no problems).

I have one more very interesting patch from Wayne Wylupski which allows command line setting of vid/pid but I haven't tried it out yet hence haven't submitted it.

----
Bill






diff -rauX ../dontdiff new/drivers/usb/serial/ftdi_sio.c 
patch_3/drivers/usb/serial/ftdi_sio.c
--- new/drivers/usb/serial/ftdi_sio.c   2003-03-26 23:32:44.000000000 +1200
+++ patch_3/drivers/usb/serial/ftdi_sio.c       2003-03-26 23:47:39.000000000 +1200
@@ -17,6 +17,14 @@
  * See http://ftdi-usb-sio.sourceforge.net for upto date testing info
  *     and extra documentation
  *
+ * (24/Feb/2003) Richard Shooter
+ *      Increase read buffer size to improve read speeds at higher baud rates
+ *      (specifically tested with up to 1Mb/sec at 1.5M baud)
+ *
+ * (23/Feb/2003) John Wilkins
+ *      Added Xon/xoff flow control (activating support in the ftdi device)
+ *      Added vid/pid for Videonetworks/Homechoice (UK ISP)
+ *
  * (23/Feb/2003) Bill Ryder
  *      Added matrix orb device vid/pids from Wayne Wylupski
  *
@@ -175,7 +183,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.3.2"
+#define DRIVER_VERSION "v1.3.3"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <[EMAIL PROTECTED]>, Bill Ryder <[EMAIL 
PROTECTED]>, Kuba Ober <[EMAIL PROTECTED]>"
 #define DRIVER_DESC "USB FTDI Serial Converters Driver"
 
@@ -206,6 +214,7 @@
        { USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0, 0x3ff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_1_PID, 0, 0x3ff) },
        { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_2_PID, 0, 0x3ff) },
@@ -222,6 +231,7 @@
        { USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0x400, 0xffff) },
+       { USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_1_PID, 0x400, 0xffff) },
        { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_2_PID, 0x400, 0xffff) },
@@ -240,6 +250,7 @@
        { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
        { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) },
        { USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID) },
        { USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_1_PID) },
        { USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_2_PID) },
@@ -883,6 +894,17 @@
        /* Make sure write_urb is initialised since a write_pool is used now */
        port->write_urb = NULL; /* prevents usbserial.c from trying something silly */
 
+// Read speed increase - start
+       /* increase the size of read buffers */
+#define BUFSZ 512
+       if( port->bulk_in_buffer != NULL)
+       {
+               kfree(port->bulk_in_buffer);
+               port->bulk_in_buffer = kmalloc( BUFSZ, GFP_KERNEL);
+               port->read_urb->transfer_buffer = port->bulk_in_buffer;
+               port->read_urb->transfer_buffer_length = BUFSZ;
+       }
+// Read speed increase --end 
 
        /* Start reading from the device */
        FILL_BULK_URB(port->read_urb, serial->dev, 
@@ -1183,6 +1205,15 @@
        int i;
        int result;
 
+       int packet_offset;
+#define PKTSZ 64
+       if( urb->number_of_packets > 0 )
+       {
+               err("%s transfer_buffer_length %d actual_length %d number of packets 
%d",__FUNCTION__,
+                   urb->transfer_buffer_length, urb->actual_length, 
urb->number_of_packets );
+               err("%s transfer_flags %x USB_QUEUE_BULK %x ", 
__FUNCTION__,urb->transfer_flags, USB_QUEUE_BULK );
+       }
+
        dbg("%s", __FUNCTION__);
 
        if (port_paranoia_check (port, __FUNCTION__)) {
@@ -1221,9 +1252,12 @@
        /* See acm.c - you do a tty_hangup  - eg tty_hangup(tty) */
        /* if CD is dropped and the line is not CLOCAL then we should hangup */
 
+       for(packet_offset=0; packet_offset < urb->actual_length; packet_offset += 
PKTSZ )
+       {
+
        /* Compare new line status to the old one, signal if different */
        if (priv != NULL) {
-               char new_status = data[0] & FTDI_STATUS_B0_MASK;
+                       char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK;
                if (new_status != priv->prev_status) {
                        priv->diff_status |= new_status ^ priv->prev_status;
                        wake_up_interruptible(&priv->delta_msr_wait);
@@ -1237,25 +1271,27 @@
         /* errors on a packet - the order here sets the priority the */
         /* error is returned to the tty layer  */
        
-       if ( data[1] & FTDI_RS_OE ) { 
+               if ( data[packet_offset+1] & FTDI_RS_OE ) {
                error_flag = TTY_OVERRUN;
                 dbg("OVERRRUN error");
        }
-       if ( data[1] & FTDI_RS_BI ) { 
+               if ( data[packet_offset+1] & FTDI_RS_BI ) {
                error_flag = TTY_BREAK;
                 dbg("BREAK received");
        }
-       if ( data[1] & FTDI_RS_PE ) { 
+               if ( data[packet_offset+1] & FTDI_RS_PE ) {
                error_flag = TTY_PARITY;
                 dbg("PARITY error");
        }
-       if ( data[1] & FTDI_RS_FE ) { 
+               if ( data[packet_offset+1] & FTDI_RS_FE ) {
                error_flag = TTY_FRAME;
                 dbg("FRAMING error");
        }
        if (urb->actual_length > data_offset) {
 
-               for (i = data_offset ; i < urb->actual_length ; ++i) {
+                       /* CHECKME - Does this have any side affects for devices that 
dont have */
+                       /* two status bytes at the start of each packet ? */
+                       for (i = data_offset ; (i < PKTSZ) && ((i+packet_offset) < 
urb->actual_length) ; ++i) {
                        /* have to make sure we don't overflow the buffer
                          with tty_insert_flip_char's */
                        if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
@@ -1264,12 +1300,12 @@
                        /* Note that the error flag is duplicated for 
                           every character received since we don't know
                           which character it applied to */
-                       tty_insert_flip_char(tty, data[i], error_flag);
+                               tty_insert_flip_char(tty, data[packet_offset+i], 
error_flag);
                }
                tty_flip_buffer_push(tty);
        } 
 
-#ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW
+       #ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW
        /* if a parity error is detected you get status packets forever
           until a character is sent without a parity error.
           This doesn't work well since the application receives a never
@@ -1290,6 +1326,7 @@
                }
        }
 #endif
+       } /* "for(packet_offset=0..." */
 
        /* if the port is closed stop trying to read */
        if (port->open_count > 0){
@@ -1352,6 +1389,10 @@
        __u16 urb_value; /* will hold the new flags */
        char buf[1]; /* Perhaps I should dynamically alloc this? */
        
+       // Added for xon/xoff support
+       unsigned int iflag = port->tty->termios->c_iflag;
+       unsigned char vstop;
+       unsigned char vstart;
        
        dbg("%s", __FUNCTION__);
 
@@ -1434,6 +1475,33 @@
                }               
                
        } else { 
+               /*
+                * Xon/Xoff code
+                *
+                * Check the IXOFF status in the iflag component of the termios 
structure
+                * if IXOFF is not set, the pre-xon/xoff code is executed.
+               */
+               if(iflag & IXOFF) {
+                       dbg("%s  request to enable xonxoff 
iflag=%04x",__FUNCTION__,iflag);
+                       // Try to enable the XON/XOFF on the ftdi_sio
+                       // Set the vstart and vstop -- could have been done up above 
where
+                       // a lot of other dereferencing is done but that would be very
+                       // inefficient as vstart and vstop are not always needed
+                       vstart=port->tty->termios->c_cc[VSTART];
+                       vstop=port->tty->termios->c_cc[VSTOP];
+                       urb_value=(vstop << 8) | (vstart);
+
+                       if (usb_control_msg(serial->dev,
+                                           usb_sndctrlpipe(serial->dev, 0),
+                                           FTDI_SIO_SET_FLOW_CTRL_REQUEST,
+                                           FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
+                                           urb_value , FTDI_SIO_XON_XOFF_HS,
+                                           buf, 0, WDR_TIMEOUT) < 0) {
+                               err("urb failed to set to xon/xoff flow control");
+                       }
+
+               }else{
+                       /* else clause to only run if cfag ! CRTSCTS and iflag ! XOFF 
*/
                /* CHECKME Assuming XON/XOFF handled by tty stack - not by device */
                dbg("%s Turning off hardware flow control", __FUNCTION__);
                if (usb_control_msg(serial->dev, 
@@ -1444,6 +1512,7 @@
                                    buf, 0, WDR_TIMEOUT) < 0) {
                        err("urb failed to clear flow control");
                }                               
+               }
                
        }
        return;
diff -rauX ../dontdiff new/drivers/usb/serial/ftdi_sio.h 
patch_3/drivers/usb/serial/ftdi_sio.h
--- new/drivers/usb/serial/ftdi_sio.h   2003-03-26 23:32:44.000000000 +1200
+++ patch_3/drivers/usb/serial/ftdi_sio.h       2003-03-25 23:26:52.000000000 +1200
@@ -25,12 +25,15 @@
 #define FTDI_NF_RIC_VID        0x0DCD  /* Vendor Id */
 #define FTDI_NF_RIC_PID        0x0001  /* Product Id */
 
-
 /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */
 /* they use the ftdi chipset for the USB interface and the vendor id is the same */
 #define FTDI_XF_634_PID  0xFC09        /* Four line device */
 #define FTDI_XF_632_PID  0xFC08        /* Two line device */
 
+/* Video Networks Limited / Homechoice in the UK use an ftdi-based device for their 
1Mb */
+/* broadband internet service.  The following PID is exhibited by the usb device 
supplied */
+/* (the VID is the standard ftdi vid (FTDI_VID) */
+#define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */
 
 /*
  * The following are the values for the Matrix Orbital LCD displays,

Reply via email to