diff options
Diffstat (limited to 'drivers/sdio/stack/busdriver/sdio_function.c')
-rw-r--r-- | drivers/sdio/stack/busdriver/sdio_function.c | 715 |
1 files changed, 0 insertions, 715 deletions
diff --git a/drivers/sdio/stack/busdriver/sdio_function.c b/drivers/sdio/stack/busdriver/sdio_function.c deleted file mode 100644 index 78b8e17999a..00000000000 --- a/drivers/sdio/stack/busdriver/sdio_function.c +++ /dev/null @@ -1,715 +0,0 @@ -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -@file: sdio_function.c - -@abstract: OS independent bus driver support for function drivers - -@notes: This file supports the interface between SDIO function drivers and the bus driver. - -@notice: Copyright (c), 2004-2005 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. - * - * Portions of this code were developed with information supplied from the - * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply: - * - * The following conditions apply to the release of the SD simplified specification (�Simplified - * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete - * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided - * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified - * Specification may require a license from the SD Card Association or other third parties. - * Disclaimers: - * The information contained in the Simplified Specification is presented only as a standard - * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any - * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for - * any damages, any infringements of patents or other right of the SD Card Association or any third - * parties, which may result from its use. No license is granted by implication, estoppel or otherwise - * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall - * be construed as an obligation by the SD Card Association to disclose or distribute any technical - * information, know-how or other confidential information to any third party. - * - * - * The initial developers of the original code are Seung Yi and Paul Lever - * - * sdio@atheros.com - * - * - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -#define MODULE_NAME SDBUSDRIVER -#include <linux/sdio/ctsystem.h> -#include <linux/sdio/sdio_busdriver.h> -#include <linux/sdio/sdio_lib.h> -#include "_busdriver.h" - -static SDIO_STATUS ProbeForDevice(PSDFUNCTION pFunction); - -#ifdef CT_MAN_CODE_CHECK -static UINT16 ManCodeCheck = CT_MAN_CODE_CHECK; -#endif - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @function: Register a function driver with the bus driver. - - @function name: SDIO_RegisterFunction - @prototype: SDIO_STATUS SDIO_RegisterFunction(PSDFUNCTION pFunction) - @category: PD_Reference - @input: pFunction - the function definition structure. - - @output: none - - @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when succesful. - - @notes: Each function driver must register with the bus driver once upon loading. - The calling function must be prepared to receive a Probe callback before - this function returns. This will occur when an perpheral device is already - pluugged in that is supported by this function. - The function driver should unregister itself when exiting. - The bus driver checks for possible function drivers to support a device - in reverse registration order. - - @example: Registering a function driver: - //list of devices supported by this function driver - static SD_PNP_INFO Ids[] = { - {.SDIO_ManufacturerID = 0xaa55, - .SDIO_ManufacturerCode = 0x5555, - .SDIO_FunctionNo = 1}, - {} //list is null termintaed - }; - static GENERIC_FUNCTION_CONTEXT FunctionContext = { - .Function.pName = "sdio_generic", //name of the device - .Function.Version = CT_SDIO_STACK_VERSION_CODE, // set stack version - .Function.MaxDevices = 1, //maximum number of devices supported by this driver - .Function.NumDevices = 0, //current number of devices, always zero to start - .Function.pIds = Ids, //the list of devices supported by this device - .Function.pProbe = Probe, //pointer to the function drivers Probe function - // that will be called when a possibly supported device - // is inserted. - .Function.pRemove = Remove, //pointer to the function drivers Remove function - / that will be called when a device is removed. - .Function.pContext = &FunctionContext, //data value that will be passed into Probe and - // Remove callbacks. - }; - SDIO_STATUS status; - status = SDIO_RegisterFunction(&FunctionContext.Function) - if (!SDIO_SUCCESS(status)) { - ...failed to register - } - - @see also: SDIO_UnregisterFunction - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -SDIO_STATUS _SDIO_RegisterFunction(PSDFUNCTION pFunction) -{ - SDIO_STATUS status = SDIO_STATUS_SUCCESS; - -#ifdef CT_MAN_CODE_CHECK - DBG_PRINT(SDDBG_TRACE, - ("SDIO Bus Driver: _SDIO_RegisterFunction: WARNING, this version is locked to Memory cards and SDIO cards with JEDEC IDs of: 0x%X\n", - ManCodeCheck)); -#else - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: _SDIO_RegisterFunction\n")); -#endif - - DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: Function Driver Stack Version: %d.%d \n", - GET_SDIO_STACK_VERSION_MAJOR(pFunction),GET_SDIO_STACK_VERSION_MINOR(pFunction))); - - if (!CHECK_FUNCTION_DRIVER_VERSION(pFunction)) { - DBG_PRINT(SDDBG_ERROR, - ("SDIO Bus Driver: Function Major Version Mismatch (hcd = %d, bus driver = %d)\n", - GET_SDIO_STACK_VERSION_MAJOR(pFunction), CT_SDIO_STACK_VERSION_MAJOR(g_Version))); - return SDIO_STATUS_INVALID_PARAMETER; - } - - - /* sanity check the driver */ - if ((pFunction == NULL) || - (pFunction->pProbe == NULL) || - (pFunction->pIds == NULL)) { - DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_RegisterFunction, invalid registration data\n")); - return SDIO_STATUS_INVALID_PARAMETER; - } - /* protect the function list and add the function */ - if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->FunctionListSem)))) { - goto cleanup; /* wait interrupted */ - } - SignalInitialize(&pFunction->CleanupReqSig); - SDLIST_INIT(&pFunction->DeviceList); - SDListAdd(&pBusContext->FunctionList, &pFunction->SDList); - if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) { - goto cleanup; /* wait interrupted */ - } - - /* see if we have devices for this new function driver */ - ProbeForDevice(pFunction); - - return status; -cleanup: - DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_RegisterFunction, error exit 0x%X\n", status)); - return status; -} - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @function: Unregister a function driver with the bus driver. - - @function name: SDIO_UnregisterFunction - @prototype: SDIO_STATUS SDIO_UnregisterFunction(PSDFUNCTION pFunction) - @category: PD_Reference - - @input: pFunction - the function definition structure. - - @output: none - - @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when succesful. - - @notes: Each function driver must unregister from the bus driver when the function driver - exits. - A function driver must disconnect from any interrupts before calling this function. - - @example: Unregistering a function driver: - SDIO_UnregisterFunction(&FunctionContext.Function); - - @see also: SDIO_RegisterFunction - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -SDIO_STATUS _SDIO_UnregisterFunction(PSDFUNCTION pFunction) -{ - SDIO_STATUS status = SDIO_STATUS_SUCCESS; - PSDDEVICE pDevice; - - DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: _SDIO_UnregisterFunction\n")); - - /* protect the function list and synchronize with Probe() and Remove()*/ - if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->FunctionListSem)))) { - goto cleanup; /* wait interrupted */ - } - /* remove this function from the function list */ - SDListRemove(&pFunction->SDList); - /* now remove this function as the handler for any of its devices */ - SDITERATE_OVER_LIST_ALLOW_REMOVE(&pFunction->DeviceList, pDevice, SDDEVICE,FuncListLink) { - if (pDevice->pFunction == pFunction) { - /* notify removal */ - NotifyDeviceRemove(pDevice); - } - }SDITERATE_END; - - SignalDelete(&pFunction->CleanupReqSig); - - if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) { - goto cleanup; /* wait interrupted */ - } - DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: _SDIO_UnregisterFunction\n")); - return status; - -cleanup: - DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: _SDIO_UnregisterFunction, error exit 0x%X\n", status)); - return status; -} - -/* documentation headers only for Probe and Remove */ -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @function: This function is called by the Busdriver when a device is inserted that can be supported by this function driver. - - @function name: Probe - @prototype: BOOL (*pProbe)(struct _SDFUNCTION *pFunction, struct _SDDEVICE *pDevice) - @category: PD_Reference - - @input: pFunction - the function definition structure that was passed to Busdriver - via the SDIO_RegisterFunction. - @input: pDevice - the description of the newly inserted device. - - @output: none - - @return: TRUE - this function driver will suport this device - FALSE - this function driver will not support this device - - @notes: The Busdriver calls the Probe function of a function driver to inform it that device is - available for the function driver to control. The function driver should initialize the - device and be pepared to acceopt any interrupts from the device before returning. - - @example: Example of typical Probe function callback: - static BOOL Probe(PSDFUNCTION pFunction, PSDDEVICE pDevice) { - ...get the our context info passed into the SDIO_RegisterFunction - PSDXXX_DRIVER_CONTEXT pFunctionContext = - (PSDXXX_DRIVER_CONTEXT)pFunction->pContext; - SDIO_STATUS status; - //test the identification of this device and ensure we want to support it - // we can test based on class, or use more specific tests on SDIO_ManufacturerID, etc. - if (pDevice->pId[0].SDIO_FunctionClass == XXX) { - DBG_PRINT(SDDBG_TRACE, ("SDIO XXX Function: Probe - card matched (0x%X/0x%X/0x%X)\n", - pDevice->pId[0].SDIO_ManufacturerID, - pDevice->pId[0].SDIO_ManufacturerCode, - pDevice->pId[0].SDIO_FunctionNo)); - ... - - @see also: SDIO_RegisterFunction - @see also: Remove - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -BOOL FilterPnpInfo(PSDDEVICE pDevice) -{ -#ifdef CT_MAN_CODE_CHECK - if (pDevice->pId[0].CardFlags & CARD_SDIO) { - if (pDevice->pId[0].SDIO_ManufacturerCode != ManCodeCheck) { - DBG_PRINT(SDDBG_ERROR, - ("SDIO Card with JEDEC ID:0x%X , not Allowed! Driver check halted. " - "Please Contact sales@codetelligence.com.\n", - pDevice->pId[0].SDIO_ManufacturerCode)); - return FALSE; - } - } - return TRUE; -#else - return TRUE; -#endif -} - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @function: This function is called by the Busdriver when a device controlled by this function - function driver is removed. - - @function name: Remove - @prototype: void (*pRemove)(struct _SDFUNCTION *pFunction, struct _SDDEVICE *pDevice) - @category: PD_Reference - - @input: pFunction - the function definition structure that was passed to Busdriver - via the SDIO_RegisterFunction. - @input: pDevice - the description of the device being removed. - - @output: none - - @return: none - - @notes: The Busdriver calls the Remove function of a function driver to inform it that device it - was supporting has been removed. The device has already been removed, so no further I/O - to the device can be performed. - - @example: Example of typical Remove function callback: - void Remove(PSDFUNCTION pFunction, PSDDEVICE pDevice) { - // get the our context info passed into the SDIO_RegisterFunction - PSDXXX_DRIVER_CONTEXT pFunctionContext = - (PSDXXX_DRIVER_CONTEXT)pFunction->pContext; - ...free any acquired resources. - - @see also: SDIO_RegisterFunction - @see also: Probe - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/* - * ProbeForFunction - look for a function driver to handle this card - * -*/ -SDIO_STATUS ProbeForFunction(PSDDEVICE pDevice, PSDHCD pHcd) { - SDIO_STATUS status; - PSDLIST pList; - PSDFUNCTION pFunction; - - DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: ProbeForFunction\n")); - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction - Dump of Device PNP Data: \n")); - DBG_PRINT(SDDBG_TRACE, (" Card Flags 0x%X \n", pDevice->pId[0].CardFlags)); - if (pDevice->pId[0].CardFlags & CARD_SDIO) { - DBG_PRINT(SDDBG_TRACE, (" SDIO MANF: 0x%X \n", pDevice->pId[0].SDIO_ManufacturerID)); - DBG_PRINT(SDDBG_TRACE, (" SDIO MANFCODE: 0x%X \n", pDevice->pId[0].SDIO_ManufacturerCode)); - DBG_PRINT(SDDBG_TRACE, (" SDIO FuncNo: %d \n", pDevice->pId[0].SDIO_FunctionNo)); - DBG_PRINT(SDDBG_TRACE, (" SDIO FuncClass: %d \n", pDevice->pId[0].SDIO_FunctionClass)); - } - if (pDevice->pId[0].CardFlags & (CARD_MMC | CARD_SD)) { - DBG_PRINT(SDDBG_TRACE, (" SDMMC MANFID: 0x%X \n",pDevice->pId[0].SDMMC_ManfacturerID)); - DBG_PRINT(SDDBG_TRACE, (" SDMMC OEMID: 0x%X \n",pDevice->pId[0].SDMMC_OEMApplicationID)); - } - - if (!FilterPnpInfo(pDevice)) { - status = SDIO_STATUS_SUCCESS; - goto cleanup; - } - - /* protect the function list */ - if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->FunctionListSem)))) { - goto cleanup; /* wait interrupted */ - } - - /* protect against ProbeForDevice */ - if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->DeviceListSem)))) { - /* release the function list semaphore we just took */ - SemaphorePost(&pBusContext->FunctionListSem); - goto cleanup; - } - - if (pDevice->pFunction != NULL) { - /* device already has a function driver handling it */ - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction, device already has function\n")); - /* release function list */ - SemaphorePost(&pBusContext->DeviceListSem); - /* release function list */ - SemaphorePost(&pBusContext->FunctionListSem); - /* just return success */ - status = SDIO_STATUS_SUCCESS; - goto cleanup; - } - - /* release device list */ - SemaphorePost(&pBusContext->DeviceListSem); - - /* walk functions looking for one that can handle this device */ - SDITERATE_OVER_LIST(&pBusContext->FunctionList, pList) { - pFunction = CONTAINING_STRUCT(pList, SDFUNCTION, SDList); - if (pFunction->NumDevices >= pFunction->MaxDevices) { - /* function can't support any more devices */ - continue; - } - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction - checking: %s \n", - pFunction->pName)); - - /* see if this function handles this device */ - if (IsPotentialIdMatch(pDevice->pId, pFunction->pIds)) { - if (!FilterPnpInfo(pDevice)) { - break; - } - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction -Got Match, probing: %s \n", - pFunction->pName)); - /* we need to setup with the OS bus driver before the probe, so probe can - do OS operations. */ - OS_InitializeDevice(pDevice, pFunction); - if (!SDIO_SUCCESS(OS_AddDevice(pDevice, pFunction))) { - break; - } - /* close enough match, ask the function driver if it supports us */ - if (pFunction->pProbe(pFunction, pDevice)) { - /* she accepted the device, add to list */ - pDevice->pFunction = pFunction; - SDListAdd(&pFunction->DeviceList, &pDevice->FuncListLink); - pFunction->NumDevices++; - break; - } else { - DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: %s did not claim the device \n", - pFunction->pName)); - /* didn't take this device */ - OS_RemoveDevice(pDevice); - } - - } - } - if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) { - goto cleanup; /* wait interrupted */ - } - DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: ProbeForFunction\n")); - return status; -cleanup: - DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: ProbeForFunction, error exit 0x%X\n", status)); - return status; -} - -/* - * ProbeForDevice - look for a device that this function driver supports - * -*/ -static SDIO_STATUS ProbeForDevice(PSDFUNCTION pFunction) { - SDIO_STATUS status; - PSDLIST pList; - PSDDEVICE pDevice; - - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice\n")); - if (pFunction->NumDevices >= pFunction->MaxDevices) { - /* function can't support any more devices */ - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice, too many devices in function\n")); - return SDIO_STATUS_SUCCESS; - } - - /* protect the driver list */ - if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->DeviceListSem)))) { - goto cleanup; /* wait interrupted */ - } - /* walk device list */ - SDITERATE_OVER_LIST(&pBusContext->DeviceList, pList) { - pDevice = CONTAINING_STRUCT(pList, SDDEVICE, SDList); - if (pDevice->pFunction != NULL) { - /* device already has a function driver handling it */ - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice, device already has function\n")); - continue; - } - /* see if this function handles this device */ - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice, matching ID:%d %d class:%d\n", - pDevice->pId[0].SDIO_ManufacturerID, - pDevice->pId[0].SDIO_FunctionNo, - pDevice->pId[0].SDIO_FunctionClass)); - if (IsPotentialIdMatch(pDevice->pId, pFunction->pIds)) { - if (!FilterPnpInfo(pDevice)) { - break; - } - /* we need to setup with the OS bus driver before the probe, so probe can - do OS operations. */ - OS_InitializeDevice(pDevice, pFunction); - if (!SDIO_SUCCESS(OS_AddDevice(pDevice, pFunction))) { - break; - } - /* close enough match, ask the function driver if it supports us */ - if (pFunction->pProbe(pFunction, pDevice)) { - /* she accepted the device, add to list */ - pDevice->pFunction = pFunction; - SDListAdd(&pFunction->DeviceList, &pDevice->FuncListLink); - pFunction->NumDevices++; - break; - } else { - DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: %s did not claim the device \n", - pFunction->pName)); - /* didn't take this device */ - OS_RemoveDevice(pDevice); - } - } - } - if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->DeviceListSem)))) { - goto cleanup; /* wait interrupted */ - } - - return status; -cleanup: - DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: ProbeForDevice, error exit 0x%X\n", status)); - return status; -} - -#if 0 -static void DumpPnpEntry(PSD_PNP_INFO pInfo) -{ - DBG_PRINT(SDDBG_TRACE, ("Function PnpInfo Dump: \n")); - DBG_PRINT(SDDBG_TRACE, (" Card Flags 0x%X \n", pInfo->CardFlags)); - DBG_PRINT(SDDBG_TRACE, (" SDIO MANF: 0x%X \n", pInfo->SDIO_ManufacturerID)); - DBG_PRINT(SDDBG_TRACE, (" SDIO MANFCODE: 0x%X \n", pInfo->SDIO_ManufacturerCode)); - DBG_PRINT(SDDBG_TRACE, (" SDIO FuncNo: %d \n", pInfo->SDIO_FunctionNo)); - DBG_PRINT(SDDBG_TRACE, (" SDIO FuncClass: %d \n", pInfo->SDIO_FunctionClass)); - DBG_PRINT(SDDBG_TRACE, (" SDMMC MANFID: 0x%X \n", pInfo->SDMMC_ManfacturerID)); - DBG_PRINT(SDDBG_TRACE, (" SDMMC OEMID: 0x%X \n", pInfo->SDMMC_OEMApplicationID)); -} -#endif -/* - * IsPotentialIdMatch - test for potential device match - * -*/ -BOOL IsPotentialIdMatch(PSD_PNP_INFO pIdsDev, PSD_PNP_INFO pIdsFuncList) { - PSD_PNP_INFO pTFn; - BOOL match = FALSE; - - for (pTFn = pIdsFuncList;!IS_LAST_SDPNPINFO_ENTRY(pTFn);pTFn++) { - //DumpPnpEntry(pTFn); - /* check specific SDIO Card manufacturer ID, Code and Function number */ - if ((pIdsDev->SDIO_ManufacturerID != 0) && - (pTFn->SDIO_ManufacturerID != 0) && - (pIdsDev->SDIO_ManufacturerID == pTFn->SDIO_ManufacturerID) && - (pIdsDev->SDIO_ManufacturerCode == pTFn->SDIO_ManufacturerCode) && - ((pIdsDev->SDIO_FunctionNo == pTFn->SDIO_FunctionNo) || - (pTFn->SDIO_FunctionNo == 0)) ) { - match = TRUE; - break; - } - /* check generic function class */ - if ((pIdsDev->SDIO_FunctionClass != 0) && - (pTFn->SDIO_FunctionClass != 0) && - (pIdsDev->SDIO_FunctionClass == pTFn->SDIO_FunctionClass)) { - match = TRUE; - break; - } - /* check specific SDMMC MANFID and APPLICATION ID, NOTE SANDISK - * uses a MANFID of zero! */ - if ((pTFn->SDMMC_OEMApplicationID != 0) && - (pIdsDev->SDMMC_ManfacturerID == pTFn->SDMMC_ManfacturerID) && - (pIdsDev->SDMMC_OEMApplicationID == pTFn->SDMMC_OEMApplicationID)) { - match = TRUE; - break; - } - - /* check generic SD Card */ - if ((pIdsDev->CardFlags & CARD_SD) && - (pTFn->CardFlags & CARD_SD)){ - match = TRUE; - break; - } - - /* check generic MMC Card */ - if ((pIdsDev->CardFlags & CARD_MMC) && - (pTFn->CardFlags & CARD_MMC)){ - match = TRUE; - break; - } - - /* check raw Card */ - if ((pIdsDev->CardFlags & CARD_RAW) && - (pTFn->CardFlags & CARD_RAW)){ - match = TRUE; - break; - } - } - - return match; -} - -/* - * NotifyDeviceRemove - tell function driver on this device that the device is being removed - * -*/ -SDIO_STATUS NotifyDeviceRemove(PSDDEVICE pDevice) { - SDIO_STATUS status; - SDREQUESTQUEUE cancelQueue; - PSDREQUEST pReq; - CT_DECLARE_IRQ_SYNC_CONTEXT(); - - InitializeRequestQueue(&cancelQueue); - - if ((pDevice->pFunction != NULL) && - (pDevice->pFunction->pRemove != NULL)){ - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: removing device 0x%X\n", (INT)pDevice)); - /* fail any outstanding requests for this device */ - /* acquire lock for request queue */ - status = _AcquireHcdLock(pDevice->pHcd); - if (!SDIO_SUCCESS(status)) { - return status; - } - /* mark the function to block any more requests comming down */ - pDevice->pFunction->Flags |= SDFUNCTION_FLAG_REMOVING; - /* walk through HCD queue and remove this function's requests */ - SDITERATE_OVER_LIST_ALLOW_REMOVE(&pDevice->pHcd->RequestQueue.Queue, pReq, SDREQUEST, SDList) { - if (pReq->pFunction == pDevice->pFunction) { - /* cancel this request, as this device or function is being removed */ - /* note that these request are getting completed out of order */ - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - NotifyDeviceRemove: canceling req 0x%X\n", (UINT)pReq)); - pReq->Status = SDIO_STATUS_CANCELED; - /* remove it from the HCD queue */ - SDListRemove(&pReq->SDList); - /* add it to the cancel queue */ - QueueRequest(&cancelQueue, pReq); - } - }SDITERATE_END; - - status = _ReleaseHcdLock(pDevice->pHcd); - - /* now empty the cancel queue if anything is in there */ - while (TRUE) { - pReq = DequeueRequest(&cancelQueue); - if (NULL == pReq) { - break; - } - /* complete the request */ - DoRequestCompletion(pReq, pDevice->pHcd); - } - /* re-acquire the lock to deal with the current request */ - status = _AcquireHcdLock(pDevice->pHcd); - if (!SDIO_SUCCESS(status)) { - return status; - } - /* now deal with the current request */ - pReq = GET_CURRENT_REQUEST(pDevice->pHcd); - if ((pReq !=NULL) && (pReq->pFunction == pDevice->pFunction) && (pReq->pFunction != NULL)) { - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - NotifyDeviceRemove: Outstanding Req 0x%X on HCD: 0x%X.. waiting...\n", - (UINT)pReq, (UINT)pDevice->pHcd)); - /* the outstanding request on this device is for the function being removed */ - pReq->Flags |= SDREQ_FLAGS_CANCELED; - /* wait for this request to get completed normally */ - status = _ReleaseHcdLock(pDevice->pHcd); - SignalWait(&pDevice->pFunction->CleanupReqSig); - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - NotifyDeviceRemove: Outstanding HCD Req 0x%X completed \n", (UINT)pReq)); - } else { - /* release lock */ - status = _ReleaseHcdLock(pDevice->pHcd); - } - - /* synchronize with ISR SYNC Handlers */ - status = SemaphorePendInterruptable(&pBusContext->DeviceListSem); - if (!SDIO_SUCCESS(status)) { - return status; - } - /* call this devices Remove function */ - pDevice->pFunction->pRemove(pDevice->pFunction,pDevice); - pDevice->pFunction->NumDevices--; - /* make sure the sync handler is NULLed out */ - pDevice->pIrqFunction = NULL; - SemaphorePost(&pBusContext->DeviceListSem); - - OS_RemoveDevice(pDevice); - /* detach this device from the function list it belongs to */ - SDListRemove(&pDevice->FuncListLink); - pDevice->pFunction->Flags &= ~SDFUNCTION_FLAG_REMOVING; - pDevice->pFunction = NULL; - } - return SDIO_STATUS_SUCCESS; -} - - -/* - * RemoveHcdFunctions - remove all functions attached to an HCD - * -*/ -SDIO_STATUS RemoveHcdFunctions(PSDHCD pHcd) { - SDIO_STATUS status; - PSDLIST pList; - PSDFUNCTION pFunction; - PSDDEVICE pDevice; - DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: RemoveHcdFunctions\n")); - - /* walk through the functions and remove the ones associated with this HCD */ - /* protect the driver list */ - if (!SDIO_SUCCESS((status = SemaphorePend(&pBusContext->FunctionListSem)))) { - goto cleanup; /* wait interrupted */ - } - /* mark that card is being removed */ - pHcd->CardProperties.CardState |= CARD_STATE_REMOVED; - SDITERATE_OVER_LIST(&pBusContext->FunctionList, pList) { - pFunction = CONTAINING_STRUCT(pList, SDFUNCTION, SDList); - DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: scanning function 0x%X, %s\n", (INT)pFunction, - (pFunction == NULL)?"NULL":pFunction->pName)); - - /* walk the devices on this function and look for a match */ - SDITERATE_OVER_LIST_ALLOW_REMOVE(&pFunction->DeviceList, pDevice, SDDEVICE,FuncListLink) { - if (pDevice->pHcd == pHcd) { - /* match, remove it */ - NotifyDeviceRemove(pDevice); - } - SDITERATE_END; - SDITERATE_END; - if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) { - goto cleanup; /* wait interrupted */ - } - DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: RemoveHcdFunctions\n")); - return SDIO_STATUS_SUCCESS; - -cleanup: - DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: RemoveHcdFunctions, error exit 0x%X\n", status)); - return status; -} - -/* - * RemoveAllFunctions - remove all functions attached - * -*/ -SDIO_STATUS RemoveAllFunctions() -{ - SDIO_STATUS status; - PSDLIST pList; - PSDHCD pHcd; - - /* walk through the HCDs */ - /* protect the driver list */ - if (!SDIO_SUCCESS((status = SemaphorePend(&pBusContext->HcdListSem)))) { - goto cleanup; /* wait interrupted */ - } - SDITERATE_OVER_LIST(&pBusContext->HcdList, pList) { - pHcd = CONTAINING_STRUCT(pList, SDHCD, SDList); - /* remove the functions */ - RemoveHcdFunctions(pHcd); - } - if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->HcdListSem)))) { - goto cleanup; /* wait interrupted */ - } - return SDIO_STATUS_SUCCESS; -cleanup: - DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: RemoveAllFunctions, error exit 0x%X\n", status)); - return status; -} - |