ath6kl: remove-typedef HIF_DEVICE
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / ath6kl / hif / sdio / linux_sdio / src / hif.c
blobe6d9cd802dee1209d9668c45d76266c16fe845e1
1 //------------------------------------------------------------------------------
2 // <copyright file="hif.c" company="Atheros">
3 // Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
4 //
5 //
6 // Permission to use, copy, modify, and/or distribute this software for any
7 // purpose with or without fee is hereby granted, provided that the above
8 // copyright notice and this permission notice appear in all copies.
9 //
10 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 //------------------------------------------------------------------------------
20 //==============================================================================
21 // HIF layer reference implementation for Linux Native MMC stack
23 // Author(s): ="Atheros"
24 //==============================================================================
25 #include <linux/mmc/card.h>
26 #include <linux/mmc/mmc.h>
27 #include <linux/mmc/host.h>
28 #include <linux/mmc/sdio_func.h>
29 #include <linux/mmc/sdio_ids.h>
30 #include <linux/mmc/sdio.h>
31 #include <linux/mmc/sd.h>
32 #include <linux/kthread.h>
34 /* by default setup a bounce buffer for the data packets, if the underlying host controller driver
35 does not use DMA you may be able to skip this step and save the memory allocation and transfer time */
36 #define HIF_USE_DMA_BOUNCE_BUFFER 1
37 #include "hif_internal.h"
38 #define ATH_MODULE_NAME hif
39 #include "a_debug.h"
40 #include "AR6002/hw2.0/hw/mbox_host_reg.h"
42 #if HIF_USE_DMA_BOUNCE_BUFFER
43 /* macro to check if DMA buffer is WORD-aligned and DMA-able. Most host controllers assume the
44 * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack).
45 * virt_addr_valid check fails on stack memory.
47 #define BUFFER_NEEDS_BOUNCE(buffer) (((unsigned long)(buffer) & 0x3) || !virt_addr_valid((buffer)))
48 #else
49 #define BUFFER_NEEDS_BOUNCE(buffer) (false)
50 #endif
52 /* ATHENV */
53 #if defined(CONFIG_PM)
54 #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev)
55 #define to_sdio_driver(d) container_of(d, struct sdio_driver, drv)
56 static int hifDeviceSuspend(struct device *dev);
57 static int hifDeviceResume(struct device *dev);
58 #endif /* CONFIG_PM */
59 static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id);
60 static void hifDeviceRemoved(struct sdio_func *func);
61 static struct hif_device *addHifDevice(struct sdio_func *func);
62 static struct hif_device *getHifDevice(struct sdio_func *func);
63 static void delHifDevice(struct hif_device * device);
64 static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte);
65 static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte);
67 int reset_sdio_on_unload = 0;
68 module_param(reset_sdio_on_unload, int, 0644);
70 extern u32 nohifscattersupport;
73 /* ------ Static Variables ------ */
74 static const struct sdio_device_id ar6k_id_table[] = {
75 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) },
76 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) },
77 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) },
78 { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) },
79 { /* null */ },
81 MODULE_DEVICE_TABLE(sdio, ar6k_id_table);
83 static struct sdio_driver ar6k_driver = {
84 .name = "ar6k_wlan",
85 .id_table = ar6k_id_table,
86 .probe = hifDeviceInserted,
87 .remove = hifDeviceRemoved,
90 #if defined(CONFIG_PM)
91 /* New suspend/resume based on linux-2.6.32
92 * Need to patch linux-2.6.32 with mmc2.6.32_suspend.patch
93 * Need to patch with msmsdcc2.6.29_suspend.patch for msm_sdcc host
95 static struct dev_pm_ops ar6k_device_pm_ops = {
96 .suspend = hifDeviceSuspend,
97 .resume = hifDeviceResume,
99 #endif /* CONFIG_PM */
101 /* make sure we only unregister when registered. */
102 static int registered = 0;
104 OSDRV_CALLBACKS osdrvCallbacks;
105 extern u32 onebitmode;
106 extern u32 busspeedlow;
107 extern u32 debughif;
109 static void ResetAllCards(void);
110 static int hifDisableFunc(struct hif_device *device, struct sdio_func *func);
111 static int hifEnableFunc(struct hif_device *device, struct sdio_func *func);
113 #ifdef DEBUG
115 ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif,
116 "hif",
117 "(Linux MMC) Host Interconnect Framework",
118 ATH_DEBUG_MASK_DEFAULTS,
120 NULL);
122 #endif
125 /* ------ Functions ------ */
126 int HIFInit(OSDRV_CALLBACKS *callbacks)
128 int status;
129 AR_DEBUG_ASSERT(callbacks != NULL);
131 A_REGISTER_MODULE_DEBUG_INFO(hif);
133 /* store the callback handlers */
134 osdrvCallbacks = *callbacks;
136 /* Register with bus driver core */
137 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFInit registering\n"));
138 registered = 1;
139 #if defined(CONFIG_PM)
140 if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) {
141 ar6k_driver.drv.pm = &ar6k_device_pm_ops;
143 #endif /* CONFIG_PM */
144 status = sdio_register_driver(&ar6k_driver);
145 AR_DEBUG_ASSERT(status==0);
147 if (status != 0) {
148 return A_ERROR;
151 return 0;
155 static int
156 __HIFReadWrite(struct hif_device *device,
157 u32 address,
158 u8 *buffer,
159 u32 length,
160 u32 request,
161 void *context)
163 u8 opcode;
164 int status = 0;
165 int ret;
166 u8 *tbuffer;
167 bool bounced = false;
169 AR_DEBUG_ASSERT(device != NULL);
170 AR_DEBUG_ASSERT(device->func != NULL);
172 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: 0x%p, buffer:0x%p (addr:0x%X)\n",
173 device, buffer, address));
175 do {
176 if (request & HIF_EXTENDED_IO) {
177 //AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Command type: CMD53\n"));
178 } else {
179 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
180 ("AR6000: Invalid command type: 0x%08x\n", request));
181 status = A_EINVAL;
182 break;
185 if (request & HIF_BLOCK_BASIS) {
186 /* round to whole block length size */
187 length = (length / HIF_MBOX_BLOCK_SIZE) * HIF_MBOX_BLOCK_SIZE;
188 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
189 ("AR6000: Block mode (BlockLen: %d)\n",
190 length));
191 } else if (request & HIF_BYTE_BASIS) {
192 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
193 ("AR6000: Byte mode (BlockLen: %d)\n",
194 length));
195 } else {
196 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
197 ("AR6000: Invalid data mode: 0x%08x\n", request));
198 status = A_EINVAL;
199 break;
202 #if 0
203 /* useful for checking register accesses */
204 if (length & 0x3) {
205 A_PRINTF(KERN_ALERT"AR6000: HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n",
206 request & HIF_WRITE ? "write":"read", address, length);
208 #endif
210 if (request & HIF_WRITE) {
211 if ((address >= HIF_MBOX_START_ADDR(0)) &&
212 (address <= HIF_MBOX_END_ADDR(3)))
215 AR_DEBUG_ASSERT(length <= HIF_MBOX_WIDTH);
218 * Mailbox write. Adjust the address so that the last byte
219 * falls on the EOM address.
221 address += (HIF_MBOX_WIDTH - length);
225 if (request & HIF_FIXED_ADDRESS) {
226 opcode = CMD53_FIXED_ADDRESS;
227 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Fixed 0x%X\n", address));
228 } else if (request & HIF_INCREMENTAL_ADDRESS) {
229 opcode = CMD53_INCR_ADDRESS;
230 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Incremental 0x%X\n", address));
231 } else {
232 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
233 ("AR6000: Invalid address mode: 0x%08x\n", request));
234 status = A_EINVAL;
235 break;
238 if (request & HIF_WRITE) {
239 #if HIF_USE_DMA_BOUNCE_BUFFER
240 if (BUFFER_NEEDS_BOUNCE(buffer)) {
241 AR_DEBUG_ASSERT(device->dma_buffer != NULL);
242 tbuffer = device->dma_buffer;
243 /* copy the write data to the dma buffer */
244 AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
245 memcpy(tbuffer, buffer, length);
246 bounced = true;
247 } else {
248 tbuffer = buffer;
250 #else
251 tbuffer = buffer;
252 #endif
253 if (opcode == CMD53_FIXED_ADDRESS) {
254 ret = sdio_writesb(device->func, address, tbuffer, length);
255 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writesb ret=%d address: 0x%X, len: %d, 0x%X\n",
256 ret, address, length, *(int *)tbuffer));
257 } else {
258 ret = sdio_memcpy_toio(device->func, address, tbuffer, length);
259 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writeio ret=%d address: 0x%X, len: %d, 0x%X\n",
260 ret, address, length, *(int *)tbuffer));
262 } else if (request & HIF_READ) {
263 #if HIF_USE_DMA_BOUNCE_BUFFER
264 if (BUFFER_NEEDS_BOUNCE(buffer)) {
265 AR_DEBUG_ASSERT(device->dma_buffer != NULL);
266 AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
267 tbuffer = device->dma_buffer;
268 bounced = true;
269 } else {
270 tbuffer = buffer;
272 #else
273 tbuffer = buffer;
274 #endif
275 if (opcode == CMD53_FIXED_ADDRESS) {
276 ret = sdio_readsb(device->func, tbuffer, address, length);
277 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readsb ret=%d address: 0x%X, len: %d, 0x%X\n",
278 ret, address, length, *(int *)tbuffer));
279 } else {
280 ret = sdio_memcpy_fromio(device->func, tbuffer, address, length);
281 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readio ret=%d address: 0x%X, len: %d, 0x%X\n",
282 ret, address, length, *(int *)tbuffer));
284 #if HIF_USE_DMA_BOUNCE_BUFFER
285 if (bounced) {
286 /* copy the read data from the dma buffer */
287 memcpy(buffer, tbuffer, length);
289 #endif
290 } else {
291 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
292 ("AR6000: Invalid direction: 0x%08x\n", request));
293 status = A_EINVAL;
294 break;
297 if (ret) {
298 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
299 ("AR6000: SDIO bus operation failed! MMC stack returned : %d \n", ret));
300 status = A_ERROR;
302 } while (false);
304 return status;
307 void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest)
309 unsigned long flags;
310 BUS_REQUEST *async;
311 BUS_REQUEST *active;
313 spin_lock_irqsave(&device->asynclock, flags);
314 active = device->asyncreq;
315 if (active == NULL) {
316 device->asyncreq = busrequest;
317 device->asyncreq->inusenext = NULL;
318 } else {
319 for (async = device->asyncreq;
320 async != NULL;
321 async = async->inusenext) {
322 active = async;
324 active->inusenext = busrequest;
325 busrequest->inusenext = NULL;
327 spin_unlock_irqrestore(&device->asynclock, flags);
331 /* queue a read/write request */
333 HIFReadWrite(struct hif_device *device,
334 u32 address,
335 u8 *buffer,
336 u32 length,
337 u32 request,
338 void *context)
340 int status = 0;
341 BUS_REQUEST *busrequest;
344 AR_DEBUG_ASSERT(device != NULL);
345 AR_DEBUG_ASSERT(device->func != NULL);
347 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: %p addr:0x%X\n", device,address));
349 do {
350 if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)){
351 /* serialize all requests through the async thread */
352 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Execution mode: %s\n",
353 (request & HIF_ASYNCHRONOUS)?"Async":"Synch"));
354 busrequest = hifAllocateBusRequest(device);
355 if (busrequest == NULL) {
356 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
357 ("AR6000: no async bus requests available (%s, addr:0x%X, len:%d) \n",
358 request & HIF_READ ? "READ":"WRITE", address, length));
359 return A_ERROR;
361 busrequest->address = address;
362 busrequest->buffer = buffer;
363 busrequest->length = length;
364 busrequest->request = request;
365 busrequest->context = context;
367 AddToAsyncList(device, busrequest);
369 if (request & HIF_SYNCHRONOUS) {
370 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%lX\n", (unsigned long)busrequest));
372 /* wait for completion */
373 up(&device->sem_async);
374 if (down_interruptible(&busrequest->sem_req) != 0) {
375 /* interrupted, exit */
376 return A_ERROR;
377 } else {
378 int status = busrequest->status;
379 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%lX: 0x%X\n",
380 (unsigned long)busrequest, busrequest->status));
381 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request));
382 hifFreeBusRequest(device, busrequest);
383 return status;
385 } else {
386 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%lX\n", (unsigned long)busrequest));
387 up(&device->sem_async);
388 return A_PENDING;
390 } else {
391 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
392 ("AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request));
393 status = A_EINVAL;
394 break;
396 } while(0);
398 return status;
400 /* thread to serialize all requests, both sync and async */
401 static int async_task(void *param)
403 struct hif_device *device;
404 BUS_REQUEST *request;
405 int status;
406 unsigned long flags;
408 device = (struct hif_device *)param;
409 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n"));
410 set_current_state(TASK_INTERRUPTIBLE);
411 while(!device->async_shutdown) {
412 /* wait for work */
413 if (down_interruptible(&device->sem_async) != 0) {
414 /* interrupted, exit */
415 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n"));
416 break;
418 if (device->async_shutdown) {
419 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n"));
420 break;
422 /* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */
423 sdio_claim_host(device->func);
424 spin_lock_irqsave(&device->asynclock, flags);
425 /* pull the request to work on */
426 while (device->asyncreq != NULL) {
427 request = device->asyncreq;
428 if (request->inusenext != NULL) {
429 device->asyncreq = request->inusenext;
430 } else {
431 device->asyncreq = NULL;
433 spin_unlock_irqrestore(&device->asynclock, flags);
434 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%lX\n", (unsigned long)request));
436 if (request->pScatterReq != NULL) {
437 A_ASSERT(device->scatter_enabled);
438 /* this is a queued scatter request, pass the request to scatter routine which
439 * executes it synchronously, note, no need to free the request since scatter requests
440 * are maintained on a separate list */
441 status = DoHifReadWriteScatter(device,request);
442 } else {
443 /* call HIFReadWrite in sync mode to do the work */
444 status = __HIFReadWrite(device, request->address, request->buffer,
445 request->length, request->request & ~HIF_SYNCHRONOUS, NULL);
446 if (request->request & HIF_ASYNCHRONOUS) {
447 void *context = request->context;
448 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%lX\n", (unsigned long)request));
449 hifFreeBusRequest(device, request);
450 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%lX\n", (unsigned long)request));
451 device->htcCallbacks.rwCompletionHandler(context, status);
452 } else {
453 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%lX\n", (unsigned long)request));
454 request->status = status;
455 up(&request->sem_req);
458 spin_lock_irqsave(&device->asynclock, flags);
460 spin_unlock_irqrestore(&device->asynclock, flags);
461 sdio_release_host(device->func);
464 complete_and_exit(&device->async_completion, 0);
465 return 0;
468 static s32 IssueSDCommand(struct hif_device *device, u32 opcode, u32 arg, u32 flags, u32 *resp)
470 struct mmc_command cmd;
471 s32 err;
472 struct mmc_host *host;
473 struct sdio_func *func;
475 func = device->func;
476 host = func->card->host;
478 memset(&cmd, 0, sizeof(struct mmc_command));
479 cmd.opcode = opcode;
480 cmd.arg = arg;
481 cmd.flags = flags;
482 err = mmc_wait_for_cmd(host, &cmd, 3);
484 if ((!err) && (resp)) {
485 *resp = cmd.resp[0];
488 return err;
491 int ReinitSDIO(struct hif_device *device)
493 s32 err;
494 struct mmc_host *host;
495 struct mmc_card *card;
496 struct sdio_func *func;
497 u8 cmd52_resp;
498 u32 clock;
500 func = device->func;
501 card = func->card;
502 host = card->host;
504 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n"));
505 sdio_claim_host(func);
507 do {
508 if (!device->is_suspend) {
509 u32 resp;
510 u16 rca;
511 u32 i;
512 int bit = fls(host->ocr_avail) - 1;
513 /* emulate the mmc_power_up(...) */
514 host->ios.vdd = bit;
515 host->ios.chip_select = MMC_CS_DONTCARE;
516 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
517 host->ios.power_mode = MMC_POWER_UP;
518 host->ios.bus_width = MMC_BUS_WIDTH_1;
519 host->ios.timing = MMC_TIMING_LEGACY;
520 host->ops->set_ios(host, &host->ios);
522 * This delay should be sufficient to allow the power supply
523 * to reach the minimum voltage.
525 msleep(2);
527 host->ios.clock = host->f_min;
528 host->ios.power_mode = MMC_POWER_ON;
529 host->ops->set_ios(host, &host->ios);
532 * This delay must be at least 74 clock sizes, or 1 ms, or the
533 * time required to reach a stable voltage.
535 msleep(2);
537 /* Issue CMD0. Goto idle state */
538 host->ios.chip_select = MMC_CS_HIGH;
539 host->ops->set_ios(host, &host->ios);
540 msleep(1);
541 err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL);
542 host->ios.chip_select = MMC_CS_DONTCARE;
543 host->ops->set_ios(host, &host->ios);
544 msleep(1);
545 host->use_spi_crc = 0;
547 if (err) {
548 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n",err));
549 break;
552 if (!host->ocr) {
553 /* Issue CMD5, arg = 0 */
554 err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
555 if (err) {
556 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));
557 break;
559 host->ocr = resp;
562 /* Issue CMD5, arg = ocr. Wait till card is ready */
563 for (i=0;i<100;i++) {
564 err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
565 if (err) {
566 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));
567 break;
569 if (resp & MMC_CARD_BUSY) {
570 break;
572 msleep(10);
575 if ((i == 100) || (err)) {
576 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready : %d %d \n",i,err));
577 break;
580 /* Issue CMD3, get RCA */
581 err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp);
582 if (err) {
583 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n",err));
584 break;
586 rca = resp >> 16;
587 host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
588 host->ops->set_ios(host, &host->ios);
590 /* Issue CMD7, select card */
591 err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL);
592 if (err) {
593 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n",err));
594 break;
598 /* Enable high speed */
599 if (card->host->caps & MMC_CAP_SD_HIGHSPEED) {
600 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n"));
601 err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp);
602 if (err) {
603 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR speed register failed : %d \n",err));
604 card->state &= ~MMC_STATE_HIGHSPEED;
605 /* no need to break */
606 } else {
607 err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS));
608 if (err) {
609 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to CCCR speed register failed : %d \n",err));
610 break;
612 mmc_card_set_highspeed(card);
613 host->ios.timing = MMC_TIMING_SD_HS;
614 host->ops->set_ios(host, &host->ios);
618 /* Set clock */
619 if (mmc_card_highspeed(card)) {
620 clock = 50000000;
621 } else {
622 clock = card->cis.max_dtr;
625 if (clock > host->f_max) {
626 clock = host->f_max;
628 host->ios.clock = clock;
629 host->ops->set_ios(host, &host->ios);
632 if (card->host->caps & MMC_CAP_4_BIT_DATA) {
633 /* CMD52: Set bus width & disable card detect resistor */
634 err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT);
635 if (err) {
636 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mode failed : %d \n",err));
637 break;
639 host->ios.bus_width = MMC_BUS_WIDTH_4;
640 host->ops->set_ios(host, &host->ios);
642 } while (0);
644 sdio_release_host(func);
645 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ReinitSDIO \n"));
647 return (err) ? A_ERROR : 0;
651 PowerStateChangeNotify(struct hif_device *device, HIF_DEVICE_POWER_CHANGE_TYPE config)
653 int status = 0;
654 #if defined(CONFIG_PM)
655 struct sdio_func *func = device->func;
656 int old_reset_val;
657 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +PowerStateChangeNotify %d\n", config));
658 switch (config) {
659 case HIF_DEVICE_POWER_DOWN:
660 case HIF_DEVICE_POWER_CUT:
661 old_reset_val = reset_sdio_on_unload;
662 reset_sdio_on_unload = 1;
663 status = hifDisableFunc(device, func);
664 reset_sdio_on_unload = old_reset_val;
665 if (!device->is_suspend) {
666 struct mmc_host *host = func->card->host;
667 host->ios.clock = 0;
668 host->ios.vdd = 0;
669 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
670 host->ios.chip_select = MMC_CS_DONTCARE;
671 host->ios.power_mode = MMC_POWER_OFF;
672 host->ios.bus_width = MMC_BUS_WIDTH_1;
673 host->ios.timing = MMC_TIMING_LEGACY;
674 host->ops->set_ios(host, &host->ios);
676 break;
677 case HIF_DEVICE_POWER_UP:
678 if (device->powerConfig == HIF_DEVICE_POWER_CUT) {
679 status = ReinitSDIO(device);
681 if (status == 0) {
682 status = hifEnableFunc(device, func);
684 break;
686 device->powerConfig = config;
688 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -PowerStateChangeNotify\n"));
689 #endif
690 return status;
694 HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode,
695 void *config, u32 configLen)
697 u32 count;
698 int status = 0;
700 switch(opcode) {
701 case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
702 ((u32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
703 ((u32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
704 ((u32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
705 ((u32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
706 break;
708 case HIF_DEVICE_GET_MBOX_ADDR:
709 for (count = 0; count < 4; count ++) {
710 ((u32 *)config)[count] = HIF_MBOX_START_ADDR(count);
713 if (configLen >= sizeof(struct hif_device_mbox_info)) {
714 SetExtendedMboxWindowInfo((u16)device->func->device,
715 (struct hif_device_mbox_info *)config);
718 break;
719 case HIF_DEVICE_GET_IRQ_PROC_MODE:
720 *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY;
721 break;
722 case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT:
723 if (!device->scatter_enabled) {
724 return A_ENOTSUP;
726 status = SetupHIFScatterSupport(device, (struct hif_device_scatter_support_info *)config);
727 if (status) {
728 device->scatter_enabled = false;
730 break;
731 case HIF_DEVICE_GET_OS_DEVICE:
732 /* pass back a pointer to the SDIO function's "dev" struct */
733 ((struct hif_device_os_device_info *)config)->pOSDevice = &device->func->dev;
734 break;
735 case HIF_DEVICE_POWER_STATE_CHANGE:
736 status = PowerStateChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TYPE *)config);
737 break;
738 default:
739 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
740 ("AR6000: Unsupported configuration opcode: %d\n", opcode));
741 status = A_ERROR;
744 return status;
747 void
748 HIFShutDownDevice(struct hif_device *device)
750 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n"));
751 if (device != NULL) {
752 AR_DEBUG_ASSERT(device->func != NULL);
753 } else {
754 /* since we are unloading the driver anyways, reset all cards in case the SDIO card
755 * is externally powered and we are unloading the SDIO stack. This avoids the problem when
756 * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already
757 * enumerated */
758 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFShutDownDevice, resetting\n"));
759 ResetAllCards();
761 /* Unregister with bus driver core */
762 if (registered) {
763 registered = 0;
764 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
765 ("AR6000: Unregistering with the bus driver\n"));
766 sdio_unregister_driver(&ar6k_driver);
767 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
768 ("AR6000: Unregistered\n"));
771 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -HIFShutDownDevice\n"));
774 static void
775 hifIRQHandler(struct sdio_func *func)
777 int status;
778 struct hif_device *device;
779 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n"));
781 device = getHifDevice(func);
782 atomic_set(&device->irqHandling, 1);
783 /* release the host during ints so we can pick it back up when we process cmds */
784 sdio_release_host(device->func);
785 status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context);
786 sdio_claim_host(device->func);
787 atomic_set(&device->irqHandling, 0);
788 AR_DEBUG_ASSERT(status == 0 || status == A_ECANCELED);
789 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifIRQHandler\n"));
792 /* handle HTC startup via thread*/
793 static int startup_task(void *param)
795 struct hif_device *device;
797 device = (struct hif_device *)param;
798 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n"));
799 /* start up inform DRV layer */
800 if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != 0) {
801 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
803 return 0;
806 #if defined(CONFIG_PM)
807 static int enable_task(void *param)
809 struct hif_device *device;
810 device = (struct hif_device *)param;
811 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call from resume_task\n"));
813 /* start up inform DRV layer */
814 if (device &&
815 device->claimedContext &&
816 osdrvCallbacks.devicePowerChangeHandler &&
817 osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != 0)
819 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
822 return 0;
824 #endif
826 static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id)
828 int ret;
829 struct hif_device * device;
830 int count;
832 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
833 ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n",
834 func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize));
836 addHifDevice(func);
837 device = getHifDevice(func);
839 device->id = id;
840 device->is_disabled = true;
842 spin_lock_init(&device->lock);
844 spin_lock_init(&device->asynclock);
846 DL_LIST_INIT(&device->ScatterReqHead);
848 if (!nohifscattersupport) {
849 /* try to allow scatter operation on all instances,
850 * unless globally overridden */
851 device->scatter_enabled = true;
854 /* Initialize the bus requests to be used later */
855 A_MEMZERO(device->busRequest, sizeof(device->busRequest));
856 for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) {
857 sema_init(&device->busRequest[count].sem_req, 0);
858 hifFreeBusRequest(device, &device->busRequest[count]);
860 sema_init(&device->sem_async, 0);
862 ret = hifEnableFunc(device, func);
864 return ret;
868 void
869 HIFAckInterrupt(struct hif_device *device)
871 AR_DEBUG_ASSERT(device != NULL);
873 /* Acknowledge our function IRQ */
876 void
877 HIFUnMaskInterrupt(struct hif_device *device)
879 int ret;
881 AR_DEBUG_ASSERT(device != NULL);
882 AR_DEBUG_ASSERT(device->func != NULL);
884 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFUnMaskInterrupt\n"));
886 /* Register the IRQ Handler */
887 sdio_claim_host(device->func);
888 ret = sdio_claim_irq(device->func, hifIRQHandler);
889 sdio_release_host(device->func);
890 AR_DEBUG_ASSERT(ret == 0);
893 void HIFMaskInterrupt(struct hif_device *device)
895 int ret;
896 AR_DEBUG_ASSERT(device != NULL);
897 AR_DEBUG_ASSERT(device->func != NULL);
899 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFMaskInterrupt\n"));
901 /* Mask our function IRQ */
902 sdio_claim_host(device->func);
903 while (atomic_read(&device->irqHandling)) {
904 sdio_release_host(device->func);
905 schedule_timeout(HZ/10);
906 sdio_claim_host(device->func);
908 ret = sdio_release_irq(device->func);
909 sdio_release_host(device->func);
910 AR_DEBUG_ASSERT(ret == 0);
913 BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device)
915 BUS_REQUEST *busrequest;
916 unsigned long flag;
918 /* Acquire lock */
919 spin_lock_irqsave(&device->lock, flag);
921 /* Remove first in list */
922 if((busrequest = device->s_busRequestFreeQueue) != NULL)
924 device->s_busRequestFreeQueue = busrequest->next;
926 /* Release lock */
927 spin_unlock_irqrestore(&device->lock, flag);
928 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifAllocateBusRequest: 0x%p\n", busrequest));
929 return busrequest;
932 void
933 hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest)
935 unsigned long flag;
937 AR_DEBUG_ASSERT(busrequest != NULL);
938 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifFreeBusRequest: 0x%p\n", busrequest));
939 /* Acquire lock */
940 spin_lock_irqsave(&device->lock, flag);
943 /* Insert first in list */
944 busrequest->next = device->s_busRequestFreeQueue;
945 busrequest->inusenext = NULL;
946 device->s_busRequestFreeQueue = busrequest;
948 /* Release lock */
949 spin_unlock_irqrestore(&device->lock, flag);
952 static int hifDisableFunc(struct hif_device *device, struct sdio_func *func)
954 int ret;
955 int status = 0;
957 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n"));
958 device = getHifDevice(func);
959 if (!IS_ERR(device->async_task)) {
960 init_completion(&device->async_completion);
961 device->async_shutdown = 1;
962 up(&device->sem_async);
963 wait_for_completion(&device->async_completion);
964 device->async_task = NULL;
966 /* Disable the card */
967 sdio_claim_host(device->func);
968 ret = sdio_disable_func(device->func);
969 if (ret) {
970 status = A_ERROR;
973 if (reset_sdio_on_unload) {
974 /* reset the SDIO interface. This is useful in automated testing where the card
975 * does not need to be removed at the end of the test. It is expected that the user will
976 * also unload/reload the host controller driver to force the bus driver to re-enumerate the slot */
977 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uninitialized state \n"));
979 /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows access
980 * to undefined registers in the range of: 0xF0-0xFF */
982 ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3));
983 if (ret) {
984 status = A_ERROR;
985 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret));
989 sdio_release_host(device->func);
991 if (status == 0) {
992 device->is_disabled = true;
994 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDisableFunc\n"));
996 return status;
999 static int hifEnableFunc(struct hif_device *device, struct sdio_func *func)
1001 struct task_struct* pTask;
1002 const char *taskName = NULL;
1003 int (*taskFunc)(void *) = NULL;
1004 int ret = 0;
1006 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n"));
1007 device = getHifDevice(func);
1009 if (device->is_disabled) {
1010 /* enable the SDIO function */
1011 sdio_claim_host(func);
1013 if ((device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_BASE) {
1014 /* enable 4-bit ASYNC interrupt on AR6003 or later devices */
1015 ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
1016 if (ret) {
1017 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret));
1018 sdio_release_host(func);
1019 return A_ERROR;
1021 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n"));
1023 /* give us some time to enable, in ms */
1024 func->enable_timeout = 100;
1025 ret = sdio_enable_func(func);
1026 if (ret) {
1027 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n",
1028 __FUNCTION__, ret));
1029 sdio_release_host(func);
1030 return A_ERROR;
1032 ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
1033 sdio_release_host(func);
1034 if (ret) {
1035 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n",
1036 __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret));
1037 return A_ERROR;
1039 device->is_disabled = false;
1040 /* create async I/O thread */
1041 if (!device->async_task) {
1042 device->async_shutdown = 0;
1043 device->async_task = kthread_create(async_task,
1044 (void *)device,
1045 "AR6K Async");
1046 if (IS_ERR(device->async_task)) {
1047 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__));
1048 return A_ERROR;
1050 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n"));
1051 wake_up_process(device->async_task );
1055 if (!device->claimedContext) {
1056 taskFunc = startup_task;
1057 taskName = "AR6K startup";
1058 ret = 0;
1059 #if defined(CONFIG_PM)
1060 } else {
1061 taskFunc = enable_task;
1062 taskName = "AR6K enable";
1063 ret = A_PENDING;
1064 #endif /* CONFIG_PM */
1066 /* create resume thread */
1067 pTask = kthread_create(taskFunc, (void *)device, taskName);
1068 if (IS_ERR(pTask)) {
1069 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__));
1070 return A_ERROR;
1072 wake_up_process(pTask);
1073 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n"));
1075 /* task will call the enable func, indicate pending */
1076 return ret;
1079 #if defined(CONFIG_PM)
1080 static int hifDeviceSuspend(struct device *dev)
1082 struct sdio_func *func=dev_to_sdio_func(dev);
1083 int status = 0;
1084 struct hif_device *device;
1086 device = getHifDevice(func);
1087 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n"));
1088 if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) {
1089 device->is_suspend = true; /* set true first for PowerStateChangeNotify(..) */
1090 status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext);
1091 if (status) {
1092 device->is_suspend = false;
1095 CleanupHIFScatterResources(device);
1096 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n"));
1098 switch (status) {
1099 case 0:
1100 return 0;
1101 case A_EBUSY:
1102 return -EBUSY; /* Hack for kernel in order to support deep sleep and wow */
1103 default:
1104 return -1;
1108 static int hifDeviceResume(struct device *dev)
1110 struct sdio_func *func=dev_to_sdio_func(dev);
1111 int status = 0;
1112 struct hif_device *device;
1114 device = getHifDevice(func);
1115 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n"));
1116 if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) {
1117 status = osdrvCallbacks.deviceResumeHandler(device->claimedContext);
1118 if (status == 0) {
1119 device->is_suspend = false;
1122 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n"));
1124 return status;
1126 #endif /* CONFIG_PM */
1128 static void hifDeviceRemoved(struct sdio_func *func)
1130 int status = 0;
1131 struct hif_device *device;
1132 AR_DEBUG_ASSERT(func != NULL);
1134 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n"));
1135 device = getHifDevice(func);
1136 if (device->claimedContext != NULL) {
1137 status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device);
1140 if (device->is_disabled) {
1141 device->is_disabled = false;
1142 } else {
1143 status = hifDisableFunc(device, func);
1145 CleanupHIFScatterResources(device);
1147 delHifDevice(device);
1148 AR_DEBUG_ASSERT(status == 0);
1149 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n"));
1153 * This should be moved to AR6K HTC layer.
1155 int hifWaitForPendingRecv(struct hif_device *device)
1157 s32 cnt = 10;
1158 u8 host_int_status;
1159 int status = 0;
1161 do {
1162 while (atomic_read(&device->irqHandling)) {
1163 /* wait until irq handler finished all the jobs */
1164 schedule_timeout(HZ/10);
1166 /* check if there is any pending irq due to force done */
1167 host_int_status = 0;
1168 status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS,
1169 (u8 *)&host_int_status, sizeof(host_int_status),
1170 HIF_RD_SYNC_BYTE_INC, NULL);
1171 host_int_status = !status ? (host_int_status & (1 << 0)) : 0;
1172 if (host_int_status) {
1173 schedule(); /* schedule for next dsrHandler */
1175 } while (host_int_status && --cnt > 0);
1177 if (host_int_status && cnt == 0) {
1178 AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
1179 ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__));
1182 return 0;
1186 static struct hif_device *
1187 addHifDevice(struct sdio_func *func)
1189 struct hif_device *hifdevice;
1190 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n"));
1191 AR_DEBUG_ASSERT(func != NULL);
1192 hifdevice = kzalloc(sizeof(struct hif_device), GFP_KERNEL);
1193 AR_DEBUG_ASSERT(hifdevice != NULL);
1194 #if HIF_USE_DMA_BOUNCE_BUFFER
1195 hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
1196 AR_DEBUG_ASSERT(hifdevice->dma_buffer != NULL);
1197 #endif
1198 hifdevice->func = func;
1199 hifdevice->powerConfig = HIF_DEVICE_POWER_UP;
1200 sdio_set_drvdata(func, hifdevice);
1201 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice; 0x%p\n", hifdevice));
1202 return hifdevice;
1205 static struct hif_device *
1206 getHifDevice(struct sdio_func *func)
1208 AR_DEBUG_ASSERT(func != NULL);
1209 return (struct hif_device *)sdio_get_drvdata(func);
1212 static void
1213 delHifDevice(struct hif_device * device)
1215 AR_DEBUG_ASSERT(device!= NULL);
1216 AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: delHifDevice; 0x%p\n", device));
1217 kfree(device->dma_buffer);
1218 kfree(device);
1221 static void ResetAllCards(void)
1225 void HIFClaimDevice(struct hif_device *device, void *context)
1227 device->claimedContext = context;
1230 void HIFReleaseDevice(struct hif_device *device)
1232 device->claimedContext = NULL;
1235 int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks)
1237 if (device->htcCallbacks.context != NULL) {
1238 /* already in use! */
1239 return A_ERROR;
1241 device->htcCallbacks = *callbacks;
1242 return 0;
1245 void HIFDetachHTC(struct hif_device *device)
1247 A_MEMZERO(&device->htcCallbacks,sizeof(device->htcCallbacks));
1250 #define SDIO_SET_CMD52_ARG(arg,rw,func,raw,address,writedata) \
1251 (arg) = (((rw) & 1) << 31) | \
1252 (((func) & 0x7) << 28) | \
1253 (((raw) & 1) << 27) | \
1254 (1 << 26) | \
1255 (((address) & 0x1FFFF) << 9) | \
1256 (1 << 8) | \
1257 ((writedata) & 0xFF)
1259 #define SDIO_SET_CMD52_READ_ARG(arg,func,address) \
1260 SDIO_SET_CMD52_ARG(arg,0,(func),0,address,0x00)
1261 #define SDIO_SET_CMD52_WRITE_ARG(arg,func,address,value) \
1262 SDIO_SET_CMD52_ARG(arg,1,(func),0,address,value)
1264 static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte)
1266 struct mmc_command ioCmd;
1267 unsigned long arg;
1269 memset(&ioCmd,0,sizeof(ioCmd));
1270 SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte);
1271 ioCmd.opcode = SD_IO_RW_DIRECT;
1272 ioCmd.arg = arg;
1273 ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
1275 return mmc_wait_for_cmd(card->host, &ioCmd, 0);
1278 static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte)
1280 struct mmc_command ioCmd;
1281 unsigned long arg;
1282 s32 err;
1284 memset(&ioCmd,0,sizeof(ioCmd));
1285 SDIO_SET_CMD52_READ_ARG(arg,0,address);
1286 ioCmd.opcode = SD_IO_RW_DIRECT;
1287 ioCmd.arg = arg;
1288 ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
1290 err = mmc_wait_for_cmd(card->host, &ioCmd, 0);
1292 if ((!err) && (byte)) {
1293 *byte = ioCmd.resp[0] & 0xFF;
1296 return err;