Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[pandora-kernel.git] / drivers / staging / brcm80211 / brcmfmac / bcmsdh.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 /* ****************** BCMSDH Interface Functions *************************** */
17
18 #include <linux/types.h>
19 #include <bcmdefs.h>
20 #include <bcmdevs.h>
21 #include <bcmendian.h>
22 #include <bcmutils.h>
23 #include <hndsoc.h>
24 #include <siutils.h>
25 #include <osl.h>
26
27 #include <bcmsdh.h>             /* BRCM API for SDIO
28                          clients (such as wl, dhd) */
29 #include <bcmsdbus.h>           /* common SDIO/controller interface */
30 #include <sbsdio.h>             /* BRCM sdio device core */
31
32 #include <sdio.h>               /* sdio spec */
33
34 #define SDIOH_API_ACCESS_RETRY_LIMIT    2
35 const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
36
37 struct bcmsdh_info {
38         bool init_success;      /* underlying driver successfully attached */
39         void *sdioh;            /* handler for sdioh */
40         u32 vendevid;   /* Target Vendor and Device ID on SD bus */
41         osl_t *osh;
42         bool regfail;           /* Save status of last
43                                  reg_read/reg_write call */
44         u32 sbwad;              /* Save backplane window address */
45 };
46 /* local copy of bcm sd handler */
47 bcmsdh_info_t *l_bcmsdh;
48
49 #if defined(OOB_INTR_ONLY) && defined(HW_OOB)
50 extern int sdioh_enable_hw_oob_intr(void *sdioh, bool enable);
51
52 void bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
53 {
54         sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
55 }
56 #endif
57
58 bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq)
59 {
60         bcmsdh_info_t *bcmsdh;
61
62         bcmsdh = kzalloc(sizeof(bcmsdh_info_t), GFP_ATOMIC);
63         if (bcmsdh == NULL) {
64                 BCMSDH_ERROR(("bcmsdh_attach: out of memory"));
65                 return NULL;
66         }
67
68         /* save the handler locally */
69         l_bcmsdh = bcmsdh;
70
71         bcmsdh->sdioh = sdioh_attach(osh, cfghdl, irq);
72         if (!bcmsdh->sdioh) {
73                 bcmsdh_detach(osh, bcmsdh);
74                 return NULL;
75         }
76
77         bcmsdh->osh = osh;
78         bcmsdh->init_success = true;
79
80         *regsva = (u32 *) SI_ENUM_BASE;
81
82         /* Report the BAR, to fix if needed */
83         bcmsdh->sbwad = SI_ENUM_BASE;
84         return bcmsdh;
85 }
86
87 int bcmsdh_detach(osl_t *osh, void *sdh)
88 {
89         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
90
91         if (bcmsdh != NULL) {
92                 if (bcmsdh->sdioh) {
93                         sdioh_detach(osh, bcmsdh->sdioh);
94                         bcmsdh->sdioh = NULL;
95                 }
96                 kfree(bcmsdh);
97         }
98
99         l_bcmsdh = NULL;
100         return 0;
101 }
102
103 int
104 bcmsdh_iovar_op(void *sdh, const char *name,
105                 void *params, int plen, void *arg, int len, bool set)
106 {
107         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
108         return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set);
109 }
110
111 bool bcmsdh_intr_query(void *sdh)
112 {
113         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
114         SDIOH_API_RC status;
115         bool on;
116
117         ASSERT(bcmsdh);
118         status = sdioh_interrupt_query(bcmsdh->sdioh, &on);
119         if (SDIOH_API_SUCCESS(status))
120                 return false;
121         else
122                 return on;
123 }
124
125 int bcmsdh_intr_enable(void *sdh)
126 {
127         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
128         SDIOH_API_RC status;
129         ASSERT(bcmsdh);
130
131         status = sdioh_interrupt_set(bcmsdh->sdioh, true);
132         return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
133 }
134
135 int bcmsdh_intr_disable(void *sdh)
136 {
137         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
138         SDIOH_API_RC status;
139         ASSERT(bcmsdh);
140
141         status = sdioh_interrupt_set(bcmsdh->sdioh, false);
142         return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
143 }
144
145 int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
146 {
147         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
148         SDIOH_API_RC status;
149         ASSERT(bcmsdh);
150
151         status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
152         return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
153 }
154
155 int bcmsdh_intr_dereg(void *sdh)
156 {
157         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
158         SDIOH_API_RC status;
159         ASSERT(bcmsdh);
160
161         status = sdioh_interrupt_deregister(bcmsdh->sdioh);
162         return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
163 }
164
165 #if defined(DHD_DEBUG)
166 bool bcmsdh_intr_pending(void *sdh)
167 {
168         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
169
170         ASSERT(sdh);
171         return sdioh_interrupt_pending(bcmsdh->sdioh);
172 }
173 #endif
174
175 int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
176 {
177         ASSERT(sdh);
178
179         /* don't support yet */
180         return BCME_UNSUPPORTED;
181 }
182
183 u8 bcmsdh_cfg_read(void *sdh, uint fnc_num, u32 addr, int *err)
184 {
185         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
186         SDIOH_API_RC status;
187 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
188         s32 retry = 0;
189 #endif
190         u8 data = 0;
191
192         if (!bcmsdh)
193                 bcmsdh = l_bcmsdh;
194
195         ASSERT(bcmsdh->init_success);
196
197 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
198         do {
199                 if (retry)      /* wait for 1 ms till bus get settled down */
200                         udelay(1000);
201 #endif
202                 status =
203                     sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr,
204                                    (u8 *) &data);
205 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
206         } while (!SDIOH_API_SUCCESS(status)
207                  && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
208 #endif
209         if (err)
210                 *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
211
212         BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
213                      __func__, fnc_num, addr, data));
214
215         return data;
216 }
217
218 void
219 bcmsdh_cfg_write(void *sdh, uint fnc_num, u32 addr, u8 data, int *err)
220 {
221         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
222         SDIOH_API_RC status;
223 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
224         s32 retry = 0;
225 #endif
226
227         if (!bcmsdh)
228                 bcmsdh = l_bcmsdh;
229
230         ASSERT(bcmsdh->init_success);
231
232 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
233         do {
234                 if (retry)      /* wait for 1 ms till bus get settled down */
235                         udelay(1000);
236 #endif
237                 status =
238                     sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr,
239                                     (u8 *) &data);
240 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
241         } while (!SDIOH_API_SUCCESS(status)
242                  && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
243 #endif
244         if (err)
245                 *err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR;
246
247         BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
248                      __func__, fnc_num, addr, data));
249 }
250
251 u32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, u32 addr, int *err)
252 {
253         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
254         SDIOH_API_RC status;
255         u32 data = 0;
256
257         if (!bcmsdh)
258                 bcmsdh = l_bcmsdh;
259
260         ASSERT(bcmsdh->init_success);
261
262         status =
263             sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ,
264                                fnc_num, addr, &data, 4);
265
266         if (err)
267                 *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
268
269         BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
270                      __func__, fnc_num, addr, data));
271
272         return data;
273 }
274
275 void
276 bcmsdh_cfg_write_word(void *sdh, uint fnc_num, u32 addr, u32 data,
277                       int *err)
278 {
279         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
280         SDIOH_API_RC status;
281
282         if (!bcmsdh)
283                 bcmsdh = l_bcmsdh;
284
285         ASSERT(bcmsdh->init_success);
286
287         status =
288             sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
289                                SDIOH_WRITE, fnc_num, addr, &data, 4);
290
291         if (err)
292                 *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
293
294         BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
295                      __func__, fnc_num, addr, data));
296 }
297
298 int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length)
299 {
300         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
301         SDIOH_API_RC status;
302
303         u8 *tmp_buf, *tmp_ptr;
304         u8 *ptr;
305         bool ascii = func & ~0xf;
306         func &= 0x7;
307
308         if (!bcmsdh)
309                 bcmsdh = l_bcmsdh;
310
311         ASSERT(bcmsdh->init_success);
312         ASSERT(cis);
313         ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT);
314
315         status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length);
316
317         if (ascii) {
318                 /* Move binary bits to tmp and format them
319                          into the provided buffer. */
320                 tmp_buf = kmalloc(length, GFP_ATOMIC);
321                 if (tmp_buf == NULL) {
322                         BCMSDH_ERROR(("%s: out of memory\n", __func__));
323                         return BCME_NOMEM;
324                 }
325                 bcopy(cis, tmp_buf, length);
326                 for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4);
327                      tmp_ptr++) {
328                         ptr += sprintf((char *)ptr, "%.2x ", *tmp_ptr & 0xff);
329                         if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
330                                 ptr += sprintf((char *)ptr, "\n");
331                 }
332                 kfree(tmp_buf);
333         }
334
335         return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
336 }
337
338 static int bcmsdhsdio_set_sbaddr_window(void *sdh, u32 address)
339 {
340         int err = 0;
341         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
342         bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
343                          (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
344         if (!err)
345                 bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
346                                  (address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
347         if (!err)
348                 bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
349                                  (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
350                                  &err);
351
352         return err;
353 }
354
355 u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size)
356 {
357         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
358         SDIOH_API_RC status;
359         u32 word = 0;
360         uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
361
362         BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
363
364         if (!bcmsdh)
365                 bcmsdh = l_bcmsdh;
366
367         ASSERT(bcmsdh->init_success);
368
369         if (bar0 != bcmsdh->sbwad) {
370                 if (bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))
371                         return 0xFFFFFFFF;
372
373                 bcmsdh->sbwad = bar0;
374         }
375
376         addr &= SBSDIO_SB_OFT_ADDR_MASK;
377         if (size == 4)
378                 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
379
380         status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
381                                     SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
382
383         bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
384
385         BCMSDH_INFO(("u32data = 0x%x\n", word));
386
387         /* if ok, return appropriately masked word */
388         if (SDIOH_API_SUCCESS(status)) {
389                 switch (size) {
390                 case sizeof(u8):
391                         return word & 0xff;
392                 case sizeof(u16):
393                         return word & 0xffff;
394                 case sizeof(u32):
395                         return word;
396                 default:
397                         bcmsdh->regfail = true;
398
399                 }
400         }
401
402         /* otherwise, bad sdio access or invalid size */
403         BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
404                       addr, size));
405         return 0xFFFFFFFF;
406 }
407
408 u32 bcmsdh_reg_write(void *sdh, u32 addr, uint size, u32 data)
409 {
410         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
411         SDIOH_API_RC status;
412         uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
413         int err = 0;
414
415         BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
416                      __func__, addr, size * 8, data));
417
418         if (!bcmsdh)
419                 bcmsdh = l_bcmsdh;
420
421         ASSERT(bcmsdh->init_success);
422
423         if (bar0 != bcmsdh->sbwad) {
424                 err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
425                 if (err)
426                         return err;
427
428                 bcmsdh->sbwad = bar0;
429         }
430
431         addr &= SBSDIO_SB_OFT_ADDR_MASK;
432         if (size == 4)
433                 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
434         status =
435             sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
436                                SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size);
437         bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
438
439         if (SDIOH_API_SUCCESS(status))
440                 return 0;
441
442         BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
443                       __func__, data, addr, size));
444         return 0xFFFFFFFF;
445 }
446
447 bool bcmsdh_regfail(void *sdh)
448 {
449         return ((bcmsdh_info_t *) sdh)->regfail;
450 }
451
452 int
453 bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
454                 u8 *buf, uint nbytes, void *pkt,
455                 bcmsdh_cmplt_fn_t complete, void *handle)
456 {
457         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
458         SDIOH_API_RC status;
459         uint incr_fix;
460         uint width;
461         uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
462         int err = 0;
463
464         ASSERT(bcmsdh);
465         ASSERT(bcmsdh->init_success);
466
467         BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
468                      __func__, fn, addr, nbytes));
469
470         /* Async not implemented yet */
471         ASSERT(!(flags & SDIO_REQ_ASYNC));
472         if (flags & SDIO_REQ_ASYNC)
473                 return BCME_UNSUPPORTED;
474
475         if (bar0 != bcmsdh->sbwad) {
476                 err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
477                 if (err)
478                         return err;
479
480                 bcmsdh->sbwad = bar0;
481         }
482
483         addr &= SBSDIO_SB_OFT_ADDR_MASK;
484
485         incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
486         width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
487         if (width == 4)
488                 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
489
490         status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
491                                       SDIOH_READ, fn, addr, width, nbytes, buf,
492                                       pkt);
493
494         return SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR;
495 }
496
497 int
498 bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags,
499                 u8 *buf, uint nbytes, void *pkt,
500                 bcmsdh_cmplt_fn_t complete, void *handle)
501 {
502         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
503         SDIOH_API_RC status;
504         uint incr_fix;
505         uint width;
506         uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
507         int err = 0;
508
509         ASSERT(bcmsdh);
510         ASSERT(bcmsdh->init_success);
511
512         BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
513                      __func__, fn, addr, nbytes));
514
515         /* Async not implemented yet */
516         ASSERT(!(flags & SDIO_REQ_ASYNC));
517         if (flags & SDIO_REQ_ASYNC)
518                 return BCME_UNSUPPORTED;
519
520         if (bar0 != bcmsdh->sbwad) {
521                 err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
522                 if (err)
523                         return err;
524
525                 bcmsdh->sbwad = bar0;
526         }
527
528         addr &= SBSDIO_SB_OFT_ADDR_MASK;
529
530         incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
531         width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
532         if (width == 4)
533                 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
534
535         status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
536                                       SDIOH_WRITE, fn, addr, width, nbytes, buf,
537                                       pkt);
538
539         return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
540 }
541
542 int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf, uint nbytes)
543 {
544         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
545         SDIOH_API_RC status;
546
547         ASSERT(bcmsdh);
548         ASSERT(bcmsdh->init_success);
549         ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0);
550
551         addr &= SBSDIO_SB_OFT_ADDR_MASK;
552         addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
553
554         status =
555             sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC,
556                                  (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
557                                  addr, 4, nbytes, buf, NULL);
558
559         return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
560 }
561
562 int bcmsdh_abort(void *sdh, uint fn)
563 {
564         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
565
566         return sdioh_abort(bcmsdh->sdioh, fn);
567 }
568
569 int bcmsdh_start(void *sdh, int stage)
570 {
571         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
572
573         return sdioh_start(bcmsdh->sdioh, stage);
574 }
575
576 int bcmsdh_stop(void *sdh)
577 {
578         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
579
580         return sdioh_stop(bcmsdh->sdioh);
581 }
582
583 int bcmsdh_query_device(void *sdh)
584 {
585         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
586         bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0;
587         return bcmsdh->vendevid;
588 }
589
590 uint bcmsdh_query_iofnum(void *sdh)
591 {
592         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
593
594         if (!bcmsdh)
595                 bcmsdh = l_bcmsdh;
596
597         return sdioh_query_iofnum(bcmsdh->sdioh);
598 }
599
600 int bcmsdh_reset(bcmsdh_info_t *sdh)
601 {
602         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
603
604         return sdioh_sdio_reset(bcmsdh->sdioh);
605 }
606
607 void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh)
608 {
609         ASSERT(sdh);
610         return sdh->sdioh;
611 }
612
613 /* Function to pass device-status bits to DHD. */
614 u32 bcmsdh_get_dstatus(void *sdh)
615 {
616         return 0;
617 }
618
619 u32 bcmsdh_cur_sbwad(void *sdh)
620 {
621         bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
622
623         if (!bcmsdh)
624                 bcmsdh = l_bcmsdh;
625
626         return bcmsdh->sbwad;
627 }
628
629 void bcmsdh_chipinfo(void *sdh, u32 chip, u32 chiprev)
630 {
631         return;
632 }