]> git.karo-electronics.de Git - linux-beck.git/blob - drivers/staging/brcm80211/util/linux_osl.c
Staging: brcm80211: remove ARRAYSIZE macro
[linux-beck.git] / drivers / staging / brcm80211 / util / linux_osl.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
17 #include <typedefs.h>
18 #include <bcmendian.h>
19 #include <linuxver.h>
20 #include <bcmdefs.h>
21 #include <osl.h>
22 #include <bcmutils.h>
23 #include <linux/delay.h>
24 #ifdef mips
25 #include <asm/paccess.h>
26 #endif                          /* mips */
27 #include <pcicfg.h>
28
29 #include <linux/fs.h>
30
31 #define PCI_CFG_RETRY           10
32
33 #define OS_HANDLE_MAGIC         0x1234abcd      /* Magic # to recognise osh */
34 #define BCM_MEM_FILENAME_LEN    24      /* Mem. filename length */
35
36 #if defined(BRCM_FULLMAC) && defined(DHD_USE_STATIC_BUF)
37 #define MAX_STATIC_BUF_NUM 16
38 #define STATIC_BUF_SIZE (PAGE_SIZE*2)
39 #define STATIC_BUF_TOTAL_LEN (MAX_STATIC_BUF_NUM*STATIC_BUF_SIZE)
40 typedef struct bcm_static_buf {
41         struct semaphore static_sem;
42         unsigned char *buf_ptr;
43         unsigned char buf_use[MAX_STATIC_BUF_NUM];
44 } bcm_static_buf_t;
45
46 static bcm_static_buf_t *bcm_static_buf = 0;
47
48 #define MAX_STATIC_PKT_NUM 8
49 typedef struct bcm_static_pkt {
50         struct sk_buff *skb_4k[MAX_STATIC_PKT_NUM];
51         struct sk_buff *skb_8k[MAX_STATIC_PKT_NUM];
52         struct semaphore osl_pkt_sem;
53         unsigned char pkt_use[MAX_STATIC_PKT_NUM * 2];
54 } bcm_static_pkt_t;
55 static bcm_static_pkt_t *bcm_static_skb = 0;
56 #endif                          /* DHD_USE_STATIC_BUF */
57 typedef struct bcm_mem_link {
58         struct bcm_mem_link *prev;
59         struct bcm_mem_link *next;
60         uint size;
61         int line;
62         char file[BCM_MEM_FILENAME_LEN];
63 } bcm_mem_link_t;
64
65 struct osl_info {
66         osl_pubinfo_t pub;
67         uint magic;
68         void *pdev;
69         uint malloced;
70         uint failed;
71         uint bustype;
72         bcm_mem_link_t *dbgmem_list;
73 };
74
75 /* Global ASSERT type flag */
76 u32 g_assert_type;
77
78 #ifdef BRCM_FULLMAC
79 static s16 linuxbcmerrormap[] = { 0,    /* 0 */
80         -EINVAL,                /* BCME_ERROR */
81         -EINVAL,                /* BCME_BADARG */
82         -EINVAL,                /* BCME_BADOPTION */
83         -EINVAL,                /* BCME_NOTUP */
84         -EINVAL,                /* BCME_NOTDOWN */
85         -EINVAL,                /* BCME_NOTAP */
86         -EINVAL,                /* BCME_NOTSTA */
87         -EINVAL,                /* BCME_BADKEYIDX */
88         -EINVAL,                /* BCME_RADIOOFF */
89         -EINVAL,                /* BCME_NOTBANDLOCKED */
90         -EINVAL,                /* BCME_NOCLK */
91         -EINVAL,                /* BCME_BADRATESET */
92         -EINVAL,                /* BCME_BADBAND */
93         -E2BIG,                 /* BCME_BUFTOOSHORT */
94         -E2BIG,                 /* BCME_BUFTOOLONG */
95         -EBUSY,                 /* BCME_BUSY */
96         -EINVAL,                /* BCME_NOTASSOCIATED */
97         -EINVAL,                /* BCME_BADSSIDLEN */
98         -EINVAL,                /* BCME_OUTOFRANGECHAN */
99         -EINVAL,                /* BCME_BADCHAN */
100         -EFAULT,                /* BCME_BADADDR */
101         -ENOMEM,                /* BCME_NORESOURCE */
102         -EOPNOTSUPP,            /* BCME_UNSUPPORTED */
103         -EMSGSIZE,              /* BCME_BADLENGTH */
104         -EINVAL,                /* BCME_NOTREADY */
105         -EPERM,                 /* BCME_NOTPERMITTED */
106         -ENOMEM,                /* BCME_NOMEM */
107         -EINVAL,                /* BCME_ASSOCIATED */
108         -ERANGE,                /* BCME_RANGE */
109         -EINVAL,                /* BCME_NOTFOUND */
110         -EINVAL,                /* BCME_WME_NOT_ENABLED */
111         -EINVAL,                /* BCME_TSPEC_NOTFOUND */
112         -EINVAL,                /* BCME_ACM_NOTSUPPORTED */
113         -EINVAL,                /* BCME_NOT_WME_ASSOCIATION */
114         -EIO,                   /* BCME_SDIO_ERROR */
115         -ENODEV,                /* BCME_DONGLE_DOWN */
116         -EINVAL,                /* BCME_VERSION */
117         -EIO,                   /* BCME_TXFAIL */
118         -EIO,                   /* BCME_RXFAIL */
119         -EINVAL,                /* BCME_NODEVICE */
120         -EINVAL,                /* BCME_NMODE_DISABLED */
121         -ENODATA,               /* BCME_NONRESIDENT */
122
123 /* When an new error code is added to bcmutils.h, add os
124  * spcecific error translation here as well
125  */
126 /* check if BCME_LAST changed since the last time this function was updated */
127 #if BCME_LAST != -42
128 #error "You need to add a OS error translation in the linuxbcmerrormap \
129         for new error code defined in bcmutils.h"
130 #endif
131 };
132
133 /* translate bcmerrors into linux errors */
134 int osl_error(int bcmerror)
135 {
136         if (bcmerror > 0)
137                 bcmerror = 0;
138         else if (bcmerror < BCME_LAST)
139                 bcmerror = BCME_ERROR;
140
141         /* Array bounds covered by ASSERT in osl_attach */
142         return linuxbcmerrormap[-bcmerror];
143 }
144 #endif /* BRCM_FULLMAC */
145
146 osl_t *osl_attach(void *pdev, uint bustype, bool pkttag)
147 {
148         osl_t *osh;
149
150         osh = kmalloc(sizeof(osl_t), GFP_ATOMIC);
151         ASSERT(osh);
152
153         bzero(osh, sizeof(osl_t));
154
155 #ifdef BRCM_FULLMAC
156         /* Check that error map has the right number of entries in it */
157         ASSERT(ABS(BCME_LAST) == (ARRAY_SIZE(linuxbcmerrormap) - 1));
158 #endif /* BRCM_FULLMAC */
159
160         osh->magic = OS_HANDLE_MAGIC;
161         osh->malloced = 0;
162         osh->failed = 0;
163         osh->dbgmem_list = NULL;
164         osh->pdev = pdev;
165         osh->pub.pkttag = pkttag;
166         osh->bustype = bustype;
167
168         switch (bustype) {
169         case PCI_BUS:
170         case SI_BUS:
171         case PCMCIA_BUS:
172                 osh->pub.mmbus = TRUE;
173                 break;
174         case JTAG_BUS:
175         case SDIO_BUS:
176         case USB_BUS:
177         case SPI_BUS:
178         case RPC_BUS:
179                 osh->pub.mmbus = FALSE;
180                 break;
181         default:
182                 ASSERT(FALSE);
183                 break;
184         }
185
186 #if defined(BRCM_FULLMAC) && defined(DHD_USE_STATIC_BUF)
187         if (!bcm_static_buf) {
188                 if (!(bcm_static_buf =
189                      (bcm_static_buf_t *) dhd_os_prealloc(3,
190                           STATIC_BUF_SIZE + STATIC_BUF_TOTAL_LEN))) {
191                         printk(KERN_ERR "can not alloc static buf!\n");
192                 } else
193                         printk(KERN_ERR "alloc static buf at %x!\n",
194                                (unsigned int)bcm_static_buf);
195
196                 init_MUTEX(&bcm_static_buf->static_sem);
197
198                 bcm_static_buf->buf_ptr =
199                     (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE;
200
201         }
202
203         if (!bcm_static_skb) {
204                 int i;
205                 void *skb_buff_ptr = 0;
206                 bcm_static_skb =
207                     (bcm_static_pkt_t *) ((char *)bcm_static_buf + 2048);
208                 skb_buff_ptr = dhd_os_prealloc(4, 0);
209
210                 bcopy(skb_buff_ptr, bcm_static_skb,
211                       sizeof(struct sk_buff *) * 16);
212                 for (i = 0; i < MAX_STATIC_PKT_NUM * 2; i++)
213                         bcm_static_skb->pkt_use[i] = 0;
214
215                 init_MUTEX(&bcm_static_skb->osl_pkt_sem);
216         }
217 #endif /* defined(BRCM_FULLMAC) && defined(DHD_USE_STATIC_BUF) */
218
219 #if defined(BCMDBG) && !defined(BRCM_FULLMAC)
220         if (pkttag) {
221                 struct sk_buff *skb;
222                 ASSERT(OSL_PKTTAG_SZ <= sizeof(skb->cb));
223         }
224 #endif
225         return osh;
226 }
227
228 void osl_detach(osl_t *osh)
229 {
230         if (osh == NULL)
231                 return;
232
233 #if defined(BRCM_FULLMAC) && defined(DHD_USE_STATIC_BUF)
234         if (bcm_static_buf)
235                 bcm_static_buf = 0;
236
237         if (bcm_static_skb)
238                 bcm_static_skb = 0;
239 #endif
240         ASSERT(osh->magic == OS_HANDLE_MAGIC);
241         kfree(osh);
242 }
243
244 /* Return a new packet. zero out pkttag */
245 void *BCMFASTPATH osl_pktget(osl_t *osh, uint len)
246 {
247         struct sk_buff *skb;
248
249         skb = dev_alloc_skb(len);
250         if (skb) {
251                 skb_put(skb, len);
252                 skb->priority = 0;
253
254                 osh->pub.pktalloced++;
255         }
256
257         return (void *)skb;
258 }
259
260 /* Free the driver packet. Free the tag if present */
261 void BCMFASTPATH osl_pktfree(osl_t *osh, void *p, bool send)
262 {
263         struct sk_buff *skb, *nskb;
264         int nest = 0;
265
266         skb = (struct sk_buff *)p;
267         ASSERT(skb);
268
269         if (send && osh->pub.tx_fn)
270                 osh->pub.tx_fn(osh->pub.tx_ctx, p, 0);
271
272         /* perversion: we use skb->next to chain multi-skb packets */
273         while (skb) {
274                 nskb = skb->next;
275                 skb->next = NULL;
276
277                 if (skb->destructor)
278                         /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
279                          * destructor exists
280                          */
281                         dev_kfree_skb_any(skb);
282                 else
283                         /* can free immediately (even in_irq()) if destructor
284                          * does not exist
285                          */
286                         dev_kfree_skb(skb);
287
288                 osh->pub.pktalloced--;
289                 nest++;
290                 skb = nskb;
291         }
292 }
293
294 #if defined(BRCM_FULLMAC) && defined(DHD_USE_STATIC_BUF)
295 void *osl_pktget_static(osl_t *osh, uint len)
296 {
297         int i = 0;
298         struct sk_buff *skb;
299
300         if (len > (PAGE_SIZE * 2)) {
301                 printk(KERN_ERR "Do we really need this big skb??\n");
302                 return osl_pktget(osh, len);
303         }
304
305         down(&bcm_static_skb->osl_pkt_sem);
306         if (len <= PAGE_SIZE) {
307                 for (i = 0; i < MAX_STATIC_PKT_NUM; i++) {
308                         if (bcm_static_skb->pkt_use[i] == 0)
309                                 break;
310                 }
311
312                 if (i != MAX_STATIC_PKT_NUM) {
313                         bcm_static_skb->pkt_use[i] = 1;
314                         up(&bcm_static_skb->osl_pkt_sem);
315
316                         skb = bcm_static_skb->skb_4k[i];
317                         skb->tail = skb->data + len;
318                         skb->len = len;
319
320                         return skb;
321                 }
322         }
323
324         for (i = 0; i < MAX_STATIC_PKT_NUM; i++) {
325                 if (bcm_static_skb->pkt_use[i + MAX_STATIC_PKT_NUM] == 0)
326                         break;
327         }
328
329         if (i != MAX_STATIC_PKT_NUM) {
330                 bcm_static_skb->pkt_use[i + MAX_STATIC_PKT_NUM] = 1;
331                 up(&bcm_static_skb->osl_pkt_sem);
332                 skb = bcm_static_skb->skb_8k[i];
333                 skb->tail = skb->data + len;
334                 skb->len = len;
335
336                 return skb;
337         }
338
339         up(&bcm_static_skb->osl_pkt_sem);
340         printk(KERN_ERR "all static pkt in use!\n");
341         return osl_pktget(osh, len);
342 }
343
344 void osl_pktfree_static(osl_t *osh, void *p, bool send)
345 {
346         int i;
347
348         for (i = 0; i < MAX_STATIC_PKT_NUM * 2; i++) {
349                 if (p == bcm_static_skb->skb_4k[i]) {
350                         down(&bcm_static_skb->osl_pkt_sem);
351                         bcm_static_skb->pkt_use[i] = 0;
352                         up(&bcm_static_skb->osl_pkt_sem);
353
354                         return;
355                 }
356         }
357         return osl_pktfree(osh, p, send);
358 }
359 #endif /* defined(BRCM_FULLMAC) && defined(DHD_USE_STATIC_BUF) */
360
361 u32 osl_pci_read_config(osl_t *osh, uint offset, uint size)
362 {
363         uint val = 0;
364         uint retry = PCI_CFG_RETRY;
365
366         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
367
368         /* only 4byte access supported */
369         ASSERT(size == 4);
370
371         do {
372                 pci_read_config_dword(osh->pdev, offset, &val);
373                 if (val != 0xffffffff)
374                         break;
375         } while (retry--);
376
377 #ifdef BCMDBG
378         if (retry < PCI_CFG_RETRY)
379                 printk("PCI CONFIG READ access to %d required %d retries\n",
380                        offset, (PCI_CFG_RETRY - retry));
381 #endif                          /* BCMDBG */
382
383         return val;
384 }
385
386 void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
387 {
388         uint retry = PCI_CFG_RETRY;
389
390         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
391
392         /* only 4byte access supported */
393         ASSERT(size == 4);
394
395         do {
396                 pci_write_config_dword(osh->pdev, offset, val);
397                 if (offset != PCI_BAR0_WIN)
398                         break;
399                 if (osl_pci_read_config(osh, offset, size) == val)
400                         break;
401         } while (retry--);
402
403 #if defined(BCMDBG) && !defined(BRCM_FULLMAC)
404         if (retry < PCI_CFG_RETRY)
405                 printk("PCI CONFIG WRITE access to %d required %d retries\n",
406                        offset, (PCI_CFG_RETRY - retry));
407 #endif                          /* BCMDBG */
408 }
409
410 /* return bus # for the pci device pointed by osh->pdev */
411 uint osl_pci_bus(osl_t *osh)
412 {
413         ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
414
415         return ((struct pci_dev *)osh->pdev)->bus->number;
416 }
417
418 /* return slot # for the pci device pointed by osh->pdev */
419 uint osl_pci_slot(osl_t *osh)
420 {
421         ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
422
423         return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
424 }
425
426 void *osl_malloc(osl_t *osh, uint size)
427 {
428         void *addr;
429
430         /* only ASSERT if osh is defined */
431         if (osh)
432                 ASSERT(osh->magic == OS_HANDLE_MAGIC);
433
434 #if defined(BRCM_FULLMAC) && defined(DHD_USE_STATIC_BUF)
435                 if (bcm_static_buf) {
436                         int i = 0;
437                         if ((size >= PAGE_SIZE) && (size <= STATIC_BUF_SIZE)) {
438                                 down(&bcm_static_buf->static_sem);
439                                 for (i = 0; i < MAX_STATIC_BUF_NUM; i++) {
440                                         if (bcm_static_buf->buf_use[i] == 0)
441                                                 break;
442                                 }
443                                 if (i == MAX_STATIC_BUF_NUM) {
444                                         up(&bcm_static_buf->static_sem);
445                                         printk(KERN_ERR "all static buff in use!\n");
446                                         goto original;
447                                 }
448                                 bcm_static_buf->buf_use[i] = 1;
449                                 up(&bcm_static_buf->static_sem);
450
451                                 bzero(bcm_static_buf->buf_ptr + STATIC_BUF_SIZE * i,
452                                           size);
453                                 if (osh)
454                                         osh->malloced += size;
455
456                                 return (void *)(bcm_static_buf->buf_ptr +
457                                                  STATIC_BUF_SIZE * i);
458                         }
459                 }
460         original:
461 #endif /* defined(BRCM_FULLMAC) && defined(DHD_USE_STATIC_BUF) */
462
463         addr = kmalloc(size, GFP_ATOMIC);
464         if (addr == NULL) {
465                 if (osh)
466                         osh->failed++;
467                 return NULL;
468         }
469         if (osh)
470                 osh->malloced += size;
471
472         return addr;
473 }
474
475 void osl_mfree(osl_t *osh, void *addr, uint size)
476 {
477 #if defined(BRCM_FULLMAC) && defined(DHD_USE_STATIC_BUF)
478         if (bcm_static_buf) {
479                 if ((addr > (void *)bcm_static_buf) && ((unsigned char *)addr
480                                 <= ((unsigned char *)
481                                     bcm_static_buf +
482                                     STATIC_BUF_TOTAL_LEN))) {
483                         int buf_idx = 0;
484                         buf_idx =
485                             ((unsigned char *)addr -
486                              bcm_static_buf->buf_ptr) / STATIC_BUF_SIZE;
487                         down(&bcm_static_buf->static_sem);
488                         bcm_static_buf->buf_use[buf_idx] = 0;
489                         up(&bcm_static_buf->static_sem);
490
491                         if (osh) {
492                                 ASSERT(osh->magic == OS_HANDLE_MAGIC);
493                                 osh->malloced -= size;
494                         }
495                         return;
496                 }
497         }
498 #endif /* defined(BRCM_FULLMAC) && defined(DHD_USE_STATIC_BUF) */
499         if (osh) {
500                 ASSERT(osh->magic == OS_HANDLE_MAGIC);
501                 osh->malloced -= size;
502         }
503         kfree(addr);
504 }
505
506 uint osl_malloced(osl_t *osh)
507 {
508         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
509         return osh->malloced;
510 }
511
512 uint osl_dma_consistent_align(void)
513 {
514         return PAGE_SIZE;
515 }
516
517 #ifdef BRCM_FULLMAC
518 void *osl_dma_alloc_consistent(osl_t *osh, uint size, unsigned long *pap)
519 {
520         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
521
522         return pci_alloc_consistent(osh->pdev, size, (dma_addr_t *) pap);
523 }
524 #else /* !BRCM_FULLMAC */
525 void *osl_dma_alloc_consistent(osl_t *osh, uint size, u16 align_bits,
526                                uint *alloced, unsigned long *pap)
527 {
528         u16 align = (1 << align_bits);
529         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
530
531         if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align))
532                 size += align;
533         *alloced = size;
534
535         return pci_alloc_consistent(osh->pdev, size, (dma_addr_t *) pap);
536 }
537 #endif /* BRCM_FULLMAC */
538
539 void osl_dma_free_consistent(osl_t *osh, void *va, uint size, unsigned long pa)
540 {
541         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
542
543         pci_free_consistent(osh->pdev, size, va, (dma_addr_t) pa);
544 }
545
546 uint BCMFASTPATH osl_dma_map(osl_t *osh, void *va, uint size, int direction)
547 {
548         int dir;
549
550         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
551         dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
552         return pci_map_single(osh->pdev, va, size, dir);
553 }
554
555 void BCMFASTPATH osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction)
556 {
557         int dir;
558
559         ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
560         dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
561         pci_unmap_single(osh->pdev, (u32) pa, size, dir);
562 }
563
564 #if defined(BCMDBG_ASSERT)
565 void osl_assert(char *exp, char *file, int line)
566 {
567         char tempbuf[256];
568         char *basename;
569
570         basename = strrchr(file, '/');
571         /* skip the '/' */
572         if (basename)
573                 basename++;
574
575         if (!basename)
576                 basename = file;
577
578 #ifdef BCMDBG_ASSERT
579         snprintf(tempbuf, 256,
580                  "assertion \"%s\" failed: file \"%s\", line %d\n", exp,
581                  basename, line);
582
583         /* Print assert message and give it time to be written to /var/log/messages */
584         if (!in_interrupt()) {
585                 const int delay = 3;
586                 printk(KERN_ERR "%s", tempbuf);
587                 printk(KERN_ERR "panic in %d seconds\n", delay);
588                 set_current_state(TASK_INTERRUPTIBLE);
589                 schedule_timeout(delay * HZ);
590         }
591
592         switch (g_assert_type) {
593         case 0:
594                 panic(KERN_ERR "%s", tempbuf);
595                 break;
596         case 1:
597                 printk(KERN_ERR "%s", tempbuf);
598                 BUG();
599                 break;
600         case 2:
601                 printk(KERN_ERR "%s", tempbuf);
602                 break;
603         default:
604                 break;
605         }
606 #endif                          /* BCMDBG_ASSERT */
607
608 }
609 #endif                          /* defined(BCMDBG_ASSERT) */
610
611 void osl_delay(uint usec)
612 {
613         uint d;
614
615         while (usec > 0) {
616                 d = min(usec, (uint)1000);
617                 udelay(d);
618                 usec -= d;
619         }
620 }
621
622 #if defined(BCMSDIO) && !defined(BRCM_FULLMAC)
623 u8 osl_readb(osl_t *osh, volatile u8 *r)
624 {
625         osl_rreg_fn_t rreg = ((osl_pubinfo_t *) osh)->rreg_fn;
626         void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
627
628         return (u8) ((rreg) (ctx, (void *)r, sizeof(u8)));
629 }
630
631 u16 osl_readw(osl_t *osh, volatile u16 *r)
632 {
633         osl_rreg_fn_t rreg = ((osl_pubinfo_t *) osh)->rreg_fn;
634         void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
635
636         return (u16) ((rreg) (ctx, (void *)r, sizeof(u16)));
637 }
638
639 u32 osl_readl(osl_t *osh, volatile u32 *r)
640 {
641         osl_rreg_fn_t rreg = ((osl_pubinfo_t *) osh)->rreg_fn;
642         void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
643
644         return (u32) ((rreg) (ctx, (void *)r, sizeof(u32)));
645 }
646
647 void osl_writeb(osl_t *osh, volatile u8 *r, u8 v)
648 {
649         osl_wreg_fn_t wreg = ((osl_pubinfo_t *) osh)->wreg_fn;
650         void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
651
652         ((wreg) (ctx, (void *)r, v, sizeof(u8)));
653 }
654
655 void osl_writew(osl_t *osh, volatile u16 *r, u16 v)
656 {
657         osl_wreg_fn_t wreg = ((osl_pubinfo_t *) osh)->wreg_fn;
658         void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
659
660         ((wreg) (ctx, (void *)r, v, sizeof(u16)));
661 }
662
663 void osl_writel(osl_t *osh, volatile u32 *r, u32 v)
664 {
665         osl_wreg_fn_t wreg = ((osl_pubinfo_t *) osh)->wreg_fn;
666         void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
667
668         ((wreg) (ctx, (void *)r, v, sizeof(u32)));
669 }
670 #endif  /* BCMSDIO */