aboutsummaryrefslogtreecommitdiff
path: root/drivers/sdio/stack/busdriver/sdio_function.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sdio/stack/busdriver/sdio_function.c')
-rw-r--r--drivers/sdio/stack/busdriver/sdio_function.c715
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;
-}
-