Diff for /src/sys/dev/netif/cue/if_cue.c between versions 1.4 and 1.5

version 1.4, 2003/11/20 22:07:26 version 1.5, 2003/12/30 01:01:46
Line 29 Line 29
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.   * THE POSSIBILITY OF SUCH DAMAGE.
  *   *
 * $FreeBSD: src/sys/dev/usb/if_cue.c,v 1.7.2.6 2002/11/06 14:23:20 joe Exp $ * $FreeBSD: src/sys/dev/usb/if_cue.c,v 1.45 2003/12/08 07:54:14 obrien Exp $
  * $DragonFly$   * $DragonFly$
  *   *
  * $FreeBSD: src/sys/dev/usb/if_cue.c,v 1.7.2.6 2002/11/06 14:23:20 joe Exp $  
  */   */
   
 /*  /*
Line 68 Line 67
   
 #include <net/bpf.h>  #include <net/bpf.h>
   
 #include <machine/clock.h>      /* for DELAY */  
 #include <sys/bus.h>  #include <sys/bus.h>
   #include <machine/bus.h>
   #if __FreeBSD_version < 500000
   #include <machine/clock.h>
   #endif
   
 #include <bus/usb/usb.h>  #include <bus/usb/usb.h>
 #include <bus/usb/usbdi.h>  #include <bus/usb/usbdi.h>
Line 92  Static struct cue_type cue_devs[] = { Line 94  Static struct cue_type cue_devs[] = {
   
 Static struct usb_qdat cue_qdat;  Static struct usb_qdat cue_qdat;
   
Static int cue_match(device_t);Static int cue_match(device_ptr_t);
Static int cue_attach(device_t);Static int cue_attach(device_ptr_t);
Static int cue_detach(device_t);Static int cue_detach(device_ptr_t);
   
 Static int cue_tx_list_init(struct cue_softc *);  Static int cue_tx_list_init(struct cue_softc *);
 Static int cue_rx_list_init(struct cue_softc *);  Static int cue_rx_list_init(struct cue_softc *);
Line 109  Static int cue_ioctl(struct ifnet *, u_l Line 111  Static int cue_ioctl(struct ifnet *, u_l
 Static void cue_init(void *);  Static void cue_init(void *);
 Static void cue_stop(struct cue_softc *);  Static void cue_stop(struct cue_softc *);
 Static void cue_watchdog(struct ifnet *);  Static void cue_watchdog(struct ifnet *);
Static void cue_shutdown(device_t);Static void cue_shutdown(device_ptr_t);
   
 Static void cue_setmulti(struct cue_softc *);  Static void cue_setmulti(struct cue_softc *);
Static u_int32_t cue_crc(caddr_t);Static uint32_t cue_mchash(const uint8_t *);
 Static void cue_reset(struct cue_softc *);  Static void cue_reset(struct cue_softc *);
   
Static int csr_read_1(struct cue_softc *, int);Static int cue_csr_read_1(struct cue_softc *, int);
Static int csr_write_1(struct cue_softc *, int, int);Static int cue_csr_write_1(struct cue_softc *, int, int);
Static int csr_read_2(struct cue_softc *, int);Static int cue_csr_read_2(struct cue_softc *, int);
 #ifdef notdef  #ifdef notdef
Static int csr_write_2(struct cue_softc *, int, int);Static int cue_csr_write_2(struct cue_softc *, int, int);
 #endif  #endif
 Static int cue_mem(struct cue_softc *, int, int, void *, int);  Static int cue_mem(struct cue_softc *, int, int, void *, int);
 Static int cue_getmac(struct cue_softc *, void *);  Static int cue_getmac(struct cue_softc *, void *);
Line 143  Static driver_t cue_driver = { Line 145  Static driver_t cue_driver = {
 Static devclass_t cue_devclass;  Static devclass_t cue_devclass;
   
 DECLARE_DUMMY_MODULE(if_cue);  DECLARE_DUMMY_MODULE(if_cue);
DRIVER_MODULE(if_cue, uhub, cue_driver, cue_devclass, usbd_driver_load, 0);DRIVER_MODULE(cue, uhub, cue_driver, cue_devclass, usbd_driver_load, 0);
 MODULE_DEPEND(cue, usb, 1, 1, 1);
 MODULE_DEPEND(cue, ether, 1, 1, 1);
   
 #define CUE_SETBIT(sc, reg, x)                          \  #define CUE_SETBIT(sc, reg, x)                          \
        csr_write_1(sc, reg, csr_read_1(sc, reg) | (x))        cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x))
   
 #define CUE_CLRBIT(sc, reg, x)                          \  #define CUE_CLRBIT(sc, reg, x)                          \
        csr_write_1(sc, reg, csr_read_1(sc, reg) & ~(x))        cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x))
   
 Static int  Static int
csr_read_1(struct cue_softc *sc, int reg)cue_csr_read_1(struct cue_softc *sc, int reg)
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         u_int8_t                val = 0;          u_int8_t                val = 0;
         int                     s;  
   
        if (sc->cue_gone)        if (sc->cue_dying)
                 return(0);                  return(0);
   
        s = splusb();        CUE_LOCK(sc);
   
         req.bmRequestType = UT_READ_VENDOR_DEVICE;          req.bmRequestType = UT_READ_VENDOR_DEVICE;
         req.bRequest = CUE_CMD_READREG;          req.bRequest = CUE_CMD_READREG;
Line 170  csr_read_1(struct cue_softc *sc, int reg Line 173  csr_read_1(struct cue_softc *sc, int reg
         USETW(req.wIndex, reg);          USETW(req.wIndex, reg);
         USETW(req.wLength, 1);          USETW(req.wLength, 1);
   
        err = usbd_do_request_flags(sc->cue_udev,        err = usbd_do_request(sc->cue_udev, &req, &val);
            &req, &val, USBD_NO_TSLEEP, NULL); 
   
        splx(s);        CUE_UNLOCK(sc);
   
         if (err)          if (err)
                 return(0);                  return(0);
Line 182  csr_read_1(struct cue_softc *sc, int reg Line 184  csr_read_1(struct cue_softc *sc, int reg
 }  }
   
 Static int  Static int
csr_read_2(struct cue_softc *sc, int reg)cue_csr_read_2(struct cue_softc *sc, int reg)
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         u_int16_t               val = 0;          u_int16_t               val = 0;
         int                     s;  
   
        if (sc->cue_gone)        if (sc->cue_dying)
                 return(0);                  return(0);
   
        s = splusb();        CUE_LOCK(sc);
   
         req.bmRequestType = UT_READ_VENDOR_DEVICE;          req.bmRequestType = UT_READ_VENDOR_DEVICE;
         req.bRequest = CUE_CMD_READREG;          req.bRequest = CUE_CMD_READREG;
Line 200  csr_read_2(struct cue_softc *sc, int reg Line 201  csr_read_2(struct cue_softc *sc, int reg
         USETW(req.wIndex, reg);          USETW(req.wIndex, reg);
         USETW(req.wLength, 2);          USETW(req.wLength, 2);
   
        err = usbd_do_request_flags(sc->cue_udev,        err = usbd_do_request(sc->cue_udev, &req, &val);
            &req, &val, USBD_NO_TSLEEP, NULL); 
   
        splx(s);        CUE_UNLOCK(sc);
   
         if (err)          if (err)
                 return(0);                  return(0);
Line 212  csr_read_2(struct cue_softc *sc, int reg Line 212  csr_read_2(struct cue_softc *sc, int reg
 }  }
   
 Static int  Static int
csr_write_1(struct cue_softc *sc, int reg, int val)cue_csr_write_1(struct cue_softc *sc, int reg, int val)
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         int                     s;  
   
        if (sc->cue_gone)        if (sc->cue_dying)
                 return(0);                  return(0);
   
        s = splusb();        CUE_LOCK(sc);
   
         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;          req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
         req.bRequest = CUE_CMD_WRITEREG;          req.bRequest = CUE_CMD_WRITEREG;
Line 229  csr_write_1(struct cue_softc *sc, int re Line 228  csr_write_1(struct cue_softc *sc, int re
         USETW(req.wIndex, reg);          USETW(req.wIndex, reg);
         USETW(req.wLength, 0);          USETW(req.wLength, 0);
   
        err = usbd_do_request_flags(sc->cue_udev,        err = usbd_do_request(sc->cue_udev, &req, NULL);
            &req, &val, USBD_NO_TSLEEP, NULL); 
   
        splx(s);        CUE_UNLOCK(sc);
   
         if (err)          if (err)
                 return(-1);                  return(-1);
Line 242  csr_write_1(struct cue_softc *sc, int re Line 240  csr_write_1(struct cue_softc *sc, int re
   
 #ifdef notdef  #ifdef notdef
 Static int  Static int
csr_write_2(struct cue_softc *sc, int reg, int val)cue_csr_write_2(struct cue_softc *sc, int reg, int val)
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         int                     s;  
   
        if (sc->cue_gone)        if (sc->cue_dying)
                 return(0);                  return(0);
   
        s = splusb();        CUE_LOCK(sc);
   
         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;          req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
         req.bRequest = CUE_CMD_WRITEREG;          req.bRequest = CUE_CMD_WRITEREG;
Line 259  csr_write_2(struct cue_softc *sc, int re Line 256  csr_write_2(struct cue_softc *sc, int re
         USETW(req.wIndex, reg);          USETW(req.wIndex, reg);
         USETW(req.wLength, 0);          USETW(req.wLength, 0);
   
        err = usbd_do_request_flags(sc->cue_udev,        err = usbd_do_request(sc->cue_udev, &req, NULL);
            &req, &val, USBD_NO_TSLEEP, NULL); 
   
        splx(s);        CUE_UNLOCK(sc);
   
         if (err)          if (err)
                 return(-1);                  return(-1);
Line 276  cue_mem(struct cue_softc *sc, int cmd, i Line 272  cue_mem(struct cue_softc *sc, int cmd, i
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         int                     s;  
   
        if (sc->cue_gone)        if (sc->cue_dying)
                 return(0);                  return(0);
   
        s = splusb();        CUE_LOCK(sc);
   
         if (cmd == CUE_CMD_READSRAM)          if (cmd == CUE_CMD_READSRAM)
                 req.bmRequestType = UT_READ_VENDOR_DEVICE;                  req.bmRequestType = UT_READ_VENDOR_DEVICE;
Line 292  cue_mem(struct cue_softc *sc, int cmd, i Line 287  cue_mem(struct cue_softc *sc, int cmd, i
         USETW(req.wIndex, addr);          USETW(req.wIndex, addr);
         USETW(req.wLength, len);          USETW(req.wLength, len);
   
        err = usbd_do_request_flags(sc->cue_udev,        err = usbd_do_request(sc->cue_udev, &req, buf);
            &req, &buf, USBD_NO_TSLEEP, NULL); 
   
        splx(s);        CUE_UNLOCK(sc);
   
         if (err)          if (err)
                 return(-1);                  return(-1);
Line 308  cue_getmac(struct cue_softc *sc, void *b Line 302  cue_getmac(struct cue_softc *sc, void *b
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         int                     s;  
   
        if (sc->cue_gone)        if (sc->cue_dying)
                 return(0);                  return(0);
   
        s = splusb();        CUE_LOCK(sc);
   
         req.bmRequestType = UT_READ_VENDOR_DEVICE;          req.bmRequestType = UT_READ_VENDOR_DEVICE;
         req.bRequest = CUE_CMD_GET_MACADDR;          req.bRequest = CUE_CMD_GET_MACADDR;
Line 321  cue_getmac(struct cue_softc *sc, void *b Line 314  cue_getmac(struct cue_softc *sc, void *b
         USETW(req.wIndex, 0);          USETW(req.wIndex, 0);
         USETW(req.wLength, ETHER_ADDR_LEN);          USETW(req.wLength, ETHER_ADDR_LEN);
   
        err = usbd_do_request_flags(sc->cue_udev,        err = usbd_do_request(sc->cue_udev, &req, buf);
            &req, buf, USBD_NO_TSLEEP, NULL); 
   
        splx(s);        CUE_UNLOCK(sc);
   
         if (err) {          if (err) {
                 printf("cue%d: read MAC address failed\n", sc->cue_unit);                  printf("cue%d: read MAC address failed\n", sc->cue_unit);
Line 337  cue_getmac(struct cue_softc *sc, void *b Line 329  cue_getmac(struct cue_softc *sc, void *b
 #define CUE_POLY        0xEDB88320  #define CUE_POLY        0xEDB88320
 #define CUE_BITS        9  #define CUE_BITS        9
   
Static u_int32_tStatic uint32_t
cue_crc(caddr_t addr)cue_mchash(const uint8_t *addr)
 {  {
        u_int32_t         idx, bit, data, crc;        uint32_t crc;
         int idx, bit;
         uint8_t data;
   
         /* Compute CRC for the address value. */          /* Compute CRC for the address value. */
         crc = 0xFFFFFFFF; /* initial value */          crc = 0xFFFFFFFF; /* initial value */
Line 365  cue_setmulti(struct cue_softc *sc) Line 359  cue_setmulti(struct cue_softc *sc)
         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {          if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
                 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)                  for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
                         sc->cue_mctab[i] = 0xFF;                          sc->cue_mctab[i] = 0xFF;
                        cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,                cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
                            &sc->cue_mctab, CUE_MCAST_TABLE_LEN);                    &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
                 return;                  return;
         }          }
   
Line 375  cue_setmulti(struct cue_softc *sc) Line 369  cue_setmulti(struct cue_softc *sc)
                 sc->cue_mctab[i] = 0;                  sc->cue_mctab[i] = 0;
   
         /* now program new ones */          /* now program new ones */
        for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;#if __FreeBSD_version >= 500000
            ifma = ifma->ifma_link.le_next) {        TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
 #else
         LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
 #endif
         {
                 if (ifma->ifma_addr->sa_family != AF_LINK)                  if (ifma->ifma_addr->sa_family != AF_LINK)
                         continue;                          continue;
                h = cue_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));                h = cue_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
                sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);                                sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
         }          }
   
         /*          /*
Line 388  cue_setmulti(struct cue_softc *sc) Line 386  cue_setmulti(struct cue_softc *sc)
          * so we can receive broadcast frames.           * so we can receive broadcast frames.
          */           */
         if (ifp->if_flags & IFF_BROADCAST) {          if (ifp->if_flags & IFF_BROADCAST) {
                h = cue_crc(etherbroadcastaddr);#if __FreeBSD_version >= 500000
                sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);                                h = cue_mchash(ifp->if_broadcastaddr);
 #else
                 h = cue_mchash(etherbroadcastaddr);
 #endif
                 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
         }          }
   
         cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,          cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
Line 403  cue_reset(struct cue_softc *sc) Line 405  cue_reset(struct cue_softc *sc)
 {  {
         usb_device_request_t    req;          usb_device_request_t    req;
         usbd_status             err;          usbd_status             err;
         int                     s;  
   
        if (sc->cue_gone)        if (sc->cue_dying)
                 return;                  return;
   
         s = splusb();  
   
         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;          req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
         req.bRequest = CUE_CMD_RESET;          req.bRequest = CUE_CMD_RESET;
         USETW(req.wValue, 0);          USETW(req.wValue, 0);
         USETW(req.wIndex, 0);          USETW(req.wIndex, 0);
         USETW(req.wLength, 0);          USETW(req.wLength, 0);
        err = usbd_do_request_flags(sc->cue_udev,        err = usbd_do_request(sc->cue_udev, &req, NULL);
            &req, NULL, USBD_NO_TSLEEP, NULL); 
 
        splx(s); 
 
         if (err)          if (err)
                 printf("cue%d: reset failed\n", sc->cue_unit);                  printf("cue%d: reset failed\n", sc->cue_unit);
   
Line 459  USB_ATTACH(cue) Line 454  USB_ATTACH(cue)
 {  {
         USB_ATTACH_START(cue, sc, uaa);          USB_ATTACH_START(cue, sc, uaa);
         char                    devinfo[1024];          char                    devinfo[1024];
         int                     s;  
         u_char                  eaddr[ETHER_ADDR_LEN];          u_char                  eaddr[ETHER_ADDR_LEN];
         struct ifnet            *ifp;          struct ifnet            *ifp;
         usb_interface_descriptor_t      *id;          usb_interface_descriptor_t      *id;
         usb_endpoint_descriptor_t       *ed;          usb_endpoint_descriptor_t       *ed;
         int                     i;          int                     i;
   
         s = splimp();  
   
         bzero(sc, sizeof(struct cue_softc));          bzero(sc, sizeof(struct cue_softc));
         sc->cue_iface = uaa->iface;          sc->cue_iface = uaa->iface;
         sc->cue_udev = uaa->device;          sc->cue_udev = uaa->device;
Line 476  USB_ATTACH(cue) Line 468  USB_ATTACH(cue)
         if (usbd_set_config_no(sc->cue_udev, CUE_CONFIG_NO, 0)) {          if (usbd_set_config_no(sc->cue_udev, CUE_CONFIG_NO, 0)) {
                 printf("cue%d: getting interface handle failed\n",                  printf("cue%d: getting interface handle failed\n",
                     sc->cue_unit);                      sc->cue_unit);
                 splx(s);  
                 USB_ATTACH_ERROR_RETURN;                  USB_ATTACH_ERROR_RETURN;
         }          }
   
Line 492  USB_ATTACH(cue) Line 483  USB_ATTACH(cue)
                 if (!ed) {                  if (!ed) {
                         printf("cue%d: couldn't get ep %d\n",                          printf("cue%d: couldn't get ep %d\n",
                             sc->cue_unit, i);                              sc->cue_unit, i);
                         splx(s);  
                         USB_ATTACH_ERROR_RETURN;                          USB_ATTACH_ERROR_RETURN;
                 }                  }
                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&                  if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
                    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {                    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
                         sc->cue_ed[CUE_ENDPT_RX] = ed->bEndpointAddress;                          sc->cue_ed[CUE_ENDPT_RX] = ed->bEndpointAddress;
                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&                  } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
                    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {                           UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
                         sc->cue_ed[CUE_ENDPT_TX] = ed->bEndpointAddress;                          sc->cue_ed[CUE_ENDPT_TX] = ed->bEndpointAddress;
                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&                  } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
                    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {                           UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
                         sc->cue_ed[CUE_ENDPT_INTR] = ed->bEndpointAddress;                          sc->cue_ed[CUE_ENDPT_INTR] = ed->bEndpointAddress;
                 }                  }
         }          }
   
   #if __FreeBSD_version >= 500000
           mtx_init(&sc->cue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
               MTX_DEF | MTX_RECURSE);
   #endif
           CUE_LOCK(sc);
   
 #ifdef notdef  #ifdef notdef
         /* Reset the adapter. */          /* Reset the adapter. */
         cue_reset(sc);          cue_reset(sc);
Line 525  USB_ATTACH(cue) Line 521  USB_ATTACH(cue)
   
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
         ifp->if_softc = sc;          ifp->if_softc = sc;
        ifp->if_unit = sc->cue_unit;        if_initname(ifp, "cue", sc->cue_unit);
        ifp->if_name = "cue"; 
         ifp->if_mtu = ETHERMTU;          ifp->if_mtu = ETHERMTU;
         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;          ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
         ifp->if_ioctl = cue_ioctl;          ifp->if_ioctl = cue_ioctl;
Line 543  USB_ATTACH(cue) Line 538  USB_ATTACH(cue)
         /*          /*
          * Call MI attach routine.           * Call MI attach routine.
          */           */
   #if __FreeBSD_version >= 500000
           ether_ifattach(ifp, eaddr);
   #else
         ether_ifattach(ifp, ETHER_BPF_SUPPORTED);          ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
   #endif
         callout_handle_init(&sc->cue_stat_ch);          callout_handle_init(&sc->cue_stat_ch);
         usb_register_netisr();          usb_register_netisr();
        sc->cue_gone = 0;        sc->cue_dying = 0;
   
        splx(s);        CUE_UNLOCK(sc);
         USB_ATTACH_SUCCESS_RETURN;          USB_ATTACH_SUCCESS_RETURN;
 }  }
   
Line 557  cue_detach(device_ptr_t dev) Line 556  cue_detach(device_ptr_t dev)
 {  {
         struct cue_softc        *sc;          struct cue_softc        *sc;
         struct ifnet            *ifp;          struct ifnet            *ifp;
         int                     s;  
   
         s = splusb();  
   
         sc = device_get_softc(dev);          sc = device_get_softc(dev);
           CUE_LOCK(sc);
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
   
        sc->cue_gone = 1;        sc->cue_dying = 1;
         untimeout(cue_tick, sc, sc->cue_stat_ch);          untimeout(cue_tick, sc, sc->cue_stat_ch);
   #if __FreeBSD_version >= 500000
           ether_ifdetach(ifp);
   #else
         ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);          ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
   #endif
   
         if (sc->cue_ep[CUE_ENDPT_TX] != NULL)          if (sc->cue_ep[CUE_ENDPT_TX] != NULL)
                 usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]);                  usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]);
Line 575  cue_detach(device_ptr_t dev) Line 576  cue_detach(device_ptr_t dev)
         if (sc->cue_ep[CUE_ENDPT_INTR] != NULL)          if (sc->cue_ep[CUE_ENDPT_INTR] != NULL)
                 usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]);                  usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
   
        splx(s);        CUE_UNLOCK(sc);
 #if __FreeBSD_version >= 500000
         mtx_destroy(&sc->cue_mtx);
 #endif
   
         return(0);          return(0);
 }  }
Line 673  cue_rxstart(struct ifnet *ifp) Line 677  cue_rxstart(struct ifnet *ifp)
         struct cue_chain        *c;          struct cue_chain        *c;
   
         sc = ifp->if_softc;          sc = ifp->if_softc;
           CUE_LOCK(sc);
         c = &sc->cue_cdata.cue_rx_chain[sc->cue_cdata.cue_rx_prod];          c = &sc->cue_cdata.cue_rx_chain[sc->cue_cdata.cue_rx_prod];
   
         if (cue_newbuf(sc, c, NULL) == ENOBUFS) {          if (cue_newbuf(sc, c, NULL) == ENOBUFS) {
                 ifp->if_ierrors++;                  ifp->if_ierrors++;
                   CUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 685  cue_rxstart(struct ifnet *ifp) Line 691  cue_rxstart(struct ifnet *ifp)
             c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK,              c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK,
             USBD_NO_TIMEOUT, cue_rxeof);              USBD_NO_TIMEOUT, cue_rxeof);
         usbd_transfer(c->cue_xfer);          usbd_transfer(c->cue_xfer);
           CUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 705  cue_rxeof(usbd_xfer_handle xfer, usbd_pr Line 712  cue_rxeof(usbd_xfer_handle xfer, usbd_pr
   
         c = priv;          c = priv;
         sc = c->cue_sc;          sc = c->cue_sc;
           CUE_LOCK(sc);
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
   
        if (!(ifp->if_flags & IFF_RUNNING))        if (!(ifp->if_flags & IFF_RUNNING)) {
                 CUE_UNLOCK(sc);
                 return;                  return;
           }
   
         if (status != USBD_NORMAL_COMPLETION) {          if (status != USBD_NORMAL_COMPLETION) {
                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
                         CUE_UNLOCK(sc);
                         return;                          return;
                printf("cue%d: usb error on rx: %s\n", sc->cue_unit,                }
                    usbd_errstr(status));                if (usbd_ratecheck(&sc->cue_rx_notice))
                         printf("cue%d: usb error on rx: %s\n", sc->cue_unit,
                             usbd_errstr(status));
                 if (status == USBD_STALLED)                  if (status == USBD_STALLED)
                         usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_RX]);                          usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_RX]);
                 goto done;                  goto done;
Line 740  cue_rxeof(usbd_xfer_handle xfer, usbd_pr Line 753  cue_rxeof(usbd_xfer_handle xfer, usbd_pr
   
         /* Put the packet on the special USB input queue. */          /* Put the packet on the special USB input queue. */
         usb_ether_input(m);          usb_ether_input(m);
           CUE_UNLOCK(sc);
   
         return;          return;
 done:  done:
Line 748  done: Line 762  done:
             c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK,              c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK,
             USBD_NO_TIMEOUT, cue_rxeof);              USBD_NO_TIMEOUT, cue_rxeof);
         usbd_transfer(c->cue_xfer);          usbd_transfer(c->cue_xfer);
           CUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 764  cue_txeof(usbd_xfer_handle xfer, usbd_pr Line 779  cue_txeof(usbd_xfer_handle xfer, usbd_pr
         struct cue_chain        *c;          struct cue_chain        *c;
         struct ifnet            *ifp;          struct ifnet            *ifp;
         usbd_status             err;          usbd_status             err;
         int                     s;  
   
         s = splimp();  
   
         c = priv;          c = priv;
         sc = c->cue_sc;          sc = c->cue_sc;
           CUE_LOCK(sc);
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
   
         if (status != USBD_NORMAL_COMPLETION) {          if (status != USBD_NORMAL_COMPLETION) {
                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {                  if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
                        splx(s);                        CUE_UNLOCK(sc);
                         return;                          return;
                 }                  }
                 printf("cue%d: usb error on tx: %s\n", sc->cue_unit,                  printf("cue%d: usb error on tx: %s\n", sc->cue_unit,
                     usbd_errstr(status));                      usbd_errstr(status));
                 if (status == USBD_STALLED)                  if (status == USBD_STALLED)
                         usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]);                          usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]);
                splx(s);                CUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 800  cue_txeof(usbd_xfer_handle xfer, usbd_pr Line 813  cue_txeof(usbd_xfer_handle xfer, usbd_pr
         else          else
                 ifp->if_opackets++;                  ifp->if_opackets++;
   
        splx(s);        CUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 810  cue_tick(void *xsc) Line 823  cue_tick(void *xsc)
 {  {
         struct cue_softc        *sc;          struct cue_softc        *sc;
         struct ifnet            *ifp;          struct ifnet            *ifp;
         int                     s;  
   
         s = splimp();  
   
         sc = xsc;          sc = xsc;
   
        if (sc == NULL) {        if (sc == NULL)
                splx(s); 
                 return;                  return;
        }
         CUE_LOCK(sc);
   
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
   
        ifp->if_collisions += csr_read_2(sc, CUE_TX_SINGLECOLL);        ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL);
        ifp->if_collisions += csr_read_2(sc, CUE_TX_MULTICOLL);        ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL);
        ifp->if_collisions += csr_read_2(sc, CUE_TX_EXCESSCOLL);        ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL);
   
        if (csr_read_2(sc, CUE_RX_FRAMEERR))        if (cue_csr_read_2(sc, CUE_RX_FRAMEERR))
                 ifp->if_ierrors++;                  ifp->if_ierrors++;
   
         sc->cue_stat_ch = timeout(cue_tick, sc, hz);          sc->cue_stat_ch = timeout(cue_tick, sc, hz);
   
        splx(s);        CUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 881  cue_start(struct ifnet *ifp) Line 891  cue_start(struct ifnet *ifp)
         struct mbuf             *m_head = NULL;          struct mbuf             *m_head = NULL;
   
         sc = ifp->if_softc;          sc = ifp->if_softc;
           CUE_LOCK(sc);
   
        if (ifp->if_flags & IFF_OACTIVE)        if (ifp->if_flags & IFF_OACTIVE) {
                 CUE_UNLOCK(sc);
                 return;                  return;
           }
   
         IF_DEQUEUE(&ifp->if_snd, m_head);          IF_DEQUEUE(&ifp->if_snd, m_head);
        if (m_head == NULL)        if (m_head == NULL) {
                 CUE_UNLOCK(sc);
                 return;                  return;
           }
   
         if (cue_encap(sc, m_head, 0)) {          if (cue_encap(sc, m_head, 0)) {
                 IF_PREPEND(&ifp->if_snd, m_head);                  IF_PREPEND(&ifp->if_snd, m_head);
                 ifp->if_flags |= IFF_OACTIVE;                  ifp->if_flags |= IFF_OACTIVE;
                   CUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 899  cue_start(struct ifnet *ifp) Line 915  cue_start(struct ifnet *ifp)
          * If there's a BPF listener, bounce a copy of this frame           * If there's a BPF listener, bounce a copy of this frame
          * to him.           * to him.
          */           */
        if (ifp->if_bpf)        BPF_MTAP(ifp, m_head);
                bpf_mtap(ifp, m_head); 
   
         ifp->if_flags |= IFF_OACTIVE;          ifp->if_flags |= IFF_OACTIVE;
   
Line 908  cue_start(struct ifnet *ifp) Line 923  cue_start(struct ifnet *ifp)
          * Set a timeout in case the chip goes out to lunch.           * Set a timeout in case the chip goes out to lunch.
          */           */
         ifp->if_timer = 5;          ifp->if_timer = 5;
           CUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 919  cue_init(void *xsc) Line 935  cue_init(void *xsc)
         struct ifnet            *ifp = &sc->arpcom.ac_if;          struct ifnet            *ifp = &sc->arpcom.ac_if;
         struct cue_chain        *c;          struct cue_chain        *c;
         usbd_status             err;          usbd_status             err;
        int                     i, s;        int                     i;
   
         if (ifp->if_flags & IFF_RUNNING)          if (ifp->if_flags & IFF_RUNNING)
                 return;                  return;
   
        s = splimp();        CUE_LOCK(sc);
   
         /*          /*
          * Cancel pending I/O and free all RX/TX buffers.           * Cancel pending I/O and free all RX/TX buffers.
Line 935  cue_init(void *xsc) Line 951  cue_init(void *xsc)
   
         /* Set MAC address */          /* Set MAC address */
         for (i = 0; i < ETHER_ADDR_LEN; i++)          for (i = 0; i < ETHER_ADDR_LEN; i++)
                csr_write_1(sc, CUE_PAR0 - i, sc->arpcom.ac_enaddr[i]);                cue_csr_write_1(sc, CUE_PAR0 - i, sc->arpcom.ac_enaddr[i]);
   
         /* Enable RX logic. */          /* Enable RX logic. */
        csr_write_1(sc, CUE_ETHCTL, CUE_ETHCTL_RX_ON|CUE_ETHCTL_MCAST_ON);        cue_csr_write_1(sc, CUE_ETHCTL, CUE_ETHCTL_RX_ON|CUE_ETHCTL_MCAST_ON);
   
          /* If we want promiscuous mode, set the allframes bit. */           /* If we want promiscuous mode, set the allframes bit. */
         if (ifp->if_flags & IFF_PROMISC) {          if (ifp->if_flags & IFF_PROMISC) {
Line 950  cue_init(void *xsc) Line 966  cue_init(void *xsc)
         /* Init TX ring. */          /* Init TX ring. */
         if (cue_tx_list_init(sc) == ENOBUFS) {          if (cue_tx_list_init(sc) == ENOBUFS) {
                 printf("cue%d: tx list init failed\n", sc->cue_unit);                  printf("cue%d: tx list init failed\n", sc->cue_unit);
                splx(s);                CUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
         /* Init RX ring. */          /* Init RX ring. */
         if (cue_rx_list_init(sc) == ENOBUFS) {          if (cue_rx_list_init(sc) == ENOBUFS) {
                 printf("cue%d: rx list init failed\n", sc->cue_unit);                  printf("cue%d: rx list init failed\n", sc->cue_unit);
                splx(s);                CUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 968  cue_init(void *xsc) Line 984  cue_init(void *xsc)
          * Set the number of RX and TX buffers that we want           * Set the number of RX and TX buffers that we want
          * to reserve inside the ASIC.           * to reserve inside the ASIC.
          */           */
        csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES);        cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES);
        csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES);        cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES);
   
         /* Set advanced operation modes. */          /* Set advanced operation modes. */
        csr_write_1(sc, CUE_ADVANCED_OPMODES,        cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
             CUE_AOP_EMBED_RXLEN|0x01); /* 1 wait state */              CUE_AOP_EMBED_RXLEN|0x01); /* 1 wait state */
   
         /* Program the LED operation. */          /* Program the LED operation. */
        csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK);        cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK);
   
         /* Open RX and TX pipes. */          /* Open RX and TX pipes. */
         err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_RX],          err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_RX],
Line 984  cue_init(void *xsc) Line 1000  cue_init(void *xsc)
         if (err) {          if (err) {
                 printf("cue%d: open rx pipe failed: %s\n",                  printf("cue%d: open rx pipe failed: %s\n",
                     sc->cue_unit, usbd_errstr(err));                      sc->cue_unit, usbd_errstr(err));
                splx(s);                CUE_UNLOCK(sc);
                 return;                  return;
         }          }
         err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX],          err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX],
Line 992  cue_init(void *xsc) Line 1008  cue_init(void *xsc)
         if (err) {          if (err) {
                 printf("cue%d: open tx pipe failed: %s\n",                  printf("cue%d: open tx pipe failed: %s\n",
                     sc->cue_unit, usbd_errstr(err));                      sc->cue_unit, usbd_errstr(err));
                splx(s);                CUE_UNLOCK(sc);
                 return;                  return;
         }          }
   
Line 1008  cue_init(void *xsc) Line 1024  cue_init(void *xsc)
         ifp->if_flags |= IFF_RUNNING;          ifp->if_flags |= IFF_RUNNING;
         ifp->if_flags &= ~IFF_OACTIVE;          ifp->if_flags &= ~IFF_OACTIVE;
   
        (void)splx(s);        CUE_UNLOCK(sc);
   
         sc->cue_stat_ch = timeout(cue_tick, sc, hz);          sc->cue_stat_ch = timeout(cue_tick, sc, hz);
   
Line 1019  Static int Line 1035  Static int
 cue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)  cue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 {  {
         struct cue_softc        *sc = ifp->if_softc;          struct cue_softc        *sc = ifp->if_softc;
        int                     s, error = 0;        int                     error = 0;
   
        s = splimp();        CUE_LOCK(sc);
   
         switch(command) {          switch(command) {
         case SIOCSIFADDR:  
         case SIOCGIFADDR:  
         case SIOCSIFMTU:  
                 error = ether_ioctl(ifp, command, data);  
                 break;  
         case SIOCSIFFLAGS:          case SIOCSIFFLAGS:
                 if (ifp->if_flags & IFF_UP) {                  if (ifp->if_flags & IFF_UP) {
                         if (ifp->if_flags & IFF_RUNNING &&                          if (ifp->if_flags & IFF_RUNNING &&
Line 1056  cue_ioctl(struct ifnet *ifp, u_long comm Line 1067  cue_ioctl(struct ifnet *ifp, u_long comm
                 error = 0;                  error = 0;
                 break;                  break;
         default:          default:
                error = EINVAL;                error = ether_ioctl(ifp, command, data);
                 break;                  break;
         }          }
   
        (void)splx(s);        CUE_UNLOCK(sc);
   
         return(error);          return(error);
 }  }
Line 1070  cue_watchdog(struct ifnet *ifp) Line 1081  cue_watchdog(struct ifnet *ifp)
 {  {
         struct cue_softc        *sc;          struct cue_softc        *sc;
         struct cue_chain        *c;          struct cue_chain        *c;
   
         usbd_status             stat;          usbd_status             stat;
   
         sc = ifp->if_softc;          sc = ifp->if_softc;
           CUE_LOCK(sc);
   
         ifp->if_oerrors++;          ifp->if_oerrors++;
         printf("cue%d: watchdog timeout\n", sc->cue_unit);          printf("cue%d: watchdog timeout\n", sc->cue_unit);
Line 1083  cue_watchdog(struct ifnet *ifp) Line 1095  cue_watchdog(struct ifnet *ifp)
   
         if (ifp->if_snd.ifq_head != NULL)          if (ifp->if_snd.ifq_head != NULL)
                 cue_start(ifp);                  cue_start(ifp);
           CUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 1098  cue_stop(struct cue_softc *sc) Line 1111  cue_stop(struct cue_softc *sc)
         struct ifnet            *ifp;          struct ifnet            *ifp;
         int                     i;          int                     i;
   
           CUE_LOCK(sc);
   
         ifp = &sc->arpcom.ac_if;          ifp = &sc->arpcom.ac_if;
         ifp->if_timer = 0;          ifp->if_timer = 0;
   
        csr_write_1(sc, CUE_ETHCTL, 0);        cue_csr_write_1(sc, CUE_ETHCTL, 0);
         cue_reset(sc);          cue_reset(sc);
         untimeout(cue_tick, sc, sc->cue_stat_ch);          untimeout(cue_tick, sc, sc->cue_stat_ch);
   
Line 1181  cue_stop(struct cue_softc *sc) Line 1196  cue_stop(struct cue_softc *sc)
         }          }
   
         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);          ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
           CUE_UNLOCK(sc);
   
         return;          return;
 }  }
Line 1196  cue_shutdown(device_ptr_t dev) Line 1212  cue_shutdown(device_ptr_t dev)
   
         sc = device_get_softc(dev);          sc = device_get_softc(dev);
   
           CUE_LOCK(sc);
         cue_reset(sc);          cue_reset(sc);
         cue_stop(sc);          cue_stop(sc);
           CUE_UNLOCK(sc);
   
         return;          return;
 }  }

Removed from v.1.4  
changed lines
  Added in v.1.5