diff options
author | Mike Fiore <mfiore@multitech.com> | 2013-03-27 11:13:38 -0500 |
---|---|---|
committer | Mike Fiore <mfiore@multitech.com> | 2013-03-27 11:13:38 -0500 |
commit | 52478a46ad08fcc9706897ed497f61cbb238b49e (patch) | |
tree | ab6ea7b61fe7c6d71579a9020969ce80fe58041d /multitech | |
parent | 3d6759beb8d2bdb12a132ce1b98694a4ed70085a (diff) |
vizzini: add flow control patch and bump
Diffstat (limited to 'multitech')
-rw-r--r-- | multitech/recipes/vizzini/vizzini-0.76/vizzini-0.76-flow-control.patch | 157 | ||||
-rw-r--r-- | multitech/recipes/vizzini/vizzini_0.76.bb | 3 |
2 files changed, 159 insertions, 1 deletions
diff --git a/multitech/recipes/vizzini/vizzini-0.76/vizzini-0.76-flow-control.patch b/multitech/recipes/vizzini/vizzini-0.76/vizzini-0.76-flow-control.patch new file mode 100644 index 0000000..77adf53 --- /dev/null +++ b/multitech/recipes/vizzini/vizzini-0.76/vizzini-0.76-flow-control.patch @@ -0,0 +1,157 @@ +--- a/vizzini.c 2013-03-26 11:34:39.362546946 -0500 ++++ b/vizzini.c 2013-03-27 10:43:03.123460275 -0500 +@@ -92,6 +92,9 @@ + #define N_OUT_URB 4 + #define IN_BUFLEN 4096 + ++#define READ_URB_RUNNING 0 ++#define READ_URB_STOPPED 1 ++ + static int debug; + + +@@ -169,6 +172,7 @@ + + struct urb *in_urbs[N_IN_URB]; + char *in_buffer[N_IN_URB]; ++ int in_urb_flags[N_IN_URB]; + + int ctrlin; + int ctrlout; +@@ -995,6 +999,8 @@ + char *transfer_buffer = urb->transfer_buffer; + int length, room, have_extra_byte; + int err; ++ unsigned long flags; ++ int j; + + if (debug) dev_dbg(&port->dev, "%s: %p\n", __func__, urb); + +@@ -1085,9 +1091,26 @@ + portdata->extra_byte = transfer_buffer[urb->actual_length - 1]; + } + +- err = usb_submit_urb(urb, GFP_ATOMIC); +- if (err) +- dev_err(&port->dev, "resubmit read urb failed. (%d)\n", err); ++ /* throttle device if requested */ ++ spin_lock_irqsave(&port->lock, flags); ++ port->throttled = port->throttle_req; ++ if (! port->throttled) { ++ spin_unlock_irqrestore(&port->lock, flags); ++ err = usb_submit_urb(urb, GFP_ATOMIC); ++ if (err) ++ dev_err(&port->dev, "resubmit read urb failed. (%d)\n", err); ++ } else { ++ spin_unlock_irqrestore(&port->lock, flags); ++ for (j = 0; j < N_IN_URB; j++) { ++ if (portdata->in_urbs[j] == urb) { ++ if (debug) dev_dbg(&port->dev, "throttling urb %d\n", j); ++ spin_lock_irqsave(&port->lock, flags); ++ portdata->in_urb_flags[j] = READ_URB_STOPPED; ++ spin_unlock_irqrestore(&port->lock, flags); ++ break; ++ } ++ } ++ } + } + + +@@ -1172,6 +1195,7 @@ + int i; + struct urb *urb; + int result; ++ unsigned long flags; + + portdata = usb_get_serial_port_data(port); + +@@ -1179,10 +1203,19 @@ + + acm_set_control(port, portdata->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS); + ++ /* unthrottle device in case TTY was closed while throttled */ ++ spin_lock_irqsave(&port->lock, flags); ++ port->throttled = 0; ++ port->throttle_req = 0; ++ spin_unlock_irqrestore(&port->lock, flags); ++ + /* Reset low level data toggle and start reading from endpoints */ + for (i = 0; i < N_IN_URB; i++) { + if (debug) dev_dbg(&port->dev, "%s urb %d\n", __func__, i); + ++ spin_lock_irqsave(&port->lock, flags); ++ portdata->in_urb_flags[i] = READ_URB_RUNNING; ++ spin_unlock_irqrestore(&port->lock, flags); + urb = portdata->in_urbs[i]; + if (!urb) + continue; +@@ -1207,8 +1240,6 @@ + } + } + +- tty->low_latency = 1; +- + /* start up the interrupt endpoint if we have one */ + if (port->interrupt_in_urb) { + result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); +@@ -1592,6 +1623,51 @@ + usb_serial_disconnect(interface); + } + ++static void vizzini_throttle(struct tty_struct *tty) ++{ ++ unsigned long flags; ++ struct usb_serial_port *port = tty->driver_data; ++ ++ if (debug) dev_dbg(&port->dev, "TTY buffer approaching limit, stopping USB reads\n"); ++ ++ spin_lock_irqsave(&port->lock, flags); ++ port->throttle_req = 1; ++ spin_unlock_irqrestore(&port->lock, flags); ++} ++ ++static void vizzini_unthrottle(struct tty_struct *tty) ++{ ++ unsigned long flags; ++ unsigned int was_throttled; ++ struct usb_serial_port *port = tty->driver_data; ++ struct vizzini_port_private *portdata = usb_get_serial_port_data(port); ++ int err; ++ int i; ++ ++ if (debug) dev_dbg(&port->dev, "Resuming USB reads\n"); ++ ++ spin_lock_irqsave(&port->lock, flags); ++ was_throttled = port->throttled; ++ port->throttled = 0; ++ port->throttle_req = 0; ++ spin_unlock_irqrestore(&port->lock, flags); ++ ++ if (was_throttled) { ++ for (i = 0; i < N_IN_URB; i++) { ++ spin_lock_irqsave(&port->lock, flags); ++ if (portdata->in_urb_flags[i] == READ_URB_STOPPED) { ++ if (debug) dev_dbg(&port->dev, "unthrottling urb %d\n", i); ++ portdata->in_urb_flags[i] = READ_URB_RUNNING; ++ spin_unlock_irqrestore(&port->lock, flags); ++ err = usb_submit_urb(portdata->in_urbs[i], GFP_ATOMIC); ++ if (err) ++ dev_err(&port->dev, "resubmit read urb failed. (%d)\n", err); ++ } else { ++ spin_unlock_irqrestore(&port->lock, flags); ++ } ++ } ++ } ++} + + + static struct usb_serial_driver vizzini_device = { +@@ -1606,6 +1682,8 @@ + .probe = vizzini_probe, + .open = vizzini_open, + .close = vizzini_close, ++ .throttle = vizzini_throttle, ++ .unthrottle = vizzini_unthrottle, + .write = vizzini_write, + .write_room = vizzini_write_room, + .ioctl = vizzini_ioctl, diff --git a/multitech/recipes/vizzini/vizzini_0.76.bb b/multitech/recipes/vizzini/vizzini_0.76.bb index ff1f421..d1cc653 100644 --- a/multitech/recipes/vizzini/vizzini_0.76.bb +++ b/multitech/recipes/vizzini/vizzini_0.76.bb @@ -1,10 +1,11 @@ require vizzini.inc -LOCAL_PR = "${INC_PR}.0" +LOCAL_PR = "${INC_PR}.1" MACHINE_KERNEL_PR_append = "${LOCAL_PR}" SRC_URI += "file://xr21v141x-lnx-3.0-pak.tar.gz \ file://vizzini-0.76-rs485.patch \ + file://vizzini-0.76-flow-control.patch \ " S = "${WORKDIR}/xr21v141x-lnx-3.0-pak" |