A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo)
{
    A_STATUS            status = A_ERROR;   
    int                 maxTransferSizePerScatter = MAX_SCATTER_REQ_TRANSFER_SIZE;
    int                 size, i;
    HIF_SCATTER_REQ     *pReq;
    SDREQUEST           *sdrequest;
        
    do {
        
        DetermineScatterMethod(device);
    
        if (device->ScatterMethod == HIF_SCATTER_NONE) {
                /* no scatter support */
            break;    
        }
        
        AR_DEBUG_PRINTF(ATH_DEBUG_INIT,("HIF : Cache Line Size: %d bytes \n",A_GET_CACHE_LINE_BYTES())); 
        
        size = sizeof(HIF_SCATTER_REQ) + 
                    (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM));
       
        for (i = 0; i < MAX_SCATTER_REQUESTS; i++) {    
            
            pReq = A_MALLOC(size);
            if (NULL == pReq) {
                break;    
            }
            A_MEMZERO(pReq, size);
            
                /* save the device instance */
            SET_DEVICE_INFO_SR(pReq, device);
            
                /* allocate a bus request for this scatter request */
            sdrequest = SDDeviceAllocRequest(device->handle);
            if (NULL == sdrequest) {
                A_FREE(pReq);
                break;    
            }
                /* store bus request into private area */
            SET_SDREQUEST_SR(pReq,sdrequest);
            
            status = SetupScatterResource(device,pReq);
            if (A_FAILED(status)) {
                SDDeviceFreeRequest(device->handle, sdrequest);
                A_FREE(pReq); 
                break;       
            }         
               
                /* add it to the free pool */
            FreeScatterReq(device, pReq);
        }
        
        if (i != MAX_SCATTER_REQUESTS) {
            status = A_NO_MEMORY;
            break;    
        }
        
            /* set function pointers */
        pInfo->pAllocateReqFunc = AllocScatterReq;
        pInfo->pFreeReqFunc = FreeScatterReq;
        pInfo->pReadWriteScatterFunc = HifReadWriteScatter;   
        pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ;
        pInfo->MaxTransferSizePerScatterReq = maxTransferSizePerScatter;
     
        status = A_OK;
        
    } while (FALSE);
    
    if (A_FAILED(status)) {
        CleanupHIFScatterResources(device);   
    }
    
    return status;
}
BOOL
hifDeviceInserted(SDFUNCTION *function, SDDEVICE *handle)
{
    A_UINT32 count;
    HIF_DEVICE *device;
    BOOL accepted = FALSE;
    AR_DEBUG_ASSERT(function != NULL);
    AR_DEBUG_ASSERT(handle != NULL);

    do {
        
        device = (HIF_DEVICE *)KernelAlloc(sizeof(HIF_DEVICE));
    
        if (NULL == device) {
            break;    
        }
    
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Device: %p\n", device));
     
        ZERO_POBJECT(device);
        
        CriticalSectionInit(&device->lock);
        device->busrequestfreelist = NULL;
        device->handle = handle;
        device->enabledSpiInts = ATH_SPI_INTR_PKT_AVAIL | ATH_SPI_INTR_CPU_INTR;
            /* set the IRQ Handler which associates the instance with the SDDEVICE */
        SDDEVICE_SET_IRQ_HANDLER(device->handle, hifIRQHandler, device);
    
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Device: %p\n", device));
       
        if (handle->pId[0].CardFlags & CARD_RAW) {
            if (strstr(SDDEVICE_GET_HCDNAME(handle), SDIO_RAW_BD_BASE) == NULL) {
                /* Not supported */
                break;
            }
        }
    
        /* Card identification */
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, 
                        ("SPI card: %s\n", SDDEVICE_GET_HCDNAME(handle)));
    
        /* Version information */
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Stack version: %d.%d\n", 
                                          SDDEVICE_GET_VERSION_MAJOR(handle), 
                                          SDDEVICE_GET_VERSION_MINOR(handle)));
    
        /* Get the maximum block size supported */
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Maximum block length: %d bytes\n",
                        SDDEVICE_GET_MAX_BLOCK_LEN(handle)));
                        
        device->curBlockSize = SDDEVICE_GET_OPER_BLOCK_LEN(handle);
        
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Current block length: %d bytes\n",
                        device->curBlockSize));
    
            /* Allocate the bus requests to be used later */
        for (count = 0; count < BUS_REQUEST_MAX_NUM_TOTAL; count ++) {
            if ((device->busrequestblob[count].request = SDDeviceAllocRequest(handle)) == NULL){
                AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Unable to allocate bus request\n"));
                break;
            }
                /* free to the list */
            hifFreeBusRequest(device, &device->busrequestblob[count]);
        }
        
        if (count != BUS_REQUEST_MAX_NUM_TOTAL) {
            break;   
        }
        
            /* Configure the SPI interface */
        if ((hifConfigureSPI(device)) != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Failed to configure the device\n"));
            break;
        }
    
        /* Inform HTC */
        if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context, (void *)device)) != A_OK) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Device rejected\n"));
            return FALSE;
        }

        accepted = TRUE;
        
    } while (FALSE);
    
    if (!accepted & (device != NULL)) {
        /* cleanup device */
        hifCleanupDevice(device);   
    }
    
    return accepted;
}