Hi Werner,

We have to be more careful about pending SDIO interrupts from the host
side. This patch fixes the iperf bug Nod has been reporting.

Signed-off-by: Samuel Ortiz <[EMAIL PROTECTED]>
---
 drivers/sdio/function/wlan/ar6000/include/wmi.h |    2 
 drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c          |   55 +++++++++++++-----------
 drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h          |    1 
 drivers/sdio/stack/busdriver/sdio_bus_events.c  |    4 -
 4 files changed, 34 insertions(+), 28 deletions(-)

Index: 
linux-2.6.24-rc8-omoko-svn/drivers/sdio/function/wlan/ar6000/include/wmi.h
===================================================================
--- 
linux-2.6.24-rc8-omoko-svn.orig/drivers/sdio/function/wlan/ar6000/include/wmi.h 
    2008-01-22 19:48:32.000000000 +0100
+++ linux-2.6.24-rc8-omoko-svn/drivers/sdio/function/wlan/ar6000/include/wmi.h  
2008-01-22 19:58:33.000000000 +0100
@@ -1103,7 +1103,7 @@
     A_UINT8     snr;
     A_INT16     rssi;
     A_UINT8     bssid[ATH_MAC_LEN];
-//    A_UINT32    ieMask;
+    A_UINT32    ieMask;
 } POSTPACK WMI_BSS_INFO_HDR;
 
 /*
Index: linux-2.6.24-rc8-omoko-svn/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
===================================================================
--- linux-2.6.24-rc8-omoko-svn.orig/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c      
2008-01-22 19:48:32.000000000 +0100
+++ linux-2.6.24-rc8-omoko-svn/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c   
2008-01-22 20:02:09.000000000 +0100
@@ -563,14 +563,10 @@
        PSDREQUEST req;
        struct s3c24xx_hcd_context * context =
                container_of(work, struct s3c24xx_hcd_context, io_work);
-       unsigned long flags;
-
-//     spin_lock_irqsave(&context->lock, flags);
 
        req = GET_CURRENT_REQUEST(&context->hcd);
        if (req == NULL) {
                DBG_PRINT(SDDBG_ERROR, ("%s(): No current request\n", 
__FUNCTION__));
-//             enable_irq(context->io_irq);
                return;
        }
 
@@ -615,12 +611,12 @@
                if (context->complete == S3C24XX_HCD_DATA_READ ||
                    context->complete == S3C24XX_HCD_DATA_WRITE) {
                        if (context->dma_en) {
+                               dma_sync_single(NULL, context->io_buffer_dma,
+                                               req->BlockCount * 
req->BlockLen, DMA_BIDIRECTIONAL);
 
                                s3c2410_dma_ctrl(context->dma_channel, 
S3C2410_DMAOP_START);
 
-//                             spin_unlock_irqrestore(&context->lock, flags);
                                wait_for_completion(&context->dma_complete);
-//                             spin_lock_irqsave(&context->lock, flags);
 
                                s3c24xx_hcd_dma_complete(context);
                        } else {
@@ -630,16 +626,12 @@
        }
 
  out:
-//     spin_unlock_irqrestore(&context->lock, flags);
-
        s3c24xx_hcd_clear_sta(context);
        s3c24xx_hcd_clear_imask(context);
 
        writel(0, context->base + S3C2410_SDICMDARG);
        writel(0, context->base + S3C2410_SDICMDCON);
 
-//     spin_unlock_irqrestore(&context->lock, flags);
-
        SDIO_HandleHcdEvent(&context->hcd, EVENT_HCD_TRANSFER_DONE);
 }
 
@@ -747,9 +739,19 @@
                        imask &= ~S3C2410_SDIIMSK_SDIOIRQ;
                        writel(imask, context->base + S3C2440_SDIIMSK);
                        SDIO_HandleHcdEvent(&context->hcd, 
EVENT_HCD_SDIO_IRQ_PENDING);
-               }
 
-               writel(S3C2410_SDIDSTA_SDIOIRQDETECT, context->base + 
S3C2410_SDIDSTA);
+                       dsta = readl(context->base + S3C2410_SDIDSTA);
+                       if (dsta & S3C2410_SDIDSTA_SDIOIRQDETECT) {
+                               writel(S3C2410_SDIDSTA_SDIOIRQDETECT,
+                                      context->base + S3C2410_SDIDSTA);
+                               SDIO_HandleHcdEvent(&context->hcd,
+                                                   EVENT_HCD_SDIO_IRQ_PENDING);
+                       }
+
+
+               } else {
+                       context->int_pending = 1;
+               }
        }
 
        req = GET_CURRENT_REQUEST(&context->hcd);
@@ -787,8 +789,8 @@
        }
 
        if (cmdsta & S3C2410_SDICMDSTAT_RSPFIN ||
-               (IS_SDREQ_WRITE_DATA(req->Flags) && (fsta &  
S3C2410_SDIFSTA_TFDET)) ||
-               (!IS_SDREQ_WRITE_DATA(req->Flags) && (fsta &  
S3C2410_SDIFSTA_RFDET))) {
+           (IS_SDREQ_WRITE_DATA(req->Flags) && (fsta &  
S3C2410_SDIFSTA_TFDET)) ||
+           (!IS_SDREQ_WRITE_DATA(req->Flags) && (fsta &  
S3C2410_SDIFSTA_RFDET))) {
 
                writel(S3C2410_SDICMDSTAT_RSPFIN, context->base + 
S3C2410_SDICMDSTAT);
 
@@ -904,6 +906,12 @@
                DBG_PRINT(SDDBG_TRACE, ("config SDIO_REARM_INT\n"));
                spin_lock_irqsave(&context->lock,flags);
 
+               if (context->int_pending) {
+                       context->int_pending = 0;
+                       SDIO_HandleHcdEvent(&context->hcd,
+                                           EVENT_HCD_SDIO_IRQ_PENDING);
+               }
+
                context->int_sdio = 1;
                imsk = readl(context->base + S3C2440_SDIIMSK);
                imsk |= S3C2410_SDIIMSK_SDIOIRQ;
@@ -951,8 +959,6 @@
        struct s3c24xx_hcd_context * context =
                (struct s3c24xx_hcd_context *)hcd->pContext;
 
-//     dump_request(context);
-
        req = GET_CURRENT_REQUEST(hcd);
        DBG_ASSERT(req != NULL);
 
@@ -968,7 +974,6 @@
 
        /* Enabling irqs */
        imask = S3C2410_SDIIMSK_READWAIT;
-//     imask = S3C2410_SDIIMSK_READWAIT | S3C2410_SDIIMSK_SDIOIRQ;
 
        cmdcon = readl(context->base + S3C2410_SDICMDCON);
 
@@ -1023,10 +1028,10 @@
                req->DataRemaining = req->BlockCount * req->BlockLen;
 
                /* Set data size, and start the transfer */
+               dcon |= S3C2410_SDIDCON_IRQPERIOD;
                if (!(req->DataRemaining % 4)) {
                        context->data_size = 4;
                        dcon |= S3C2440_SDIDCON_DS_WORD;
-                       dcon |= (1 << 24);
                } else if (!(req->DataRemaining % 2)) {
                        context->data_size = 2;
                        dcon |= S3C2440_SDIDCON_DS_HALFWORD;
@@ -1036,12 +1041,15 @@
                }
 
 #ifdef CONFIG_SDIO_S3C24XX_DMA
-               context->dma_en = 1;
-#else
-               context->dma_en = 0;
-               context->data_size = 1;
-               dcon |= S3C2440_SDIDCON_DS_BYTE;
+               if (req->DataRemaining > 16) {
+                       context->dma_en = 1;
+               } else
 #endif
+               {
+                       context->dma_en = 0;
+                       context->data_size = 1;
+                       dcon |= S3C2440_SDIDCON_DS_BYTE;
+               }
 
                if (context->dma_en) {
                        dcon |= S3C2410_SDIDCON_DMAEN;
@@ -1324,6 +1332,7 @@
        hcd_context.dma_en = 0;
 
        hcd_context.int_sdio = 0;
+       hcd_context.int_pending = 0;
 
        spin_lock_init(&hcd_context.lock);
 
Index: linux-2.6.24-rc8-omoko-svn/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
===================================================================
--- linux-2.6.24-rc8-omoko-svn.orig/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h      
2008-01-22 19:48:32.000000000 +0100
+++ linux-2.6.24-rc8-omoko-svn/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h   
2008-01-22 19:58:33.000000000 +0100
@@ -46,6 +46,7 @@
 
        UINT32                    int_mask;
        UINT32                    int_sdio;            /* Do we have SDIO 
interrupt on ? */
+       UINT32                    int_pending;
 
        UINT32                    complete;
 
Index: linux-2.6.24-rc8-omoko-svn/drivers/sdio/stack/busdriver/sdio_bus_events.c
===================================================================
--- 
linux-2.6.24-rc8-omoko-svn.orig/drivers/sdio/stack/busdriver/sdio_bus_events.c  
    2008-01-22 19:48:32.000000000 +0100
+++ linux-2.6.24-rc8-omoko-svn/drivers/sdio/stack/busdriver/sdio_bus_events.c   
2008-01-22 19:58:33.000000000 +0100
@@ -712,8 +712,6 @@
                 return status;
             }
             if (pHcd->IrqProcState != SDHCD_IDLE) {
-                DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: Already processing 
interrupts! (state = %d) \n",
-                                    pHcd->IrqProcState));
                 status = SDIO_STATUS_ERROR;
                 status2 = _ReleaseHcdLock(pHcd);
             } else {
@@ -746,8 +744,6 @@
         }
 
         if (pHcd->IrqProcState != SDHCD_IDLE) {
-            DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: Already processing 
interrupts! (state = %d) \n",
-                                    pHcd->IrqProcState));
             status = SDIO_STATUS_ERROR;
         } else {
                 /* mark that we are processing */


Reply via email to