Subject: Re: kern/37653: cdce fails with iPaq Linux
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Scott Ellis <scotte@warped.com>
List: netbsd-bugs
Date: 12/31/2007 18:05:04
The following reply was made to PR kern/37653; it has been noted by GNATS.

From: Scott Ellis <scotte@warped.com>
To: gnats-bugs@NetBSD.org
Cc: netbsd-bugs@netbsd.org
Subject: Re: kern/37653: cdce fails with iPaq Linux
Date: Mon, 31 Dec 2007 10:02:40 -0800

 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--