123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974 |
- /*
- * Linux OS Independent Layer
- *
- * Portions of this code are copyright (c) 2020 Cypress Semiconductor Corporation
- *
- * Copyright (C) 1999-2020, Broadcom Corporation
- *
- * Unless you and Broadcom execute a separate written software license
- * agreement governing use of this software, this software is licensed to you
- * under the terms of the GNU General Public License version 2 (the "GPL"),
- * available at http://www.broadcom.com/licenses/GPLv2.php, with the
- * following added to such license:
- *
- * As a special exception, the copyright holders of this software give you
- * permission to link this software with independent modules, and to copy and
- * distribute the resulting executable under terms of your choice, provided that
- * you also meet, for each linked independent module, the terms and conditions of
- * the license of that module. An independent module is a module which is not
- * derived from this software. The special exception does not apply to any
- * modifications of the software.
- *
- * Notwithstanding the above, under no circumstances may you combine this
- * software in any way with any other Broadcom software provided under a license
- * other than the GPL, without Broadcom's express prior written consent.
- *
- *
- * <<Broadcom-WL-IPTag/Open:>>
- *
- * $Id: linux_osl.c 697654 2017-05-04 11:59:40Z $
- */
- #define LINUX_PORT
- #include <typedefs.h>
- #include <bcmendian.h>
- #include <linuxver.h>
- #include <bcmdefs.h>
- #if defined(__ARM_ARCH_7A__) && !defined(DHD_USE_COHERENT_MEM_FOR_RING)
- #include <asm/cacheflush.h>
- #endif /* __ARM_ARCH_7A__ && !DHD_USE_COHERENT_MEM_FOR_RING */
- #include <linux/random.h>
- #include <osl.h>
- #include <bcmutils.h>
- #include <linux/delay.h>
- #include <linux/vmalloc.h>
- #include <pcicfg.h>
- #if defined(BCMASSERT_LOG) && !defined(OEM_ANDROID)
- #include <bcm_assert_log.h>
- #endif // endif
- #ifdef BCM_SECURE_DMA
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/io.h>
- #include <linux/printk.h>
- #include <linux/errno.h>
- #include <linux/mm.h>
- #include <linux/moduleparam.h>
- #include <asm/io.h>
- #include <linux/skbuff.h>
- #include <stbutils.h>
- #include <linux/highmem.h>
- #include <linux/dma-mapping.h>
- #include <asm/memory.h>
- #endif /* BCM_SECURE_DMA */
- #include <linux/fs.h>
- #if defined(STB)
- #include <linux/spinlock.h>
- extern spinlock_t l2x0_reg_lock;
- #endif // endif
- #ifdef BCM_OBJECT_TRACE
- #include <bcmutils.h>
- #endif /* BCM_OBJECT_TRACE */
- #include "linux_osl_priv.h"
- #define PCI_CFG_RETRY 10
- #define DUMPBUFSZ 1024
- #ifdef BCM_SECURE_DMA
- static void * osl_sec_dma_ioremap(osl_t *osh, struct page *page, size_t size,
- bool iscache, bool isdecr);
- static void osl_sec_dma_iounmap(osl_t *osh, void *contig_base_va, size_t size);
- static int osl_sec_dma_init_elem_mem_block(osl_t *osh, size_t mbsize, int max,
- sec_mem_elem_t **list);
- static void osl_sec_dma_deinit_elem_mem_block(osl_t *osh, size_t mbsize, int max,
- void *sec_list_base);
- static sec_mem_elem_t * osl_sec_dma_alloc_mem_elem(osl_t *osh, void *va, uint size,
- int direction, struct sec_cma_info *ptr_cma_info, uint offset);
- static void osl_sec_dma_free_mem_elem(osl_t *osh, sec_mem_elem_t *sec_mem_elem);
- static void osl_sec_dma_init_consistent(osl_t *osh);
- static void *osl_sec_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits,
- ulong *pap);
- static void osl_sec_dma_free_consistent(osl_t *osh, void *va, uint size, dmaaddr_t pa);
- #endif /* BCM_SECURE_DMA */
- /* PCMCIA attribute space access macros */
- #ifdef CUSTOMER_HW4_DEBUG
- uint32 g_assert_type = 1; /* By Default not cause Kernel Panic */
- #else
- uint32 g_assert_type = 0; /* By Default Kernel Panic */
- #endif /* CUSTOMER_HW4_DEBUG */
- module_param(g_assert_type, int, 0);
- #ifdef BCM_SECURE_DMA
- #define SECDMA_MODULE_PARAMS 0
- #define SECDMA_EXT_FILE 1
- unsigned long secdma_addr = 0;
- unsigned long secdma_addr2 = 0;
- u32 secdma_size = 0;
- u32 secdma_size2 = 0;
- module_param(secdma_addr, ulong, 0);
- module_param(secdma_size, int, 0);
- module_param(secdma_addr2, ulong, 0);
- module_param(secdma_size2, int, 0);
- static int secdma_found = 0;
- #endif /* BCM_SECURE_DMA */
- #ifdef USE_DMA_LOCK
- static void osl_dma_lock(osl_t *osh);
- static void osl_dma_unlock(osl_t *osh);
- static void osl_dma_lock_init(osl_t *osh);
- #define DMA_LOCK(osh) osl_dma_lock(osh)
- #define DMA_UNLOCK(osh) osl_dma_unlock(osh)
- #define DMA_LOCK_INIT(osh) osl_dma_lock_init(osh);
- #else
- #define DMA_LOCK(osh) do { /* noop */ } while(0)
- #define DMA_UNLOCK(osh) do { /* noop */ } while(0)
- #define DMA_LOCK_INIT(osh) do { /* noop */ } while(0)
- #endif /* USE_DMA_LOCK */
- static int16 linuxbcmerrormap[] =
- { 0, /* 0 */
- -EINVAL, /* BCME_ERROR */
- -EINVAL, /* BCME_BADARG */
- -EINVAL, /* BCME_BADOPTION */
- -EINVAL, /* BCME_NOTUP */
- -EINVAL, /* BCME_NOTDOWN */
- -EINVAL, /* BCME_NOTAP */
- -EINVAL, /* BCME_NOTSTA */
- -EINVAL, /* BCME_BADKEYIDX */
- -EINVAL, /* BCME_RADIOOFF */
- -EINVAL, /* BCME_NOTBANDLOCKED */
- -EINVAL, /* BCME_NOCLK */
- -EINVAL, /* BCME_BADRATESET */
- -EINVAL, /* BCME_BADBAND */
- -E2BIG, /* BCME_BUFTOOSHORT */
- -E2BIG, /* BCME_BUFTOOLONG */
- -EBUSY, /* BCME_BUSY */
- -EINVAL, /* BCME_NOTASSOCIATED */
- -EINVAL, /* BCME_BADSSIDLEN */
- -EINVAL, /* BCME_OUTOFRANGECHAN */
- -EINVAL, /* BCME_BADCHAN */
- -EFAULT, /* BCME_BADADDR */
- -ENOMEM, /* BCME_NORESOURCE */
- -EOPNOTSUPP, /* BCME_UNSUPPORTED */
- -EMSGSIZE, /* BCME_BADLENGTH */
- -EINVAL, /* BCME_NOTREADY */
- -EPERM, /* BCME_EPERM */
- -ENOMEM, /* BCME_NOMEM */
- -EINVAL, /* BCME_ASSOCIATED */
- -ERANGE, /* BCME_RANGE */
- -EINVAL, /* BCME_NOTFOUND */
- -EINVAL, /* BCME_WME_NOT_ENABLED */
- -EINVAL, /* BCME_TSPEC_NOTFOUND */
- -EINVAL, /* BCME_ACM_NOTSUPPORTED */
- -EINVAL, /* BCME_NOT_WME_ASSOCIATION */
- -EIO, /* BCME_SDIO_ERROR */
- -ENODEV, /* BCME_DONGLE_DOWN */
- -EINVAL, /* BCME_VERSION */
- -EIO, /* BCME_TXFAIL */
- -EIO, /* BCME_RXFAIL */
- -ENODEV, /* BCME_NODEVICE */
- -EINVAL, /* BCME_NMODE_DISABLED */
- -ENODATA, /* BCME_NONRESIDENT */
- -EINVAL, /* BCME_SCANREJECT */
- -EINVAL, /* BCME_USAGE_ERROR */
- -EIO, /* BCME_IOCTL_ERROR */
- -EIO, /* BCME_SERIAL_PORT_ERR */
- -EOPNOTSUPP, /* BCME_DISABLED, BCME_NOTENABLED */
- -EIO, /* BCME_DECERR */
- -EIO, /* BCME_ENCERR */
- -EIO, /* BCME_MICERR */
- -ERANGE, /* BCME_REPLAY */
- -EINVAL, /* BCME_IE_NOTFOUND */
- -EINVAL, /* BCME_DATA_NOTFOUND */
- -EINVAL, /* BCME_NOT_GC */
- -EINVAL, /* BCME_PRS_REQ_FAILED */
- -EINVAL, /* BCME_NO_P2P_SE */
- -EINVAL, /* BCME_NOA_PND */
- -EINVAL, /* BCME_FRAG_Q_FAILED */
- -EINVAL, /* BCME_GET_AF_FAILED */
- -EINVAL, /* BCME_MSCH_NOTREADY */
- -EINVAL, /* BCME_IOV_LAST_CMD */
- -EINVAL, /* BCME_MINIPMU_CAL_FAIL */
- -EINVAL, /* BCME_RCAL_FAIL */
- -EINVAL, /* BCME_LPF_RCCAL_FAIL */
- -EINVAL, /* BCME_DACBUF_RCCAL_FAIL */
- -EINVAL, /* BCME_VCOCAL_FAIL */
- -EINVAL, /* BCME_BANDLOCKED */
- -EINVAL, /* BCME_DNGL_DEVRESET */
- /* When an new error code is added to bcmutils.h, add os
- * specific error translation here as well
- */
- /* check if BCME_LAST changed since the last time this function was updated */
- #if BCME_LAST != -68
- #error "You need to add a OS error translation in the linuxbcmerrormap \
- for new error code defined in bcmutils.h"
- #endif // endif
- };
- uint lmtest = FALSE;
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 1))
- void do_gettimeofday(struct timeval *tv)
- {
- struct timespec64 ts;
- ktime_get_real_ts64(&ts);
- tv->tv_sec = ts.tv_sec;
- tv->tv_usec = ts.tv_nsec;
- }
- #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 1) */
- #ifdef DHD_MAP_LOGGING
- #define DHD_MAP_LOG_SIZE 2048
- typedef struct dhd_map_item {
- dmaaddr_t pa; /* DMA address (physical) */
- uint64 ts_nsec; /* timestamp: nsec */
- uint32 size; /* mapping size */
- uint8 rsvd[4]; /* reserved for future use */
- } dhd_map_item_t;
- typedef struct dhd_map_record {
- uint32 items; /* number of total items */
- uint32 idx; /* current index of metadata */
- dhd_map_item_t map[0]; /* metadata storage */
- } dhd_map_log_t;
- void
- osl_dma_map_dump(osl_t *osh)
- {
- dhd_map_log_t *map_log, *unmap_log;
- uint64 ts_sec, ts_usec;
- map_log = (dhd_map_log_t *)(osh->dhd_map_log);
- unmap_log = (dhd_map_log_t *)(osh->dhd_unmap_log);
- osl_get_localtime(&ts_sec, &ts_usec);
- if (map_log && unmap_log) {
- printk("%s: map_idx=%d unmap_idx=%d "
- "current time=[%5lu.%06lu]\n", __FUNCTION__,
- map_log->idx, unmap_log->idx, (unsigned long)ts_sec,
- (unsigned long)ts_usec);
- printk("%s: dhd_map_log(pa)=0x%llx size=%d,"
- " dma_unmap_log(pa)=0x%llx size=%d\n", __FUNCTION__,
- (uint64)__virt_to_phys((ulong)(map_log->map)),
- (uint32)(sizeof(dhd_map_item_t) * map_log->items),
- (uint64)__virt_to_phys((ulong)(unmap_log->map)),
- (uint32)(sizeof(dhd_map_item_t) * unmap_log->items));
- }
- }
- static void *
- osl_dma_map_log_init(uint32 item_len)
- {
- dhd_map_log_t *map_log;
- gfp_t flags;
- uint32 alloc_size = (uint32)(sizeof(dhd_map_log_t) +
- (item_len * sizeof(dhd_map_item_t)));
- flags = CAN_SLEEP() ? GFP_KERNEL : GFP_ATOMIC;
- map_log = (dhd_map_log_t *)kmalloc(alloc_size, flags);
- if (map_log) {
- memset(map_log, 0, alloc_size);
- map_log->items = item_len;
- map_log->idx = 0;
- }
- return (void *)map_log;
- }
- static void
- osl_dma_map_log_deinit(osl_t *osh)
- {
- if (osh->dhd_map_log) {
- kfree(osh->dhd_map_log);
- osh->dhd_map_log = NULL;
- }
- if (osh->dhd_unmap_log) {
- kfree(osh->dhd_unmap_log);
- osh->dhd_unmap_log = NULL;
- }
- }
- static void
- osl_dma_map_logging(osl_t *osh, void *handle, dmaaddr_t pa, uint32 len)
- {
- dhd_map_log_t *log = (dhd_map_log_t *)handle;
- uint32 idx;
- if (log == NULL) {
- printk("%s: log is NULL\n", __FUNCTION__);
- return;
- }
- idx = log->idx;
- log->map[idx].ts_nsec = osl_localtime_ns();
- log->map[idx].pa = pa;
- log->map[idx].size = len;
- log->idx = (idx + 1) % log->items;
- }
- #endif /* DHD_MAP_LOGGING */
- /* translate bcmerrors into linux errors */
- int
- osl_error(int bcmerror)
- {
- if (bcmerror > 0)
- bcmerror = 0;
- else if (bcmerror < BCME_LAST)
- bcmerror = BCME_ERROR;
- /* Array bounds covered by ASSERT in osl_attach */
- return linuxbcmerrormap[-bcmerror];
- }
- osl_t *
- osl_attach(void *pdev, uint bustype, bool pkttag)
- {
- void **osl_cmn = NULL;
- osl_t *osh;
- gfp_t flags;
- #ifdef BCM_SECURE_DMA
- u32 secdma_memsize;
- #endif // endif
- flags = CAN_SLEEP() ? GFP_KERNEL: GFP_ATOMIC;
- if (!(osh = kmalloc(sizeof(osl_t), flags)))
- return osh;
- ASSERT(osh);
- bzero(osh, sizeof(osl_t));
- if (osl_cmn == NULL || *osl_cmn == NULL) {
- if (!(osh->cmn = kmalloc(sizeof(osl_cmn_t), flags))) {
- kfree(osh);
- return NULL;
- }
- bzero(osh->cmn, sizeof(osl_cmn_t));
- if (osl_cmn)
- *osl_cmn = osh->cmn;
- atomic_set(&osh->cmn->malloced, 0);
- osh->cmn->dbgmem_list = NULL;
- spin_lock_init(&(osh->cmn->dbgmem_lock));
- spin_lock_init(&(osh->cmn->pktalloc_lock));
- } else {
- osh->cmn = *osl_cmn;
- }
- atomic_add(1, &osh->cmn->refcount);
- bcm_object_trace_init();
- /* Check that error map has the right number of entries in it */
- ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1));
- osh->failed = 0;
- osh->pdev = pdev;
- osh->pub.pkttag = pkttag;
- osh->bustype = bustype;
- osh->magic = OS_HANDLE_MAGIC;
- #ifdef BCM_SECURE_DMA
- if ((secdma_addr != 0) && (secdma_size != 0)) {
- printk("linux_osl.c: Buffer info passed via module params, using it.\n");
- if (secdma_found == 0) {
- osh->contig_base_alloc = (phys_addr_t)secdma_addr;
- secdma_memsize = secdma_size;
- } else if (secdma_found == 1) {
- osh->contig_base_alloc = (phys_addr_t)secdma_addr2;
- secdma_memsize = secdma_size2;
- } else {
- printk("linux_osl.c secdma: secDMA instances %d \n", secdma_found);
- kfree(osh);
- return NULL;
- }
- osh->contig_base = (phys_addr_t)osh->contig_base_alloc;
- printf("linux_osl.c: secdma_cma_size = 0x%x\n", secdma_memsize);
- printf("linux_osl.c: secdma_cma_addr = 0x%x \n",
- (unsigned int)osh->contig_base_alloc);
- osh->stb_ext_params = SECDMA_MODULE_PARAMS;
- }
- else if (stbpriv_init(osh) == 0) {
- printk("linux_osl.c: stbpriv.txt found. Get buffer info.\n");
- if (secdma_found == 0) {
- osh->contig_base_alloc =
- (phys_addr_t)bcm_strtoul(stbparam_get("secdma_cma_addr"), NULL, 0);
- secdma_memsize = bcm_strtoul(stbparam_get("secdma_cma_size"), NULL, 0);
- } else if (secdma_found == 1) {
- osh->contig_base_alloc =
- (phys_addr_t)bcm_strtoul(stbparam_get("secdma_cma_addr2"), NULL, 0);
- secdma_memsize = bcm_strtoul(stbparam_get("secdma_cma_size2"), NULL, 0);
- } else {
- printk("linux_osl.c secdma: secDMA instances %d \n", secdma_found);
- kfree(osh);
- return NULL;
- }
- osh->contig_base = (phys_addr_t)osh->contig_base_alloc;
- printf("linux_osl.c: secdma_cma_size = 0x%x\n", secdma_memsize);
- printf("linux_osl.c: secdma_cma_addr = 0x%x \n",
- (unsigned int)osh->contig_base_alloc);
- osh->stb_ext_params = SECDMA_EXT_FILE;
- }
- else {
- printk("linux_osl.c: secDMA no longer supports internal buffer allocation.\n");
- kfree(osh);
- return NULL;
- }
- secdma_found++;
- osh->contig_base_alloc_coherent_va = osl_sec_dma_ioremap(osh,
- phys_to_page((u32)osh->contig_base_alloc),
- CMA_DMA_DESC_MEMBLOCK, FALSE, TRUE);
- if (osh->contig_base_alloc_coherent_va == NULL) {
- if (osh->cmn)
- kfree(osh->cmn);
- kfree(osh);
- return NULL;
- }
- osh->contig_base_coherent_va = osh->contig_base_alloc_coherent_va;
- osh->contig_base_alloc_coherent = osh->contig_base_alloc;
- osl_sec_dma_init_consistent(osh);
- osh->contig_base_alloc += CMA_DMA_DESC_MEMBLOCK;
- osh->contig_base_alloc_va = osl_sec_dma_ioremap(osh,
- phys_to_page((u32)osh->contig_base_alloc), CMA_DMA_DATA_MEMBLOCK, TRUE, FALSE);
- if (osh->contig_base_alloc_va == NULL) {
- osl_sec_dma_iounmap(osh, osh->contig_base_coherent_va, CMA_DMA_DESC_MEMBLOCK);
- if (osh->cmn)
- kfree(osh->cmn);
- kfree(osh);
- return NULL;
- }
- osh->contig_base_va = osh->contig_base_alloc_va;
- if (BCME_OK != osl_sec_dma_init_elem_mem_block(osh,
- CMA_BUFSIZE_4K, CMA_BUFNUM, &osh->sec_list_4096)) {
- osl_sec_dma_iounmap(osh, osh->contig_base_coherent_va, CMA_DMA_DESC_MEMBLOCK);
- osl_sec_dma_iounmap(osh, osh->contig_base_va, CMA_DMA_DATA_MEMBLOCK);
- if (osh->cmn)
- kfree(osh->cmn);
- kfree(osh);
- return NULL;
- }
- osh->sec_list_base_4096 = osh->sec_list_4096;
- #endif /* BCM_SECURE_DMA */
- switch (bustype) {
- case PCI_BUS:
- case SI_BUS:
- case PCMCIA_BUS:
- osh->pub.mmbus = TRUE;
- break;
- case JTAG_BUS:
- case SDIO_BUS:
- case USB_BUS:
- case SPI_BUS:
- case RPC_BUS:
- osh->pub.mmbus = FALSE;
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- DMA_LOCK_INIT(osh);
- #ifdef DHD_MAP_LOGGING
- osh->dhd_map_log = osl_dma_map_log_init(DHD_MAP_LOG_SIZE);
- if (osh->dhd_map_log == NULL) {
- printk("%s: Failed to alloc dhd_map_log\n", __FUNCTION__);
- }
- osh->dhd_unmap_log = osl_dma_map_log_init(DHD_MAP_LOG_SIZE);
- if (osh->dhd_unmap_log == NULL) {
- printk("%s: Failed to alloc dhd_unmap_log\n", __FUNCTION__);
- }
- #endif /* DHD_MAP_LOGGING */
- return osh;
- }
- void osl_set_bus_handle(osl_t *osh, void *bus_handle)
- {
- osh->bus_handle = bus_handle;
- }
- void* osl_get_bus_handle(osl_t *osh)
- {
- return osh->bus_handle;
- }
- #if defined(BCM_BACKPLANE_TIMEOUT)
- void osl_set_bpt_cb(osl_t *osh, void *bpt_cb, void *bpt_ctx)
- {
- if (osh) {
- osh->bpt_cb = (bpt_cb_fn)bpt_cb;
- osh->sih = bpt_ctx;
- }
- }
- #endif /* BCM_BACKPLANE_TIMEOUT */
- void
- osl_detach(osl_t *osh)
- {
- if (osh == NULL)
- return;
- #ifdef BCM_SECURE_DMA
- if (osh->stb_ext_params == SECDMA_EXT_FILE)
- stbpriv_exit(osh);
- osl_sec_dma_deinit_elem_mem_block(osh, CMA_BUFSIZE_4K, CMA_BUFNUM, osh->sec_list_base_4096);
- osl_sec_dma_iounmap(osh, osh->contig_base_coherent_va, CMA_DMA_DESC_MEMBLOCK);
- osl_sec_dma_iounmap(osh, osh->contig_base_va, CMA_DMA_DATA_MEMBLOCK);
- secdma_found--;
- #endif /* BCM_SECURE_DMA */
- bcm_object_trace_deinit();
- #ifdef DHD_MAP_LOGGING
- osl_dma_map_log_deinit(osh->dhd_map_log);
- osl_dma_map_log_deinit(osh->dhd_unmap_log);
- #endif /* DHD_MAP_LOGGING */
- ASSERT(osh->magic == OS_HANDLE_MAGIC);
- atomic_sub(1, &osh->cmn->refcount);
- if (atomic_read(&osh->cmn->refcount) == 0) {
- kfree(osh->cmn);
- }
- kfree(osh);
- }
- /* APIs to set/get specific quirks in OSL layer */
- void BCMFASTPATH
- osl_flag_set(osl_t *osh, uint32 mask)
- {
- osh->flags |= mask;
- }
- void
- osl_flag_clr(osl_t *osh, uint32 mask)
- {
- osh->flags &= ~mask;
- }
- #if defined(STB)
- inline bool BCMFASTPATH
- #else
- bool
- #endif // endif
- osl_is_flag_set(osl_t *osh, uint32 mask)
- {
- return (osh->flags & mask);
- }
- #if (defined(__ARM_ARCH_7A__) && !defined(DHD_USE_COHERENT_MEM_FOR_RING)) || \
- defined(STB_SOC_WIFI)
- inline int BCMFASTPATH
- osl_arch_is_coherent(void)
- {
- return 0;
- }
- inline int BCMFASTPATH
- osl_acp_war_enab(void)
- {
- return 0;
- }
- inline void BCMFASTPATH
- osl_cache_flush(void *va, uint size)
- {
- if (size > 0)
- #ifdef STB_SOC_WIFI
- dma_sync_single_for_device(OSH_NULL, virt_to_phys(va), size, DMA_TX);
- #else /* STB_SOC_WIFI */
- dma_sync_single_for_device(OSH_NULL, virt_to_dma(OSH_NULL, va), size,
- DMA_TO_DEVICE);
- #endif /* STB_SOC_WIFI */
- }
- inline void BCMFASTPATH
- osl_cache_inv(void *va, uint size)
- {
- #ifdef STB_SOC_WIFI
- dma_sync_single_for_cpu(OSH_NULL, virt_to_phys(va), size, DMA_RX);
- #else /* STB_SOC_WIFI */
- dma_sync_single_for_cpu(OSH_NULL, virt_to_dma(OSH_NULL, va), size, DMA_FROM_DEVICE);
- #endif /* STB_SOC_WIFI */
- }
- inline void BCMFASTPATH
- osl_prefetch(const void *ptr)
- {
- #if !defined(STB_SOC_WIFI)
- __asm__ __volatile__("pld\t%0" :: "o"(*(const char *)ptr) : "cc");
- #endif // endif
- }
- #endif // endif
- uint32
- osl_pci_read_config(osl_t *osh, uint offset, uint size)
- {
- uint val = 0;
- uint retry = PCI_CFG_RETRY;
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- /* only 4byte access supported */
- ASSERT(size == 4);
- do {
- pci_read_config_dword(osh->pdev, offset, &val);
- if (val != 0xffffffff)
- break;
- } while (retry--);
- return (val);
- }
- void
- osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
- {
- uint retry = PCI_CFG_RETRY;
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- /* only 4byte access supported */
- ASSERT(size == 4);
- do {
- pci_write_config_dword(osh->pdev, offset, val);
- if (offset != PCI_BAR0_WIN)
- break;
- if (osl_pci_read_config(osh, offset, size) == val)
- break;
- } while (retry--);
- }
- /* return bus # for the pci device pointed by osh->pdev */
- uint
- osl_pci_bus(osl_t *osh)
- {
- ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
- #if defined(__ARM_ARCH_7A__)
- return pci_domain_nr(((struct pci_dev *)osh->pdev)->bus);
- #else
- return ((struct pci_dev *)osh->pdev)->bus->number;
- #endif // endif
- }
- /* return slot # for the pci device pointed by osh->pdev */
- uint
- osl_pci_slot(osl_t *osh)
- {
- ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
- #if defined(__ARM_ARCH_7A__)
- return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn) + 1;
- #else
- return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
- #endif // endif
- }
- /* return domain # for the pci device pointed by osh->pdev */
- uint
- osl_pcie_domain(osl_t *osh)
- {
- ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
- return pci_domain_nr(((struct pci_dev *)osh->pdev)->bus);
- }
- /* return bus # for the pci device pointed by osh->pdev */
- uint
- osl_pcie_bus(osl_t *osh)
- {
- ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
- return ((struct pci_dev *)osh->pdev)->bus->number;
- }
- /* return the pci device pointed by osh->pdev */
- struct pci_dev *
- osl_pci_device(osl_t *osh)
- {
- ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
- return osh->pdev;
- }
- static void
- osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write)
- {
- }
- void
- osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size)
- {
- osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE);
- }
- void
- osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size)
- {
- osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE);
- }
- void *
- osl_malloc(osl_t *osh, uint size)
- {
- void *addr;
- gfp_t flags;
- /* only ASSERT if osh is defined */
- if (osh)
- ASSERT(osh->magic == OS_HANDLE_MAGIC);
- #ifdef CONFIG_DHD_USE_STATIC_BUF
- if (bcm_static_buf)
- {
- unsigned long irq_flags;
- int i = 0;
- if ((size >= PAGE_SIZE)&&(size <= STATIC_BUF_SIZE))
- {
- spin_lock_irqsave(&bcm_static_buf->static_lock, irq_flags);
- for (i = 0; i < STATIC_BUF_MAX_NUM; i++)
- {
- if (bcm_static_buf->buf_use[i] == 0)
- break;
- }
- if (i == STATIC_BUF_MAX_NUM)
- {
- spin_unlock_irqrestore(&bcm_static_buf->static_lock, irq_flags);
- printk("all static buff in use!\n");
- goto original;
- }
- bcm_static_buf->buf_use[i] = 1;
- spin_unlock_irqrestore(&bcm_static_buf->static_lock, irq_flags);
- bzero(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i, size);
- if (osh)
- atomic_add(size, &osh->cmn->malloced);
- return ((void *)(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i));
- }
- }
- original:
- #endif /* CONFIG_DHD_USE_STATIC_BUF */
- flags = CAN_SLEEP() ? GFP_KERNEL: GFP_ATOMIC;
- if ((addr = kmalloc(size, flags)) == NULL) {
- if (osh)
- osh->failed++;
- return (NULL);
- }
- if (osh && osh->cmn)
- atomic_add(size, &osh->cmn->malloced);
- return (addr);
- }
- void *
- osl_mallocz(osl_t *osh, uint size)
- {
- void *ptr;
- ptr = osl_malloc(osh, size);
- if (ptr != NULL) {
- bzero(ptr, size);
- }
- return ptr;
- }
- void
- osl_mfree(osl_t *osh, void *addr, uint size)
- {
- #ifdef CONFIG_DHD_USE_STATIC_BUF
- unsigned long flags;
- if (bcm_static_buf)
- {
- if ((addr > (void *)bcm_static_buf) && ((unsigned char *)addr
- <= ((unsigned char *)bcm_static_buf + STATIC_BUF_TOTAL_LEN)))
- {
- int buf_idx = 0;
- buf_idx = ((unsigned char *)addr - bcm_static_buf->buf_ptr)/STATIC_BUF_SIZE;
- spin_lock_irqsave(&bcm_static_buf->static_lock, flags);
- bcm_static_buf->buf_use[buf_idx] = 0;
- spin_unlock_irqrestore(&bcm_static_buf->static_lock, flags);
- if (osh && osh->cmn) {
- ASSERT(osh->magic == OS_HANDLE_MAGIC);
- atomic_sub(size, &osh->cmn->malloced);
- }
- return;
- }
- }
- #endif /* CONFIG_DHD_USE_STATIC_BUF */
- if (osh && osh->cmn) {
- ASSERT(osh->magic == OS_HANDLE_MAGIC);
- ASSERT(size <= osl_malloced(osh));
- atomic_sub(size, &osh->cmn->malloced);
- }
- kfree(addr);
- }
- void *
- osl_vmalloc(osl_t *osh, uint size)
- {
- void *addr;
- /* only ASSERT if osh is defined */
- if (osh)
- ASSERT(osh->magic == OS_HANDLE_MAGIC);
- if ((addr = vmalloc(size)) == NULL) {
- if (osh)
- osh->failed++;
- return (NULL);
- }
- if (osh && osh->cmn)
- atomic_add(size, &osh->cmn->malloced);
- return (addr);
- }
- void *
- osl_vmallocz(osl_t *osh, uint size)
- {
- void *ptr;
- ptr = osl_vmalloc(osh, size);
- if (ptr != NULL) {
- bzero(ptr, size);
- }
- return ptr;
- }
- void
- osl_vmfree(osl_t *osh, void *addr, uint size)
- {
- if (osh && osh->cmn) {
- ASSERT(osh->magic == OS_HANDLE_MAGIC);
- ASSERT(size <= osl_malloced(osh));
- atomic_sub(size, &osh->cmn->malloced);
- }
- vfree(addr);
- }
- uint
- osl_check_memleak(osl_t *osh)
- {
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- if (atomic_read(&osh->cmn->refcount) == 1)
- return (atomic_read(&osh->cmn->malloced));
- else
- return 0;
- }
- uint
- osl_malloced(osl_t *osh)
- {
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- return (atomic_read(&osh->cmn->malloced));
- }
- uint
- osl_malloc_failed(osl_t *osh)
- {
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- return (osh->failed);
- }
- uint
- osl_dma_consistent_align(void)
- {
- return (PAGE_SIZE);
- }
- void*
- osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, uint *alloced, dmaaddr_t *pap)
- {
- void *va;
- uint16 align = (1 << align_bits);
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align))
- size += align;
- *alloced = size;
- #ifndef BCM_SECURE_DMA
- #if (defined(__ARM_ARCH_7A__) && !defined(DHD_USE_COHERENT_MEM_FOR_RING)) || \
- defined(STB_SOC_WIFI)
- va = kmalloc(size, GFP_ATOMIC | __GFP_ZERO);
- if (va)
- *pap = (ulong)__virt_to_phys((ulong)va);
- #else
- {
- dma_addr_t pap_lin;
- struct pci_dev *hwdev = osh->pdev;
- gfp_t flags;
- #ifdef DHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL
- flags = GFP_ATOMIC;
- #else
- flags = CAN_SLEEP() ? GFP_KERNEL: GFP_ATOMIC;
- #endif /* DHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL */
- va = dma_alloc_coherent(&hwdev->dev, size, &pap_lin, flags);
- #ifdef BCMDMA64OSL
- PHYSADDRLOSET(*pap, pap_lin & 0xffffffff);
- PHYSADDRHISET(*pap, (pap_lin >> 32) & 0xffffffff);
- #else
- *pap = (dmaaddr_t)pap_lin;
- #endif /* BCMDMA64OSL */
- }
- #endif /* __ARM_ARCH_7A__ && !DHD_USE_COHERENT_MEM_FOR_RING */
- #else
- va = osl_sec_dma_alloc_consistent(osh, size, align_bits, pap);
- #endif /* BCM_SECURE_DMA */
- return va;
- }
- void
- osl_dma_free_consistent(osl_t *osh, void *va, uint size, dmaaddr_t pa)
- {
- #ifdef BCMDMA64OSL
- dma_addr_t paddr;
- #endif /* BCMDMA64OSL */
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- #ifndef BCM_SECURE_DMA
- #if (defined(__ARM_ARCH_7A__) && !defined(DHD_USE_COHERENT_MEM_FOR_RING)) || \
- defined(STB_SOC_WIFI)
- kfree(va);
- #else
- #ifdef BCMDMA64OSL
- PHYSADDRTOULONG(pa, paddr);
- pci_free_consistent(osh->pdev, size, va, paddr);
- #else
- pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
- #endif /* BCMDMA64OSL */
- #endif /* __ARM_ARCH_7A__ && !DHD_USE_COHERENT_MEM_FOR_RING */
- #else
- osl_sec_dma_free_consistent(osh, va, size, pa);
- #endif /* BCM_SECURE_DMA */
- }
- void *
- osl_virt_to_phys(void *va)
- {
- return (void *)(uintptr)virt_to_phys(va);
- }
- #include <asm/cacheflush.h>
- void BCMFASTPATH
- osl_dma_flush(osl_t *osh, void *va, uint size, int direction, void *p, hnddma_seg_map_t *dmah)
- {
- return;
- }
- dmaaddr_t BCMFASTPATH
- osl_dma_map(osl_t *osh, void *va, uint size, int direction, void *p, hnddma_seg_map_t *dmah)
- {
- int dir;
- dmaaddr_t ret_addr;
- dma_addr_t map_addr;
- int ret;
- DMA_LOCK(osh);
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
- #ifdef STB_SOC_WIFI
- #if (__LINUX_ARM_ARCH__ == 8)
- /* need to flush or invalidate the cache here */
- if (dir == DMA_TX) { /* to device */
- osl_cache_flush(va, size);
- } else if (dir == DMA_RX) { /* from device */
- osl_cache_inv(va, size);
- } else { /* both */
- osl_cache_flush(va, size);
- osl_cache_inv(va, size);
- }
- DMA_UNLOCK(osh);
- return virt_to_phys(va);
- #else /* (__LINUX_ARM_ARCH__ == 8) */
- map_addr = dma_map_single(osh->pdev, va, size, dir);
- DMA_UNLOCK(osh);
- return map_addr;
- #endif /* (__LINUX_ARM_ARCH__ == 8) */
- #else /* ! STB_SOC_WIFI */
- map_addr = pci_map_single(osh->pdev, va, size, dir);
- #endif /* ! STB_SOC_WIFI */
- ret = pci_dma_mapping_error(osh->pdev, map_addr);
- if (ret) {
- printk("%s: Failed to map memory\n", __FUNCTION__);
- PHYSADDRLOSET(ret_addr, 0);
- PHYSADDRHISET(ret_addr, 0);
- } else {
- PHYSADDRLOSET(ret_addr, map_addr & 0xffffffff);
- PHYSADDRHISET(ret_addr, (map_addr >> 32) & 0xffffffff);
- }
- #ifdef DHD_MAP_LOGGING
- osl_dma_map_logging(osh, osh->dhd_map_log, ret_addr, size);
- #endif /* DHD_MAP_LOGGING */
- DMA_UNLOCK(osh);
- return ret_addr;
- }
- void BCMFASTPATH
- osl_dma_unmap(osl_t *osh, dmaaddr_t pa, uint size, int direction)
- {
- int dir;
- #ifdef BCMDMA64OSL
- dma_addr_t paddr;
- #endif /* BCMDMA64OSL */
- ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
- DMA_LOCK(osh);
- dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
- #ifdef DHD_MAP_LOGGING
- osl_dma_map_logging(osh, osh->dhd_unmap_log, pa, size);
- #endif /* DHD_MAP_LOGGING */
- #ifdef BCMDMA64OSL
- PHYSADDRTOULONG(pa, paddr);
- pci_unmap_single(osh->pdev, paddr, size, dir);
- #else /* BCMDMA64OSL */
- #ifdef STB_SOC_WIFI
- #if (__LINUX_ARM_ARCH__ == 8)
- if (dir == DMA_TX) { /* to device */
- dma_sync_single_for_device(OSH_NULL, pa, size, DMA_TX);
- } else if (dir == DMA_RX) { /* from device */
- dma_sync_single_for_cpu(OSH_NULL, pa, size, DMA_RX);
- } else { /* both */
- dma_sync_single_for_device(OSH_NULL, pa, size, DMA_TX);
- dma_sync_single_for_cpu(OSH_NULL, pa, size, DMA_RX);
- }
- #else /* (__LINUX_ARM_ARCH__ == 8) */
- dma_unmap_single(osh->pdev, (uintptr)pa, size, dir);
- #endif /* (__LINUX_ARM_ARCH__ == 8) */
- #else /* STB_SOC_WIFI */
- pci_unmap_single(osh->pdev, (uint32)pa, size, dir);
- #endif /* STB_SOC_WIFI */
- #endif /* BCMDMA64OSL */
- DMA_UNLOCK(osh);
- }
- /* OSL function for CPU relax */
- inline void BCMFASTPATH
- osl_cpu_relax(void)
- {
- cpu_relax();
- }
- extern void osl_preempt_disable(osl_t *osh)
- {
- preempt_disable();
- }
- extern void osl_preempt_enable(osl_t *osh)
- {
- preempt_enable();
- }
- #if defined(BCMASSERT_LOG)
- void
- osl_assert(const char *exp, const char *file, int line)
- {
- char tempbuf[256];
- const char *basename;
- basename = strrchr(file, '/');
- /* skip the '/' */
- if (basename)
- basename++;
- if (!basename)
- basename = file;
- #ifdef BCMASSERT_LOG
- snprintf(tempbuf, 64, "\"%s\": file \"%s\", line %d\n",
- exp, basename, line);
- #ifndef OEM_ANDROID
- bcm_assert_log(tempbuf);
- #endif /* OEM_ANDROID */
- #endif /* BCMASSERT_LOG */
- switch (g_assert_type) {
- case 0:
- panic("%s", tempbuf);
- break;
- case 1:
- /* fall through */
- case 3:
- printk("%s", tempbuf);
- break;
- case 2:
- printk("%s", tempbuf);
- BUG();
- break;
- default:
- break;
- }
- }
- #endif // endif
- void
- osl_delay(uint usec)
- {
- uint d;
- while (usec > 0) {
- d = MIN(usec, 1000);
- udelay(d);
- usec -= d;
- }
- }
- void
- osl_sleep(uint ms)
- {
- if (ms < 20)
- usleep_range(ms*1000, ms*1000 + 1000);
- else
- msleep(ms);
- }
- uint64
- osl_sysuptime_us(void)
- {
- struct timeval tv;
- uint64 usec;
- do_gettimeofday(&tv);
- /* tv_usec content is fraction of a second */
- usec = (uint64)tv.tv_sec * 1000000ul + tv.tv_usec;
- return usec;
- }
- uint64
- osl_localtime_ns(void)
- {
- uint64 ts_nsec = 0;
- ts_nsec = local_clock();
- return ts_nsec;
- }
- void
- osl_get_localtime(uint64 *sec, uint64 *usec)
- {
- uint64 ts_nsec = 0;
- unsigned long rem_nsec = 0;
- ts_nsec = local_clock();
- rem_nsec = do_div(ts_nsec, NSEC_PER_SEC);
- *sec = (uint64)ts_nsec;
- *usec = (uint64)(rem_nsec / MSEC_PER_SEC);
- }
- uint64
- osl_systztime_us(void)
- {
- struct timeval tv;
- uint64 tzusec;
- do_gettimeofday(&tv);
- /* apply timezone */
- tzusec = (uint64)((tv.tv_sec - (sys_tz.tz_minuteswest * 60)) *
- USEC_PER_SEC);
- tzusec += tv.tv_usec;
- return tzusec;
- }
- /*
- * OSLREGOPS specifies the use of osl_XXX routines to be used for register access
- */
- /*
- * BINOSL selects the slightly slower function-call-based binary compatible osl.
- */
- uint32
- osl_rand(void)
- {
- uint32 rand;
- get_random_bytes(&rand, sizeof(rand));
- return rand;
- }
- /* Linux Kernel: File Operations: start */
- void *
- osl_os_open_image(char *filename)
- {
- struct file *fp;
- fp = filp_open(filename, O_RDONLY, 0);
- /*
- * 2.6.11 (FC4) supports filp_open() but later revs don't?
- * Alternative:
- * fp = open_namei(AT_FDCWD, filename, O_RD, 0);
- * ???
- */
- if (IS_ERR(fp))
- fp = NULL;
- return fp;
- }
- int
- osl_os_get_image_block(char *buf, int len, void *image)
- {
- struct file *fp = (struct file *)image;
- int rdlen;
- if (!image)
- return 0;
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
- rdlen = kernel_read(fp, buf, len, &fp->f_pos);
- #else
- rdlen = kernel_read(fp, fp->f_pos, buf, len);
- #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) */
- if (rdlen > 0)
- fp->f_pos += rdlen;
- return rdlen;
- }
- void
- osl_os_close_image(void *image)
- {
- if (image)
- filp_close((struct file *)image, NULL);
- }
- int
- osl_os_image_size(void *image)
- {
- int len = 0, curroffset;
- if (image) {
- /* store the current offset */
- curroffset = generic_file_llseek(image, 0, 1);
- /* goto end of file to get length */
- len = generic_file_llseek(image, 0, 2);
- /* restore back the offset */
- generic_file_llseek(image, curroffset, 0);
- }
- return len;
- }
- /* Linux Kernel: File Operations: end */
- #if (defined(STB) && defined(__arm__))
- inline void osl_pcie_rreg(osl_t *osh, ulong addr, volatile void *v, uint size)
- {
- unsigned long flags = 0;
- int pci_access = 0;
- int acp_war_enab = ACP_WAR_ENAB();
- if (osh && BUSTYPE(osh->bustype) == PCI_BUS)
- pci_access = 1;
- if (pci_access && acp_war_enab)
- spin_lock_irqsave(&l2x0_reg_lock, flags);
- switch (size) {
- case sizeof(uint8):
- *(volatile uint8*)v = readb((volatile uint8*)(addr));
- break;
- case sizeof(uint16):
- *(volatile uint16*)v = readw((volatile uint16*)(addr));
- break;
- case sizeof(uint32):
- *(volatile uint32*)v = readl((volatile uint32*)(addr));
- break;
- case sizeof(uint64):
- *(volatile uint64*)v = *((volatile uint64*)(addr));
- break;
- }
- if (pci_access && acp_war_enab)
- spin_unlock_irqrestore(&l2x0_reg_lock, flags);
- }
- #endif // endif
- #if defined(BCM_BACKPLANE_TIMEOUT)
- inline void osl_bpt_rreg(osl_t *osh, ulong addr, volatile void *v, uint size)
- {
- bool poll_timeout = FALSE;
- static int in_si_clear = FALSE;
- switch (size) {
- case sizeof(uint8):
- *(volatile uint8*)v = readb((volatile uint8*)(addr));
- if (*(volatile uint8*)v == 0xff)
- poll_timeout = TRUE;
- break;
- case sizeof(uint16):
- *(volatile uint16*)v = readw((volatile uint16*)(addr));
- if (*(volatile uint16*)v == 0xffff)
- poll_timeout = TRUE;
- break;
- case sizeof(uint32):
- *(volatile uint32*)v = readl((volatile uint32*)(addr));
- if (*(volatile uint32*)v == 0xffffffff)
- poll_timeout = TRUE;
- break;
- case sizeof(uint64):
- *(volatile uint64*)v = *((volatile uint64*)(addr));
- if (*(volatile uint64*)v == 0xffffffffffffffff)
- poll_timeout = TRUE;
- break;
- }
- if (osh && osh->sih && (in_si_clear == FALSE) && poll_timeout && osh->bpt_cb) {
- in_si_clear = TRUE;
- osh->bpt_cb((void *)osh->sih, (void *)addr);
- in_si_clear = FALSE;
- }
- }
- #endif /* BCM_BACKPLANE_TIMEOUT */
- #ifdef BCM_SECURE_DMA
- static void *
- osl_sec_dma_ioremap(osl_t *osh, struct page *page, size_t size, bool iscache, bool isdecr)
- {
- struct page **map;
- int order, i;
- void *addr = NULL;
- size = PAGE_ALIGN(size);
- order = get_order(size);
- map = kmalloc(sizeof(struct page *) << order, GFP_ATOMIC);
- if (map == NULL)
- return NULL;
- for (i = 0; i < (size >> PAGE_SHIFT); i++)
- map[i] = page + i;
- if (iscache) {
- addr = vmap(map, size >> PAGE_SHIFT, VM_MAP, __pgprot(PAGE_KERNEL));
- if (isdecr) {
- osh->contig_delta_va_pa = ((uint8 *)addr - page_to_phys(page));
- }
- } else {
- #if defined(__ARM_ARCH_7A__)
- addr = vmap(map, size >> PAGE_SHIFT, VM_MAP,
- pgprot_noncached(__pgprot(PAGE_KERNEL)));
- #endif // endif
- if (isdecr) {
- osh->contig_delta_va_pa = ((uint8 *)addr - page_to_phys(page));
- }
- }
- kfree(map);
- return (void *)addr;
- }
- static void
- osl_sec_dma_iounmap(osl_t *osh, void *contig_base_va, size_t size)
- {
- vunmap(contig_base_va);
- }
- static int
- osl_sec_dma_init_elem_mem_block(osl_t *osh, size_t mbsize, int max, sec_mem_elem_t **list)
- {
- int i;
- int ret = BCME_OK;
- sec_mem_elem_t *sec_mem_elem;
- if ((sec_mem_elem = kmalloc(sizeof(sec_mem_elem_t)*(max), GFP_ATOMIC)) != NULL) {
- *list = sec_mem_elem;
- bzero(sec_mem_elem, sizeof(sec_mem_elem_t)*(max));
- for (i = 0; i < max-1; i++) {
- sec_mem_elem->next = (sec_mem_elem + 1);
- sec_mem_elem->size = mbsize;
- sec_mem_elem->pa_cma = osh->contig_base_alloc;
- sec_mem_elem->vac = osh->contig_base_alloc_va;
- sec_mem_elem->pa_cma_page = phys_to_page(sec_mem_elem->pa_cma);
- osh->contig_base_alloc += mbsize;
- osh->contig_base_alloc_va = ((uint8 *)osh->contig_base_alloc_va + mbsize);
- sec_mem_elem = sec_mem_elem + 1;
- }
- sec_mem_elem->next = NULL;
- sec_mem_elem->size = mbsize;
- sec_mem_elem->pa_cma = osh->contig_base_alloc;
- sec_mem_elem->vac = osh->contig_base_alloc_va;
- sec_mem_elem->pa_cma_page = phys_to_page(sec_mem_elem->pa_cma);
- osh->contig_base_alloc += mbsize;
- osh->contig_base_alloc_va = ((uint8 *)osh->contig_base_alloc_va + mbsize);
- } else {
- printf("%s sec mem elem kmalloc failed\n", __FUNCTION__);
- ret = BCME_ERROR;
- }
- return ret;
- }
- static void
- osl_sec_dma_deinit_elem_mem_block(osl_t *osh, size_t mbsize, int max, void *sec_list_base)
- {
- if (sec_list_base)
- kfree(sec_list_base);
- }
- static sec_mem_elem_t * BCMFASTPATH
- osl_sec_dma_alloc_mem_elem(osl_t *osh, void *va, uint size, int direction,
- struct sec_cma_info *ptr_cma_info, uint offset)
- {
- sec_mem_elem_t *sec_mem_elem = NULL;
- ASSERT(osh->sec_list_4096);
- sec_mem_elem = osh->sec_list_4096;
- osh->sec_list_4096 = sec_mem_elem->next;
- sec_mem_elem->next = NULL;
- if (ptr_cma_info->sec_alloc_list_tail) {
- ptr_cma_info->sec_alloc_list_tail->next = sec_mem_elem;
- ptr_cma_info->sec_alloc_list_tail = sec_mem_elem;
- }
- else {
- /* First allocation: If tail is NULL, sec_alloc_list MUST also be NULL */
- ASSERT(ptr_cma_info->sec_alloc_list == NULL);
- ptr_cma_info->sec_alloc_list = sec_mem_elem;
- ptr_cma_info->sec_alloc_list_tail = sec_mem_elem;
- }
- return sec_mem_elem;
- }
- static void BCMFASTPATH
- osl_sec_dma_free_mem_elem(osl_t *osh, sec_mem_elem_t *sec_mem_elem)
- {
- sec_mem_elem->dma_handle = 0x0;
- sec_mem_elem->va = NULL;
- sec_mem_elem->next = osh->sec_list_4096;
- osh->sec_list_4096 = sec_mem_elem;
- }
- static sec_mem_elem_t * BCMFASTPATH
- osl_sec_dma_find_rem_elem(osl_t *osh, struct sec_cma_info *ptr_cma_info, dma_addr_t dma_handle)
- {
- sec_mem_elem_t *sec_mem_elem = ptr_cma_info->sec_alloc_list;
- sec_mem_elem_t *sec_prv_elem = ptr_cma_info->sec_alloc_list;
- if (sec_mem_elem->dma_handle == dma_handle) {
- ptr_cma_info->sec_alloc_list = sec_mem_elem->next;
- if (sec_mem_elem == ptr_cma_info->sec_alloc_list_tail) {
- ptr_cma_info->sec_alloc_list_tail = NULL;
- ASSERT(ptr_cma_info->sec_alloc_list == NULL);
- }
- return sec_mem_elem;
- }
- sec_mem_elem = sec_mem_elem->next;
- while (sec_mem_elem != NULL) {
- if (sec_mem_elem->dma_handle == dma_handle) {
- sec_prv_elem->next = sec_mem_elem->next;
- if (sec_mem_elem == ptr_cma_info->sec_alloc_list_tail)
- ptr_cma_info->sec_alloc_list_tail = sec_prv_elem;
- return sec_mem_elem;
- }
- sec_prv_elem = sec_mem_elem;
- sec_mem_elem = sec_mem_elem->next;
- }
- return NULL;
- }
- static sec_mem_elem_t *
- osl_sec_dma_rem_first_elem(osl_t *osh, struct sec_cma_info *ptr_cma_info)
- {
- sec_mem_elem_t *sec_mem_elem = ptr_cma_info->sec_alloc_list;
- if (sec_mem_elem) {
- ptr_cma_info->sec_alloc_list = sec_mem_elem->next;
- if (ptr_cma_info->sec_alloc_list == NULL)
- ptr_cma_info->sec_alloc_list_tail = NULL;
- return sec_mem_elem;
- } else
- return NULL;
- }
- static void * BCMFASTPATH
- osl_sec_dma_last_elem(osl_t *osh, struct sec_cma_info *ptr_cma_info)
- {
- return ptr_cma_info->sec_alloc_list_tail;
- }
- dma_addr_t BCMFASTPATH
- osl_sec_dma_map_txmeta(osl_t *osh, void *va, uint size, int direction, void *p,
- hnddma_seg_map_t *dmah, void *ptr_cma_info)
- {
- sec_mem_elem_t *sec_mem_elem;
- struct page *pa_cma_page;
- uint loffset;
- void *vaorig = ((uint8 *)va + size);
- dma_addr_t dma_handle = 0x0;
- /* packet will be the one added with osl_sec_dma_map() just before this call */
- sec_mem_elem = osl_sec_dma_last_elem(osh, ptr_cma_info);
- if (sec_mem_elem && sec_mem_elem->va == vaorig) {
- pa_cma_page = phys_to_page(sec_mem_elem->pa_cma);
- loffset = sec_mem_elem->pa_cma -(sec_mem_elem->pa_cma & ~(PAGE_SIZE-1));
- dma_handle = dma_map_page(OSH_NULL, pa_cma_page, loffset, size,
- (direction == DMA_TX ? DMA_TO_DEVICE:DMA_FROM_DEVICE));
- } else {
- printf("%s: error orig va not found va = 0x%p \n",
- __FUNCTION__, vaorig);
- }
- return dma_handle;
- }
- dma_addr_t BCMFASTPATH
- osl_sec_dma_map(osl_t *osh, void *va, uint size, int direction, void *p,
- hnddma_seg_map_t *dmah, void *ptr_cma_info, uint offset)
- {
- sec_mem_elem_t *sec_mem_elem;
- struct page *pa_cma_page;
- void *pa_cma_kmap_va = NULL;
- uint buflen = 0;
- dma_addr_t dma_handle = 0x0;
- uint loffset;
- ASSERT((direction == DMA_RX) || (direction == DMA_TX));
- sec_mem_elem = osl_sec_dma_alloc_mem_elem(osh, va, size, direction, ptr_cma_info, offset);
- sec_mem_elem->va = va;
- sec_mem_elem->direction = direction;
- pa_cma_page = sec_mem_elem->pa_cma_page;
- loffset = sec_mem_elem->pa_cma -(sec_mem_elem->pa_cma & ~(PAGE_SIZE-1));
- /* pa_cma_kmap_va = kmap_atomic(pa_cma_page);
- * pa_cma_kmap_va += loffset;
- */
- pa_cma_kmap_va = sec_mem_elem->vac;
- pa_cma_kmap_va = ((uint8 *)pa_cma_kmap_va + offset);
- buflen = size;
- if (direction == DMA_TX) {
- memcpy((uint8*)pa_cma_kmap_va+offset, va, size);
- if (dmah) {
- dmah->nsegs = 1;
- dmah->origsize = buflen;
- }
- }
- else
- {
- if ((p != NULL) && (dmah != NULL)) {
- dmah->nsegs = 1;
- dmah->origsize = buflen;
- }
- *(uint32 *)(pa_cma_kmap_va) = 0x0;
- }
- if (direction == DMA_RX) {
- flush_kernel_vmap_range(pa_cma_kmap_va, sizeof(int));
- }
- dma_handle = dma_map_page(OSH_NULL, pa_cma_page, loffset+offset, buflen,
- (direction == DMA_TX ? DMA_TO_DEVICE:DMA_FROM_DEVICE));
- if (dmah) {
- dmah->segs[0].addr = dma_handle;
- dmah->segs[0].length = buflen;
- }
- sec_mem_elem->dma_handle = dma_handle;
- /* kunmap_atomic(pa_cma_kmap_va-loffset); */
- return dma_handle;
- }
- dma_addr_t BCMFASTPATH
- osl_sec_dma_dd_map(osl_t *osh, void *va, uint size, int direction, void *p, hnddma_seg_map_t *map)
- {
- struct page *pa_cma_page;
- phys_addr_t pa_cma;
- dma_addr_t dma_handle = 0x0;
- uint loffset;
- pa_cma = ((uint8 *)va - (uint8 *)osh->contig_delta_va_pa);
- pa_cma_page = phys_to_page(pa_cma);
- loffset = pa_cma -(pa_cma & ~(PAGE_SIZE-1));
- dma_handle = dma_map_page(OSH_NULL, pa_cma_page, loffset, size,
- (direction == DMA_TX ? DMA_TO_DEVICE:DMA_FROM_DEVICE));
- return dma_handle;
- }
- void BCMFASTPATH
- osl_sec_dma_unmap(osl_t *osh, dma_addr_t dma_handle, uint size, int direction,
- void *p, hnddma_seg_map_t *map, void *ptr_cma_info, uint offset)
- {
- sec_mem_elem_t *sec_mem_elem;
- void *pa_cma_kmap_va = NULL;
- uint buflen = 0;
- dma_addr_t pa_cma;
- void *va;
- int read_count = 0;
- BCM_REFERENCE(buflen);
- BCM_REFERENCE(read_count);
- sec_mem_elem = osl_sec_dma_find_rem_elem(osh, ptr_cma_info, dma_handle);
- ASSERT(sec_mem_elem);
- va = sec_mem_elem->va;
- va = (uint8 *)va - offset;
- pa_cma = sec_mem_elem->pa_cma;
- if (direction == DMA_RX) {
- if (p == NULL) {
- /* pa_cma_kmap_va = kmap_atomic(pa_cma_page);
- * pa_cma_kmap_va += loffset;
- */
- pa_cma_kmap_va = sec_mem_elem->vac;
- do {
- invalidate_kernel_vmap_range(pa_cma_kmap_va, sizeof(int));
- buflen = *(uint *)(pa_cma_kmap_va);
- if (buflen)
- break;
- OSL_DELAY(1);
- read_count++;
- } while (read_count < 200);
- dma_unmap_page(OSH_NULL, pa_cma, size, DMA_FROM_DEVICE);
- memcpy(va, pa_cma_kmap_va, size);
- /* kunmap_atomic(pa_cma_kmap_va); */
- }
- } else {
- dma_unmap_page(OSH_NULL, pa_cma, size+offset, DMA_TO_DEVICE);
- }
- osl_sec_dma_free_mem_elem(osh, sec_mem_elem);
- }
- void
- osl_sec_dma_unmap_all(osl_t *osh, void *ptr_cma_info)
- {
- sec_mem_elem_t *sec_mem_elem;
- sec_mem_elem = osl_sec_dma_rem_first_elem(osh, ptr_cma_info);
- while (sec_mem_elem != NULL) {
- dma_unmap_page(OSH_NULL, sec_mem_elem->pa_cma, sec_mem_elem->size,
- sec_mem_elem->direction == DMA_TX ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
- osl_sec_dma_free_mem_elem(osh, sec_mem_elem);
- sec_mem_elem = osl_sec_dma_rem_first_elem(osh, ptr_cma_info);
- }
- }
- static void
- osl_sec_dma_init_consistent(osl_t *osh)
- {
- int i;
- void *temp_va = osh->contig_base_alloc_coherent_va;
- phys_addr_t temp_pa = osh->contig_base_alloc_coherent;
- for (i = 0; i < SEC_CMA_COHERENT_MAX; i++) {
- osh->sec_cma_coherent[i].avail = TRUE;
- osh->sec_cma_coherent[i].va = temp_va;
- osh->sec_cma_coherent[i].pa = temp_pa;
- temp_va = ((uint8 *)temp_va)+SEC_CMA_COHERENT_BLK;
- temp_pa += SEC_CMA_COHERENT_BLK;
- }
- }
- static void *
- osl_sec_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, ulong *pap)
- {
- void *temp_va = NULL;
- ulong temp_pa = 0;
- int i;
- if (size > SEC_CMA_COHERENT_BLK) {
- printf("%s unsupported size\n", __FUNCTION__);
- return NULL;
- }
- for (i = 0; i < SEC_CMA_COHERENT_MAX; i++) {
- if (osh->sec_cma_coherent[i].avail == TRUE) {
- temp_va = osh->sec_cma_coherent[i].va;
- temp_pa = osh->sec_cma_coherent[i].pa;
- osh->sec_cma_coherent[i].avail = FALSE;
- break;
- }
- }
- if (i == SEC_CMA_COHERENT_MAX)
- printf("%s:No coherent mem: va = 0x%p pa = 0x%lx size = %d\n", __FUNCTION__,
- temp_va, (ulong)temp_pa, size);
- *pap = (unsigned long)temp_pa;
- return temp_va;
- }
- static void
- osl_sec_dma_free_consistent(osl_t *osh, void *va, uint size, dmaaddr_t pa)
- {
- int i = 0;
- for (i = 0; i < SEC_CMA_COHERENT_MAX; i++) {
- if (osh->sec_cma_coherent[i].va == va) {
- osh->sec_cma_coherent[i].avail = TRUE;
- break;
- }
- }
- if (i == SEC_CMA_COHERENT_MAX)
- printf("%s:Error: va = 0x%p pa = 0x%lx size = %d\n", __FUNCTION__,
- va, (ulong)pa, size);
- }
- #endif /* BCM_SECURE_DMA */
- /* timer apis */
- /* Note: All timer api's are thread unsafe and should be protected with locks by caller */
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
- void
- timer_cb_compat(struct timer_list *tl)
- {
- timer_list_compat_t *t = container_of(tl, timer_list_compat_t, timer);
- t->callback((ulong)t->arg);
- }
- #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) */
- osl_timer_t *
- osl_timer_init(osl_t *osh, const char *name, void (*fn)(void *arg), void *arg)
- {
- osl_timer_t *t;
- BCM_REFERENCE(fn);
- if ((t = MALLOCZ(NULL, sizeof(osl_timer_t))) == NULL) {
- printk(KERN_ERR "osl_timer_init: out of memory, malloced %d bytes\n",
- (int)sizeof(osl_timer_t));
- return (NULL);
- }
- bzero(t, sizeof(osl_timer_t));
- if ((t->timer = MALLOCZ(NULL, sizeof(struct timer_list))) == NULL) {
- printf("osl_timer_init: malloc failed\n");
- MFREE(NULL, t, sizeof(osl_timer_t));
- return (NULL);
- }
- t->set = TRUE;
- init_timer_compat(t->timer, (linux_timer_fn)fn, arg);
- return (t);
- }
- void
- osl_timer_add(osl_t *osh, osl_timer_t *t, uint32 ms, bool periodic)
- {
- if (t == NULL) {
- printf("%s: Timer handle is NULL\n", __FUNCTION__);
- return;
- }
- ASSERT(!t->set);
- t->set = TRUE;
- if (periodic) {
- printf("Periodic timers are not supported by Linux timer apis\n");
- }
- timer_expires(t->timer) = jiffies + ms*HZ/1000;
- add_timer(t->timer);
- return;
- }
- void
- osl_timer_update(osl_t *osh, osl_timer_t *t, uint32 ms, bool periodic)
- {
- if (t == NULL) {
- printf("%s: Timer handle is NULL\n", __FUNCTION__);
- return;
- }
- if (periodic) {
- printf("Periodic timers are not supported by Linux timer apis\n");
- }
- t->set = TRUE;
- timer_expires(t->timer) = jiffies + ms*HZ/1000;
- mod_timer(t->timer, timer_expires(t->timer));
- return;
- }
- /*
- * Return TRUE if timer successfully deleted, FALSE if still pending
- */
- bool
- osl_timer_del(osl_t *osh, osl_timer_t *t)
- {
- if (t == NULL) {
- printf("%s: Timer handle is NULL\n", __FUNCTION__);
- return (FALSE);
- }
- if (t->set) {
- t->set = FALSE;
- if (t->timer) {
- del_timer(t->timer);
- MFREE(NULL, t->timer, sizeof(struct timer_list));
- }
- MFREE(NULL, t, sizeof(osl_timer_t));
- }
- return (TRUE);
- }
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
- int
- kernel_read_compat(struct file *file, loff_t offset, char *addr, unsigned long count)
- {
- return (int)kernel_read(file, addr, (size_t)count, &offset);
- }
- #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) */
- void *
- osl_spin_lock_init(osl_t *osh)
- {
- /* Adding 4 bytes since the sizeof(spinlock_t) could be 0 */
- /* if CONFIG_SMP and CONFIG_DEBUG_SPINLOCK are not defined */
- /* and this results in kernel asserts in internal builds */
- spinlock_t * lock = MALLOC(osh, sizeof(spinlock_t) + 4);
- if (lock)
- spin_lock_init(lock);
- return ((void *)lock);
- }
- void
- osl_spin_lock_deinit(osl_t *osh, void *lock)
- {
- if (lock)
- MFREE(osh, lock, sizeof(spinlock_t) + 4);
- }
- unsigned long
- osl_spin_lock(void *lock)
- {
- unsigned long flags = 0;
- if (lock)
- spin_lock_irqsave((spinlock_t *)lock, flags);
- return flags;
- }
- void
- osl_spin_unlock(void *lock, unsigned long flags)
- {
- if (lock)
- spin_unlock_irqrestore((spinlock_t *)lock, flags);
- }
- #ifdef USE_DMA_LOCK
- static void
- osl_dma_lock(osl_t *osh)
- {
- if (likely(in_irq() || irqs_disabled())) {
- spin_lock(&osh->dma_lock);
- } else {
- spin_lock_bh(&osh->dma_lock);
- osh->dma_lock_bh = TRUE;
- }
- }
- static void
- osl_dma_unlock(osl_t *osh)
- {
- if (unlikely(osh->dma_lock_bh)) {
- osh->dma_lock_bh = FALSE;
- spin_unlock_bh(&osh->dma_lock);
- } else {
- spin_unlock(&osh->dma_lock);
- }
- }
- static void
- osl_dma_lock_init(osl_t *osh)
- {
- spin_lock_init(&osh->dma_lock);
- osh->dma_lock_bh = FALSE;
- }
- #endif /* USE_DMA_LOCK */
|