Author: hselasky
Date: Mon Sep 10 08:23:56 2012
New Revision: 240302
URL: http://svn.freebsd.org/changeset/base/240302

Log:
  Cleanup interrupt handling in Host Mode.

Modified:
  head/sys/dev/usb/controller/dwc_otg.c
  head/sys/dev/usb/controller/dwc_otg.h

Modified: head/sys/dev/usb/controller/dwc_otg.c
==============================================================================
--- head/sys/dev/usb/controller/dwc_otg.c       Mon Sep 10 08:16:45 2012        
(r240301)
+++ head/sys/dev/usb/controller/dwc_otg.c       Mon Sep 10 08:23:56 2012        
(r240302)
@@ -488,13 +488,15 @@ dwc_otg_host_channel_alloc(struct dwc_ot
 
                        /* check if channel is enabled */
                        temp = DWC_OTG_READ_4(sc, DOTG_HCCHAR(x));
-                       if (temp & HCCHAR_CHENA)
+                       if (temp & HCCHAR_CHENA) {
+                               DPRINTF("CH=%d is BUSY\n", x);
                                continue;
+                       }
 
                        sc->sc_hcchar[x] = td->hcchar;
 
-                       DPRINTF("HCCHAR=0x%08x HCSPLT=0x%08x\n",
-                           td->hcchar, td->hcsplt);
+                       DPRINTF("HCCHAR=0x%08x(0x%08x) HCSPLT=0x%08x\n",
+                           td->hcchar, temp, td->hcsplt);
 
                        temp = DWC_OTG_READ_4(sc, DOTG_HCINT(x));
                        DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), temp);
@@ -502,6 +504,11 @@ dwc_otg_host_channel_alloc(struct dwc_ot
                        DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(x), 0);
                        DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x), 0);
 
+                       /* reset TX FIFO */
+                       DWC_OTG_WRITE_4(sc, DOTG_GRSTCTL,
+                           GRSTCTL_TXFIFO(x) |
+                           GRSTCTL_TXFFLSH);
+
                        /* set channel */
                        td->channel = x;
 
@@ -534,7 +541,8 @@ dwc_otg_host_setup_tx(struct dwc_otg_td 
        DPRINTF("HPTXSTS=0x%08x\n", temp);
 
        max_buffer = 4 * (temp & HPTXSTS_PTXFSPCAVAIL_MASK);
-       max_frames = (temp & HPTXSTS_PTXQSPCAVAIL_MASK) >> 
HPTXSTS_PTXQSPCAVAIL_SHIFT;
+       max_frames = (temp & HPTXSTS_PTXQSPCAVAIL_MASK)
+           >> HPTXSTS_PTXQSPCAVAIL_SHIFT;
 
        max_buffer = max_buffer - (max_buffer % td->max_packet_size);
        if (max_buffer == 0 || max_frames == 0)
@@ -563,11 +571,9 @@ dwc_otg_host_setup_tx(struct dwc_otg_td 
 
        /* enable interrupts */
        DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel),
-           HCINT_STALL | HCINT_DATATGLERR | HCINT_BBLERR |
-           HCINT_AHBERR | HCINT_CHHLTD | HCINT_XFERCOMPL);
-
-       sc->sc_haint_mask |= (1 << td->channel);
-       DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, sc->sc_haint_mask);
+           HCINT_STALL | HCINT_BBLERR |
+           HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR |
+           HCINT_XFERCOMPL);
 
        /* transfer data into FIFO */
        bus_space_write_region_4(sc->sc_io_tag, sc->sc_io_hdl,
@@ -744,8 +750,8 @@ dwc_otg_host_data_rx(struct dwc_otg_td *
                return (0);             /* complete */
        }
 
-       if (temp & (HCINT_DATATGLERR | HCINT_BBLERR |
-           HCINT_AHBERR | HCINT_CHHLTD)) {
+       if (temp & (HCINT_BBLERR |
+           HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR)) {
                td->error_any = 1;
                return (0);             /* complete */
        }
@@ -871,11 +877,9 @@ not_complete:
 
        /* enable interrupts */
        DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel),
-           HCINT_STALL | HCINT_DATATGLERR | HCINT_BBLERR |
-           HCINT_AHBERR | HCINT_CHHLTD | HCINT_XFERCOMPL);
-
-       sc->sc_haint_mask |= (1 << td->channel);
-       DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, sc->sc_haint_mask);
+           HCINT_STALL | HCINT_BBLERR |
+           HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR |
+           HCINT_XFERCOMPL);
 
        temp |= HCCHAR_EPDIR_IN;
 
@@ -1029,8 +1033,8 @@ dwc_otg_host_data_tx(struct dwc_otg_td *
                return (0);             /* complete */
        }
 
-       if (temp & (HCINT_DATATGLERR | HCINT_BBLERR |
-           HCINT_AHBERR | HCINT_CHHLTD)) {
+       if (temp & (HCINT_BBLERR |
+           HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR)) {
                td->error_any = 1;
                return (0);             /* complete */
        }
@@ -1067,7 +1071,8 @@ dwc_otg_host_data_tx(struct dwc_otg_td *
        temp = DWC_OTG_READ_4(sc, DOTG_HPTXSTS);
 
        max_buffer = 4 * (temp & HPTXSTS_PTXFSPCAVAIL_MASK);
-       max_frames = (temp & HPTXSTS_PTXQSPCAVAIL_MASK) >> 
HPTXSTS_PTXQSPCAVAIL_SHIFT;
+       max_frames = (temp & HPTXSTS_PTXQSPCAVAIL_MASK)
+           >> HPTXSTS_PTXQSPCAVAIL_SHIFT;
 
        max_buffer = max_buffer - (max_buffer % td->max_packet_size);
        if (max_buffer == 0 || max_frames < 2)
@@ -1120,11 +1125,9 @@ dwc_otg_host_data_tx(struct dwc_otg_td *
 
        /* enable interrupts */
        DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel),
-           HCINT_STALL | HCINT_DATATGLERR | HCINT_BBLERR |
-           HCINT_AHBERR | HCINT_CHHLTD | HCINT_XFERCOMPL);
-
-       sc->sc_haint_mask |= (1 << td->channel);
-       DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, sc->sc_haint_mask);
+           HCINT_STALL | HCINT_BBLERR |
+           HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR |
+           HCINT_XFERCOMPL);
 
        if (count != 0) {
 
@@ -1372,8 +1375,8 @@ dwc_otg_host_data_tx_sync(struct dwc_otg
                return (0);             /* complete */
        }
 
-       if (temp & (HCINT_DATATGLERR | HCINT_BBLERR |
-           HCINT_AHBERR | HCINT_CHHLTD)) {
+       if (temp & (HCINT_BBLERR |
+           HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR)) {
                td->error_any = 1;
                return (0);             /* complete */
        }
@@ -1615,6 +1618,7 @@ void
 dwc_otg_interrupt(struct dwc_otg_softc *sc)
 {
        uint32_t status;
+       uint32_t haint;
 
        USB_BUS_LOCK(&sc->sc_bus);
 
@@ -1622,13 +1626,13 @@ dwc_otg_interrupt(struct dwc_otg_softc *
        status = DWC_OTG_READ_4(sc, DOTG_GINTSTS);
        DWC_OTG_WRITE_4(sc, DOTG_GINTSTS, status);
 
-       DPRINTFN(14, "GINTSTS=0x%08x\n", status);
+       haint = DWC_OTG_READ_4(sc, DOTG_HAINT);
+
+       DPRINTFN(14, "GINTSTS=0x%08x HAINT=0x%08x HFNUM=0x%08x\n",
+           status, haint, DWC_OTG_READ_4(sc, DOTG_HFNUM));
+
+       if (haint != 0) {
 
-       if (status & GINTSTS_HCHINT) {
-               uint32_t temp = DWC_OTG_READ_4(sc, DOTG_HAINT);
-               DWC_OTG_WRITE_4(sc, DOTG_HAINT, temp);
-               DPRINTFN(14, "HAINT=0x%08x HFNUM=0x%08x\n",
-                   temp, DWC_OTG_READ_4(sc, DOTG_HFNUM));
        }
 
        if (status & GINTSTS_USBRST) {
@@ -2208,8 +2212,7 @@ dwc_otg_standard_done_sub(struct usb_xfe
 
        xfer->td_transfer_cache = td;
 
-       return (error ?
-           USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
+       return (error);
 }
 
 static void
@@ -2278,8 +2281,7 @@ dwc_otg_device_done(struct usb_xfer *xfe
 
                        struct dwc_otg_softc *sc = 
DWC_OTG_BUS2SC(xfer->xroot->bus);
 
-                       sc->sc_haint_mask &= ~(1 << td->channel);
-                       DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, sc->sc_haint_mask);
+                       DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel), 0);
                        DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel),
                            HCCHAR_CHENA | HCCHAR_CHDIS);
 
@@ -2627,16 +2629,15 @@ dwc_otg_init(struct dwc_otg_softc *sc)
                uint8_t x;
 
                for (x = 0; x != sc->sc_host_ch_max; x++) {
-                       /* disable interrupt */
+                       /* disable channel interrupts */
                        DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(x), 0);
-                       DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x), HCCHAR_CHENA | 
HCCHAR_CHDIS);
-                       temp = DWC_OTG_READ_4(sc, DOTG_HCINT(x));
-                       DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), temp);
+                       DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x),
+                           HCCHAR_CHENA | HCCHAR_CHDIS);
                }
 
-               /* disable host channel interrupts */
-               sc->sc_haint_mask = 0;
-               DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, 0);
+               /* enable host channel interrupts */
+               DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK,
+                   (1 << sc->sc_host_ch_max) - 1);
 
                /* setup clocks */
                temp = DWC_OTG_READ_4(sc, DOTG_HCFG);
@@ -3569,7 +3570,7 @@ dwc_otg_device_resume(struct usb_device 
 
        DPRINTF("\n");
 
-       /* Disable relevant Host channels before going to suspend */
+       /* Enable relevant Host channels before resuming */
 
        USB_BUS_LOCK(udev->bus);
 

Modified: head/sys/dev/usb/controller/dwc_otg.h
==============================================================================
--- head/sys/dev/usb/controller/dwc_otg.h       Mon Sep 10 08:16:45 2012        
(r240301)
+++ head/sys/dev/usb/controller/dwc_otg.h       Mon Sep 10 08:23:56 2012        
(r240302)
@@ -151,7 +151,6 @@ struct dwc_otg_softc {
        uint32_t sc_sof_refs;
        uint32_t sc_sof_val;
        uint32_t sc_hprt_val;
-       uint32_t sc_haint_mask;
 
        uint16_t sc_active_rx_ep;
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to