linux/drivers/staging/brcm80211/util/linux_osl.c
<<
>>
Prefs
   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 <linux/delay.h>
  18#include <linux/fs.h>
  19#ifdef mips
  20#include <asm/paccess.h>
  21#endif                          /* mips */
  22#include <bcmendian.h>
  23#include <linux/module.h>
  24#include <linux/pci.h>
  25#include <linux/netdevice.h>
  26#include <linux/sched.h>
  27#include <bcmdefs.h>
  28#include <osl.h>
  29#include <bcmutils.h>
  30#include <pcicfg.h>
  31
  32
  33#define OS_HANDLE_MAGIC         0x1234abcd      /* Magic # to recognise osh */
  34#define BCM_MEM_FILENAME_LEN    24      /* Mem. filename length */
  35
  36/* Global ASSERT type flag */
  37u32 g_assert_type;
  38
  39struct osl_info *osl_attach(void *pdev, uint bustype)
  40{
  41        struct osl_info *osh;
  42
  43        osh = kmalloc(sizeof(struct osl_info), GFP_ATOMIC);
  44        ASSERT(osh);
  45
  46        memset(osh, 0, sizeof(struct osl_info));
  47
  48        osh->magic = OS_HANDLE_MAGIC;
  49        osh->pdev = pdev;
  50        osh->bustype = bustype;
  51
  52        switch (bustype) {
  53        case PCI_BUS:
  54        case SI_BUS:
  55        case PCMCIA_BUS:
  56                osh->mmbus = true;
  57                break;
  58        case JTAG_BUS:
  59        case SDIO_BUS:
  60        case USB_BUS:
  61        case SPI_BUS:
  62        case RPC_BUS:
  63                osh->mmbus = false;
  64                break;
  65        default:
  66                ASSERT(false);
  67                break;
  68        }
  69
  70        return osh;
  71}
  72
  73void osl_detach(struct osl_info *osh)
  74{
  75        if (osh == NULL)
  76                return;
  77
  78        ASSERT(osh->magic == OS_HANDLE_MAGIC);
  79        kfree(osh);
  80}
  81
  82struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len)
  83{
  84        struct sk_buff *skb;
  85
  86        skb = dev_alloc_skb(len);
  87        if (skb) {
  88                skb_put(skb, len);
  89                skb->priority = 0;
  90
  91                osh->pktalloced++;
  92        }
  93
  94        return skb;
  95}
  96
  97/* Free the driver packet. Free the tag if present */
  98void BCMFASTPATH pkt_buf_free_skb(struct osl_info *osh, struct sk_buff *skb, bool send)
  99{
 100        struct sk_buff *nskb;
 101        int nest = 0;
 102
 103        ASSERT(skb);
 104
 105        /* perversion: we use skb->next to chain multi-skb packets */
 106        while (skb) {
 107                nskb = skb->next;
 108                skb->next = NULL;
 109
 110                if (skb->destructor)
 111                        /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
 112                         * destructor exists
 113                         */
 114                        dev_kfree_skb_any(skb);
 115                else
 116                        /* can free immediately (even in_irq()) if destructor
 117                         * does not exist
 118                         */
 119                        dev_kfree_skb(skb);
 120
 121                osh->pktalloced--;
 122                nest++;
 123                skb = nskb;
 124        }
 125}
 126
 127/* return bus # for the pci device pointed by osh->pdev */
 128uint osl_pci_bus(struct osl_info *osh)
 129{
 130        ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
 131
 132        return ((struct pci_dev *)osh->pdev)->bus->number;
 133}
 134
 135/* return slot # for the pci device pointed by osh->pdev */
 136uint osl_pci_slot(struct osl_info *osh)
 137{
 138        ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
 139
 140        return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
 141}
 142
 143void *osl_dma_alloc_consistent(struct osl_info *osh, uint size, u16 align_bits,
 144                               uint *alloced, unsigned long *pap)
 145{
 146        ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
 147
 148        if (align_bits) {
 149                u16 align = (1 << align_bits);
 150                if (!IS_ALIGNED(PAGE_SIZE, align))
 151                        size += align;
 152                *alloced = size;
 153        }
 154        return pci_alloc_consistent(osh->pdev, size, (dma_addr_t *) pap);
 155}
 156
 157void osl_dma_free_consistent(struct osl_info *osh, void *va, uint size,
 158                             unsigned long pa)
 159{
 160        ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
 161
 162        pci_free_consistent(osh->pdev, size, va, (dma_addr_t) pa);
 163}
 164
 165uint BCMFASTPATH osl_dma_map(struct osl_info *osh, void *va, uint size,
 166                             int direction)
 167{
 168        int dir;
 169
 170        ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
 171        dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
 172        return pci_map_single(osh->pdev, va, size, dir);
 173}
 174
 175void BCMFASTPATH osl_dma_unmap(struct osl_info *osh, uint pa, uint size,
 176                               int direction)
 177{
 178        int dir;
 179
 180        ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
 181        dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
 182        pci_unmap_single(osh->pdev, (u32) pa, size, dir);
 183}
 184
 185#if defined(BCMDBG_ASSERT)
 186void osl_assert(char *exp, char *file, int line)
 187{
 188        char tempbuf[256];
 189        char *basename;
 190
 191        basename = strrchr(file, '/');
 192        /* skip the '/' */
 193        if (basename)
 194                basename++;
 195
 196        if (!basename)
 197                basename = file;
 198
 199#ifdef BCMDBG_ASSERT
 200        snprintf(tempbuf, 256,
 201                 "assertion \"%s\" failed: file \"%s\", line %d\n", exp,
 202                 basename, line);
 203
 204        /* Print assert message and give it time to be written to /var/log/messages */
 205        if (!in_interrupt()) {
 206                const int delay = 3;
 207                printk(KERN_ERR "%s", tempbuf);
 208                printk(KERN_ERR "panic in %d seconds\n", delay);
 209                set_current_state(TASK_INTERRUPTIBLE);
 210                schedule_timeout(delay * HZ);
 211        }
 212
 213        switch (g_assert_type) {
 214        case 0:
 215                panic(KERN_ERR "%s", tempbuf);
 216                break;
 217        case 1:
 218                printk(KERN_ERR "%s", tempbuf);
 219                BUG();
 220                break;
 221        case 2:
 222                printk(KERN_ERR "%s", tempbuf);
 223                break;
 224        default:
 225                break;
 226        }
 227#endif                          /* BCMDBG_ASSERT */
 228
 229}
 230#endif                          /* defined(BCMDBG_ASSERT) */
 231
 232