summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Sobolev <sobomax@FreeBSD.org>2005-02-27 22:12:10 +0000
committerMaxim Sobolev <sobomax@FreeBSD.org>2005-02-27 22:12:10 +0000
commit92357779c4b7eea9286fdff2f10a64cfe233cbaf (patch)
tree940cd1bda7a57ecaac71068fb13f9bfdea63a95d
parentDocument curl -- authentication buffer overflow vulnerability. (diff)
Add support for some DOCSIS USB Cable Modems. This makes my Terayon TJ715,
which previously has been failing with "cdce0: Could not find data bulk in", working like a charm. Bump PORTREVISION. Based on patch by: Barry Bouwsma Approved by: MAINTAINER
Notes
Notes: svn path=/head/; revision=129928
-rw-r--r--comms/cdce/Makefile1
-rw-r--r--comms/cdce/files/patch-if_cdce.c103
2 files changed, 104 insertions, 0 deletions
diff --git a/comms/cdce/Makefile b/comms/cdce/Makefile
index b1d61a8be0a8..2b0fee2c6088 100644
--- a/comms/cdce/Makefile
+++ b/comms/cdce/Makefile
@@ -7,6 +7,7 @@
PORTNAME= cdce
PORTVERSION= 1.0
+PORTREVISION= 1
CATEGORIES= comms
MASTER_SITES= http://www.gank.org/freebsd/cdce/
diff --git a/comms/cdce/files/patch-if_cdce.c b/comms/cdce/files/patch-if_cdce.c
new file mode 100644
index 000000000000..18d48f299ade
--- /dev/null
+++ b/comms/cdce/files/patch-if_cdce.c
@@ -0,0 +1,103 @@
+
+$FreeBSD$
+
+--- if_cdce.c
++++ if_cdce.c
+@@ -32,7 +32,7 @@
+ */
+
+ #include <sys/cdefs.h>
+-__FBSDID("$Id: if_cdce.c,v 1.1 2005/02/27 08:06:48 root Exp root $");
++__FBSDID("$Id: if_cdce.c 148 2005-01-16 02:20:53Z craig $");
+
+ /* USB Communication Device Class (Ethernet Networking Control Model)
+ *
+@@ -158,11 +158,12 @@
+ usb_interface_descriptor_t *id;
+ usb_endpoint_descriptor_t *ed;
+ usb_cdc_union_descriptor_t *ud;
++ usb_config_descriptor_t *cd;
+ struct ifnet *ifp;
+ int data_ifcno;
+ u_int16_t macaddr_hi;
+ char devinfo[1024];
+- int i;
++ int i, j, numalts;
+
+ bzero(sc, sizeof(struct cdce_softc));
+ sc->cdce_udev = uaa->device;
+@@ -206,29 +207,52 @@
+ USB_ATTACH_ERROR_RETURN;
+ }
+
+- /* Find endpoints. */
++ /*
++ * In the case of my CDCEthernet modem, there are several alternate
++ * interface possibilities -- the default first one does not work
++ * (though in the original code it probably worked for those devices
++ * which were supported), and in my case, the next alternate setting
++ * gives me the desired interface. There's another one that also
++ * does not work, so we loop through the possibilities and take the
++ * first one that works.
++ */
+ id = usbd_get_interface_descriptor(sc->cdce_data_iface);
+- sc->cdce_bulkin_no = sc->cdce_bulkout_no = -1;
+- for (i = 0; i < id->bNumEndpoints; i++) {
+- ed = usbd_interface2endpoint_descriptor(sc->cdce_data_iface, i);
+- if (!ed) {
+- printf("%s: could not read endpoint descriptor\n",
+- sc->cdce_name);
+- USB_ATTACH_ERROR_RETURN;
+- }
+- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
+- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
+- sc->cdce_bulkin_no = ed->bEndpointAddress;
+- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
+- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
+- sc->cdce_bulkout_no = ed->bEndpointAddress;
+- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
+- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
+- /* XXX: CDC spec defines an interrupt pipe, but it is not
+- * needed for simple host-to-host applications. */
+- } else {
+- printf("%s: unexpected endpoint\n", sc->cdce_name);
+- }
++ cd = usbd_get_config_descriptor(sc->cdce_udev);
++ numalts = usbd_get_no_alts(cd, id->bInterfaceNumber);
++
++ for (j = 0; j < numalts; j++) {
++ if (usbd_set_interface(sc->cdce_data_iface, j)) {
++ printf("%s: setting alternate interface failed\n",
++ sc->cdce_name);
++ USB_ATTACH_ERROR_RETURN;
++ }
++ /* Find endpoints. */
++ id = usbd_get_interface_descriptor(sc->cdce_data_iface);
++ sc->cdce_bulkin_no = sc->cdce_bulkout_no = -1;
++ for (i = 0; i < id->bNumEndpoints; i++) {
++ ed = usbd_interface2endpoint_descriptor(sc->cdce_data_iface, i);
++ if (!ed) {
++ printf("%s: could not read endpoint descriptor\n",
++ sc->cdce_name);
++ USB_ATTACH_ERROR_RETURN;
++ }
++ if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
++ UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
++ sc->cdce_bulkin_no = ed->bEndpointAddress;
++ } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
++ UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
++ sc->cdce_bulkout_no = ed->bEndpointAddress;
++ } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
++ UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
++ /* XXX: CDC spec defines an interrupt pipe, but it is not
++ * needed for simple host-to-host applications. */
++ } else {
++ printf("%s: unexpected endpoint\n", sc->cdce_name);
++ }
++ }
++ /* If we found something, try and use it... */
++ if ((sc->cdce_bulkin_no != -1) && (sc->cdce_bulkout_no != -1))
++ break;
+ }
+
+ if (sc->cdce_bulkin_no == -1) {