linux/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
<<
>>
Prefs
   1//------------------------------------------------------------------------------
   2// <copyright file="hif.c" company="Atheros">
   3//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
   4// 
   5//
   6// Permission to use, copy, modify, and/or distribute this software for any
   7// purpose with or without fee is hereby granted, provided that the above
   8// copyright notice and this permission notice appear in all copies.
   9//
  10// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17//
  18//
  19//------------------------------------------------------------------------------
  20//==============================================================================
  21// HIF layer reference implementation for Linux Native MMC stack
  22//
  23// Author(s): ="Atheros"
  24//==============================================================================
  25#include <linux/mmc/card.h>
  26#include <linux/mmc/mmc.h>
  27#include <linux/mmc/host.h>
  28#include <linux/mmc/sdio_func.h>
  29#include <linux/mmc/sdio_ids.h>
  30#include <linux/mmc/sdio.h>
  31#include <linux/mmc/sd.h>
  32#include <linux/kthread.h>
  33
  34/* by default setup a bounce buffer for the data packets, if the underlying host controller driver
  35   does not use DMA you may be able to skip this step and save the memory allocation and transfer time */
  36#define HIF_USE_DMA_BOUNCE_BUFFER 1
  37#include "hif_internal.h"
  38#define ATH_MODULE_NAME hif
  39#include "a_debug.h"
  40#include "AR6002/hw2.0/hw/mbox_host_reg.h"
  41
  42#if HIF_USE_DMA_BOUNCE_BUFFER
  43/* macro to check if DMA buffer is WORD-aligned and DMA-able.  Most host controllers assume the
  44 * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack).  
  45 * virt_addr_valid check fails on stack memory.  
  46 */
  47#define BUFFER_NEEDS_BOUNCE(buffer)  (((unsigned long)(buffer) & 0x3) || !virt_addr_valid((buffer)))
  48#else
  49#define BUFFER_NEEDS_BOUNCE(buffer)   (FALSE)
  50#endif
  51
  52/* ATHENV */
  53#if defined(CONFIG_PM)
  54#define dev_to_sdio_func(d)     container_of(d, struct sdio_func, dev)
  55#define to_sdio_driver(d)      container_of(d, struct sdio_driver, drv)
  56static int hifDeviceSuspend(struct device *dev);
  57static int hifDeviceResume(struct device *dev);
  58#endif /* CONFIG_PM */
  59static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id);
  60static void hifDeviceRemoved(struct sdio_func *func);
  61static HIF_DEVICE *addHifDevice(struct sdio_func *func);
  62static HIF_DEVICE *getHifDevice(struct sdio_func *func);
  63static void delHifDevice(HIF_DEVICE * device);
  64static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte);
  65static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte);
  66
  67int reset_sdio_on_unload = 0;
  68module_param(reset_sdio_on_unload, int, 0644);
  69
  70extern A_UINT32 nohifscattersupport;
  71
  72
  73/* ------ Static Variables ------ */
  74static const struct sdio_device_id ar6k_id_table[] = {
  75    {  SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0))  },
  76    {  SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1))  },
  77    {  SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0))  },
  78    {  SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))  },
  79    { /* null */                                         },
  80};
  81MODULE_DEVICE_TABLE(sdio, ar6k_id_table);
  82
  83static struct sdio_driver ar6k_driver = {
  84        .name = "ar6k_wlan",
  85        .id_table = ar6k_id_table,
  86        .probe = hifDeviceInserted,
  87        .remove = hifDeviceRemoved,
  88};
  89
  90#if defined(CONFIG_PM)
  91/* New suspend/resume based on linux-2.6.32
  92 * Need to patch linux-2.6.32 with mmc2.6.32_suspend.patch
  93 * Need to patch with msmsdcc2.6.29_suspend.patch for msm_sdcc host
  94     */
  95static struct dev_pm_ops ar6k_device_pm_ops = {
  96        .suspend = hifDeviceSuspend,
  97        .resume = hifDeviceResume,
  98};
  99#endif /* CONFIG_PM */
 100
 101/* make sure we only unregister when registered. */
 102static int registered = 0;
 103
 104OSDRV_CALLBACKS osdrvCallbacks;
 105extern A_UINT32 onebitmode;
 106extern A_UINT32 busspeedlow;
 107extern A_UINT32 debughif;
 108
 109static void ResetAllCards(void);
 110static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func);
 111static A_STATUS hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func);
 112
 113#ifdef DEBUG
 114
 115ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif,
 116                                 "hif",
 117                                 "(Linux MMC) Host Interconnect Framework",
 118                                 ATH_DEBUG_MASK_DEFAULTS,
 119                                 0,
 120                                 NULL);
 121                                 
 122#endif
 123
 124
 125/* ------ Functions ------ */
 126A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks)
 127{
 128    int status;
 129    AR_DEBUG_ASSERT(callbacks != NULL);
 130
 131    A_REGISTER_MODULE_DEBUG_INFO(hif);
 132
 133    /* store the callback handlers */
 134    osdrvCallbacks = *callbacks;
 135
 136    /* Register with bus driver core */
 137    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFInit registering\n"));
 138    registered = 1;
 139#if defined(CONFIG_PM)
 140    if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) {
 141        ar6k_driver.drv.pm = &ar6k_device_pm_ops;
 142    }
 143#endif /* CONFIG_PM */
 144    status = sdio_register_driver(&ar6k_driver);
 145    AR_DEBUG_ASSERT(status==0);
 146
 147    if (status != 0) {
 148        return A_ERROR;
 149    }
 150
 151    return A_OK;
 152
 153}
 154
 155static A_STATUS
 156__HIFReadWrite(HIF_DEVICE *device,
 157             A_UINT32 address,
 158             A_UCHAR *buffer,
 159             A_UINT32 length,
 160             A_UINT32 request,
 161             void *context)
 162{
 163    A_UINT8 opcode;
 164    A_STATUS    status = A_OK;
 165    int     ret;
 166    A_UINT8 *tbuffer;
 167    A_BOOL   bounced = FALSE;
 168
 169    AR_DEBUG_ASSERT(device != NULL);
 170    AR_DEBUG_ASSERT(device->func != NULL);
 171
 172    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: 0x%p, buffer:0x%p (addr:0x%X)\n", 
 173                    device, buffer, address));
 174
 175    do {
 176        if (request & HIF_EXTENDED_IO) {
 177            //AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Command type: CMD53\n"));
 178        } else {
 179            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
 180                            ("AR6000: Invalid command type: 0x%08x\n", request));
 181            status = A_EINVAL;
 182            break;
 183        }
 184
 185        if (request & HIF_BLOCK_BASIS) {
 186            /* round to whole block length size */
 187            length = (length / HIF_MBOX_BLOCK_SIZE) * HIF_MBOX_BLOCK_SIZE;
 188            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
 189                            ("AR6000: Block mode (BlockLen: %d)\n",
 190                            length));
 191        } else if (request & HIF_BYTE_BASIS) {
 192            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
 193                            ("AR6000: Byte mode (BlockLen: %d)\n",
 194                            length));
 195        } else {
 196            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
 197                            ("AR6000: Invalid data mode: 0x%08x\n", request));
 198            status = A_EINVAL;
 199            break;
 200        }
 201
 202#if 0
 203        /* useful for checking register accesses */
 204        if (length & 0x3) {
 205            A_PRINTF(KERN_ALERT"AR6000: HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n",
 206                                request & HIF_WRITE ? "write":"read", address, length);
 207        }
 208#endif
 209
 210        if (request & HIF_WRITE) {
 211            if ((address >= HIF_MBOX_START_ADDR(0)) &&
 212                (address <= HIF_MBOX_END_ADDR(3)))
 213            {
 214    
 215                AR_DEBUG_ASSERT(length <= HIF_MBOX_WIDTH);
 216    
 217                /*
 218                 * Mailbox write. Adjust the address so that the last byte
 219                 * falls on the EOM address.
 220                 */
 221                address += (HIF_MBOX_WIDTH - length);
 222            }
 223        }
 224
 225        if (request & HIF_FIXED_ADDRESS) {
 226            opcode = CMD53_FIXED_ADDRESS;
 227            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Fixed 0x%X\n", address));
 228        } else if (request & HIF_INCREMENTAL_ADDRESS) {
 229            opcode = CMD53_INCR_ADDRESS;
 230            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Incremental 0x%X\n", address));
 231        } else {
 232            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
 233                            ("AR6000: Invalid address mode: 0x%08x\n", request));
 234            status = A_EINVAL;
 235            break;
 236        }
 237
 238        if (request & HIF_WRITE) {
 239#if HIF_USE_DMA_BOUNCE_BUFFER
 240            if (BUFFER_NEEDS_BOUNCE(buffer)) {
 241                AR_DEBUG_ASSERT(device->dma_buffer != NULL);
 242                tbuffer = device->dma_buffer;
 243                    /* copy the write data to the dma buffer */
 244                AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
 245                memcpy(tbuffer, buffer, length);
 246                bounced = TRUE;
 247            } else {
 248                tbuffer = buffer;    
 249            }
 250#else
 251                tbuffer = buffer;
 252#endif
 253            if (opcode == CMD53_FIXED_ADDRESS) {
 254                ret = sdio_writesb(device->func, address, tbuffer, length);
 255                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writesb ret=%d address: 0x%X, len: %d, 0x%X\n",
 256                                                  ret, address, length, *(int *)tbuffer));
 257            } else {
 258                ret = sdio_memcpy_toio(device->func, address, tbuffer, length);
 259                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writeio ret=%d address: 0x%X, len: %d, 0x%X\n",
 260                                                  ret, address, length, *(int *)tbuffer));
 261            }
 262        } else if (request & HIF_READ) {
 263#if HIF_USE_DMA_BOUNCE_BUFFER
 264            if (BUFFER_NEEDS_BOUNCE(buffer)) {
 265                AR_DEBUG_ASSERT(device->dma_buffer != NULL);
 266                AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
 267                tbuffer = device->dma_buffer;
 268                bounced = TRUE;
 269            } else {
 270                tbuffer = buffer;    
 271            }
 272#else
 273            tbuffer = buffer;
 274#endif
 275            if (opcode == CMD53_FIXED_ADDRESS) {
 276                ret = sdio_readsb(device->func, tbuffer, address, length);
 277                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readsb ret=%d address: 0x%X, len: %d, 0x%X\n",
 278                                                  ret, address, length, *(int *)tbuffer));
 279            } else {
 280                ret = sdio_memcpy_fromio(device->func, tbuffer, address, length);
 281                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readio ret=%d address: 0x%X, len: %d, 0x%X\n",
 282                                                  ret, address, length, *(int *)tbuffer));
 283            }
 284#if HIF_USE_DMA_BOUNCE_BUFFER
 285            if (bounced) {
 286                   /* copy the read data from the dma buffer */
 287                memcpy(buffer, tbuffer, length);
 288            }
 289#endif
 290        } else {
 291            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
 292                            ("AR6000: Invalid direction: 0x%08x\n", request));
 293            status = A_EINVAL;
 294            break;
 295        }
 296
 297        if (ret) {
 298            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
 299                            ("AR6000: SDIO bus operation failed! MMC stack returned : %d \n", ret));
 300            status = A_ERROR;
 301        }
 302    } while (FALSE);
 303
 304    return status;
 305}
 306
 307void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest)
 308{
 309    unsigned long flags;
 310    BUS_REQUEST *async;
 311    BUS_REQUEST *active;
 312    
 313    spin_lock_irqsave(&device->asynclock, flags);
 314    active = device->asyncreq;
 315    if (active == NULL) {
 316        device->asyncreq = busrequest;
 317        device->asyncreq->inusenext = NULL;
 318    } else {
 319        for (async = device->asyncreq;
 320             async != NULL;
 321             async = async->inusenext) {
 322             active =  async;
 323        }
 324        active->inusenext = busrequest;
 325        busrequest->inusenext = NULL;
 326    }
 327    spin_unlock_irqrestore(&device->asynclock, flags);
 328}
 329
 330
 331/* queue a read/write request */
 332A_STATUS
 333HIFReadWrite(HIF_DEVICE *device,
 334             A_UINT32 address,
 335             A_UCHAR *buffer,
 336             A_UINT32 length,
 337             A_UINT32 request,
 338             void *context)
 339{
 340    A_STATUS    status = A_OK;
 341    BUS_REQUEST *busrequest;
 342
 343
 344    AR_DEBUG_ASSERT(device != NULL);
 345    AR_DEBUG_ASSERT(device->func != NULL);
 346
 347    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: %p addr:0x%X\n", device,address));
 348
 349    do {            
 350        if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)){
 351            /* serialize all requests through the async thread */
 352            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Execution mode: %s\n", 
 353                        (request & HIF_ASYNCHRONOUS)?"Async":"Synch"));
 354            busrequest = hifAllocateBusRequest(device);
 355            if (busrequest == NULL) {
 356                AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
 357                    ("AR6000: no async bus requests available (%s, addr:0x%X, len:%d) \n", 
 358                        request & HIF_READ ? "READ":"WRITE", address, length));
 359                return A_ERROR;
 360            }
 361            busrequest->address = address;
 362            busrequest->buffer = buffer;
 363            busrequest->length = length;
 364            busrequest->request = request;
 365            busrequest->context = context;
 366            
 367            AddToAsyncList(device, busrequest);
 368            
 369            if (request & HIF_SYNCHRONOUS) {
 370                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%lX\n", (unsigned long)busrequest));
 371
 372                /* wait for completion */
 373                up(&device->sem_async);
 374                if (down_interruptible(&busrequest->sem_req) != 0) {
 375                    /* interrupted, exit */
 376                    return A_ERROR;
 377                } else {
 378                    A_STATUS status = busrequest->status;
 379                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%lX: 0x%X\n", 
 380                                                      (unsigned long)busrequest, busrequest->status));
 381                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request));
 382                    hifFreeBusRequest(device, busrequest);
 383                    return status;
 384                }
 385            } else {
 386                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%lX\n", (unsigned long)busrequest));
 387                up(&device->sem_async);
 388                return A_PENDING;
 389            }
 390        } else {
 391            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
 392                            ("AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request));
 393            status = A_EINVAL;
 394            break;
 395        }
 396    } while(0);
 397
 398    return status;
 399}
 400/* thread to serialize all requests, both sync and async */
 401static int async_task(void *param)
 402 {
 403    HIF_DEVICE *device;
 404    BUS_REQUEST *request;
 405    A_STATUS status;
 406    unsigned long flags;
 407
 408    device = (HIF_DEVICE *)param;
 409    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n"));
 410    set_current_state(TASK_INTERRUPTIBLE);
 411    while(!device->async_shutdown) {
 412        /* wait for work */
 413        if (down_interruptible(&device->sem_async) != 0) {
 414            /* interrupted, exit */
 415            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n"));
 416            break;
 417        }
 418        if (device->async_shutdown) {
 419            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n"));
 420            break;
 421        }
 422        /* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */
 423        sdio_claim_host(device->func);
 424        spin_lock_irqsave(&device->asynclock, flags);
 425        /* pull the request to work on */
 426        while (device->asyncreq != NULL) {
 427            request = device->asyncreq;
 428            if (request->inusenext != NULL) {
 429                device->asyncreq = request->inusenext;
 430            } else {
 431                device->asyncreq = NULL;
 432            }
 433            spin_unlock_irqrestore(&device->asynclock, flags);
 434            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%lX\n", (unsigned long)request));
 435            
 436            if (request->pScatterReq != NULL) {
 437                A_ASSERT(device->scatter_enabled);
 438                    /* this is a queued scatter request, pass the request to scatter routine which
 439                     * executes it synchronously, note, no need to free the request since scatter requests
 440                     * are maintained on a separate list */
 441                status = DoHifReadWriteScatter(device,request);
 442            } else {                
 443                    /* call HIFReadWrite in sync mode to do the work */
 444                status = __HIFReadWrite(device, request->address, request->buffer,
 445                                      request->length, request->request & ~HIF_SYNCHRONOUS, NULL);
 446                if (request->request & HIF_ASYNCHRONOUS) {
 447                    void *context = request->context;
 448                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%lX\n", (unsigned long)request));
 449                    hifFreeBusRequest(device, request);
 450                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%lX\n", (unsigned long)request));
 451                    device->htcCallbacks.rwCompletionHandler(context, status);
 452                } else {
 453                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%lX\n", (unsigned long)request));
 454                    request->status = status;
 455                    up(&request->sem_req);
 456                }
 457            }
 458            spin_lock_irqsave(&device->asynclock, flags);
 459        }
 460        spin_unlock_irqrestore(&device->asynclock, flags);
 461        sdio_release_host(device->func);
 462    }
 463
 464    complete_and_exit(&device->async_completion, 0);
 465    return 0;
 466}
 467
 468static A_INT32 IssueSDCommand(HIF_DEVICE *device, A_UINT32 opcode, A_UINT32 arg, A_UINT32 flags, A_UINT32 *resp)
 469{
 470    struct mmc_command cmd;
 471    A_INT32 err;
 472    struct mmc_host *host;
 473    struct sdio_func *func;
 474
 475    func = device->func;
 476    host = func->card->host;
 477
 478    memset(&cmd, 0, sizeof(struct mmc_command)); 
 479    cmd.opcode = opcode;
 480    cmd.arg = arg;
 481    cmd.flags = flags;
 482    err = mmc_wait_for_cmd(host, &cmd, 3);
 483
 484    if ((!err) && (resp)) {
 485        *resp = cmd.resp[0];
 486    }
 487
 488    return err;
 489}
 490
 491A_STATUS ReinitSDIO(HIF_DEVICE *device)
 492{
 493    A_INT32 err;
 494    struct mmc_host *host;
 495    struct mmc_card *card;
 496        struct sdio_func *func;
 497    A_UINT8  cmd52_resp;
 498    A_UINT32 clock;
 499
 500    func = device->func;
 501    card = func->card;
 502    host = card->host;
 503   
 504    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n"));
 505    sdio_claim_host(func);
 506
 507    do {
 508        if (!device->is_suspend) {
 509            A_UINT32 resp;
 510            A_UINT16 rca;
 511            A_UINT32 i;
 512            int bit = fls(host->ocr_avail) - 1;
 513            /* emulate the mmc_power_up(...) */
 514            host->ios.vdd = bit;
 515            host->ios.chip_select = MMC_CS_DONTCARE;
 516            host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
 517            host->ios.power_mode = MMC_POWER_UP;
 518            host->ios.bus_width = MMC_BUS_WIDTH_1;
 519            host->ios.timing = MMC_TIMING_LEGACY;
 520            host->ops->set_ios(host, &host->ios);
 521            /*
 522             * This delay should be sufficient to allow the power supply
 523             * to reach the minimum voltage.
 524             */
 525            msleep(2);
 526
 527            host->ios.clock = host->f_min;
 528            host->ios.power_mode = MMC_POWER_ON;
 529            host->ops->set_ios(host, &host->ios);
 530
 531            /*
 532             * This delay must be at least 74 clock sizes, or 1 ms, or the
 533             * time required to reach a stable voltage.
 534             */
 535            msleep(2);
 536
 537            /* Issue CMD0. Goto idle state */
 538                host->ios.chip_select = MMC_CS_HIGH;
 539            host->ops->set_ios(host, &host->ios);
 540                msleep(1);
 541            err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL);
 542            host->ios.chip_select = MMC_CS_DONTCARE;
 543            host->ops->set_ios(host, &host->ios);
 544                msleep(1);
 545            host->use_spi_crc = 0;
 546
 547            if (err) {
 548                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n",err));    
 549                break;
 550            }        
 551
 552            if (!host->ocr) {
 553                /* Issue CMD5, arg = 0 */
 554                err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
 555                if (err) {
 556                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));    
 557                    break;
 558                }
 559                host->ocr = resp;
 560            }
 561
 562            /* Issue CMD5, arg = ocr. Wait till card is ready  */
 563            for (i=0;i<100;i++) {
 564                err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
 565                if (err) {
 566                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));    
 567                    break;
 568                }
 569                if (resp & MMC_CARD_BUSY) {
 570                    break;
 571                }
 572                msleep(10);
 573            }
 574
 575            if ((i == 100) || (err)) {
 576                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready : %d %d \n",i,err));    
 577                break;
 578            }
 579
 580            /* Issue CMD3, get RCA */
 581            err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp);
 582            if (err) {
 583                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n",err));    
 584                break;
 585            }
 586            rca = resp >> 16;
 587            host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
 588            host->ops->set_ios(host, &host->ios);
 589
 590            /* Issue CMD7, select card  */
 591            err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL);
 592            if (err) {
 593                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n",err));    
 594                break;
 595            }
 596        }
 597        
 598        /* Enable high speed */
 599        if (card->host->caps & MMC_CAP_SD_HIGHSPEED) {
 600            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n"));    
 601            err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp);
 602            if (err) {
 603                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR speed register failed  : %d \n",err));    
 604                card->state &= ~MMC_STATE_HIGHSPEED;
 605                /* no need to break */
 606            } else {
 607                err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS));
 608                if (err) {
 609                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to CCCR speed register failed  : %d \n",err));    
 610                    break;
 611                }
 612                mmc_card_set_highspeed(card);
 613                host->ios.timing = MMC_TIMING_SD_HS;
 614                host->ops->set_ios(host, &host->ios);
 615            }
 616        }
 617
 618        /* Set clock */
 619        if (mmc_card_highspeed(card)) {
 620            clock = 50000000;
 621        } else {
 622            clock = card->cis.max_dtr;
 623        }
 624        
 625        if (clock > host->f_max) {
 626            clock = host->f_max;
 627        }
 628        host->ios.clock = clock;
 629        host->ops->set_ios(host, &host->ios);
 630        
 631
 632        if (card->host->caps & MMC_CAP_4_BIT_DATA) {
 633            /* CMD52: Set bus width & disable card detect resistor */
 634            err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT);
 635            if (err) {
 636                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mode failed : %d \n",err));    
 637                break;
 638            }
 639            host->ios.bus_width = MMC_BUS_WIDTH_4;
 640            host->ops->set_ios(host, &host->ios);
 641        }
 642    } while (0);
 643
 644    sdio_release_host(func);
 645    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ReinitSDIO \n"));
 646
 647    return (err) ? A_ERROR : A_OK;
 648}
 649
 650A_STATUS
 651PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config)
 652{
 653    A_STATUS status = A_OK;
 654#if defined(CONFIG_PM)
 655        struct sdio_func *func = device->func;
 656    int old_reset_val;
 657    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +PowerStateChangeNotify %d\n", config));
 658    switch (config) {
 659       case HIF_DEVICE_POWER_DOWN:
 660       case HIF_DEVICE_POWER_CUT:
 661            old_reset_val = reset_sdio_on_unload;
 662            reset_sdio_on_unload = 1;
 663            status = hifDisableFunc(device, func);
 664            reset_sdio_on_unload = old_reset_val;
 665            if (!device->is_suspend) {
 666                struct mmc_host *host = func->card->host;
 667                    host->ios.clock = 0;
 668                    host->ios.vdd = 0;
 669                host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
 670                host->ios.chip_select = MMC_CS_DONTCARE;
 671                host->ios.power_mode = MMC_POWER_OFF;
 672                host->ios.bus_width = MMC_BUS_WIDTH_1;
 673                host->ios.timing = MMC_TIMING_LEGACY;
 674                host->ops->set_ios(host, &host->ios);
 675            }
 676            break;
 677       case HIF_DEVICE_POWER_UP:
 678            if (device->powerConfig == HIF_DEVICE_POWER_CUT) {
 679                status = ReinitSDIO(device);
 680            }
 681            if (status == A_OK) {
 682                status = hifEnableFunc(device, func);
 683            }
 684            break;
 685    } 
 686    device->powerConfig = config;
 687
 688    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -PowerStateChangeNotify\n"));
 689#endif
 690    return status;
 691}
 692
 693A_STATUS
 694HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode,
 695                   void *config, A_UINT32 configLen)
 696{
 697    A_UINT32 count;
 698    A_STATUS status = A_OK;
 699    
 700    switch(opcode) {
 701        case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
 702            ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
 703            ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
 704            ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
 705            ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
 706            break;
 707
 708        case HIF_DEVICE_GET_MBOX_ADDR:
 709            for (count = 0; count < 4; count ++) {
 710                ((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count);
 711            }
 712            
 713            if (configLen >= sizeof(HIF_DEVICE_MBOX_INFO)) {    
 714                SetExtendedMboxWindowInfo((A_UINT16)device->func->device,
 715                                          (HIF_DEVICE_MBOX_INFO *)config);
 716            }
 717                        
 718            break;
 719        case HIF_DEVICE_GET_IRQ_PROC_MODE:
 720            *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY;
 721            break;
 722       case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT:
 723            if (!device->scatter_enabled) {
 724                return A_ENOTSUP;    
 725            }
 726            status = SetupHIFScatterSupport(device, (HIF_DEVICE_SCATTER_SUPPORT_INFO *)config);
 727            if (A_FAILED(status)) {
 728                device->scatter_enabled = FALSE;           
 729            }
 730            break; 
 731        case HIF_DEVICE_GET_OS_DEVICE:
 732                /* pass back a pointer to the SDIO function's "dev" struct */
 733            ((HIF_DEVICE_OS_DEVICE_INFO *)config)->pOSDevice = &device->func->dev;
 734            break; 
 735        case HIF_DEVICE_POWER_STATE_CHANGE:
 736            status = PowerStateChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TYPE *)config);
 737            break;
 738        default:
 739            AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
 740                            ("AR6000: Unsupported configuration opcode: %d\n", opcode));
 741            status = A_ERROR;
 742    }
 743
 744    return status;
 745}
 746
 747void
 748HIFShutDownDevice(HIF_DEVICE *device)
 749{
 750    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n"));
 751    if (device != NULL) {
 752        AR_DEBUG_ASSERT(device->func != NULL);
 753    } else {
 754            /* since we are unloading the driver anyways, reset all cards in case the SDIO card
 755             * is externally powered and we are unloading the SDIO stack.  This avoids the problem when
 756             * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already
 757             * enumerated */
 758        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFShutDownDevice, resetting\n"));
 759        ResetAllCards();
 760
 761        /* Unregister with bus driver core */
 762        if (registered) {
 763            registered = 0;
 764            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
 765                            ("AR6000: Unregistering with the bus driver\n"));
 766            sdio_unregister_driver(&ar6k_driver);
 767            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
 768                            ("AR6000: Unregistered\n"));
 769        }
 770    }
 771    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -HIFShutDownDevice\n"));
 772}
 773
 774static void
 775hifIRQHandler(struct sdio_func *func)
 776{
 777    A_STATUS status;
 778    HIF_DEVICE *device;
 779    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n"));
 780
 781    device = getHifDevice(func);
 782    atomic_set(&device->irqHandling, 1);
 783    /* release the host during ints so we can pick it back up when we process cmds */
 784    sdio_release_host(device->func);
 785    status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context);
 786    sdio_claim_host(device->func);
 787    atomic_set(&device->irqHandling, 0);
 788    AR_DEBUG_ASSERT(status == A_OK || status == A_ECANCELED);
 789    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifIRQHandler\n"));
 790}
 791
 792/* handle HTC startup via thread*/
 793static int startup_task(void *param)
 794{
 795    HIF_DEVICE *device;
 796
 797    device = (HIF_DEVICE *)param;
 798    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n"));
 799        /* start  up inform DRV layer */
 800    if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != A_OK) {
 801        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
 802    }
 803    return 0;
 804}
 805
 806#if defined(CONFIG_PM)
 807static int enable_task(void *param)
 808{
 809    HIF_DEVICE *device;
 810    device = (HIF_DEVICE *)param;
 811    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call  from resume_task\n"));
 812
 813        /* start  up inform DRV layer */
 814    if (device && 
 815        device->claimedContext && 
 816        osdrvCallbacks.devicePowerChangeHandler &&
 817        osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != A_OK) 
 818    {
 819        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
 820    }
 821
 822    return 0;
 823}
 824#endif
 825
 826static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id)
 827{
 828    int ret;
 829    HIF_DEVICE * device;
 830    int count;
 831
 832    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
 833                    ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n",
 834                     func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize));
 835
 836    addHifDevice(func);
 837    device = getHifDevice(func);
 838
 839    device->id = id;
 840    device->is_disabled = TRUE;
 841
 842    spin_lock_init(&device->lock);
 843
 844    spin_lock_init(&device->asynclock);
 845    
 846    DL_LIST_INIT(&device->ScatterReqHead);
 847    
 848    if (!nohifscattersupport) {
 849            /* try to allow scatter operation on all instances,
 850             * unless globally overridden */
 851        device->scatter_enabled = TRUE;
 852    }
 853
 854    /* Initialize the bus requests to be used later */
 855    A_MEMZERO(device->busRequest, sizeof(device->busRequest));
 856    for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) {
 857        sema_init(&device->busRequest[count].sem_req, 0);
 858        hifFreeBusRequest(device, &device->busRequest[count]);
 859    }
 860    sema_init(&device->sem_async, 0);
 861    
 862    ret  = hifEnableFunc(device, func);
 863
 864    return ret;
 865}
 866
 867
 868void
 869HIFAckInterrupt(HIF_DEVICE *device)
 870{
 871    AR_DEBUG_ASSERT(device != NULL);
 872
 873    /* Acknowledge our function IRQ */
 874}
 875
 876void
 877HIFUnMaskInterrupt(HIF_DEVICE *device)
 878{
 879    int ret;
 880
 881    AR_DEBUG_ASSERT(device != NULL);
 882    AR_DEBUG_ASSERT(device->func != NULL);
 883
 884    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFUnMaskInterrupt\n"));
 885
 886    /* Register the IRQ Handler */
 887    sdio_claim_host(device->func);
 888    ret = sdio_claim_irq(device->func, hifIRQHandler);
 889    sdio_release_host(device->func);
 890    AR_DEBUG_ASSERT(ret == 0);
 891}
 892
 893void HIFMaskInterrupt(HIF_DEVICE *device)
 894{
 895    int ret;
 896    AR_DEBUG_ASSERT(device != NULL);
 897    AR_DEBUG_ASSERT(device->func != NULL);
 898
 899    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFMaskInterrupt\n"));
 900
 901    /* Mask our function IRQ */
 902    sdio_claim_host(device->func);
 903    while (atomic_read(&device->irqHandling)) {        
 904        sdio_release_host(device->func);
 905        schedule_timeout(HZ/10);
 906        sdio_claim_host(device->func);
 907    }
 908    ret = sdio_release_irq(device->func);
 909    sdio_release_host(device->func);
 910    AR_DEBUG_ASSERT(ret == 0);
 911}
 912
 913BUS_REQUEST *hifAllocateBusRequest(HIF_DEVICE *device)
 914{
 915    BUS_REQUEST *busrequest;
 916    unsigned long flag;
 917
 918    /* Acquire lock */
 919    spin_lock_irqsave(&device->lock, flag);
 920
 921    /* Remove first in list */
 922    if((busrequest = device->s_busRequestFreeQueue) != NULL)
 923    {
 924        device->s_busRequestFreeQueue = busrequest->next;
 925    }
 926    /* Release lock */
 927    spin_unlock_irqrestore(&device->lock, flag);
 928    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifAllocateBusRequest: 0x%p\n", busrequest));
 929    return busrequest;
 930}
 931
 932void
 933hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest)
 934{
 935    unsigned long flag;
 936
 937    AR_DEBUG_ASSERT(busrequest != NULL);
 938    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifFreeBusRequest: 0x%p\n", busrequest));
 939    /* Acquire lock */
 940    spin_lock_irqsave(&device->lock, flag);
 941
 942
 943    /* Insert first in list */
 944    busrequest->next = device->s_busRequestFreeQueue;
 945    busrequest->inusenext = NULL;
 946    device->s_busRequestFreeQueue = busrequest;
 947
 948    /* Release lock */
 949    spin_unlock_irqrestore(&device->lock, flag);
 950}
 951
 952static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func)
 953{
 954    int ret;
 955    A_STATUS status = A_OK;
 956
 957    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n"));
 958    device = getHifDevice(func);
 959    if (!IS_ERR(device->async_task)) {
 960        init_completion(&device->async_completion);
 961        device->async_shutdown = 1;
 962        up(&device->sem_async);
 963        wait_for_completion(&device->async_completion);
 964        device->async_task = NULL;
 965    }
 966    /* Disable the card */
 967    sdio_claim_host(device->func);
 968    ret = sdio_disable_func(device->func);
 969    if (ret) {
 970        status = A_ERROR;
 971    } 
 972
 973    if (reset_sdio_on_unload) {
 974        /* reset the SDIO interface.  This is useful in automated testing where the card
 975         * does not need to be removed at the end of the test.  It is expected that the user will 
 976         * also unload/reload the host controller driver to force the bus driver to re-enumerate the slot */
 977        AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uninitialized state \n"));
 978        
 979        /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows access
 980         *        to undefined registers in the range of: 0xF0-0xFF */
 981         
 982        ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3)); 
 983        if (ret) {
 984            status = A_ERROR;
 985            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret));    
 986        }
 987    }
 988
 989    sdio_release_host(device->func);
 990
 991    if (status == A_OK) {
 992        device->is_disabled = TRUE;
 993    }
 994    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDisableFunc\n"));
 995
 996    return status;
 997}
 998
 999static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func)
1000{
1001    struct task_struct* pTask;
1002    const char *taskName = NULL;
1003    int (*taskFunc)(void *) = NULL;
1004    int ret = A_OK;
1005    
1006    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n"));
1007    device = getHifDevice(func);
1008
1009    if (device->is_disabled) {
1010       /* enable the SDIO function */
1011        sdio_claim_host(func);
1012
1013        if ((device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_BASE) {
1014            /* enable 4-bit ASYNC interrupt on AR6003 or later devices */
1015            ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
1016            if (ret) {
1017                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret));
1018                sdio_release_host(func);
1019                return A_ERROR;
1020            }
1021            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n"));
1022        }
1023        /* give us some time to enable, in ms */
1024        func->enable_timeout = 100;
1025        ret = sdio_enable_func(func);
1026        if (ret) {
1027            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n",
1028                                          __FUNCTION__, ret));
1029            sdio_release_host(func);
1030            return A_ERROR;
1031        }
1032        ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
1033        sdio_release_host(func);
1034        if (ret) {
1035            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x  AR6K: 0x%X\n",
1036                                          __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret));
1037            return A_ERROR;
1038        }
1039        device->is_disabled = FALSE;
1040        /* create async I/O thread */
1041        if (!device->async_task) {
1042            device->async_shutdown = 0;
1043            device->async_task = kthread_create(async_task,
1044                                           (void *)device,
1045                                           "AR6K Async");
1046           if (IS_ERR(device->async_task)) {
1047               AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__));
1048                return A_ERROR;
1049           }
1050           AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n"));
1051           wake_up_process(device->async_task );    
1052        }
1053    }
1054
1055    if (!device->claimedContext) {
1056        taskFunc = startup_task;
1057        taskName = "AR6K startup";
1058        ret = A_OK;
1059#if defined(CONFIG_PM)
1060    } else {
1061        taskFunc = enable_task;
1062        taskName = "AR6K enable";
1063        ret = A_PENDING;
1064#endif /* CONFIG_PM */
1065    }
1066    /* create resume thread */
1067    pTask = kthread_create(taskFunc, (void *)device, taskName);
1068    if (IS_ERR(pTask)) {
1069        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__));
1070        return A_ERROR;
1071    }
1072    wake_up_process(pTask);
1073    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n"));
1074
1075    /* task will call the enable func, indicate pending */
1076    return ret;
1077}
1078
1079#if defined(CONFIG_PM)
1080static int hifDeviceSuspend(struct device *dev)
1081{
1082    struct sdio_func *func=dev_to_sdio_func(dev);
1083    A_STATUS status = A_OK;
1084    HIF_DEVICE *device;   
1085
1086    device = getHifDevice(func);
1087    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n"));
1088    if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) {
1089        device->is_suspend = TRUE; /* set true first for PowerStateChangeNotify(..) */
1090        status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext);
1091        if (status != A_OK) {
1092            device->is_suspend = FALSE;
1093        }
1094    }
1095    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n"));
1096
1097    switch (status) {
1098    case A_OK:
1099        return 0;
1100    case A_EBUSY:
1101        return -EBUSY; /* Hack for kernel in order to support deep sleep and wow */
1102    default:
1103        return -1;
1104    }
1105}
1106
1107static int hifDeviceResume(struct device *dev)
1108{
1109    struct sdio_func *func=dev_to_sdio_func(dev);
1110    A_STATUS status = A_OK;
1111    HIF_DEVICE *device;   
1112
1113    device = getHifDevice(func);
1114    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n"));
1115    if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) {
1116        status = osdrvCallbacks.deviceResumeHandler(device->claimedContext);
1117        if (status == A_OK) {
1118            device->is_suspend = FALSE;
1119        }
1120    }
1121    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n"));
1122
1123    return A_SUCCESS(status) ? 0 : status;
1124}
1125#endif /* CONFIG_PM */
1126
1127static void hifDeviceRemoved(struct sdio_func *func)
1128{
1129    A_STATUS status = A_OK;
1130    HIF_DEVICE *device;
1131    AR_DEBUG_ASSERT(func != NULL);
1132
1133    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n"));
1134    device = getHifDevice(func);
1135    if (device->claimedContext != NULL) {
1136        status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device);
1137    }
1138
1139    if (device->is_disabled) {
1140        device->is_disabled = FALSE;
1141    } else {
1142        status = hifDisableFunc(device, func);
1143    }
1144    CleanupHIFScatterResources(device);
1145     
1146    delHifDevice(device);
1147    AR_DEBUG_ASSERT(status == A_OK);
1148    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n"));
1149}
1150
1151/*
1152 * This should be moved to AR6K HTC layer.
1153 */
1154A_STATUS hifWaitForPendingRecv(HIF_DEVICE *device)
1155{
1156    A_INT32 cnt = 10;
1157    A_UINT8 host_int_status;
1158    A_STATUS status = A_OK;
1159
1160    do {                            
1161        while (atomic_read(&device->irqHandling)) {
1162                /* wait until irq handler finished all the jobs */
1163                        schedule_timeout(HZ/10);
1164            }
1165                /* check if there is any pending irq due to force done */
1166                host_int_status = 0;
1167            status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS,
1168                                    (A_UINT8 *)&host_int_status, sizeof(host_int_status),
1169                                     HIF_RD_SYNC_BYTE_INC, NULL);
1170            host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)) : 0;
1171                if (host_int_status) {
1172                schedule(); /* schedule for next dsrHandler */
1173                }
1174        } while (host_int_status && --cnt > 0);
1175
1176    if (host_int_status && cnt == 0) {
1177         AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
1178                            ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__));
1179     }
1180
1181    return A_OK;
1182}
1183    
1184
1185static HIF_DEVICE *
1186addHifDevice(struct sdio_func *func)
1187{
1188    HIF_DEVICE *hifdevice;
1189    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n"));
1190    AR_DEBUG_ASSERT(func != NULL);
1191    hifdevice = kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL);
1192    AR_DEBUG_ASSERT(hifdevice != NULL);
1193#if HIF_USE_DMA_BOUNCE_BUFFER
1194    hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
1195    AR_DEBUG_ASSERT(hifdevice->dma_buffer != NULL);
1196#endif
1197    hifdevice->func = func;
1198    hifdevice->powerConfig = HIF_DEVICE_POWER_UP;
1199    sdio_set_drvdata(func, hifdevice);
1200    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice; 0x%p\n", hifdevice));
1201    return hifdevice;
1202}
1203
1204static HIF_DEVICE *
1205getHifDevice(struct sdio_func *func)
1206{
1207    AR_DEBUG_ASSERT(func != NULL);
1208    return (HIF_DEVICE *)sdio_get_drvdata(func);
1209}
1210
1211static void
1212delHifDevice(HIF_DEVICE * device)
1213{
1214    AR_DEBUG_ASSERT(device!= NULL);
1215    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: delHifDevice; 0x%p\n", device));
1216    if (device->dma_buffer != NULL) {
1217        kfree(device->dma_buffer);
1218    }
1219    kfree(device);
1220}
1221
1222static void ResetAllCards(void)
1223{
1224}
1225
1226void HIFClaimDevice(HIF_DEVICE  *device, void *context)
1227{
1228    device->claimedContext = context;
1229}
1230
1231void HIFReleaseDevice(HIF_DEVICE  *device)
1232{
1233    device->claimedContext = NULL;
1234}
1235
1236A_STATUS HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks)
1237{
1238    if (device->htcCallbacks.context != NULL) {
1239            /* already in use! */
1240        return A_ERROR;
1241    }
1242    device->htcCallbacks = *callbacks;
1243    return A_OK;
1244}
1245
1246void HIFDetachHTC(HIF_DEVICE *device)
1247{
1248    A_MEMZERO(&device->htcCallbacks,sizeof(device->htcCallbacks));
1249}
1250
1251#define SDIO_SET_CMD52_ARG(arg,rw,func,raw,address,writedata) \
1252    (arg) = (((rw) & 1) << 31)           | \
1253            (((func) & 0x7) << 28)       | \
1254            (((raw) & 1) << 27)          | \
1255            (1 << 26)                    | \
1256            (((address) & 0x1FFFF) << 9) | \
1257            (1 << 8)                     | \
1258            ((writedata) & 0xFF)
1259            
1260#define SDIO_SET_CMD52_READ_ARG(arg,func,address) \
1261    SDIO_SET_CMD52_ARG(arg,0,(func),0,address,0x00)
1262#define SDIO_SET_CMD52_WRITE_ARG(arg,func,address,value) \
1263    SDIO_SET_CMD52_ARG(arg,1,(func),0,address,value)
1264    
1265static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte)
1266{
1267    struct mmc_command ioCmd;
1268    unsigned long      arg;
1269    
1270    memset(&ioCmd,0,sizeof(ioCmd));
1271    SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte);
1272    ioCmd.opcode = SD_IO_RW_DIRECT;
1273    ioCmd.arg = arg;
1274    ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
1275    
1276    return mmc_wait_for_cmd(card->host, &ioCmd, 0);
1277}
1278
1279static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte)
1280{
1281    struct mmc_command ioCmd;
1282    unsigned long      arg;
1283    A_INT32 err;
1284    
1285    memset(&ioCmd,0,sizeof(ioCmd));
1286    SDIO_SET_CMD52_READ_ARG(arg,0,address);
1287    ioCmd.opcode = SD_IO_RW_DIRECT;
1288    ioCmd.arg = arg;
1289    ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
1290
1291    err = mmc_wait_for_cmd(card->host, &ioCmd, 0);
1292
1293    if ((!err) && (byte)) {
1294        *byte =  ioCmd.resp[0] & 0xFF;
1295    }
1296
1297    return err;
1298}
1299