diff options
Diffstat (limited to 'drivers/sdio/stack/busdriver/sdio_bus_os.c')
-rw-r--r-- | drivers/sdio/stack/busdriver/sdio_bus_os.c | 828 |
1 files changed, 0 insertions, 828 deletions
diff --git a/drivers/sdio/stack/busdriver/sdio_bus_os.c b/drivers/sdio/stack/busdriver/sdio_bus_os.c deleted file mode 100644 index e99e5478bbf..00000000000 --- a/drivers/sdio/stack/busdriver/sdio_bus_os.c +++ /dev/null @@ -1,828 +0,0 @@ -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -@file: sdio_bus_os.c - -@abstract: Linux implementation module - -#notes: includes module load and unload functions - -@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. - * - * 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 - * - * - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -/* debug level for this module*/ -#define DBG_DECLARE 3; - -#include <linux/sdio/ctsystem.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/version.h> -#include <linux/init.h> -#include <linux/workqueue.h> -#include <linux/delay.h> -#include <linux/kthread.h> -#include <linux/pnp.h> -void pnp_remove_card_device(struct pnp_dev *dev); -#include <linux/sdio/sdio_busdriver.h> -#include <linux/sdio/sdio_lib.h> -#include "_busdriver.h" -/* new for 2.6.26-rc1 --- not sure this is a great way... */ -#include "../../../pnp/base.h" - -#define DESCRIPTION "SDIO Bus Driver" -#define AUTHOR "Atheros Communications, Inc." - -/* debug print parameter */ -/* configuration and default parameters */ -static int RequestRetries = SDMMC_DEFAULT_CMD_RETRIES; -module_param(RequestRetries, int, 0644); -MODULE_PARM_DESC(RequestRetries, "number of command retries"); -static int CardReadyPollingRetry = SDMMC_DEFAULT_CARD_READY_RETRIES; -module_param(CardReadyPollingRetry, int, 0644); -MODULE_PARM_DESC(CardReadyPollingRetry, "number of card ready retries"); -static int PowerSettleDelay = SDMMC_POWER_SETTLE_DELAY; -module_param(PowerSettleDelay, int, 0644); -MODULE_PARM_DESC(PowerSettleDelay, "delay in ms for power to settle after power changes"); -static int DefaultOperClock = 52000000; -module_param(DefaultOperClock, int, 0644); -MODULE_PARM_DESC(DefaultOperClock, "maximum operational clock limit"); -static int DefaultBusMode = SDCONFIG_BUS_WIDTH_4_BIT; -module_param(DefaultBusMode, int, 0644); -MODULE_PARM_DESC(DefaultBusMode, "default bus mode: see SDCONFIG_BUS_WIDTH_xxx"); -static int RequestListSize = SDBUS_DEFAULT_REQ_LIST_SIZE; -module_param(RequestListSize, int, 0644); -MODULE_PARM_DESC(RequestListSize, ""); -static int SignalSemListSize = SDBUS_DEFAULT_REQ_SIG_SIZE; -module_param(SignalSemListSize, int, 0644); -MODULE_PARM_DESC(SignalSemListSize, ""); -static int CDPollingInterval = SDBUS_DEFAULT_CD_POLLING_INTERVAL; -module_param(CDPollingInterval, int, 0644); -MODULE_PARM_DESC(CDPollingInterval, ""); -static int DefaultOperBlockLen = SDMMC_DEFAULT_BYTES_PER_BLOCK; -module_param(DefaultOperBlockLen, int, 0644); -MODULE_PARM_DESC(DefaultOperBlockLen, "operational block length"); -static int DefaultOperBlockCount = SDMMC_DEFAULT_BLOCKS_PER_TRANS; -module_param(DefaultOperBlockCount, int, 0644); -MODULE_PARM_DESC(DefaultOperBlockCount, "operational block count"); -static int ConfigFlags = BD_DEFAULT_CONFIG_FLAGS; -module_param(ConfigFlags, int, 0644); -MODULE_PARM_DESC(ConfigFlags, "config flags"); - -static int HcdRCount = MAX_HCD_REQ_RECURSION; -module_param(HcdRCount, int, 0644); -MODULE_PARM_DESC(HcdRCount, "HCD request recursion count"); - -static void CardDetect_WorkItem( -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -void *context); -#else -struct work_struct *ignored); -#endif -static void CardDetect_TimerFunc(unsigned long Context); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -static DECLARE_WORK(CardDetectPollWork, CardDetect_WorkItem -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -, 0); -#else -); -#endif -#endif -static int RegisterDriver(PSDFUNCTION pFunction); -static int UnregisterDriver(PSDFUNCTION pFunction); - -static struct timer_list CardDetectTimer; - -#define SDDEVICE_FROM_OSDEVICE(pOSDevice) container_of(pOSDevice, SDDEVICE, Device) -#define SDFUNCTION_FROM_OSDRIVER(pOSDriver) container_of(pOSDriver, SDFUNCTION, Driver) - - -/* - * SDIO_RegisterHostController - register a host controller bus driver -*/ -SDIO_STATUS SDIO_RegisterHostController(PSDHCD pHcd) { - /* we are the exported verison, call the internal verison */ - return _SDIO_RegisterHostController(pHcd); -} - -/* - * SDIO_UnregisterHostController - unregister a host controller bus driver -*/ -SDIO_STATUS SDIO_UnregisterHostController(PSDHCD pHcd) { - /* we are the exported verison, call the internal verison */ - return _SDIO_UnregisterHostController(pHcd); -} - -/* - * SDIO_RegisterFunction - register a function driver -*/ -SDIO_STATUS SDIO_RegisterFunction(PSDFUNCTION pFunction) { - int error; - SDIO_STATUS status; - - DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - SDIO_RegisterFunction\n")); - - /* since we do PnP registration first, we need to check the version */ - 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; - } - - /* we are the exported verison, call the internal verison after registering with the bus - we handle probes internally to the bus driver */ - if ((error = RegisterDriver(pFunction)) < 0) { - DBG_PRINT(SDDBG_ERROR, - ("SDIO BusDriver - SDIO_RegisterFunction, failed to register with system bus driver: %d\n", - error)); - status = OSErrorToSDIOError(error); - } else { - status = _SDIO_RegisterFunction(pFunction); - if (!SDIO_SUCCESS(status)) { - UnregisterDriver(pFunction); - } - } - - return status; -} - -/* - * SDIO_UnregisterFunction - unregister a function driver -*/ -SDIO_STATUS SDIO_UnregisterFunction(PSDFUNCTION pFunction) { - SDIO_STATUS status; - /* we are the exported verison, call the internal verison */ - status = _SDIO_UnregisterFunction(pFunction); - UnregisterDriver(pFunction); - return status; -} - -/* - * SDIO_HandleHcdEvent - tell core an event occurred -*/ -SDIO_STATUS SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event) { - /* we are the exported verison, call the internal verison */ - DBG_PRINT(SDIODBG_HCD_EVENTS, ("SDIO Bus Driver: SDIO_HandleHcdEvent, event type 0x%X, HCD:0x%X\n", - Event, (UINT)pHcd)); - return _SDIO_HandleHcdEvent(pHcd, Event); -} - -/* get default settings */ -SDIO_STATUS _SDIO_BusGetDefaultSettings(PBDCONTEXT pBdc) -{ - /* these defaults are module params */ - pBdc->RequestRetries = RequestRetries; - pBdc->CardReadyPollingRetry = CardReadyPollingRetry; - pBdc->PowerSettleDelay = PowerSettleDelay; - pBdc->DefaultOperClock = DefaultOperClock; - pBdc->DefaultBusMode = DefaultBusMode; - pBdc->RequestListSize = RequestListSize; - pBdc->SignalSemListSize = SignalSemListSize; - pBdc->CDPollingInterval = CDPollingInterval; - pBdc->DefaultOperBlockLen = DefaultOperBlockLen; - pBdc->DefaultOperBlockCount = DefaultOperBlockCount; - pBdc->ConfigFlags = ConfigFlags; - pBdc->MaxHcdRecursion = HcdRCount; - return SDIO_STATUS_SUCCESS; -} - -static void CardDetect_TimerFunc(unsigned long Context) -{ - DBG_PRINT(SDIODBG_CD_TIMER, ("+ SDIO BusDriver Card Detect Timer\n")); - - /* timers run in an ISR context and cannot block or sleep, so we need - * to queue a work item to call the bus driver timer notification */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - if (schedule_work(&CardDetectPollWork) <= 0) { - DBG_PRINT(SDDBG_ERROR, ("Failed to queue Card Detect timer!\n")); - } -#else - CardDetect_WorkItem(NULL); -#endif - DBG_PRINT(SDIODBG_CD_TIMER, ("- SDIO BusDriver Card Detect Timer\n")); -} - -/* - * Initialize any timers we are using -*/ -SDIO_STATUS InitializeTimers(void) -{ - init_timer(&CardDetectTimer); - printk(KERN_INFO "init_timer(&CardDetectTimer) = %p\n", &CardDetectTimer); - CardDetectTimer.function = CardDetect_TimerFunc; - CardDetectTimer.data = 0; - return SDIO_STATUS_SUCCESS; -} - -/* - * cleanup timers -*/ -SDIO_STATUS CleanupTimers(void) -{ - del_timer(&CardDetectTimer); - return SDIO_STATUS_SUCCESS; -} - - -/* - * Queue a timer, Timeout is in milliseconds -*/ -SDIO_STATUS QueueTimer(INT TimerID, UINT32 TimeOut) -{ - UINT32 delta; - - /* convert timeout to ticks */ - delta = (TimeOut * HZ)/1000; - if (delta == 0) { - delta = 1; - } - DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO BusDriver - SDIO_QueueTimer System Ticks Per Sec:%d \n",HZ)); - DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO BusDriver - SDIO_QueueTimer TimerID: %d TimeOut:%d MS, requires %d Ticks\n", - TimerID,TimeOut,delta)); - switch (TimerID) { - case SDIOBUS_CD_TIMER_ID: - CardDetectTimer.expires = jiffies + delta; - add_timer(&CardDetectTimer); - break; - default: - return SDIO_STATUS_INVALID_PARAMETER; - } - - return SDIO_STATUS_SUCCESS; -} - -/* check a response on behalf of the host controller, to allow it to proceed with a - * data transfer */ -SDIO_STATUS SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode) -{ - return _SDIO_CheckResponse(pHcd,pReq,CheckMode); -} - -/* - * CardDetect_WorkItem - the work item for handling card detect polling interrupt -*/ -static void CardDetect_WorkItem( -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -void *context) -#else -struct work_struct *ignored) -#endif -{ - /* call bus driver function */ - SDIO_NotifyTimerTriggered(SDIOBUS_CD_TIMER_ID); -} - -/* - * OS_IncHcdReference - increment host controller driver reference count -*/ -SDIO_STATUS Do_OS_IncHcdReference(PSDHCD pHcd) -{ - SDIO_STATUS status = SDIO_STATUS_SUCCESS; - - do { - if (NULL == pHcd->pModule) { - /* hcds that are 2.3 or higher should set this */ - DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: HCD:%s should set module ptr!\n", - (pHcd->pName != NULL) ? pHcd->pName : "Unknown")); - break; - } - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - if (!try_module_get(pHcd->pModule)) { - status = SDIO_STATUS_ERROR; - } -#else - if (!try_inc_mod_count(pHcd->pModule)) { - status = SDIO_STATUS_ERROR; - } -#endif - - } while (FALSE); - - if (!SDIO_SUCCESS(status)) { - DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: HCD:%s failed to get module\n", - (pHcd->pName != NULL) ? pHcd->pName : "Unknown")); - } - - return status; -} - -/* - * OS_DecHcdReference - decrement host controller driver reference count -*/ -SDIO_STATUS Do_OS_DecHcdReference(PSDHCD pHcd) -{ - if (pHcd->pModule != NULL) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - module_put(pHcd->pModule); -#else - /* 2.4 or lower */ - __MOD_DEC_USE_COUNT(pHcd->pModule); -#endif - } - return SDIO_STATUS_SUCCESS; -} - -/****************************************************************************************/ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#include <linux/pnp.h> - -#if !defined(CONFIG_PNP) -#error "CONFIG_PNP not defined" -#endif - -static ULONG InUseDevices = 0; -static spinlock_t InUseDevicesLock = SPIN_LOCK_UNLOCKED; - -static const struct pnp_device_id pnp_idtable[] = { - {"SD_XXXX", 0} -}; -static int sdio_get_resources(struct pnp_dev * pDev) -{ - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - sdio_get_resources: %s\n", - pDev->dev.bus_id)); - return 0; -} -static int sdio_set_resources(struct pnp_dev * pDev) -{ - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - sdio_set_resources: %s\n", - pDev->dev.bus_id)); - return 0; -} - -static int sdio_disable_resources(struct pnp_dev *pDev) -{ - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - sdio_disable_resources: %s\n", - pDev->dev.bus_id)); - if (pDev != NULL) { - pDev->active = 0; - } - return 0; -} -void release(struct device * pDev) { - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - release: %s\n", - pDev->bus_id)); - return; -} -struct pnp_protocol sdio_protocol = { - .name = "SDIO", - .get = sdio_get_resources, - .set = sdio_set_resources, - .disable = sdio_disable_resources, - .dev.release = release, -}; - -/* - * driver_probe - probe for OS based driver -*/ -static int driver_probe(struct pnp_dev* pOSDevice, const struct pnp_device_id *pId) -{ - PSDDEVICE pDevice = SDDEVICE_FROM_OSDEVICE(&pOSDevice); - PSDFUNCTION pFunction = pDevice->Device->dev.driver_data; - - if (pFunction == NULL) { - return -1; - } - - if (strcmp(pFunction->pName, pOSDevice->dev.driver->name) == 0) { - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - driver_probe, match: %s/%s driver: %s\n", - pOSDevice->dev.bus_id, pFunction->pName, pOSDevice->dev.driver->name)); - return 1; - } else { - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - driver_probe, no match: %s/%s driver: %s\n", - pOSDevice->dev.bus_id, pFunction->pName, pOSDevice->dev.driver->name)); - return -1; - } -/* if (pOSDevice->id != NULL) { - if (strcmp(pOSDevice->id->id, pId->id) == 0) { - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - driver_probe, match: %s/%s\n", - pOSDevice->dev.bus_id, pId->id)); - return 1; - } - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - driver_probe, did not match: %s/%s/%s\n", - pOSDevice->dev.bus_id, pId->id, pOSDevice->id->id)); - } else { - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - driver_probe, did not match: %s/%s\n", - pOSDevice->dev.bus_id, pId->id)); - } - return -1; -*/ -//?? if (pDevice->Device.dev.driver_data != NULL) { -//?? if (pDevice->Device.dev.driver_data == pFunction) { -//?? if (pDevice->Device.data != NULL) { -//?? if (pDevice->Device.data == pFunction) { -//?? DBG_PRINT(SDDBG_TRACE, -//?? ("SDIO BusDriver - driver_probe, match: %s\n", -//?? pOSDevice->dev.bus_id)); -//?? return 1; -//?? } -//?? } - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - driver_probe, match: %s\n", - pOSDevice->dev.bus_id)); - return 1; -} - -static int RegisterDriver(PSDFUNCTION pFunction) -{ - memset(&pFunction->Driver, 0, sizeof(pFunction->Driver)); - pFunction->Driver.name = pFunction->pName; - pFunction->Driver.probe = driver_probe; - pFunction->Driver.id_table = pnp_idtable; - pFunction->Driver.flags = PNP_DRIVER_RES_DO_NOT_CHANGE; - - DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - SDIO_RegisterFunction, registering driver: %s\n", - pFunction->Driver.name)); - return pnp_register_driver(&pFunction->Driver); -} - -static int UnregisterDriver(PSDFUNCTION pFunction) -{ - DBG_PRINT(SDDBG_TRACE, - ("+SDIO BusDriver - UnregisterDriver, driver: %s\n", - pFunction->Driver.name)); - pnp_unregister_driver(&pFunction->Driver); - DBG_PRINT(SDDBG_TRACE, - ("-SDIO BusDriver - UnregisterDriver\n")); - return 0; -} - -/* - * OS_InitializeDevice - initialize device that will be registered -*/ -SDIO_STATUS OS_InitializeDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction) -{ - char id_name[20]; - - /* set the id as slot number/function number */ - snprintf(id_name, sizeof(id_name) - 1, "SD_%02X%02X", - pDevice->pHcd->SlotNumber, (UINT)SDDEVICE_GET_SDIO_FUNCNO(pDevice)); - - pDevice->Device = pnp_alloc_dev(&sdio_protocol, pDevice->pHcd->SlotNumber + 1, id_name); - pDevice->Device->dev.driver_data = (PVOID)pFunction; -//?? pDevice->Device.data = (PVOID)pFunction; -//?? pDevice->Device.dev.driver = &pFunction->Driver.driver; -//?? pDevice->Device.driver = &pFunction->Driver; -//?? pDevice->Device.dev.release = release; - /* get a unique device number, must be done with locks held */ - spin_lock(&InUseDevicesLock); - pDevice->Device->number = FirstClearBit(&InUseDevices); - SetBit(&InUseDevices, pDevice->Device->number); - spin_unlock(&InUseDevicesLock); - pDevice->Device->capabilities = PNP_REMOVABLE | PNP_DISABLE; - pDevice->Device->active = 1; - - DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_InitializeDevice adding id: %s\n", - id_name)); - /* deal with DMA settings */ - if (pDevice->pHcd->pDmaDescription != NULL) { - pDevice->Device->dev.dma_mask = &pDevice->pHcd->pDmaDescription->Mask; - pDevice->Device->dev.coherent_dma_mask = pDevice->pHcd->pDmaDescription->Mask; - } - - return SDIO_STATUS_SUCCESS; -} - -/* - * OS_AddDevice - must be pre-initialized with OS_InitializeDevice -*/ -SDIO_STATUS OS_AddDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction) -{ - int error; - DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_AddDevice adding function: %s\n", - pFunction->pName)); - error = pnp_add_device(pDevice->Device); - if (error < 0) { - DBG_PRINT(SDDBG_ERROR, ("SDIO BusDriver - OS_AddDevice failed pnp_add_device: %d\n", - error)); - } - /* replace the buggy pnp's release */ - pDevice->Device->dev.release = release; - - return OSErrorToSDIOError(error); -} - -/* - * OS_RemoveDevice - unregister device with driver and bus -*/ -void OS_RemoveDevice(PSDDEVICE pDevice) -{ - DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_RemoveDevice \n")); - pnp_remove_card_device(pDevice->Device); - spin_lock(&InUseDevicesLock); - ClearBit(&InUseDevices, pDevice->Device->number); - spin_unlock(&InUseDevicesLock); - - if (pDevice->Device->id != NULL) { - KernelFree(pDevice->Device->id); - pDevice->Device->id = NULL; - } - - KernelFree(pDevice->Device); -} - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @function: Add OS device to bus driver. - - @function name: SDIO_BusAddOSDevice - @category: HD_Reference - - @output: pDma - descrip[tion of support DMA or NULL - @output: pDriver - assigned driver object - @output: pDevice - assigned device object - - @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when successful. - - @notes: If the HCD does not register with the driver sub-system directly (like in the PCI case), - then it should register with the bus driver to obtain OS dependent device objects. - All input structures should be maintained throughout the life of the driver. - - @example: getting device objects: - typedef struct _SDHCD_DRIVER { - OS_PNPDEVICE HcdDevice; / * the OS device for this HCD * / - OS_PNPDRIVER HcdDriver; / * the OS driver for this HCD * / - SDDMA_DESCRIPTION Dma; / * driver DMA description * / - }SDHCD_DRIVER, *PSDHCD_DRIVER; - - typedef struct _SDHCD_DRIVER_CONTEXT { - PTEXT pDescription; / * human readable device decsription * / - SDLIST DeviceList; / * the list of current devices handled by this driver * / - OS_SEMAPHORE DeviceListSem; / * protection for the DeviceList * / - UINT DeviceCount; / * number of devices currently installed * / - SDHCD_DRIVER Driver; / * OS dependent driver specific info * / - }SDHCD_DRIVER_CONTEXT, *PSDHCD_DRIVER_CONTEXT; - - static SDHCD_DRIVER_CONTEXT HcdContext = { - .pDescription = DESCRIPTION, - .DeviceCount = 0, - .Driver.HcdDevice.name = "sdio_xxx_hcd", - .Driver.HcdDriver.name = "sdio_xxx_hcd", - } - ..... - status = SDIO_BusAddOSDevice(NULL, &HcdContext.Driver, &HcdContext.Device); - if (SDIO_SUCCESS(status) { - return Probe(&HcdContext.Device); - } - return SDIOErrorToOSError(status); - - @see also: SDIO_BusRemoveOSDevice - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -SDIO_STATUS SDIO_BusAddOSDevice(PSDDMA_DESCRIPTION pDma, POS_PNPDRIVER pDriver, POS_PNPDEVICE *outDevice, const char* name) -{ - int err; - struct pnp_device_id *pFdid; - static int slotNumber = 0; /* we just use an increasing count for the slots number */ - struct pnp_dev* pDevice; - - pFdid = KernelAlloc(sizeof(struct pnp_device_id)*2); - /* set the id as slot number/function number */ - snprintf(pFdid[0].id, sizeof(pFdid[0].id), "SD_%02X08", - slotNumber++); - pFdid[0].driver_data = 0; - pFdid[1].id[0] = '\0'; - pFdid[1].driver_data = 0; - - pDriver->id_table = pFdid; - pDriver->flags = PNP_DRIVER_RES_DO_NOT_CHANGE; - err = pnp_register_driver(pDriver); - if (err < 0) { - DBG_PRINT(SDDBG_ERROR, - ("SDIO BusDriver - SDIO_GetBusOSDevice, failed registering driver: %s, err: %d\n", - pDriver->name, err)); - return OSErrorToSDIOError(err); - } - - pDevice = pnp_alloc_dev(&sdio_protocol, slotNumber - 1, pFdid[0].id); - if (!pDevice) - return -EINVAL; - - if (pDma != NULL) { - pDevice->dev.dma_mask = &pDma->Mask; - pDevice->dev.coherent_dma_mask = pDma->Mask; - } - DBG_PRINT(SDDBG_ERROR, - ("SDIO BusDriver - SDIO_GetBusOSDevice, registering driver: %s DMAmask: 0x%x\n", - pDriver->name, (UINT)*pDevice->dev.dma_mask)); - - pDevice->protocol = &sdio_protocol; - pDevice->capabilities = PNP_REMOVABLE | PNP_DISABLE; - pDevice->active = 1; - - - /* get a unique device number */ - spin_lock(&InUseDevicesLock); - pDevice->number = FirstClearBit(&InUseDevices); - SetBit(&InUseDevices, pDevice->number); - spin_unlock(&InUseDevicesLock); - - err = pnp_add_device(pDevice); - if (err < 0) { - DBG_PRINT(SDDBG_ERROR, ("SDIO BusDriver - SDIO_GetBusOSDevice failed pnp_device_add: %d\n", - err)); - pnp_unregister_driver(pDriver); - } - /* replace the buggy pnp's release */ - pDevice->dev.release = release; - *outDevice = pDevice; - return OSErrorToSDIOError(err); -} - -/**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @function: Return OS device from bus driver. - - @function name: SDIO_BusRemoveOSDevice - @category: HD_Reference - - @input: pDriver - setup PNP driver object - @input: pDevice - setup PNP device object - - @return: none - - - @example: returning device objects: - SDIO_BusRemoveOSDevice(&HcdContext.Driver, &HcdContext.Device); - - - @see also: SDIO_BusAddOSDevice - -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void SDIO_BusRemoveOSDevice(POS_PNPDRIVER pDriver, POS_PNPDEVICE pDevice) -{ - DBG_PRINT(SDDBG_ERROR, - ("SDIO BusDriver - SDIO_PutBusOSDevice, unregistering driver: %s\n", - pDriver->name)); - - pnp_remove_card_device(pDevice); - if (pDevice->id != NULL) { - KernelFree(pDevice->id); - pDevice->id = NULL; - } - - spin_lock(&InUseDevicesLock); - ClearBit(&InUseDevices, pDevice->number); - spin_unlock(&InUseDevicesLock); - - pnp_unregister_driver(pDriver); - if (pDriver->id_table != NULL) { - KernelFree((void *)pDriver->id_table); - pDriver->id_table = NULL; - } - -} - - -/* - * module init -*/ -static int __init sdio_busdriver_init(void) { - SDIO_STATUS status; - int error; - REL_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: loaded\n")); - if (!SDIO_SUCCESS((status = _SDIO_BusDriverInitialize()))) { - return SDIOErrorToOSError(status); - } - /* register the sdio bus */ - error = pnp_register_protocol(&sdio_protocol); - if (error < 0) { - REL_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: failed to register bus device, %d\n", error)); - _SDIO_BusDriverCleanup(); - return error; - } - return 0; -} - -/* - * module cleanup -*/ -static void __exit sdio_busdriver_cleanup(void) { - REL_PRINT(SDDBG_TRACE, ("SDIO unloaded\n")); - _SDIO_BusDriverCleanup(); - pnp_unregister_protocol(&sdio_protocol); -DBG_PRINT(SDDBG_TRACE, - ("SDIO BusDriver - unloaded 1\n")); -} -EXPORT_SYMBOL(SDIO_BusAddOSDevice); -EXPORT_SYMBOL(SDIO_BusRemoveOSDevice); - -#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - /* 2.4 */ -static int RegisterDriver(PSDFUNCTION pFunction) -{ - return 0; -} - -static int UnregisterDriver(PSDFUNCTION pFunction) -{ - DBG_PRINT(SDDBG_TRACE, - ("+-SDIO BusDriver - UnregisterDriver, driver: \n")); - return 0; -} - -/* - * OS_InitializeDevice - initialize device that will be registered -*/ -SDIO_STATUS OS_InitializeDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction) -{ - return SDIO_STATUS_SUCCESS; -} - -/* - * OS_AddDevice - must be pre-initialized with OS_InitializeDevice -*/ -SDIO_STATUS OS_AddDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction) -{ - DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_AddDevice adding function: %s\n", - pFunction->pName)); - return SDIO_STATUS_SUCCESS; - -} - -/* - * OS_RemoveDevice - unregister device with driver and bus -*/ -void OS_RemoveDevice(PSDDEVICE pDevice) -{ - DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_RemoveDevice \n")); -} - -/* - * module init -*/ -static int __init sdio_busdriver_init(void) { - SDIO_STATUS status; - REL_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: loaded\n")); - if (!SDIO_SUCCESS((status = _SDIO_BusDriverInitialize()))) { - return SDIOErrorToOSError(status); - } - return 0; -} - -/* - * module cleanup -*/ -static void __exit sdio_busdriver_cleanup(void) { - REL_PRINT(SDDBG_TRACE, ("SDIO unloaded\n")); - _SDIO_BusDriverCleanup(); -} -#else ////KERNEL_VERSION -#error "unsupported kernel version: "UTS_RELEASE -#endif //KERNEL_VERSION - -MODULE_LICENSE("GPL and additional rights"); -MODULE_DESCRIPTION(DESCRIPTION); -MODULE_AUTHOR(AUTHOR); - -module_init(sdio_busdriver_init); -module_exit(sdio_busdriver_cleanup); -EXPORT_SYMBOL(SDIO_RegisterHostController); -EXPORT_SYMBOL(SDIO_UnregisterHostController); -EXPORT_SYMBOL(SDIO_HandleHcdEvent); -EXPORT_SYMBOL(SDIO_CheckResponse); -EXPORT_SYMBOL(SDIO_RegisterFunction); -EXPORT_SYMBOL(SDIO_UnregisterFunction); |