aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/files-2.6.30/drivers/ar6000/hif/hif.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/files-2.6.30/drivers/ar6000/hif/hif.c')
-rw-r--r--target/linux/s3c24xx/files-2.6.30/drivers/ar6000/hif/hif.c824
1 files changed, 0 insertions, 824 deletions
diff --git a/target/linux/s3c24xx/files-2.6.30/drivers/ar6000/hif/hif.c b/target/linux/s3c24xx/files-2.6.30/drivers/ar6000/hif/hif.c
deleted file mode 100644
index d04486c35b..0000000000
--- a/target/linux/s3c24xx/files-2.6.30/drivers/ar6000/hif/hif.c
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
- * @file: hif.c
- *
- * @abstract: HIF layer reference implementation for Atheros SDIO stack
- *
- * @notice: Copyright (c) 2004-2006 Atheros Communications Inc.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- *
- *
- */
-
-#include "hif_internal.h"
-
-/* ------ Static Variables ------ */
-
-/* ------ Global Variable Declarations ------- */
-SD_PNP_INFO Ids[] = {
- {
- .SDIO_ManufacturerID = MANUFACTURER_ID_AR6001_BASE | 0xB,
- .SDIO_ManufacturerCode = MANUFACTURER_CODE,
- .SDIO_FunctionClass = FUNCTION_CLASS,
- .SDIO_FunctionNo = 1
- },
- {
- .SDIO_ManufacturerID = MANUFACTURER_ID_AR6001_BASE | 0xA,
- .SDIO_ManufacturerCode = MANUFACTURER_CODE,
- .SDIO_FunctionClass = FUNCTION_CLASS,
- .SDIO_FunctionNo = 1
- },
- {
- .SDIO_ManufacturerID = MANUFACTURER_ID_AR6001_BASE | 0x9,
- .SDIO_ManufacturerCode = MANUFACTURER_CODE,
- .SDIO_FunctionClass = FUNCTION_CLASS,
- .SDIO_FunctionNo = 1
- },
- {
- .SDIO_ManufacturerID = MANUFACTURER_ID_AR6001_BASE | 0x8,
- .SDIO_ManufacturerCode = MANUFACTURER_CODE,
- .SDIO_FunctionClass = FUNCTION_CLASS,
- .SDIO_FunctionNo = 1
- },
- {
- .SDIO_ManufacturerID = MANUFACTURER_ID_AR6002_BASE | 0x0,
- .SDIO_ManufacturerCode = MANUFACTURER_CODE,
- .SDIO_FunctionClass = FUNCTION_CLASS,
- .SDIO_FunctionNo = 1
- },
- {
- .SDIO_ManufacturerID = MANUFACTURER_ID_AR6002_BASE | 0x1,
- .SDIO_ManufacturerCode = MANUFACTURER_CODE,
- .SDIO_FunctionClass = FUNCTION_CLASS,
- .SDIO_FunctionNo = 1
- },
- {
- } //list is null termintaed
-};
-
-TARGET_FUNCTION_CONTEXT FunctionContext = {
- .function.Version = CT_SDIO_STACK_VERSION_CODE,
- .function.pName = "sdio_wlan",
- .function.MaxDevices = 1,
- .function.NumDevices = 0,
- .function.pIds = Ids,
- .function.pProbe = hifDeviceInserted,
- .function.pRemove = hifDeviceRemoved,
- .function.pSuspend = NULL,
- .function.pResume = NULL,
- .function.pWake = NULL,
- .function.pContext = &FunctionContext,
-};
-
-HIF_DEVICE hifDevice[HIF_MAX_DEVICES];
-HTC_CALLBACKS htcCallbacks;
-BUS_REQUEST busRequest[BUS_REQUEST_MAX_NUM];
-static BUS_REQUEST *s_busRequestFreeQueue = NULL;
-OS_CRITICALSECTION lock;
-extern A_UINT32 onebitmode;
-extern A_UINT32 busspeedlow;
-
-#ifdef DEBUG
-extern A_UINT32 debughif;
-#define ATH_DEBUG_ERROR 1
-#define ATH_DEBUG_WARN 2
-#define ATH_DEBUG_TRACE 3
-#define _AR_DEBUG_PRINTX_ARG(arg...) arg
-#define AR_DEBUG_PRINTF(lvl, args)\
- {if (lvl <= debughif)\
- A_PRINTF(KERN_ALERT _AR_DEBUG_PRINTX_ARG args);\
- }
-#else
-#define AR_DEBUG_PRINTF(lvl, args)
-#endif
-
-static BUS_REQUEST *hifAllocateBusRequest(void);
-static void hifFreeBusRequest(BUS_REQUEST *busrequest);
-static THREAD_RETURN insert_helper_func(POSKERNEL_HELPER pHelper);
-static void ResetAllCards(void);
-
-/* ------ Functions ------ */
-int HIFInit(HTC_CALLBACKS *callbacks)
-{
- SDIO_STATUS status;
- DBG_ASSERT(callbacks != NULL);
-
- /* Store the callback and event handlers */
- htcCallbacks.deviceInsertedHandler = callbacks->deviceInsertedHandler;
- htcCallbacks.deviceRemovedHandler = callbacks->deviceRemovedHandler;
- htcCallbacks.deviceSuspendHandler = callbacks->deviceSuspendHandler;
- htcCallbacks.deviceResumeHandler = callbacks->deviceResumeHandler;
- htcCallbacks.deviceWakeupHandler = callbacks->deviceWakeupHandler;
- htcCallbacks.rwCompletionHandler = callbacks->rwCompletionHandler;
- htcCallbacks.dsrHandler = callbacks->dsrHandler;
-
- CriticalSectionInit(&lock);
-
- /* Register with bus driver core */
- status = SDIO_RegisterFunction(&FunctionContext.function);
- DBG_ASSERT(SDIO_SUCCESS(status));
-
- return(0);
-}
-
-A_STATUS
-HIFReadWrite(HIF_DEVICE *device,
- A_UINT32 address,
- A_UCHAR *buffer,
- A_UINT32 length,
- A_UINT32 request,
- void *context)
-{
- A_UINT8 rw;
- A_UINT8 mode;
- A_UINT8 funcNo;
- A_UINT8 opcode;
- A_UINT16 count;
- SDREQUEST *sdrequest;
- SDIO_STATUS sdiostatus;
- BUS_REQUEST *busrequest;
- A_STATUS status = A_OK;
-
- DBG_ASSERT(device != NULL);
- DBG_ASSERT(device->handle != NULL);
-
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device: %p\n", device));
-
- do {
- busrequest = hifAllocateBusRequest();
- if (busrequest == NULL) {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF Unable to allocate bus request\n"));
- status = A_NO_RESOURCE;
- break;
- }
-
- sdrequest = busrequest->request;
- busrequest->context = context;
-
- sdrequest->pDataBuffer = buffer;
- if (request & HIF_SYNCHRONOUS) {
- sdrequest->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | SDREQ_FLAGS_DATA_TRANS;
- sdrequest->pCompleteContext = NULL;
- sdrequest->pCompletion = NULL;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Execution mode: Synchronous\n"));
- } else if (request & HIF_ASYNCHRONOUS) {
- sdrequest->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | SDREQ_FLAGS_DATA_TRANS |
- SDREQ_FLAGS_TRANS_ASYNC;
- sdrequest->pCompleteContext = busrequest;
- sdrequest->pCompletion = hifRWCompletionHandler;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Execution mode: Asynchronous\n"));
- } else {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Invalid execution mode: 0x%08x\n", request));
- status = A_EINVAL;
- break;
- }
-
- if (request & HIF_EXTENDED_IO) {
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Command type: CMD53\n"));
- sdrequest->Command = CMD53;
- } else {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Invalid command type: 0x%08x\n", request));
- status = A_EINVAL;
- break;
- }
-
- if (request & HIF_BLOCK_BASIS) {
- mode = CMD53_BLOCK_BASIS;
- sdrequest->BlockLen = HIF_MBOX_BLOCK_SIZE;
- sdrequest->BlockCount = length / HIF_MBOX_BLOCK_SIZE;
- count = sdrequest->BlockCount;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
- ("Block mode (BlockLen: %d, BlockCount: %d)\n",
- sdrequest->BlockLen, sdrequest->BlockCount));
- } else if (request & HIF_BYTE_BASIS) {
- mode = CMD53_BYTE_BASIS;
- sdrequest->BlockLen = length;
- sdrequest->BlockCount = 1;
- count = sdrequest->BlockLen;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
- ("Byte mode (BlockLen: %d, BlockCount: %d)\n",
- sdrequest->BlockLen, sdrequest->BlockCount));
- } else {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Invalid data mode: 0x%08x\n", request));
- status = A_EINVAL;
- break;
- }
-
-#if 0
- /* useful for checking register accesses */
- if (length & 0x3) {
- A_PRINTF(KERN_ALERT"HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n",
- request & HIF_WRITE ? "write":"read", address, length);
- }
-#endif
-
- if ((address >= HIF_MBOX_START_ADDR(0)) &&
- (address <= HIF_MBOX_END_ADDR(3)))
- {
-
- DBG_ASSERT(length <= HIF_MBOX_WIDTH);
-
- /*
- * Mailbox write. Adjust the address so that the last byte
- * falls on the EOM address.
- */
- address += (HIF_MBOX_WIDTH - length);
- }
-
-
-
- if (request & HIF_WRITE) {
- rw = CMD53_WRITE;
- sdrequest->Flags |= SDREQ_FLAGS_DATA_WRITE;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Direction: Write\n"));
- } else if (request & HIF_READ) {
- rw = CMD53_READ;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Direction: Read\n"));
- } else {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Invalid direction: 0x%08x\n", request));
- status = A_EINVAL;
- break;
- }
-
- if (request & HIF_FIXED_ADDRESS) {
- opcode = CMD53_FIXED_ADDRESS;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Address mode: Fixed\n"));
- } else if (request & HIF_INCREMENTAL_ADDRESS) {
- opcode = CMD53_INCR_ADDRESS;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Address mode: Incremental\n"));
- } else {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Invalid address mode: 0x%08x\n", request));
- status = A_EINVAL;
- break;
- }
-
- funcNo = SDDEVICE_GET_SDIO_FUNCNO(device->handle);
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Function number: %d\n", funcNo));
- SDIO_SET_CMD53_ARG(sdrequest->Argument, rw, funcNo,
- mode, opcode, address, count);
-
- /* Send the command out */
- sdiostatus = SDDEVICE_CALL_REQUEST_FUNC(device->handle, sdrequest);
-
- if (!SDIO_SUCCESS(sdiostatus)) {
- status = A_ERROR;
- }
-
- } while (FALSE);
-
- if (A_FAILED(status) || (request & HIF_SYNCHRONOUS)) {
- if (busrequest != NULL) {
- hifFreeBusRequest(busrequest);
- }
- }
-
- if (A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) {
- /* call back async handler on failure */
- htcCallbacks.rwCompletionHandler(context, status);
- }
-
- return status;
-}
-
-A_STATUS
-HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode,
- void *config, A_UINT32 configLen)
-{
- A_UINT32 count;
-
- switch(opcode) {
- case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
- ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
- ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
- ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
- ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
- break;
-
- case HIF_DEVICE_GET_MBOX_ADDR:
- for (count = 0; count < 4; count ++) {
- ((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count);
- }
- break;
- case HIF_DEVICE_GET_IRQ_PROC_MODE:
- /* the SDIO stack allows the interrupts to be processed either way, ASYNC or SYNC */
- *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_ASYNC_SYNC;
- break;
- default:
- AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
- ("Unsupported configuration opcode: %d\n", opcode));
- return A_ERROR;
- }
-
- return A_OK;
-}
-
-void
-HIFShutDownDevice(HIF_DEVICE *device)
-{
- A_UINT8 data;
- A_UINT32 count;
- SDIO_STATUS status;
- SDCONFIG_BUS_MODE_DATA busSettings;
- SDCONFIG_FUNC_ENABLE_DISABLE_DATA fData;
-
- if (device != NULL) {
- DBG_ASSERT(device->handle != NULL);
-
- /* Remove the allocated current if any */
- status = SDLIB_IssueConfig(device->handle,
- SDCONFIG_FUNC_FREE_SLOT_CURRENT, NULL, 0);
- DBG_ASSERT(SDIO_SUCCESS(status));
-
- /* Disable the card */
- fData.EnableFlags = SDCONFIG_DISABLE_FUNC;
- fData.TimeOut = 1;
- status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_ENABLE_DISABLE,
- &fData, sizeof(fData));
- DBG_ASSERT(SDIO_SUCCESS(status));
-
- /* Perform a soft I/O reset */
- data = SDIO_IO_RESET;
- status = SDLIB_IssueCMD52(device->handle, 0, SDIO_IO_ABORT_REG,
- &data, 1, 1);
- DBG_ASSERT(SDIO_SUCCESS(status));
-
- /*
- * WAR - Codetelligence driver does not seem to shutdown correctly in 1
- * bit mode. By default it configures the HC in the 4 bit. Its later in
- * our driver that we switch to 1 bit mode. If we try to shutdown, the
- * driver hangs so we revert to 4 bit mode, to be transparent to the
- * underlying bus driver.
- */
- if (onebitmode) {
- ZERO_OBJECT(busSettings);
- busSettings.BusModeFlags = SDDEVICE_GET_BUSMODE_FLAGS(device->handle);
- SDCONFIG_SET_BUS_WIDTH(busSettings.BusModeFlags,
- SDCONFIG_BUS_WIDTH_4_BIT);
-
- /* Issue config request to change the bus width to 4 bit */
- status = SDLIB_IssueConfig(device->handle, SDCONFIG_BUS_MODE_CTRL,
- &busSettings,
- sizeof(SDCONFIG_BUS_MODE_DATA));
- DBG_ASSERT(SDIO_SUCCESS(status));
- }
-
- /* Free the bus requests */
- for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) {
- SDDeviceFreeRequest(device->handle, busRequest[count].request);
- }
- /* Clean up the queue */
- s_busRequestFreeQueue = NULL;
- } else {
- /* since we are unloading the driver anyways, reset all cards in case the SDIO card
- * is externally powered and we are unloading the SDIO stack. This avoids the problem when
- * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already
- * enumerated */
- ResetAllCards();
- /* Unregister with bus driver core */
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
- ("Unregistering with the bus driver\n"));
- status = SDIO_UnregisterFunction(&FunctionContext.function);
- DBG_ASSERT(SDIO_SUCCESS(status));
- }
-}
-
-void
-hifRWCompletionHandler(SDREQUEST *request)
-{
- A_STATUS status;
- void *context;
- BUS_REQUEST *busrequest;
-
- if (SDIO_SUCCESS(request->Status)) {
- status = A_OK;
- } else {
- status = A_ERROR;
- }
-
- DBG_ASSERT(status == A_OK);
- busrequest = (BUS_REQUEST *) request->pCompleteContext;
- context = (void *) busrequest->context;
- /* free the request before calling the callback, in case the
- * callback submits another request, this guarantees that
- * there is at least 1 free request available everytime the callback
- * is invoked */
- hifFreeBusRequest(busrequest);
- htcCallbacks.rwCompletionHandler(context, status);
-}
-
-void
-hifIRQHandler(void *context)
-{
- A_STATUS status;
- HIF_DEVICE *device;
-
- device = (HIF_DEVICE *)context;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device: %p\n", device));
- status = htcCallbacks.dsrHandler(device->htc_handle);
- DBG_ASSERT(status == A_OK);
-}
-
-BOOL
-hifDeviceInserted(SDFUNCTION *function, SDDEVICE *handle)
-{
- BOOL enabled;
- A_UINT8 data;
- A_UINT32 count;
- HIF_DEVICE *device;
- SDIO_STATUS status;
- A_UINT16 maxBlocks;
- A_UINT16 maxBlockSize;
- SDCONFIG_BUS_MODE_DATA busSettings;
- SDCONFIG_FUNC_ENABLE_DISABLE_DATA fData;
- TARGET_FUNCTION_CONTEXT *functionContext;
- SDCONFIG_FUNC_SLOT_CURRENT_DATA slotCurrent;
- SD_BUSCLOCK_RATE currentBusClock;
-
- DBG_ASSERT(function != NULL);
- DBG_ASSERT(handle != NULL);
-
- device = addHifDevice(handle);
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device: %p\n", device));
- functionContext = (TARGET_FUNCTION_CONTEXT *)function->pContext;
-
- /*
- * Issue commands to get the manufacturer ID and stuff and compare it
- * against the rev Id derived from the ID registered during the
- * initialization process. Report the device only in the case there
- * is a match. In the case od SDIO, the bus driver has already queried
- * these details so we just need to use their data structures to get the
- * relevant values. Infact, the driver has already matched it against
- * the Ids that we registered with it so we dont need to the step here.
- */
-
- /* Configure the SDIO Bus Width */
- if (onebitmode) {
- data = SDIO_BUS_WIDTH_1_BIT;
- status = SDLIB_IssueCMD52(handle, 0, SDIO_BUS_IF_REG, &data, 1, 1);
- if (!SDIO_SUCCESS(status)) {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Unable to set the bus width to 1 bit\n"));
- return FALSE;
- }
- }
-
- /* Get current bus flags */
- ZERO_OBJECT(busSettings);
-
- busSettings.BusModeFlags = SDDEVICE_GET_BUSMODE_FLAGS(handle);
- if (onebitmode) {
- SDCONFIG_SET_BUS_WIDTH(busSettings.BusModeFlags,
- SDCONFIG_BUS_WIDTH_1_BIT);
- }
-
- /* get the current operating clock, the bus driver sets us up based
- * on what our CIS reports and what the host controller can handle
- * we can use this to determine whether we want to drop our clock rate
- * down */
- currentBusClock = SDDEVICE_GET_OPER_CLOCK(handle);
- busSettings.ClockRate = currentBusClock;
-
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
- ("HIF currently running at: %d \n",currentBusClock));
-
- /* see if HIF wants to run at a lower clock speed, we may already be
- * at that lower clock speed */
- if (currentBusClock > (SDIO_CLOCK_FREQUENCY_DEFAULT >> busspeedlow)) {
- busSettings.ClockRate = SDIO_CLOCK_FREQUENCY_DEFAULT >> busspeedlow;
- AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
- ("HIF overriding clock to %d \n",busSettings.ClockRate));
- }
-
- /* Issue config request to override clock rate */
- status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_CHANGE_BUS_MODE, &busSettings,
- sizeof(SDCONFIG_BUS_MODE_DATA));
- if (!SDIO_SUCCESS(status)) {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Unable to configure the host clock\n"));
- return FALSE;
- } else {
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
- ("Configured clock: %d, Maximum clock: %d\n",
- busSettings.ActualClockRate,
- SDDEVICE_GET_MAX_CLOCK(handle)));
- }
-
- /*
- * Check if the target supports block mode. This result of this check
- * can be used to implement the HIFReadWrite API.
- */
- if (SDDEVICE_GET_SDIO_FUNC_MAXBLKSIZE(handle)) {
- /* Limit block size to operational block limit or card function
- capability */
- maxBlockSize = min(SDDEVICE_GET_OPER_BLOCK_LEN(handle),
- SDDEVICE_GET_SDIO_FUNC_MAXBLKSIZE(handle));
-
- /* check if the card support multi-block transfers */
- if (!(SDDEVICE_GET_SDIOCARD_CAPS(handle) & SDIO_CAPS_MULTI_BLOCK)) {
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Byte basis only\n"));
-
- /* Limit block size to max byte basis */
- maxBlockSize = min(maxBlockSize,
- (A_UINT16)SDIO_MAX_LENGTH_BYTE_BASIS);
- maxBlocks = 1;
- } else {
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Multi-block capable\n"));
- maxBlocks = SDDEVICE_GET_OPER_BLOCKS(handle);
- status = SDLIB_SetFunctionBlockSize(handle, HIF_MBOX_BLOCK_SIZE);
- if (!SDIO_SUCCESS(status)) {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Failed to set block size. Err:%d\n", status));
- return FALSE;
- }
- }
-
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
- ("Bytes Per Block: %d bytes, Block Count:%d \n",
- maxBlockSize, maxBlocks));
- } else {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Function does not support Block Mode!\n"));
- return FALSE;
- }
-
- /* Allocate the slot current */
- status = SDLIB_GetDefaultOpCurrent(handle, &slotCurrent.SlotCurrent);
- if (SDIO_SUCCESS(status)) {
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Allocating Slot current: %d mA\n",
- slotCurrent.SlotCurrent));
- status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ALLOC_SLOT_CURRENT,
- &slotCurrent, sizeof(slotCurrent));
- if (!SDIO_SUCCESS(status)) {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Failed to allocate slot current %d\n", status));
- return FALSE;
- }
- }
-
- /* Enable the dragon function */
- count = 0;
- enabled = FALSE;
- fData.TimeOut = 1;
- fData.EnableFlags = SDCONFIG_ENABLE_FUNC;
- while ((count++ < SDWLAN_ENABLE_DISABLE_TIMEOUT) && !enabled)
- {
- /* Enable dragon */
- status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ENABLE_DISABLE,
- &fData, sizeof(fData));
- if (!SDIO_SUCCESS(status)) {
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
- ("Attempting to enable the card again\n"));
- continue;
- }
-
- /* Mark the status as enabled */
- enabled = TRUE;
- }
-
- /* Check if we were succesful in enabling the target */
- if (!enabled) {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
- ("Failed to communicate with the target\n"));
- return FALSE;
- }
-
- /* Allocate the bus requests to be used later */
- A_MEMZERO(busRequest, sizeof(busRequest));
- for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) {
- if ((busRequest[count].request = SDDeviceAllocRequest(handle)) == NULL){
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Unable to allocate memory\n"));
- /* TODO: Free the memory that has already been allocated */
- return FALSE;
- }
- hifFreeBusRequest(&busRequest[count]);
-
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
- ("0x%08x = busRequest[%d].request = 0x%08x\n",
- (unsigned int) &busRequest[count], count,
- (unsigned int) busRequest[count].request));
- }
-
- /* Schedule a worker to handle device inserted, this is a temporary workaround
- * to fix a deadlock if the device fails to intialize in the insertion handler
- * The failure causes the instance to shutdown the HIF layer and unregister the
- * function driver within the busdriver probe context which can deadlock
- *
- * NOTE: we cannot use the default work queue because that would block
- * SD bus request processing for all synchronous I/O. We must use a kernel
- * thread that is creating using the helper library.
- * */
-
- if (SDIO_SUCCESS(SDLIB_OSCreateHelper(&device->insert_helper,
- insert_helper_func,
- device))) {
- device->helper_started = TRUE;
- }
-
- return TRUE;
-}
-
-static THREAD_RETURN insert_helper_func(POSKERNEL_HELPER pHelper)
-{
-
- /*
- * Adding a wait of around a second before we issue the very first
- * command to dragon. During the process of loading/unloading the
- * driver repeatedly it was observed that we get a data timeout
- * while accessing function 1 registers in the chip. The theory at
- * this point is that some initialization delay in dragon is
- * causing the SDIO state in dragon core to be not ready even after
- * the ready bit indicates that function 1 is ready. Accomodating
- * for this behavior by adding some delay in the driver before it
- * issues the first command after switching on dragon. Need to
- * investigate this a bit more - TODO
- */
-
- A_MDELAY(1000);
- /* Inform HTC */
- if ((htcCallbacks.deviceInsertedHandler(SD_GET_OS_HELPER_CONTEXT(pHelper))) != A_OK) {
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device rejected\n"));
- }
-
- return 0;
-}
-
-void
-HIFAckInterrupt(HIF_DEVICE *device)
-{
- SDIO_STATUS status;
- DBG_ASSERT(device != NULL);
- DBG_ASSERT(device->handle != NULL);
-
- /* Acknowledge our function IRQ */
- status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_ACK_IRQ,
- NULL, 0);
- DBG_ASSERT(SDIO_SUCCESS(status));
-}
-
-void
-HIFUnMaskInterrupt(HIF_DEVICE *device)
-{
- SDIO_STATUS status;
-
- DBG_ASSERT(device != NULL);
- DBG_ASSERT(device->handle != NULL);
-
- /* Register the IRQ Handler */
- SDDEVICE_SET_IRQ_HANDLER(device->handle, hifIRQHandler, device);
-
- /* Unmask our function IRQ */
- status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_UNMASK_IRQ,
- NULL, 0);
- DBG_ASSERT(SDIO_SUCCESS(status));
-}
-
-void HIFMaskInterrupt(HIF_DEVICE *device)
-{
- SDIO_STATUS status;
- DBG_ASSERT(device != NULL);
- DBG_ASSERT(device->handle != NULL);
-
- /* Mask our function IRQ */
- status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_MASK_IRQ,
- NULL, 0);
- DBG_ASSERT(SDIO_SUCCESS(status));
-
- /* Unregister the IRQ Handler */
- SDDEVICE_SET_IRQ_HANDLER(device->handle, NULL, NULL);
-}
-
-static BUS_REQUEST *hifAllocateBusRequest(void)
-{
- BUS_REQUEST *busrequest;
-
- /* Acquire lock */
- CriticalSectionAcquire(&lock);
-
- /* Remove first in list */
- if((busrequest = s_busRequestFreeQueue) != NULL)
- {
- s_busRequestFreeQueue = busrequest->next;
- }
-
- /* Release lock */
- CriticalSectionRelease(&lock);
-
- return busrequest;
-}
-
-static void
-hifFreeBusRequest(BUS_REQUEST *busrequest)
-{
- DBG_ASSERT(busrequest != NULL);
-
- /* Acquire lock */
- CriticalSectionAcquire(&lock);
-
- /* Insert first in list */
- busrequest->next = s_busRequestFreeQueue;
- s_busRequestFreeQueue = busrequest;
-
- /* Release lock */
- CriticalSectionRelease(&lock);
-}
-
-void
-hifDeviceRemoved(SDFUNCTION *function, SDDEVICE *handle)
-{
- A_STATUS status;
- HIF_DEVICE *device;
- DBG_ASSERT(function != NULL);
- DBG_ASSERT(handle != NULL);
-
- device = getHifDevice(handle);
- status = htcCallbacks.deviceRemovedHandler(device->htc_handle, A_OK);
-
- /* cleanup the helper thread */
- if (device->helper_started) {
- SDLIB_OSDeleteHelper(&device->insert_helper);
- device->helper_started = FALSE;
- }
-
- delHifDevice(handle);
- DBG_ASSERT(status == A_OK);
-}
-
-HIF_DEVICE *
-addHifDevice(SDDEVICE *handle)
-{
- DBG_ASSERT(handle != NULL);
- hifDevice[0].handle = handle;
- return &hifDevice[0];
-}
-
-HIF_DEVICE *
-getHifDevice(SDDEVICE *handle)
-{
- DBG_ASSERT(handle != NULL);
- return &hifDevice[0];
-}
-
-void
-delHifDevice(SDDEVICE *handle)
-{
- DBG_ASSERT(handle != NULL);
- hifDevice[0].handle = NULL;
-}
-
-struct device*
-HIFGetOSDevice(HIF_DEVICE *device)
-{
- return &device->handle->Device->dev;
-}
-
-static void ResetAllCards(void)
-{
- UINT8 data;
- SDIO_STATUS status;
- int i;
-
- data = SDIO_IO_RESET;
-
- /* set the I/O CARD reset bit:
- * NOTE: we are exploiting a "feature" of the SDIO core that resets the core when you
- * set the RES bit in the SDIO_IO_ABORT register. This bit however "normally" resets the
- * I/O functions leaving the SDIO core in the same state (as per SDIO spec).
- * In this design, this reset can be used to reset the SDIO core itself */
- for (i = 0; i < HIF_MAX_DEVICES; i++) {
- if (hifDevice[i].handle != NULL) {
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
- ("Issuing I/O Card reset for instance: %d \n",i));
- /* set the I/O Card reset bit */
- status = SDLIB_IssueCMD52(hifDevice[i].handle,
- 0, /* function 0 space */
- SDIO_IO_ABORT_REG,
- &data,
- 1, /* 1 byte */
- TRUE); /* write */
- }
- }
-
-}
-
-void HIFSetHandle(void *hif_handle, void *handle)
-{
- HIF_DEVICE *device = (HIF_DEVICE *) hif_handle;
-
- device->htc_handle = handle;
-
- return;
-}