Author: hselasky
Date: Fri Sep 12 22:40:12 2014
New Revision: 271492
URL: http://svnweb.freebsd.org/changeset/base/271492

Log:
  Workaround for receiving Voice Calls using the E1750 dongle from
  Huawei. It might appear as if the firmware is allocating memory blocks
  according to the USB transfer size and if there is initially a lot of
  data, like at the answering machine prompt, it simply dies without any
  apparent reason. The simple workaround for this is to force a zero
  length packet at hardware level after every 512 bytes of data. This
  will force the other side to use smaller memory blocks aswell.
  
  MFC after:    1 week

Modified:
  head/sys/dev/usb/serial/u3g.c

Modified: head/sys/dev/usb/serial/u3g.c
==============================================================================
--- head/sys/dev/usb/serial/u3g.c       Fri Sep 12 22:20:07 2014        
(r271491)
+++ head/sys/dev/usb/serial/u3g.c       Fri Sep 12 22:40:12 2014        
(r271492)
@@ -75,6 +75,8 @@ SYSCTL_INT(_hw_usb_u3g, OID_AUTO, debug,
 #define        U3G_MAXPORTS            12
 #define        U3G_CONFIG_INDEX        0
 #define        U3G_BSIZE               2048
+#define        U3G_TXSIZE              (U3G_BSIZE / U3G_TXFRAMES)
+#define        U3G_TXFRAMES            4
 
 /* Eject methods; See also usb_quirks.h:UQ_MSC_EJECT_* */
 #define        U3GINIT_HUAWEI          1       /* Requires Huawei init command 
*/
@@ -145,6 +147,7 @@ static const struct usb_config u3g_confi
                .endpoint = UE_ADDR_ANY,
                .direction = UE_DIR_OUT,
                .bufsize = U3G_BSIZE,/* bytes */
+               .frames = U3G_TXFRAMES,
                .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
                .callback = &u3g_write_callback,
        },
@@ -1011,14 +1014,22 @@ u3g_write_callback(struct usb_xfer *xfer
        struct ucom_softc *ucom = usbd_xfer_softc(xfer);
        struct usb_page_cache *pc;
        uint32_t actlen;
+       uint32_t frame;
 
        switch (USB_GET_STATE(xfer)) {
        case USB_ST_TRANSFERRED:
        case USB_ST_SETUP:
 tr_setup:
-               pc = usbd_xfer_get_frame(xfer, 0);
-               if (ucom_get_data(ucom, pc, 0, U3G_BSIZE, &actlen)) {
-                       usbd_xfer_set_frame_len(xfer, 0, actlen);
+               for (frame = 0; frame != U3G_TXFRAMES; frame++) {
+                       usbd_xfer_set_frame_offset(xfer, frame * U3G_TXSIZE, 
frame);
+
+                       pc = usbd_xfer_get_frame(xfer, frame);
+                       if (ucom_get_data(ucom, pc, 0, U3G_TXSIZE, &actlen) == 
0)
+                               break;
+                       usbd_xfer_set_frame_len(xfer, frame, actlen);
+               }
+               if (frame != 0) {
+                       usbd_xfer_set_frames(xfer, frame);
                        usbd_transfer_submit(xfer);
                }
                break;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to