/* setup of HIF scatter resources */ A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo) { A_STATUS status = A_ERROR; int i; HIF_SCATTER_REQ_PRIV *pReqPriv; BUS_REQUEST *busrequest; do { /* check if host supports scatter requests and it meets our requirements */ if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n", device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ)); status = A_ENOTSUP; break; } AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HIF-SCATTER Enabled: max scatter req : %d entries: %d \n", MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ)); for (i = 0; i < MAX_SCATTER_REQUESTS; i++) { /* allocate the private request blob */ pReqPriv = (HIF_SCATTER_REQ_PRIV *)A_MALLOC(sizeof(HIF_SCATTER_REQ_PRIV)); if (NULL == pReqPriv) { break; } A_MEMZERO(pReqPriv, sizeof(HIF_SCATTER_REQ_PRIV)); /* save the device instance*/ pReqPriv->device = device; /* allocate the scatter request */ pReqPriv->pHifScatterReq = (HIF_SCATTER_REQ *)A_MALLOC(sizeof(HIF_SCATTER_REQ) + (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM))); if (NULL == pReqPriv->pHifScatterReq) { A_FREE(pReqPriv); break; } /* just zero the main part of the scatter request */ A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(HIF_SCATTER_REQ)); /* back pointer to the private struct */ pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv; /* allocate a bus request for this scatter request */ busrequest = hifAllocateBusRequest(device); if (NULL == busrequest) { A_FREE(pReqPriv->pHifScatterReq); A_FREE(pReqPriv); break; } /* assign the scatter request to this bus request */ busrequest->pScatterReq = pReqPriv; /* point back to the request */ pReqPriv->busrequest = busrequest; /* add it to the scatter pool */ FreeScatterReq(device,pReqPriv->pHifScatterReq); } if (i != MAX_SCATTER_REQUESTS) { status = A_NO_MEMORY; AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : failed to alloc scatter resources !\n")); break; } /* set scatter function pointers */ pInfo->pAllocateReqFunc = AllocScatterReq; pInfo->pFreeReqFunc = FreeScatterReq; pInfo->pReadWriteScatterFunc = HifReadWriteScatter; pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ; pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE; status = A_OK; } while (FALSE); if (A_FAILED(status)) { CleanupHIFScatterResources(device); } return status; }
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; }