Print this page
3419 usbftdi needs to support the BeagleBone
@@ -23,10 +23,14 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
+ * Copyright 2012 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+ */
+
+/*
* FTDI FT232R USB UART device-specific driver
*
* May work on the (many) devices based on earlier versions of the chip.
*/
@@ -218,10 +222,11 @@
recognized = B_TRUE;
dd = uf->uf_dev_data->dev_descr;
switch (dd->idVendor) {
case USB_VENDOR_FTDI:
switch (dd->idProduct) {
+ case USB_PRODUCT_FTDI_SERIAL_2232C:
case USB_PRODUCT_FTDI_SERIAL_8U232AM:
case USB_PRODUCT_FTDI_SEMC_DSS20:
case USB_PRODUCT_FTDI_CFA_631:
case USB_PRODUCT_FTDI_CFA_632:
case USB_PRODUCT_FTDI_CFA_633:
@@ -326,27 +331,10 @@
uf->uf_usb_events, 0) != USB_SUCCESS) {
uftdi_cleanup(uf, 4);
return (USB_FAILURE);
}
- if (usb_pipe_get_max_bulk_transfer_size(uf->uf_dip,
- &uf->uf_xfer_sz) != USB_SUCCESS) {
- uftdi_cleanup(uf, 5);
- return (USB_FAILURE);
- }
-
- /*
- * TODO: modern ftdi devices have deeper (and asymmetric)
- * fifos than this minimal 64 bytes .. but how to tell
- * -safely- ?
- */
-
-#define FTDI_MAX_XFERSIZE 64
-
- if (uf->uf_xfer_sz > FTDI_MAX_XFERSIZE)
- uf->uf_xfer_sz = FTDI_MAX_XFERSIZE;
-
if (uftdi_dev_attach(uf) != USB_SUCCESS) {
uftdi_cleanup(uf, 5);
return (USB_FAILURE);
}
@@ -1499,11 +1487,17 @@
uftdi_open_pipes(uftdi_state_t *uf)
{
int ifc, alt;
usb_pipe_policy_t policy;
usb_ep_data_t *in_data, *out_data;
+ size_t max_xfer_sz;
+ /* get max transfer size */
+ if (usb_pipe_get_max_bulk_transfer_size(uf->uf_dip, &max_xfer_sz)
+ != USB_SUCCESS)
+ return (USB_FAILURE);
+
/* get ep data */
ifc = uf->uf_dev_data->dev_curr_if;
alt = 0;
in_data = usb_lookup_ep_data(uf->uf_dip, uf->uf_dev_data, ifc, alt,
@@ -1516,10 +1510,25 @@
USB_DPRINTF_L2(DPRINT_ATTACH, uf->uf_lh,
"uftdi_open_pipes: can't get ep data");
return (USB_FAILURE);
}
+ /*
+ * Set buffer sizes. Default to UFTDI_XFER_SZ_MAX.
+ * Use wMaxPacketSize from endpoint descriptor if it is nonzero..
+ * Cap at a max transfer size of host controller.
+ */
+ uf->uf_ibuf_sz = uf->uf_obuf_sz = UFTDI_XFER_SZ_MAX;
+
+ if (in_data->ep_descr.wMaxPacketSize)
+ uf->uf_ibuf_sz = in_data->ep_descr.wMaxPacketSize;
+ uf->uf_ibuf_sz = min(uf->uf_ibuf_sz, max_xfer_sz);
+
+ if (out_data->ep_descr.wMaxPacketSize)
+ uf->uf_obuf_sz = out_data->ep_descr.wMaxPacketSize;
+ uf->uf_obuf_sz = min(uf->uf_obuf_sz, max_xfer_sz);
+
/* open pipes */
policy.pp_max_async_reqs = 2;
if (usb_pipe_open(uf->uf_dip, &in_data->ep_descr, &policy,
USB_FLAGS_SLEEP, &uf->uf_bulkin_ph) != USB_SUCCESS)
@@ -1804,12 +1813,12 @@
ASSERT(mutex_owned(&uf->uf_lock));
uf->uf_bulkin_state = UFTDI_PIPE_BUSY;
mutex_exit(&uf->uf_lock);
- br = usb_alloc_bulk_req(uf->uf_dip, uf->uf_xfer_sz, USB_FLAGS_SLEEP);
- br->bulk_len = uf->uf_xfer_sz;
+ br = usb_alloc_bulk_req(uf->uf_dip, uf->uf_ibuf_sz, USB_FLAGS_SLEEP);
+ br->bulk_len = uf->uf_ibuf_sz;
br->bulk_timeout = UFTDI_BULKIN_TIMEOUT;
br->bulk_cb = uftdi_bulkin_cb;
br->bulk_exc_cb = uftdi_bulkin_cb;
br->bulk_client_private = (usb_opaque_t)uf;
br->bulk_attributes = USB_ATTRS_AUTOCLEARING | USB_ATTRS_SHORT_XFER_OK;
@@ -1859,11 +1868,11 @@
return;
}
ASSERT(MBLKL(uf->uf_tx_mp) > 0);
/* send as much data as port can receive */
- len = min(msgdsize(uf->uf_tx_mp), uf->uf_xfer_sz);
+ len = min(msgdsize(uf->uf_tx_mp), uf->uf_obuf_sz);
if (len <= 0)
return;
if ((data = allocb(len, BPRI_LO)) == NULL)
return;