[BACK]Return to ehci.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / usb

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/usb/ehci.c between version 1.124.2.2 and 1.124.2.3

version 1.124.2.2, 2008/01/09 01:54:37 version 1.124.2.3, 2008/03/23 02:04:53
Line 1 
Line 1 
 /*      $NetBSD$ */  /*      ehci.c,v 1.124.2.2 2008/01/09 01:54:37 matt Exp */
   
 /*  /*
  * Copyright (c) 2004,2005 The NetBSD Foundation, Inc.   * Copyright (c) 2004,2005 The NetBSD Foundation, Inc.
Line 61 
Line 61 
 */  */
   
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD$");  __KERNEL_RCSID(0, "ehci.c,v 1.124.2.2 2008/01/09 01:54:37 matt Exp");
   
 #include "ohci.h"  #include "ohci.h"
 #include "uhci.h"  #include "uhci.h"
Line 87  __KERNEL_RCSID(0, "$NetBSD$");
Line 87  __KERNEL_RCSID(0, "$NetBSD$");
   
 #include <dev/usb/ehcireg.h>  #include <dev/usb/ehcireg.h>
 #include <dev/usb/ehcivar.h>  #include <dev/usb/ehcivar.h>
   #include <dev/usb/usbroothub_subr.h>
   
 #ifdef EHCI_DEBUG  #ifdef EHCI_DEBUG
 #define DPRINTF(x)      do { if (ehcidebug) printf x; } while(0)  #define DPRINTF(x)      do { if (ehcidebug) printf x; } while(0)
Line 128  struct ehci_pipe {
Line 129  struct ehci_pipe {
         } u;          } u;
 };  };
   
 Static void             ehci_shutdown(void *);  
   
 Static usbd_status      ehci_open(usbd_pipe_handle);  Static usbd_status      ehci_open(usbd_pipe_handle);
 Static void             ehci_poll(struct usbd_bus *);  Static void             ehci_poll(struct usbd_bus *);
 Static void             ehci_softintr(void *);  Static void             ehci_softintr(void *);
Line 186  Static void  ehci_device_isoc_done(usbd_
Line 185  Static void  ehci_device_isoc_done(usbd_
 Static void             ehci_device_clear_toggle(usbd_pipe_handle pipe);  Static void             ehci_device_clear_toggle(usbd_pipe_handle pipe);
 Static void             ehci_noop(usbd_pipe_handle pipe);  Static void             ehci_noop(usbd_pipe_handle pipe);
   
 Static int              ehci_str(usb_string_descriptor_t *, int, const char *);  
 Static void             ehci_pcd(ehci_softc_t *, usbd_xfer_handle);  Static void             ehci_pcd(ehci_softc_t *, usbd_xfer_handle);
 Static void             ehci_disown(ehci_softc_t *, int, int);  Static void             ehci_disown(ehci_softc_t *, int, int);
   
Line 415  ehci_init(ehci_softc_t *sc)
Line 413  ehci_init(ehci_softc_t *sc)
         sc->sc_bus.methods = &ehci_bus_methods;          sc->sc_bus.methods = &ehci_bus_methods;
         sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);          sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
   
         sc->sc_shutdownhook = shutdownhook_establish(ehci_shutdown, sc);  
   
         sc->sc_eintrs = EHCI_NORMAL_INTRS;          sc->sc_eintrs = EHCI_NORMAL_INTRS;
   
         /*          /*
Line 909  ehci_poll(struct usbd_bus *bus)
Line 905  ehci_poll(struct usbd_bus *bus)
                 ehci_intr1(sc);                  ehci_intr1(sc);
 }  }
   
   void
   ehci_childdet(device_t self, device_t child)
   {
           struct ehci_softc *sc = device_private(self);
   
           KASSERT(sc->sc_child == child);
           sc->sc_child = NULL;
   }
   
 int  int
 ehci_detach(struct ehci_softc *sc, int flags)  ehci_detach(struct ehci_softc *sc, int flags)
 {  {
Line 922  ehci_detach(struct ehci_softc *sc, int f
Line 927  ehci_detach(struct ehci_softc *sc, int f
   
         usb_uncallout(sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);          usb_uncallout(sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);
   
         if (sc->sc_shutdownhook != NULL)  
                 shutdownhook_disestablish(sc->sc_shutdownhook);  
   
         usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */          usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
   
         /* XXX free other data structures XXX */          /* XXX free other data structures XXX */
         mutex_destroy(&sc->sc_doorbell_lock);          mutex_destroy(&sc->sc_doorbell_lock);
   
           EOWRITE4(sc, EHCI_CONFIGFLAG, 0);
   
         return (rv);          return (rv);
 }  }
   
   
 int  int
 ehci_activate(device_ptr_t self, enum devact act)  ehci_activate(device_t self, enum devact act)
 {  {
         struct ehci_softc *sc = (struct ehci_softc *)self;          struct ehci_softc *sc = device_private(self);
         int rv = 0;          int rv = 0;
   
         switch (act) {          switch (act) {
Line 964  ehci_activate(device_ptr_t self, enum de
Line 968  ehci_activate(device_ptr_t self, enum de
  * bus glue needs to call out to it.   * bus glue needs to call out to it.
  */   */
 bool  bool
 ehci_suspend(device_t dv)  ehci_suspend(device_t dv PMF_FN_ARGS)
 {  {
         ehci_softc_t *sc = (ehci_softc_t *)dv;          ehci_softc_t *sc = device_private(dv);
         int i, s;          int i, s;
         uint32_t cmd, hcr;          uint32_t cmd, hcr;
   
Line 975  ehci_suspend(device_t dv)
Line 979  ehci_suspend(device_t dv)
         sc->sc_bus.use_polling++;          sc->sc_bus.use_polling++;
   
         for (i = 1; i <= sc->sc_noport; i++) {          for (i = 1; i <= sc->sc_noport; i++) {
                 cmd = EOREAD4(sc, EHCI_PORTSC(i));                  cmd = EOREAD4(sc, EHCI_PORTSC(i)) & ~EHCI_PS_CLEAR;
                 if ((cmd & EHCI_PS_PO) == 0 && (cmd & EHCI_PS_PE) == EHCI_PS_PE)                  if ((cmd & EHCI_PS_PO) == 0 && (cmd & EHCI_PS_PE) == EHCI_PS_PE)
                         EOWRITE4(sc, EHCI_PORTSC(i), cmd | EHCI_PS_SUSP);                          EOWRITE4(sc, EHCI_PORTSC(i), cmd | EHCI_PS_SUSP);
         }          }
Line 1015  ehci_suspend(device_t dv)
Line 1019  ehci_suspend(device_t dv)
 }  }
   
 bool  bool
 ehci_resume(device_t dv)  ehci_resume(device_t dv PMF_FN_ARGS)
 {  {
         ehci_softc_t *sc = (ehci_softc_t *)dv;          ehci_softc_t *sc = device_private(dv);
         int i, s;          int i;
         uint32_t cmd, hcr;          uint32_t cmd, hcr;
   
         s = splhardusb();  
   
         sc->sc_bus.use_polling++;  
   
         /* restore things in case the bios sucks */          /* restore things in case the bios sucks */
         EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);          EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
         EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));          EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
         EOWRITE4(sc, EHCI_ASYNCLISTADDR,          EOWRITE4(sc, EHCI_ASYNCLISTADDR,
             sc->sc_async_head->physaddr | EHCI_LINK_QH);              sc->sc_async_head->physaddr | EHCI_LINK_QH);
         EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);  
           EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs & ~EHCI_INTR_PCIE);
   
         EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);          EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
   
         hcr = 0;          hcr = 0;
         for (i = 1; i <= sc->sc_noport; i++) {          for (i = 1; i <= sc->sc_noport; i++) {
                 cmd = EOREAD4(sc, EHCI_PORTSC(i));                  cmd = EOREAD4(sc, EHCI_PORTSC(i)) & ~EHCI_PS_CLEAR;
                 if ((cmd & EHCI_PS_PO) == 0 &&                  if ((cmd & EHCI_PS_PO) == 0 &&
                     (cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP) {                      (cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP) {
                         EOWRITE4(sc, EHCI_PORTSC(i), cmd | EHCI_PS_FPR);                          EOWRITE4(sc, EHCI_PORTSC(i), cmd | EHCI_PS_FPR);
Line 1048  ehci_resume(device_t dv)
Line 1049  ehci_resume(device_t dv)
                 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);                  usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
   
                 for (i = 1; i <= sc->sc_noport; i++) {                  for (i = 1; i <= sc->sc_noport; i++) {
                         cmd = EOREAD4(sc, EHCI_PORTSC(i));                          cmd = EOREAD4(sc, EHCI_PORTSC(i)) & ~EHCI_PS_CLEAR;
                         if ((cmd & EHCI_PS_PO) == 0 &&                          if ((cmd & EHCI_PS_PO) == 0 &&
                             (cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)                              (cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)
                                 EOWRITE4(sc, EHCI_PORTSC(i),                                  EOWRITE4(sc, EHCI_PORTSC(i),
Line 1057  ehci_resume(device_t dv)
Line 1058  ehci_resume(device_t dv)
         }          }
   
         EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);          EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
           EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
   
         for (i = 0; i < 100; i++) {          for (i = 0; i < 100; i++) {
                 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;                  hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
Line 1068  ehci_resume(device_t dv)
Line 1070  ehci_resume(device_t dv)
         if (hcr == EHCI_STS_HCH)          if (hcr == EHCI_STS_HCH)
                 printf("%s: config timeout\n", USBDEVNAME(sc->sc_bus.bdev));                  printf("%s: config timeout\n", USBDEVNAME(sc->sc_bus.bdev));
   
         usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);  
   
         sc->sc_bus.use_polling--;  
   
         splx(s);  
   
         return true;          return true;
 }  }
   
 /*  /*
  * Shut down the controller when the system is going down.   * Shut down the controller when the system is going down.
  */   */
 void  bool
 ehci_shutdown(void *v)  ehci_shutdown(device_t self, int flags)
 {  {
         ehci_softc_t *sc = v;          ehci_softc_t *sc = device_private(self);
   
         DPRINTF(("ehci_shutdown: stopping the HC\n"));          DPRINTF(("ehci_shutdown: stopping the HC\n"));
         EOWRITE4(sc, EHCI_USBCMD, 0);   /* Halt controller */          EOWRITE4(sc, EHCI_USBCMD, 0);   /* Halt controller */
         EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);          EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
           return true;
 }  }
   
 usbd_status  usbd_status
Line 1635  Static const usb_hub_descriptor_t ehci_h
Line 1632  Static const usb_hub_descriptor_t ehci_h
         {""},          {""},
 };  };
   
 Static int  
 ehci_str(usb_string_descriptor_t *p, int l, const char *s)  
 {  
         int i;  
   
         if (l == 0)  
                 return (0);  
         p->bLength = 2 * strlen(s) + 2;  
         if (l == 1)  
                 return (1);  
         p->bDescriptorType = UDESC_STRING;  
         l -= 2;  
         for (i = 0; s[i] && l > 1; i++, l -= 2)  
                 USETW2(p->bString[i], 0, s[i]);  
         return (2*i+2);  
 }  
   
 /*  /*
  * Simulate a hardware hub by handling all the necessary requests.   * Simulate a hardware hub by handling all the necessary requests.
  */   */
Line 1770  ehci_root_ctrl_start(usbd_xfer_handle xf
Line 1750  ehci_root_ctrl_start(usbd_xfer_handle xf
                         memcpy(buf, &ehci_endpd, l);                          memcpy(buf, &ehci_endpd, l);
                         break;                          break;
                 case UDESC_STRING:                  case UDESC_STRING:
                         *(u_int8_t *)buf = 0;  #define sd ((usb_string_descriptor_t *)buf)
                         totlen = 1;  
                         switch (value & 0xff) {                          switch (value & 0xff) {
                         case 0: /* Language table */                          case 0: /* Language table */
                                 if (len > 0)                                  totlen = usb_makelangtbl(sd, len);
                                         *(u_int8_t *)buf = 4;  
                                 if (len >=  4) {  
                 USETW(((usb_string_descriptor_t *)buf)->bString[0], 0x0409);  
                                         totlen = 4;  
                                 }  
                                 break;                                  break;
                         case 1: /* Vendor */                          case 1: /* Vendor */
                                 totlen = ehci_str(buf, len, sc->sc_vendor);                                  totlen = usb_makestrdesc(sd, len,
                                                            sc->sc_vendor);
                                 break;                                  break;
                         case 2: /* Product */                          case 2: /* Product */
                                 totlen = ehci_str(buf, len, "EHCI root hub");                                  totlen = usb_makestrdesc(sd, len,
                                                            "EHCI root hub");
                                 break;                                  break;
                         }                          }
   #undef sd
                         break;                          break;
                 default:                  default:
                         err = USBD_IOERROR;                          err = USBD_IOERROR;

Legend:
Removed from v.1.124.2.2  
changed lines
  Added in v.1.124.2.3

CVSweb <webmaster@jp.NetBSD.org>