Subject: Re: kern/37653: cdce fails with iPaq Linux
To: None <gnats-bugs@NetBSD.org>
From: Scott Ellis <scotte@warped.com>
List: netbsd-bugs
Date: 12/31/2007 10:02:40
This is a multi-part message in MIME format.
--------------030103050502070606030901
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Wrong diff was attahed to the original PR.  Attached below is the 
correct diff.



--------------030103050502070606030901
Content-Type: text/plain;
 name="if_cdce.c.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="if_cdce.c.diff"

--- if_cdce.c	2007-12-31 10:00:00.000000000 -0800
+++ /home/scotte/if_cdce.c.scotte_ipaqlinux	2007-12-29 11:33:03.000000000 -0800
@@ -109,9 +109,9 @@
 Static void	 cdce_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
 Static void	 cdce_start(struct ifnet *);
 Static int	 cdce_ioctl(struct ifnet *, u_long, void *);
-Static void	 cdce_init(void *);
+Static int	 cdce_init(struct ifnet *);
 Static void	 cdce_watchdog(struct ifnet *);
-Static void	 cdce_stop(struct cdce_softc *);
+Static void	 cdce_stop(struct ifnet *, int);
 Static uint32_t	 cdce_crc32(const void *, size_t);
 
 Static const struct cdce_type cdce_devs[] = {
@@ -121,6 +121,7 @@
   {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600 }, CDCE_ZAURUS | CDCE_NO_UNION },
   {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C700 }, CDCE_ZAURUS | CDCE_NO_UNION },
   {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C750 }, CDCE_ZAURUS | CDCE_NO_UNION },
+  {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX }, CDCE_NO_UNION },
 };
 #define cdce_lookup(v, p) ((const struct cdce_type *)usb_lookup(cdce_devs, v, p))
 
@@ -272,6 +273,8 @@
 	ifp->if_ioctl = cdce_ioctl;
 	ifp->if_start = cdce_start;
 	ifp->if_watchdog = cdce_watchdog;
+	ifp->if_init = cdce_init;
+	ifp->if_stop = cdce_stop;
 	strncpy(ifp->if_xname, USBDEVNAME(sc->cdce_dev), IFNAMSIZ);
 
 	IFQ_SET_READY(&ifp->if_snd);
@@ -302,7 +305,7 @@
 	}
 
 	if (ifp->if_flags & IFF_RUNNING)
-		cdce_stop(sc);
+		cdce_stop(ifp, 1);
 
 	ether_ifdetach(ifp);
 
@@ -368,7 +371,7 @@
 	    m->m_pkthdr.len + extra, USBD_NO_COPY, 10000, cdce_txeof);
 	err = usbd_transfer(c->cdce_xfer);
 	if (err != USBD_IN_PROGRESS) {
-		cdce_stop(sc);
+		cdce_stop(GET_IFP(sc), 0);
 		return (EIO);
 	}
 
@@ -378,10 +381,10 @@
 }
 
 Static void
-cdce_stop(struct cdce_softc *sc)
+cdce_stop(struct ifnet *ifp, int disable)
 {
+	struct cdce_softc	*sc = ifp->if_softc;
 	usbd_status	 err;
-	struct ifnet	*ifp = GET_IFP(sc);
 	int		 i;
 
 	ifp->if_timer = 0;
@@ -439,8 +442,6 @@
 cdce_ioctl(struct ifnet *ifp, u_long command, void *data)
 {
 	struct cdce_softc	*sc = ifp->if_softc;
-	struct ifaddr		*ifa = (struct ifaddr *)data;
-	struct ifreq		*ifr = (struct ifreq *)data;
 	int			 s, error = 0;
 
 	if (sc->cdce_dying)
@@ -449,42 +450,11 @@
 	s = splnet();
 
 	switch(command) {
-	case SIOCSIFADDR:
-		ifp->if_flags |= IFF_UP;
-		cdce_init(sc);
-		switch (ifa->ifa_addr->sa_family) {
-#ifdef INET
-		case AF_INET:
-#if defined(__NetBSD__)
-			arp_ifinit(ifp, ifa);
-#else
-			arp_ifinit(&sc->arpcom, ifa);
-#endif
-			break;
-#endif /* INET */
-		}
-		break;
-
-	case SIOCSIFMTU:
-		if (ifr->ifr_mtu > ETHERMTU)
-			error = EINVAL;
-		else
-			ifp->if_mtu = ifr->ifr_mtu;
-		break;
-
-	case SIOCSIFFLAGS:
-		if (ifp->if_flags & IFF_UP) {
-			if (!(ifp->if_flags & IFF_RUNNING))
-				cdce_init(sc);
-		} else {
-			if (ifp->if_flags & IFF_RUNNING)
-				cdce_stop(sc);
-		}
-		error = 0;
-		break;
-
 	default:
-		error = EINVAL;
+			error = ether_ioctl(ifp, command, data);
+			if (error == ENETRESET) {
+			error = 0;
+			}
 		break;
 	}
 
@@ -505,30 +475,29 @@
 	printf("%s: watchdog timeout\n", USBDEVNAME(sc->cdce_dev));
 }
 
-Static void
-cdce_init(void *xsc)
+Static int
+cdce_init(struct ifnet *ifp)
 {
-	struct cdce_softc	*sc = xsc;
-	struct ifnet		*ifp = GET_IFP(sc);
+	struct cdce_softc	*sc = ifp->if_softc;
 	struct cdce_chain	*c;
 	usbd_status		 err;
 	int			 s, i;
 
 	if (ifp->if_flags & IFF_RUNNING)
-		return;
+		return (EIO);
 
 	s = splnet();
 
 	if (cdce_tx_list_init(sc) == ENOBUFS) {
 		printf("%s: tx list init failed\n", USBDEVNAME(sc->cdce_dev));
 		splx(s);
-		return;
+		return (ENOMEM);
 	}
 
 	if (cdce_rx_list_init(sc) == ENOBUFS) {
 		printf("%s: rx list init failed\n", USBDEVNAME(sc->cdce_dev));
 		splx(s);
-		return;
+		return (ENOMEM);
 	}
 
 	/* Maybe set multicast / broadcast here??? */
@@ -539,7 +508,7 @@
 		printf("%s: open rx pipe failed: %s\n", USBDEVNAME(sc->cdce_dev),
 		    usbd_errstr(err));
 		splx(s);
-		return;
+		return (EIO);
 	}
 
 	err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkout_no,
@@ -548,7 +517,7 @@
 		printf("%s: open tx pipe failed: %s\n", USBDEVNAME(sc->cdce_dev),
 		    usbd_errstr(err));
 		splx(s);
-		return;
+		return (EIO);
 	}
 
 	for (i = 0; i < CDCE_RX_LIST_CNT; i++) {
@@ -563,6 +532,8 @@
 	ifp->if_flags &= ~IFF_OACTIVE;
 
 	splx(s);
+
+	return (0);
 }
 
 Static int

--------------030103050502070606030901--