Hello,

[Maximum packet size issue]
>> diff --git a/src/ftdi.c b/src/ftdi.c
>> index d7f4bb0..26d08a4 100644
>> --- a/src/ftdi.c
>> +++ b/src/ftdi.c
>> @@ -1268,11 +1268,7 @@ int ftdi_read_data(struct ftdi_context *ftdi, 
>> unsigned char *buf, int size)
>>      int offset = 0, ret = 1, i, num_of_chunks, chunk_remains;
>>      int packet_size;
>>  
>> -    // New hi-speed devices from FTDI use a packet size of 512 bytes
>> -    if (ftdi->type == TYPE_2232H || ftdi->type == TYPE_4232H)
>> -        packet_size = 512;
>> -    else
>> -        packet_size = 64;
>> +    packet_size = 
>> usb_device(ftdi->usb_dev)->config[0].interface[ftdi->interface].altsetting[0].endpoint[0].wMaxPacketSize;
> 
> Like that, yes.  I'd check for null pointers and array boundaries though,
> and apply the right mask to wMaxPacketSize ... just in case.

Please give the attached patch a try. Works fine on my FT245BM type chip.

Cheers,
Thomas


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to [email protected]   
>From dad8dd7499954cb72dad89e371d9fce0685c7f8f Mon Sep 17 00:00:00 2001
From: Thomas Jarosch <[email protected]>
Date: Sun, 15 Nov 2009 12:45:03 +0100
Subject: [PATCH] Determine maximum packet size via usb config descriptor

---
 src/ftdi.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++------
 src/ftdi.h |    2 ++
 2 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/src/ftdi.c b/src/ftdi.c
index d7f4bb0..a87d653 100644
--- a/src/ftdi.c
+++ b/src/ftdi.c
@@ -98,6 +98,7 @@ int ftdi_init(struct ftdi_context *ftdi)
     ftdi->readbuffer_offset = 0;
     ftdi->readbuffer_remaining = 0;
     ftdi->writebuffer_chunksize = 4096;
+    ftdi->max_packet_size = 0;
 
     ftdi->interface = 0;
     ftdi->index = 0;
@@ -385,6 +386,45 @@ int ftdi_usb_get_strings(struct ftdi_context * ftdi, struct usb_device * dev,
 }
 
 /**
+ * Internal function to determine the maximum packet size.
+ * \param ftdi pointer to ftdi_context
+ * \param dev libusb usb_dev to use
+ * \retval Maximum packet size for this device
+ */
+static unsigned int _ftdi_determine_max_packet_size(struct ftdi_context *ftdi, struct usb_device *dev)
+{
+    unsigned int packet_size;
+
+    // Determine maximum packet size. Init with default value.
+    // New hi-speed devices from FTDI use a packet size of 512 bytes
+    // but could be connected to a normal speed USB hub -> 64 bytes packet size.
+    if (ftdi->type == TYPE_2232H || ftdi->type == TYPE_4232H)
+        packet_size = 512;
+    else
+        packet_size = 64;
+
+    if (dev->descriptor.bNumConfigurations > 0 && dev->config)
+    {
+        struct usb_config_descriptor config = dev->config[0];
+
+        if (ftdi->interface < config.bNumInterfaces)
+        {
+            struct usb_interface interface = config.interface[ftdi->interface];
+            if (interface.num_altsetting > 0)
+            {
+                struct usb_interface_descriptor descriptor = interface.altsetting[0];
+                if (descriptor.bNumEndpoints > 0)
+                {
+                    packet_size = descriptor.endpoint[0].wMaxPacketSize;
+                }
+            }
+        }
+    }
+
+    return packet_size;
+}
+
+/**
     Opens a ftdi device given by a usb_device.
 
     \param ftdi pointer to ftdi_context
@@ -491,6 +531,9 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct usb_device *dev)
             break;
     }
 
+    // Determine maximum packet size
+    ftdi->max_packet_size = _ftdi_determine_max_packet_size(ftdi, dev);
+
     if (ftdi_set_baudrate (ftdi, 9600) != 0)
     {
         ftdi_usb_close_internal (ftdi);
@@ -1266,13 +1309,11 @@ int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunk
 int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size)
 {
     int offset = 0, ret = 1, i, num_of_chunks, chunk_remains;
-    int packet_size;
+    int packet_size = ftdi->max_packet_size;
 
-    // New hi-speed devices from FTDI use a packet size of 512 bytes
-    if (ftdi->type == TYPE_2232H || ftdi->type == TYPE_4232H)
-        packet_size = 512;
-    else
-        packet_size = 64;
+    // Packet size sanity check (avoid division by zero)
+    if (packet_size == 0)
+        ftdi_error_return(-1, "max_packet_size is bogus (zero)");
 
     // everything we want is still in the readbuffer?
     if (size <= ftdi->readbuffer_remaining)
diff --git a/src/ftdi.h b/src/ftdi.h
index 74a397b..9ba3950 100644
--- a/src/ftdi.h
+++ b/src/ftdi.h
@@ -179,6 +179,8 @@ struct ftdi_context
     unsigned int readbuffer_chunksize;
     /** write buffer chunk size */
     unsigned int writebuffer_chunksize;
+    /** maximum packet size. Needed for filtering modem status bytes every n packets. */
+    unsigned int max_packet_size;
 
     /* FTDI FT2232C requirecments */
     /** FT2232C interface number: 0 or 1 */
-- 
1.6.4.4

Reply via email to