[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.111 and 1.111.2.4

version 1.111, 2006/08/30 00:49:56 version 1.111.2.4, 2007/02/06 13:32:31
Line 188  Static void  ehci_noop(usbd_pipe_handle 
Line 188  Static void  ehci_noop(usbd_pipe_handle 
   
 Static int              ehci_str(usb_string_descriptor_t *, int, const char *);  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_pcd_able(ehci_softc_t *, int);  
 Static void             ehci_pcd_enable(void *);  
 Static void             ehci_disown(ehci_softc_t *, int, int);  Static void             ehci_disown(ehci_softc_t *, int, int);
   
 Static ehci_soft_qh_t  *ehci_alloc_sqh(ehci_softc_t *);  Static ehci_soft_qh_t  *ehci_alloc_sqh(ehci_softc_t *);
Line 336  ehci_init(ehci_softc_t *sc)
Line 334  ehci_init(ehci_softc_t *sc)
         sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);          sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
   
         vers = EREAD2(sc, EHCI_HCIVERSION);          vers = EREAD2(sc, EHCI_HCIVERSION);
         aprint_normal("%s: EHCI version %x.%x\n", USBDEVNAME(sc->sc_bus.bdev),          aprint_verbose("%s: EHCI version %x.%x\n", USBDEVNAME(sc->sc_bus.bdev),
                vers >> 8, vers & 0xff);                 vers >> 8, vers & 0xff);
   
         sparams = EREAD4(sc, EHCI_HCSPARAMS);          sparams = EREAD4(sc, EHCI_HCSPARAMS);
Line 344  ehci_init(ehci_softc_t *sc)
Line 342  ehci_init(ehci_softc_t *sc)
         sc->sc_npcomp = EHCI_HCS_N_PCC(sparams);          sc->sc_npcomp = EHCI_HCS_N_PCC(sparams);
         ncomp = EHCI_HCS_N_CC(sparams);          ncomp = EHCI_HCS_N_CC(sparams);
         if (ncomp != sc->sc_ncomp) {          if (ncomp != sc->sc_ncomp) {
                 aprint_error("%s: wrong number of companions (%d != %d)\n",                  aprint_verbose("%s: wrong number of companions (%d != %d)\n",
                        USBDEVNAME(sc->sc_bus.bdev),                         USBDEVNAME(sc->sc_bus.bdev),
                        ncomp, sc->sc_ncomp);                         ncomp, sc->sc_ncomp);
 #if NOHCI == 0 || NUHCI == 0  #if NOHCI == 0 || NUHCI == 0
Line 417  ehci_init(ehci_softc_t *sc)
Line 415  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_powerhook = powerhook_establish(ehci_power, sc);          sc->sc_powerhook = powerhook_establish(USBDEVNAME(sc->sc_bus.bdev),
               ehci_power, sc);
         sc->sc_shutdownhook = shutdownhook_establish(ehci_shutdown, sc);          sc->sc_shutdownhook = shutdownhook_establish(ehci_shutdown, sc);
   
         sc->sc_eintrs = EHCI_NORMAL_INTRS;          sc->sc_eintrs = EHCI_NORMAL_INTRS;
Line 493  ehci_init(ehci_softc_t *sc)
Line 492  ehci_init(ehci_softc_t *sc)
         sc->sc_async_head = sqh;          sc->sc_async_head = sqh;
         EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH);          EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH);
   
         usb_callout_init(sc->sc_tmo_pcd);  
         usb_callout_init(sc->sc_tmo_intrlist);          usb_callout_init(sc->sc_tmo_intrlist);
   
         lockinit(&sc->sc_doorbell_lock, PZERO, "ehcidb", 0, 0);          lockinit(&sc->sc_doorbell_lock, PZERO, "ehcidb", 0, 0);
Line 606  ehci_intr1(ehci_softc_t *sc)
Line 604  ehci_intr1(ehci_softc_t *sc)
         }          }
         if (eintrs & EHCI_STS_PCD) {          if (eintrs & EHCI_STS_PCD) {
                 ehci_pcd(sc, sc->sc_intrxfer);                  ehci_pcd(sc, sc->sc_intrxfer);
                 /*  
                  * Disable PCD interrupt for now, because it will be  
                  * on until the port has been reset.  
                  */  
                 ehci_pcd_able(sc, 0);  
                 /* Do not allow RHSC interrupts > 1 per second */  
                 usb_callout(sc->sc_tmo_pcd, hz, ehci_pcd_enable, sc);  
                 eintrs &= ~EHCI_STS_PCD;                  eintrs &= ~EHCI_STS_PCD;
         }          }
   
Line 629  ehci_intr1(ehci_softc_t *sc)
Line 620  ehci_intr1(ehci_softc_t *sc)
         return (1);          return (1);
 }  }
   
 void  
 ehci_pcd_able(ehci_softc_t *sc, int on)  
 {  
         DPRINTFN(4, ("ehci_pcd_able: on=%d\n", on));  
         if (on)  
                 sc->sc_eintrs |= EHCI_STS_PCD;  
         else  
                 sc->sc_eintrs &= ~EHCI_STS_PCD;  
         EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);  
 }  
   
 void  
 ehci_pcd_enable(void *v_sc)  
 {  
         ehci_softc_t *sc = v_sc;  
   
         ehci_pcd_able(sc, 1);  
 }  
   
 void  void
 ehci_pcd(ehci_softc_t *sc, usbd_xfer_handle xfer)  ehci_pcd(ehci_softc_t *sc, usbd_xfer_handle xfer)
Line 772  ehci_idone(struct ehci_xfer *ex)
Line 745  ehci_idone(struct ehci_xfer *ex)
         ehci_soft_qtd_t *sqtd, *lsqtd;          ehci_soft_qtd_t *sqtd, *lsqtd;
         u_int32_t status = 0, nstatus = 0;          u_int32_t status = 0, nstatus = 0;
         int actlen;          int actlen;
         uint pkts_left;  
   
         DPRINTFN(/*12*/2, ("ehci_idone: ex=%p\n", ex));          DPRINTFN(/*12*/2, ("ehci_idone: ex=%p\n", ex));
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
Line 822  ehci_idone(struct ehci_xfer *ex)
Line 794  ehci_idone(struct ehci_xfer *ex)
          * If there are left over TDs we need to update the toggle.           * If there are left over TDs we need to update the toggle.
          * The default pipe doesn't need it since control transfers           * The default pipe doesn't need it since control transfers
          * start the toggle at 0 every time.           * start the toggle at 0 every time.
            * For a short transfer we need to update the toggle for the missing
            * packets within the qTD.
          */           */
         if (sqtd != lsqtd->nextqtd &&          if ((sqtd != lsqtd->nextqtd || EHCI_QTD_GET_BYTES(status)) &&
             xfer->pipe->device->default_pipe != xfer->pipe) {              xfer->pipe->device->default_pipe != xfer->pipe) {
                 printf("ehci_idone: need toggle update status=%08x nstatus=%08x\n", status, nstatus);                  DPRINTFN(2, ("ehci_idone: need toggle update "
                                "status=%08x nstatus=%08x\n", status, nstatus));
 #if 0  #if 0
                 ehci_dump_sqh(epipe->sqh);                  ehci_dump_sqh(epipe->sqh);
                 ehci_dump_sqtds(ex->sqtdstart);                  ehci_dump_sqtds(ex->sqtdstart);
Line 833  ehci_idone(struct ehci_xfer *ex)
Line 808  ehci_idone(struct ehci_xfer *ex)
                 epipe->nexttoggle = EHCI_QTD_GET_TOGGLE(nstatus);                  epipe->nexttoggle = EHCI_QTD_GET_TOGGLE(nstatus);
         }          }
   
         /*  
          * For a short transfer we need to update the toggle for the missing  
          * packets within the qTD.  
          */  
         pkts_left = EHCI_QTD_GET_BYTES(status) /  
             UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize);  
         epipe->nexttoggle ^= pkts_left % 2;  
   
         DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, status=0x%x\n",          DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, status=0x%x\n",
                            xfer->length, actlen, status));                             xfer->length, actlen, status));
         xfer->actlen = actlen;          xfer->actlen = actlen;
Line 956  ehci_detach(struct ehci_softc *sc, int f
Line 923  ehci_detach(struct ehci_softc *sc, int f
                 return (rv);                  return (rv);
   
         usb_uncallout(sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);          usb_uncallout(sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);
         usb_uncallout(sc->sc_tmo_pcd, ehci_pcd_enable, sc);  
   
         if (sc->sc_powerhook != NULL)          if (sc->sc_powerhook != NULL)
                 powerhook_disestablish(sc->sc_powerhook);                  powerhook_disestablish(sc->sc_powerhook);
Line 1398  ehci_open(usbd_pipe_handle pipe)
Line 1364  ehci_open(usbd_pipe_handle pipe)
         naks = 8;               /* XXX */          naks = 8;               /* XXX */
         sqh = ehci_alloc_sqh(sc);          sqh = ehci_alloc_sqh(sc);
         if (sqh == NULL)          if (sqh == NULL)
                 goto bad0;                  return (USBD_NOMEM);
         /* qh_link filled when the QH is added */          /* qh_link filled when the QH is added */
         sqh->qh.qh_endp = htole32(          sqh->qh.qh_endp = htole32(
                 EHCI_QH_SET_ADDR(addr) |                  EHCI_QH_SET_ADDR(addr) |
Line 1434  ehci_open(usbd_pipe_handle pipe)
Line 1400  ehci_open(usbd_pipe_handle pipe)
                         printf("ehci_open: usb_allocmem()=%d\n", err);                          printf("ehci_open: usb_allocmem()=%d\n", err);
 #endif  #endif
                 if (err)                  if (err)
                         goto bad1;                          goto bad;
                 pipe->methods = &ehci_device_ctrl_methods;                  pipe->methods = &ehci_device_ctrl_methods;
                 s = splusb();                  s = splusb();
                 ehci_add_qh(sqh, sc->sc_async_head);                  ehci_add_qh(sqh, sc->sc_async_head);
Line 1449  ehci_open(usbd_pipe_handle pipe)
Line 1415  ehci_open(usbd_pipe_handle pipe)
         case UE_INTERRUPT:          case UE_INTERRUPT:
                 pipe->methods = &ehci_device_intr_methods;                  pipe->methods = &ehci_device_intr_methods;
                 ival = pipe->interval;                  ival = pipe->interval;
                 if (ival == USBD_DEFAULT_INTERVAL)                  if (ival == USBD_DEFAULT_INTERVAL) {
                         ival = ed->bInterval;                          if (speed == EHCI_QH_SPEED_HIGH) {
                 return (ehci_device_setintr(sc, sqh, ival));                                  if (ed->bInterval > 16) {
                                           /*
                                            * illegal with high-speed, but there
                                            * were documentation bugs in the spec,
                                            * so be generous
                                            */
                                           ival = 256;
                                   } else
                                           ival = (1 << (ed->bInterval - 1)) / 8;
                           } else
                                   ival = ed->bInterval;
                   }
                   err = ehci_device_setintr(sc, sqh, ival);
                   if (err)
                           goto bad;
                   break;
         case UE_ISOCHRONOUS:          case UE_ISOCHRONOUS:
                 pipe->methods = &ehci_device_isoc_methods;                  pipe->methods = &ehci_device_isoc_methods;
                 return (USBD_INVAL);                  /* FALLTHROUGH */
         default:          default:
                 return (USBD_INVAL);                  err = USBD_INVAL;
                   goto bad;
         }          }
         return (USBD_NORMAL_COMPLETION);          return (USBD_NORMAL_COMPLETION);
   
  bad1:   bad:
         ehci_free_sqh(sc, sqh);          ehci_free_sqh(sc, sqh);
  bad0:          return (err);
         return (USBD_NOMEM);  
 }  }
   
 /*  /*
Line 1603  Static usb_config_descriptor_t ehci_conf
Line 1584  Static usb_config_descriptor_t ehci_conf
         1,          1,
         1,          1,
         0,          0,
         UC_SELF_POWERED,          UC_ATTR_MBO | UC_SELF_POWERED,
         0                       /* max power */          0                       /* max power */
 };  };
   
Line 1625  Static usb_endpoint_descriptor_t ehci_en
Line 1606  Static usb_endpoint_descriptor_t ehci_en
         UE_DIR_IN | EHCI_INTR_ENDPT,          UE_DIR_IN | EHCI_INTR_ENDPT,
         UE_INTERRUPT,          UE_INTERRUPT,
         {8, 0},                 /* max packet */          {8, 0},                 /* max packet */
         255          12
 };  };
   
 Static usb_hub_descriptor_t ehci_hubd = {  Static usb_hub_descriptor_t ehci_hubd = {
Line 1898  ehci_root_ctrl_start(usbd_xfer_handle xf
Line 1879  ehci_root_ctrl_start(usbd_xfer_handle xf
                 case UHF_C_PORT_SUSPEND:                  case UHF_C_PORT_SUSPEND:
                 case UHF_C_PORT_OVER_CURRENT:                  case UHF_C_PORT_OVER_CURRENT:
                 case UHF_C_PORT_RESET:                  case UHF_C_PORT_RESET:
                         /* Enable RHSC interrupt if condition is cleared. */  
                         if ((OREAD4(sc, port) >> 16) == 0)  
                                 ehci_pcd_able(sc, 1);  
                         break;  
                 default:                  default:
                         break;                          break;
                 }                  }
Line 2598  ehci_timeout(void *addr)
Line 2575  ehci_timeout(void *addr)
   
         /* Execute the abort in a process context. */          /* Execute the abort in a process context. */
         usb_init_task(&exfer->abort_task, ehci_timeout_task, addr);          usb_init_task(&exfer->abort_task, ehci_timeout_task, addr);
         usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task);          usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task,
               USB_TASKQ_HC);
 }  }
   
 void  void
Line 3230  ehci_device_intr_done(usbd_xfer_handle x
Line 3208  ehci_device_intr_done(usbd_xfer_handle x
   
 /************************/  /************************/
   
 Static usbd_status      ehci_device_isoc_transfer(usbd_xfer_handle xfer) { return USBD_IOERROR; }  Static usbd_status
 Static usbd_status      ehci_device_isoc_start(usbd_xfer_handle xfer) { return USBD_IOERROR; }  ehci_device_isoc_transfer(usbd_xfer_handle xfer)
 Static void             ehci_device_isoc_abort(usbd_xfer_handle xfer) { }  {
 Static void             ehci_device_isoc_close(usbd_pipe_handle pipe) { }          return USBD_IOERROR;
 Static void             ehci_device_isoc_done(usbd_xfer_handle xfer) { }  }
   Static usbd_status
   ehci_device_isoc_start(usbd_xfer_handle xfer)
   {
           return USBD_IOERROR;
   }
   Static void
   ehci_device_isoc_abort(usbd_xfer_handle xfer)
   {
   }
   Static void
   ehci_device_isoc_close(usbd_pipe_handle pipe)
   {
   }
   Static void
   ehci_device_isoc_done(usbd_xfer_handle xfer)
   {
   }

Legend:
Removed from v.1.111  
changed lines
  Added in v.1.111.2.4

CVSweb <webmaster@jp.NetBSD.org>