Branch data Line data Source code
1 : : #include <linux/kernel.h>
2 : : #include <linux/init.h>
3 : : #include <linux/module.h>
4 : : #include <linux/kthread.h>
5 : :
6 : : #ifdef DWC_CCLIB
7 : : # include "dwc_cc.h"
8 : : #endif
9 : :
10 : : #ifdef DWC_CRYPTOLIB
11 : : # include "dwc_modpow.h"
12 : : # include "dwc_dh.h"
13 : : # include "dwc_crypto.h"
14 : : #endif
15 : :
16 : : #ifdef DWC_NOTIFYLIB
17 : : # include "dwc_notifier.h"
18 : : #endif
19 : :
20 : : /* OS-Level Implementations */
21 : :
22 : : /* This is the Linux kernel implementation of the DWC platform library. */
23 : : #include <linux/moduleparam.h>
24 : : #include <linux/ctype.h>
25 : : #include <linux/crypto.h>
26 : : #include <linux/delay.h>
27 : : #include <linux/device.h>
28 : : #include <linux/dma-mapping.h>
29 : : #include <linux/cdev.h>
30 : : #include <linux/errno.h>
31 : : #include <linux/interrupt.h>
32 : : #include <linux/jiffies.h>
33 : : #include <linux/list.h>
34 : : #include <linux/pci.h>
35 : : #include <linux/random.h>
36 : : #include <linux/scatterlist.h>
37 : : #include <linux/slab.h>
38 : : #include <linux/stat.h>
39 : : #include <linux/string.h>
40 : : #include <linux/timer.h>
41 : : #include <linux/usb.h>
42 : :
43 : : #include <linux/version.h>
44 : :
45 : : #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
46 : : # include <linux/usb/gadget.h>
47 : : #else
48 : : # include <linux/usb_gadget.h>
49 : : #endif
50 : :
51 : : #include <asm/io.h>
52 : : #include <asm/page.h>
53 : : #include <asm/uaccess.h>
54 : : #include <asm/unaligned.h>
55 : :
56 : : #include "dwc_os.h"
57 : : #include "dwc_list.h"
58 : :
59 : :
60 : : /* MISC */
61 : :
62 : 4480346 : void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size)
63 : : {
64 : 4480346 : return memset(dest, byte, size);
65 : : }
66 : :
67 : 10104 : void *DWC_MEMCPY(void *dest, void const *src, uint32_t size)
68 : : {
69 : 11139 : return memcpy(dest, src, size);
70 : : }
71 : :
72 : 0 : void *DWC_MEMMOVE(void *dest, void *src, uint32_t size)
73 : : {
74 : 0 : return memmove(dest, src, size);
75 : : }
76 : :
77 : 0 : int DWC_MEMCMP(void *m1, void *m2, uint32_t size)
78 : : {
79 : 0 : return memcmp(m1, m2, size);
80 : : }
81 : :
82 : 0 : int DWC_STRNCMP(void *s1, void *s2, uint32_t size)
83 : : {
84 : 0 : return strncmp(s1, s2, size);
85 : : }
86 : :
87 : 0 : int DWC_STRCMP(void *s1, void *s2)
88 : : {
89 : 0 : return strcmp(s1, s2);
90 : : }
91 : :
92 : 0 : int DWC_STRLEN(char const *str)
93 : : {
94 : 1035 : return strlen(str);
95 : : }
96 : :
97 : 0 : char *DWC_STRCPY(char *to, char const *from)
98 : : {
99 : 0 : return strcpy(to, from);
100 : : }
101 : :
102 : 1035 : char *DWC_STRDUP(char const *str)
103 : : {
104 : 1035 : int len = DWC_STRLEN(str) + 1;
105 : 1035 : char *new = DWC_ALLOC_ATOMIC(len);
106 : :
107 [ + - ]: 1035 : if (!new) {
108 : : return NULL;
109 : : }
110 : :
111 : : DWC_MEMCPY(new, str, len);
112 : 1035 : return new;
113 : : }
114 : :
115 : 0 : int DWC_ATOI(const char *str, int32_t *value)
116 : : {
117 : 0 : char *end = NULL;
118 : :
119 : 0 : *value = simple_strtol(str, &end, 0);
120 [ # # ]: 0 : if (*end == '\0') {
121 : : return 0;
122 : : }
123 : :
124 : 0 : return -1;
125 : : }
126 : :
127 : 0 : int DWC_ATOUI(const char *str, uint32_t *value)
128 : : {
129 : 0 : char *end = NULL;
130 : :
131 : 0 : *value = simple_strtoul(str, &end, 0);
132 [ # # ]: 0 : if (*end == '\0') {
133 : : return 0;
134 : : }
135 : :
136 : 0 : return -1;
137 : : }
138 : :
139 : :
140 : : #ifdef DWC_UTFLIB
141 : : /* From usbstring.c */
142 : :
143 : 0 : int DWC_UTF8_TO_UTF16LE(uint8_t const *s, uint16_t *cp, unsigned len)
144 : : {
145 : : int count = 0;
146 : : u8 c;
147 : : u16 uchar;
148 : :
149 : : /* this insists on correct encodings, though not minimal ones.
150 : : * BUT it currently rejects legit 4-byte UTF-8 code points,
151 : : * which need surrogate pairs. (Unicode 3.1 can use them.)
152 : : */
153 [ # # # # ]: 0 : while (len != 0 && (c = (u8) *s++) != 0) {
154 [ # # ]: 0 : if (unlikely(c & 0x80)) {
155 : : // 2-byte sequence:
156 : : // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
157 [ # # ]: 0 : if ((c & 0xe0) == 0xc0) {
158 : 0 : uchar = (c & 0x1f) << 6;
159 : :
160 : 0 : c = (u8) *s++;
161 [ # # ]: 0 : if ((c & 0xc0) != 0xc0)
162 : : goto fail;
163 : 0 : c &= 0x3f;
164 : 0 : uchar |= c;
165 : :
166 : : // 3-byte sequence (most CJKV characters):
167 : : // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
168 [ # # ]: 0 : } else if ((c & 0xf0) == 0xe0) {
169 : 0 : uchar = (c & 0x0f) << 12;
170 : :
171 : 0 : c = (u8) *s++;
172 [ # # ]: 0 : if ((c & 0xc0) != 0xc0)
173 : : goto fail;
174 : 0 : c &= 0x3f;
175 : 0 : uchar |= c << 6;
176 : :
177 : 0 : c = (u8) *s++;
178 [ # # ]: 0 : if ((c & 0xc0) != 0xc0)
179 : : goto fail;
180 : 0 : c &= 0x3f;
181 : 0 : uchar |= c;
182 : :
183 : : /* no bogus surrogates */
184 [ # # ]: 0 : if (0xd800 <= uchar && uchar <= 0xdfff)
185 : : goto fail;
186 : :
187 : : // 4-byte sequence (surrogate pairs, currently rare):
188 : : // 11101110wwwwzzzzyy + 110111yyyyxxxxxx
189 : : // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
190 : : // (uuuuu = wwww + 1)
191 : : // FIXME accept the surrogate code points (only)
192 : : } else
193 : : goto fail;
194 : : } else
195 : 0 : uchar = c;
196 : 0 : put_unaligned (cpu_to_le16 (uchar), cp++);
197 : 0 : count++;
198 : 0 : len--;
199 : : }
200 : 0 : return count;
201 : : fail:
202 : : return -1;
203 : : }
204 : : #endif /* DWC_UTFLIB */
205 : :
206 : :
207 : : /* dwc_debug.h */
208 : :
209 : 828 : dwc_bool_t DWC_IN_IRQ(void)
210 : : {
211 : 828 : return in_irq();
212 : : }
213 : :
214 : 0 : dwc_bool_t DWC_IN_BH(void)
215 : : {
216 : 0 : return in_softirq();
217 : : }
218 : :
219 : 0 : void DWC_VPRINTF(char *format, va_list args)
220 : : {
221 : 4347 : vprintk(format, args);
222 : 0 : }
223 : :
224 : 0 : int DWC_VSNPRINTF(char *str, int size, char *format, va_list args)
225 : : {
226 : 0 : return vsnprintf(str, size, format, args);
227 : : }
228 : :
229 : 3519 : void DWC_PRINTF(char *format, ...)
230 : : {
231 : : va_list args;
232 : :
233 : 3519 : va_start(args, format);
234 : : DWC_VPRINTF(format, args);
235 : 3519 : va_end(args);
236 : 3519 : }
237 : :
238 : 0 : int DWC_SPRINTF(char *buffer, char *format, ...)
239 : : {
240 : : int retval;
241 : : va_list args;
242 : :
243 : 0 : va_start(args, format);
244 : 0 : retval = vsprintf(buffer, format, args);
245 : 0 : va_end(args);
246 : 0 : return retval;
247 : : }
248 : :
249 : 0 : int DWC_SNPRINTF(char *buffer, int size, char *format, ...)
250 : : {
251 : : int retval;
252 : : va_list args;
253 : :
254 : 0 : va_start(args, format);
255 : 0 : retval = vsnprintf(buffer, size, format, args);
256 : 0 : va_end(args);
257 : 0 : return retval;
258 : : }
259 : :
260 : 828 : void __DWC_WARN(char *format, ...)
261 : : {
262 : : va_list args;
263 : :
264 : 828 : va_start(args, format);
265 : 828 : DWC_PRINTF(KERN_WARNING);
266 : : DWC_VPRINTF(format, args);
267 : 828 : va_end(args);
268 : 828 : }
269 : :
270 : 0 : void __DWC_ERROR(char *format, ...)
271 : : {
272 : : va_list args;
273 : :
274 : 0 : va_start(args, format);
275 : 0 : DWC_PRINTF(KERN_ERR);
276 : : DWC_VPRINTF(format, args);
277 : 0 : va_end(args);
278 : 0 : }
279 : :
280 : 0 : void DWC_EXCEPTION(char *format, ...)
281 : : {
282 : : va_list args;
283 : :
284 : 0 : va_start(args, format);
285 : 0 : DWC_PRINTF(KERN_ERR);
286 : : DWC_VPRINTF(format, args);
287 : 0 : va_end(args);
288 : 0 : BUG_ON(1);
289 : : }
290 : :
291 : : #ifdef DEBUG
292 : : void __DWC_DEBUG(char *format, ...)
293 : : {
294 : : va_list args;
295 : :
296 : : va_start(args, format);
297 : : DWC_PRINTF(KERN_DEBUG);
298 : : DWC_VPRINTF(format, args);
299 : : va_end(args);
300 : : }
301 : : #endif
302 : :
303 : :
304 : : /* dwc_mem.h */
305 : :
306 : : #if 0
307 : : dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size,
308 : : uint32_t align,
309 : : uint32_t alloc)
310 : : {
311 : : struct dma_pool *pool = dma_pool_create("Pool", NULL,
312 : : size, align, alloc);
313 : : return (dwc_pool_t *)pool;
314 : : }
315 : :
316 : : void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool)
317 : : {
318 : : dma_pool_destroy((struct dma_pool *)pool);
319 : : }
320 : :
321 : : void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
322 : : {
323 : : return dma_pool_alloc((struct dma_pool *)pool, GFP_KERNEL, dma_addr);
324 : : }
325 : :
326 : : void *DWC_DMA_POOL_ZALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
327 : : {
328 : : void *vaddr = DWC_DMA_POOL_ALLOC(pool, dma_addr);
329 : : memset(..);
330 : : }
331 : :
332 : : void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr)
333 : : {
334 : : dma_pool_free(pool, vaddr, daddr);
335 : : }
336 : : #endif
337 : :
338 : 828 : void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
339 : : {
340 : 828 : return dma_alloc_coherent(dma_ctx, size, dma_addr, GFP_KERNEL | GFP_DMA32);
341 : : }
342 : :
343 : 621 : void *__DWC_DMA_ALLOC_ATOMIC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
344 : : {
345 : 621 : return dma_alloc_coherent(dma_ctx, size, dma_addr, GFP_ATOMIC);
346 : : }
347 : :
348 : 0 : void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr)
349 : : {
350 : : dma_free_coherent(dma_ctx, size, virt_addr, dma_addr);
351 : 0 : }
352 : :
353 : 98739 : void *__DWC_ALLOC(void *mem_ctx, uint32_t size)
354 : : {
355 : 103293 : return kzalloc(size, GFP_KERNEL);
356 : : }
357 : :
358 : 297323 : void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size)
359 : : {
360 : 298358 : return kzalloc(size, GFP_ATOMIC);
361 : : }
362 : :
363 : 373293 : void __DWC_FREE(void *mem_ctx, void *addr)
364 : : {
365 : 373293 : kfree(addr);
366 : 373293 : }
367 : :
368 : :
369 : : #ifdef DWC_CRYPTOLIB
370 : : /* dwc_crypto.h */
371 : :
372 : : void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length)
373 : : {
374 : : get_random_bytes(buffer, length);
375 : : }
376 : :
377 : : int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out)
378 : : {
379 : : struct crypto_blkcipher *tfm;
380 : : struct blkcipher_desc desc;
381 : : struct scatterlist sgd;
382 : : struct scatterlist sgs;
383 : :
384 : : tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
385 : : if (tfm == NULL) {
386 : : printk("failed to load transform for aes CBC\n");
387 : : return -1;
388 : : }
389 : :
390 : : crypto_blkcipher_setkey(tfm, key, keylen);
391 : : crypto_blkcipher_set_iv(tfm, iv, 16);
392 : :
393 : : sg_init_one(&sgd, out, messagelen);
394 : : sg_init_one(&sgs, message, messagelen);
395 : :
396 : : desc.tfm = tfm;
397 : : desc.flags = 0;
398 : :
399 : : if (crypto_blkcipher_encrypt(&desc, &sgd, &sgs, messagelen)) {
400 : : crypto_free_blkcipher(tfm);
401 : : DWC_ERROR("AES CBC encryption failed");
402 : : return -1;
403 : : }
404 : :
405 : : crypto_free_blkcipher(tfm);
406 : : return 0;
407 : : }
408 : :
409 : : int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out)
410 : : {
411 : : struct crypto_hash *tfm;
412 : : struct hash_desc desc;
413 : : struct scatterlist sg;
414 : :
415 : : tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
416 : : if (IS_ERR(tfm)) {
417 : : DWC_ERROR("Failed to load transform for sha256: %ld\n", PTR_ERR(tfm));
418 : : return 0;
419 : : }
420 : : desc.tfm = tfm;
421 : : desc.flags = 0;
422 : :
423 : : sg_init_one(&sg, message, len);
424 : : crypto_hash_digest(&desc, &sg, len, out);
425 : : crypto_free_hash(tfm);
426 : :
427 : : return 1;
428 : : }
429 : :
430 : : int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen,
431 : : uint8_t *key, uint32_t keylen, uint8_t *out)
432 : : {
433 : : struct crypto_hash *tfm;
434 : : struct hash_desc desc;
435 : : struct scatterlist sg;
436 : :
437 : : tfm = crypto_alloc_hash("hmac(sha256)", 0, CRYPTO_ALG_ASYNC);
438 : : if (IS_ERR(tfm)) {
439 : : DWC_ERROR("Failed to load transform for hmac(sha256): %ld\n", PTR_ERR(tfm));
440 : : return 0;
441 : : }
442 : : desc.tfm = tfm;
443 : : desc.flags = 0;
444 : :
445 : : sg_init_one(&sg, message, messagelen);
446 : : crypto_hash_setkey(tfm, key, keylen);
447 : : crypto_hash_digest(&desc, &sg, messagelen, out);
448 : : crypto_free_hash(tfm);
449 : :
450 : : return 1;
451 : : }
452 : : #endif /* DWC_CRYPTOLIB */
453 : :
454 : :
455 : : /* Byte Ordering Conversions */
456 : :
457 : 1035 : uint32_t DWC_CPU_TO_LE32(uint32_t *p)
458 : : {
459 : : #ifdef __LITTLE_ENDIAN
460 : 1035 : return *p;
461 : : #else
462 : : uint8_t *u_p = (uint8_t *)p;
463 : :
464 : : return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
465 : : #endif
466 : : }
467 : :
468 : 0 : uint32_t DWC_CPU_TO_BE32(uint32_t *p)
469 : : {
470 : : #ifdef __BIG_ENDIAN
471 : : return *p;
472 : : #else
473 : : uint8_t *u_p = (uint8_t *)p;
474 : :
475 : 0 : return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
476 : : #endif
477 : : }
478 : :
479 : 0 : uint32_t DWC_LE32_TO_CPU(uint32_t *p)
480 : : {
481 : : #ifdef __LITTLE_ENDIAN
482 : 0 : return *p;
483 : : #else
484 : : uint8_t *u_p = (uint8_t *)p;
485 : :
486 : : return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
487 : : #endif
488 : : }
489 : :
490 : 0 : uint32_t DWC_BE32_TO_CPU(uint32_t *p)
491 : : {
492 : : #ifdef __BIG_ENDIAN
493 : : return *p;
494 : : #else
495 : : uint8_t *u_p = (uint8_t *)p;
496 : :
497 : 0 : return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
498 : : #endif
499 : : }
500 : :
501 : 0 : uint16_t DWC_CPU_TO_LE16(uint16_t *p)
502 : : {
503 : : #ifdef __LITTLE_ENDIAN
504 : 0 : return *p;
505 : : #else
506 : : uint8_t *u_p = (uint8_t *)p;
507 : : return (u_p[1] | (u_p[0] << 8));
508 : : #endif
509 : : }
510 : :
511 : 0 : uint16_t DWC_CPU_TO_BE16(uint16_t *p)
512 : : {
513 : : #ifdef __BIG_ENDIAN
514 : : return *p;
515 : : #else
516 : : uint8_t *u_p = (uint8_t *)p;
517 : 0 : return (u_p[1] | (u_p[0] << 8));
518 : : #endif
519 : : }
520 : :
521 : 0 : uint16_t DWC_LE16_TO_CPU(uint16_t *p)
522 : : {
523 : : #ifdef __LITTLE_ENDIAN
524 : 0 : return *p;
525 : : #else
526 : : uint8_t *u_p = (uint8_t *)p;
527 : : return (u_p[1] | (u_p[0] << 8));
528 : : #endif
529 : : }
530 : :
531 : 0 : uint16_t DWC_BE16_TO_CPU(uint16_t *p)
532 : : {
533 : : #ifdef __BIG_ENDIAN
534 : : return *p;
535 : : #else
536 : : uint8_t *u_p = (uint8_t *)p;
537 : 0 : return (u_p[1] | (u_p[0] << 8));
538 : : #endif
539 : : }
540 : :
541 : :
542 : : /* Registers */
543 : :
544 : 241546088 : uint32_t DWC_READ_REG32(uint32_t volatile *reg)
545 : : {
546 : 241545319 : return readl(reg);
547 : : }
548 : :
549 : : #if 0
550 : : uint64_t DWC_READ_REG64(uint64_t volatile *reg)
551 : : {
552 : : }
553 : : #endif
554 : :
555 : 91251129 : void DWC_WRITE_REG32(uint32_t volatile *reg, uint32_t value)
556 : : {
557 : 91251129 : writel(value, reg);
558 : 91251129 : }
559 : :
560 : : #if 0
561 : : void DWC_WRITE_REG64(uint64_t volatile *reg, uint64_t value)
562 : : {
563 : : }
564 : : #endif
565 : :
566 : 21276647 : void DWC_MODIFY_REG32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask)
567 : : {
568 : 42553294 : writel((readl(reg) & ~clear_mask) | set_mask, reg);
569 : 21276647 : }
570 : :
571 : : #if 0
572 : : void DWC_MODIFY_REG64(uint64_t volatile *reg, uint64_t clear_mask, uint64_t set_mask)
573 : : {
574 : : }
575 : : #endif
576 : :
577 : :
578 : : /* Locking */
579 : :
580 : 1863 : dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void)
581 : : {
582 : : spinlock_t *sl = (spinlock_t *)1;
583 : :
584 : : #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
585 : : sl = DWC_ALLOC(sizeof(*sl));
586 [ - + ]: 1863 : if (!sl) {
587 : 0 : DWC_ERROR("Cannot allocate memory for spinlock\n");
588 : 0 : return NULL;
589 : : }
590 : :
591 : 1863 : spin_lock_init(sl);
592 : : #endif
593 : 1863 : return (dwc_spinlock_t *)sl;
594 : : }
595 : :
596 : 0 : void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock)
597 : : {
598 : : #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
599 : : DWC_FREE(lock);
600 : : #endif
601 : 0 : }
602 : :
603 : 27644293 : void DWC_SPINLOCK(dwc_spinlock_t *lock)
604 : : {
605 : : #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
606 : : spin_lock((spinlock_t *)lock);
607 : : #endif
608 : 27644293 : }
609 : :
610 : 27644283 : void DWC_SPINUNLOCK(dwc_spinlock_t *lock)
611 : : {
612 : : #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
613 : : spin_unlock((spinlock_t *)lock);
614 : : #endif
615 : 27644282 : }
616 : :
617 : 381588 : void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags)
618 : : {
619 : : dwc_irqflags_t f;
620 : :
621 : : #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
622 : 381588 : spin_lock_irqsave((spinlock_t *)lock, f);
623 : : #else
624 : : local_irq_save(f);
625 : : #endif
626 : 381591 : *flags = f;
627 : 381591 : }
628 : :
629 : 381591 : void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags)
630 : : {
631 : : #if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
632 : : spin_unlock_irqrestore((spinlock_t *)lock, flags);
633 : : #else
634 : : local_irq_restore(flags);
635 : : #endif
636 : 381569 : }
637 : :
638 : 0 : dwc_mutex_t *DWC_MUTEX_ALLOC(void)
639 : : {
640 : : struct mutex *m;
641 : : dwc_mutex_t *mutex = (dwc_mutex_t *)DWC_ALLOC(sizeof(struct mutex));
642 : :
643 [ # # ]: 0 : if (!mutex) {
644 : 0 : DWC_ERROR("Cannot allocate memory for mutex\n");
645 : 0 : return NULL;
646 : : }
647 : :
648 : : m = (struct mutex *)mutex;
649 : 0 : mutex_init(m);
650 : 0 : return mutex;
651 : : }
652 : :
653 : : #if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES))
654 : : #else
655 : 0 : void DWC_MUTEX_FREE(dwc_mutex_t *mutex)
656 : : {
657 : : mutex_destroy((struct mutex *)mutex);
658 : : DWC_FREE(mutex);
659 : 0 : }
660 : : #endif
661 : :
662 : 0 : void DWC_MUTEX_LOCK(dwc_mutex_t *mutex)
663 : : {
664 : : struct mutex *m = (struct mutex *)mutex;
665 : 0 : mutex_lock(m);
666 : 0 : }
667 : :
668 : 0 : int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex)
669 : : {
670 : : struct mutex *m = (struct mutex *)mutex;
671 : 0 : return mutex_trylock(m);
672 : : }
673 : :
674 : 0 : void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex)
675 : : {
676 : : struct mutex *m = (struct mutex *)mutex;
677 : 0 : mutex_unlock(m);
678 : 0 : }
679 : :
680 : :
681 : : /* Timing */
682 : :
683 : 5299 : void DWC_UDELAY(uint32_t usecs)
684 : : {
685 [ - + # # ]: 5299 : udelay(usecs);
686 : 5299 : }
687 : :
688 : 1242 : void DWC_MDELAY(uint32_t msecs)
689 : : {
690 [ - + # # : 1242 : mdelay(msecs);
# # # # +
+ ]
691 : 1242 : }
692 : :
693 : 0 : void DWC_MSLEEP(uint32_t msecs)
694 : : {
695 : 0 : msleep(msecs);
696 : 0 : }
697 : :
698 : 0 : uint32_t DWC_TIME(void)
699 : : {
700 : 0 : return jiffies_to_msecs(jiffies);
701 : : }
702 : :
703 : :
704 : : /* Timers */
705 : :
706 : : struct dwc_timer {
707 : : struct timer_list t;
708 : : char *name;
709 : : dwc_timer_callback_t cb;
710 : : void *data;
711 : : uint8_t scheduled;
712 : : dwc_spinlock_t *lock;
713 : : };
714 : :
715 : 0 : static void timer_callback(struct timer_list *tt)
716 : : {
717 : : dwc_timer_t *timer = from_timer(timer, tt, t);
718 : : dwc_irqflags_t flags;
719 : :
720 : 0 : DWC_SPINLOCK_IRQSAVE(timer->lock, &flags);
721 : 0 : timer->scheduled = 0;
722 : 0 : DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags);
723 : : DWC_DEBUGC("Timer %s callback", timer->name);
724 : 0 : timer->cb(timer->data);
725 : 0 : }
726 : :
727 : 1035 : dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data)
728 : : {
729 : : dwc_timer_t *t = DWC_ALLOC(sizeof(*t));
730 : :
731 [ - + ]: 1035 : if (!t) {
732 : 0 : DWC_ERROR("Cannot allocate memory for timer");
733 : 0 : return NULL;
734 : : }
735 : :
736 : 1035 : t->name = DWC_STRDUP(name);
737 [ - + ]: 1035 : if (!t->name) {
738 : 0 : DWC_ERROR("Cannot allocate memory for timer->name");
739 : 0 : goto no_name;
740 : : }
741 : :
742 : : #if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_SPINLOCK))
743 : : DWC_SPINLOCK_ALLOC_LINUX_DEBUG(t->lock);
744 : : #else
745 : 1035 : t->lock = DWC_SPINLOCK_ALLOC();
746 : : #endif
747 [ - + ]: 1035 : if (!t->lock) {
748 : 0 : DWC_ERROR("Cannot allocate memory for lock");
749 : : goto no_lock;
750 : : }
751 : :
752 : 1035 : t->scheduled = 0;
753 : 1035 : t->t.expires = jiffies;
754 : 1035 : timer_setup(&t->t, timer_callback, 0);
755 : :
756 : 1035 : t->cb = cb;
757 : 1035 : t->data = data;
758 : :
759 : 1035 : return t;
760 : :
761 : : no_lock:
762 : 0 : DWC_FREE(t->name);
763 : : no_name:
764 : : DWC_FREE(t);
765 : 0 : return NULL;
766 : : }
767 : :
768 : 0 : void DWC_TIMER_FREE(dwc_timer_t *timer)
769 : : {
770 : : dwc_irqflags_t flags;
771 : :
772 : 0 : DWC_SPINLOCK_IRQSAVE(timer->lock, &flags);
773 : :
774 [ # # ]: 0 : if (timer->scheduled) {
775 : 0 : del_timer(&timer->t);
776 : 0 : timer->scheduled = 0;
777 : : }
778 : :
779 : 0 : DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags);
780 : 0 : DWC_SPINLOCK_FREE(timer->lock);
781 : 0 : DWC_FREE(timer->name);
782 : : DWC_FREE(timer);
783 : 0 : }
784 : :
785 : 0 : void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time)
786 : : {
787 : : dwc_irqflags_t flags;
788 : :
789 : 0 : DWC_SPINLOCK_IRQSAVE(timer->lock, &flags);
790 : :
791 [ # # ]: 0 : if (!timer->scheduled) {
792 : 0 : timer->scheduled = 1;
793 : : DWC_DEBUGC("Scheduling timer %s to expire in +%d msec", timer->name, time);
794 : 0 : timer->t.expires = jiffies + msecs_to_jiffies(time);
795 : 0 : add_timer(&timer->t);
796 : : } else {
797 : : DWC_DEBUGC("Modifying timer %s to expire in +%d msec", timer->name, time);
798 : 0 : mod_timer(&timer->t, jiffies + msecs_to_jiffies(time));
799 : : }
800 : :
801 : 0 : DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags);
802 : 0 : }
803 : :
804 : 207 : void DWC_TIMER_CANCEL(dwc_timer_t *timer)
805 : : {
806 : 207 : del_timer(&timer->t);
807 : 207 : }
808 : :
809 : :
810 : : /* Wait Queues */
811 : :
812 : : struct dwc_waitq {
813 : : wait_queue_head_t queue;
814 : : int abort;
815 : : };
816 : :
817 : 414 : dwc_waitq_t *DWC_WAITQ_ALLOC(void)
818 : : {
819 : : dwc_waitq_t *wq = DWC_ALLOC(sizeof(*wq));
820 : :
821 [ - + ]: 414 : if (!wq) {
822 : 0 : DWC_ERROR("Cannot allocate memory for waitqueue\n");
823 : 0 : return NULL;
824 : : }
825 : :
826 : 414 : init_waitqueue_head(&wq->queue);
827 : 414 : wq->abort = 0;
828 : 414 : return wq;
829 : : }
830 : :
831 : 0 : void DWC_WAITQ_FREE(dwc_waitq_t *wq)
832 : : {
833 : : DWC_FREE(wq);
834 : 0 : }
835 : :
836 : 0 : int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data)
837 : : {
838 [ # # # # : 0 : int result = wait_event_interruptible(wq->queue,
# # # # #
# ]
839 : : cond(data) || wq->abort);
840 [ # # ]: 0 : if (result == -ERESTARTSYS) {
841 : 0 : wq->abort = 0;
842 : 0 : return -DWC_E_RESTART;
843 : : }
844 : :
845 [ # # ]: 0 : if (wq->abort == 1) {
846 : 0 : wq->abort = 0;
847 : 0 : return -DWC_E_ABORT;
848 : : }
849 : :
850 : 0 : wq->abort = 0;
851 : :
852 [ # # ]: 0 : if (result == 0) {
853 : : return 0;
854 : : }
855 : :
856 : 0 : return -DWC_E_UNKNOWN;
857 : : }
858 : :
859 : 0 : int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond,
860 : : void *data, int32_t msecs)
861 : : {
862 : : int32_t tmsecs;
863 [ # # # # : 0 : int result = wait_event_interruptible_timeout(wq->queue,
# # # # #
# # # # #
# # # # ]
864 : : cond(data) || wq->abort,
865 : : msecs_to_jiffies(msecs));
866 [ # # ]: 0 : if (result == -ERESTARTSYS) {
867 : 0 : wq->abort = 0;
868 : 0 : return -DWC_E_RESTART;
869 : : }
870 : :
871 [ # # ]: 0 : if (wq->abort == 1) {
872 : 0 : wq->abort = 0;
873 : 0 : return -DWC_E_ABORT;
874 : : }
875 : :
876 : 0 : wq->abort = 0;
877 : :
878 [ # # ]: 0 : if (result > 0) {
879 : 0 : tmsecs = jiffies_to_msecs(result);
880 [ # # ]: 0 : if (!tmsecs) {
881 : : return 1;
882 : : }
883 : :
884 : 0 : return tmsecs;
885 : : }
886 : :
887 [ # # ]: 0 : if (result == 0) {
888 : : return -DWC_E_TIMEOUT;
889 : : }
890 : :
891 : 0 : return -DWC_E_UNKNOWN;
892 : : }
893 : :
894 : 0 : void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq)
895 : : {
896 : 0 : wq->abort = 0;
897 : 0 : wake_up_interruptible(&wq->queue);
898 : 0 : }
899 : :
900 : 0 : void DWC_WAITQ_ABORT(dwc_waitq_t *wq)
901 : : {
902 : 0 : wq->abort = 1;
903 : 0 : wake_up_interruptible(&wq->queue);
904 : 0 : }
905 : :
906 : :
907 : : /* Threading */
908 : :
909 : 0 : dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data)
910 : : {
911 [ # # ]: 0 : struct task_struct *thread = kthread_run(func, data, name);
912 : :
913 [ # # ]: 0 : if (thread == ERR_PTR(-ENOMEM)) {
914 : : return NULL;
915 : : }
916 : :
917 : 0 : return (dwc_thread_t *)thread;
918 : : }
919 : :
920 : 0 : int DWC_THREAD_STOP(dwc_thread_t *thread)
921 : : {
922 : 0 : return kthread_stop((struct task_struct *)thread);
923 : : }
924 : :
925 : 0 : dwc_bool_t DWC_THREAD_SHOULD_STOP(void)
926 : : {
927 : 0 : return kthread_should_stop();
928 : : }
929 : :
930 : :
931 : : /* tasklets
932 : : - run in interrupt context (cannot sleep)
933 : : - each tasklet runs on a single CPU
934 : : - different tasklets can be running simultaneously on different CPUs
935 : : */
936 : : struct dwc_tasklet {
937 : : struct tasklet_struct t;
938 : : dwc_tasklet_callback_t cb;
939 : : void *data;
940 : : };
941 : :
942 : 115203 : static void tasklet_callback(unsigned long data)
943 : : {
944 : 115203 : dwc_tasklet_t *t = (dwc_tasklet_t *)data;
945 : 115203 : t->cb(t->data);
946 : 115203 : }
947 : :
948 : 828 : dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data)
949 : : {
950 : : dwc_tasklet_t *t = DWC_ALLOC(sizeof(*t));
951 : :
952 [ + - ]: 828 : if (t) {
953 : 828 : t->cb = cb;
954 : 828 : t->data = data;
955 : 828 : tasklet_init(&t->t, tasklet_callback, (unsigned long)t);
956 : : } else {
957 : 0 : DWC_ERROR("Cannot allocate memory for tasklet\n");
958 : : }
959 : :
960 : 828 : return t;
961 : : }
962 : :
963 : 0 : void DWC_TASK_FREE(dwc_tasklet_t *task)
964 : : {
965 : : DWC_FREE(task);
966 : 0 : }
967 : :
968 : 0 : void DWC_TASK_SCHEDULE(dwc_tasklet_t *task)
969 : : {
970 : 0 : tasklet_schedule(&task->t);
971 : 0 : }
972 : :
973 : 119325 : void DWC_TASK_HI_SCHEDULE(dwc_tasklet_t *task)
974 : : {
975 : 119325 : tasklet_hi_schedule(&task->t);
976 : 119325 : }
977 : :
978 : :
979 : : /* workqueues
980 : : - run in process context (can sleep)
981 : : */
982 : : typedef struct work_container {
983 : : dwc_work_callback_t cb;
984 : : void *data;
985 : : dwc_workq_t *wq;
986 : : char *name;
987 : :
988 : : #ifdef DEBUG
989 : : DWC_CIRCLEQ_ENTRY(work_container) entry;
990 : : #endif
991 : : struct delayed_work work;
992 : : } work_container_t;
993 : :
994 : : #ifdef DEBUG
995 : : DWC_CIRCLEQ_HEAD(work_container_queue, work_container);
996 : : #endif
997 : :
998 : : struct dwc_workq {
999 : : struct workqueue_struct *wq;
1000 : : dwc_spinlock_t *lock;
1001 : : dwc_waitq_t *waitq;
1002 : : int pending;
1003 : :
1004 : : #ifdef DEBUG
1005 : : struct work_container_queue entries;
1006 : : #endif
1007 : : };
1008 : :
1009 : 0 : static void do_work(struct work_struct *work)
1010 : : {
1011 : : dwc_irqflags_t flags;
1012 : : struct delayed_work *dw = container_of(work, struct delayed_work, work);
1013 : 0 : work_container_t *container = container_of(dw, struct work_container, work);
1014 : 0 : dwc_workq_t *wq = container->wq;
1015 : :
1016 : 0 : container->cb(container->data);
1017 : :
1018 : : #ifdef DEBUG
1019 : : DWC_CIRCLEQ_REMOVE(&wq->entries, container, entry);
1020 : : #endif
1021 : : DWC_DEBUGC("Work done: %s, container=%p", container->name, container);
1022 [ # # ]: 0 : if (container->name) {
1023 : : DWC_FREE(container->name);
1024 : : }
1025 : : DWC_FREE(container);
1026 : :
1027 : 0 : DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
1028 : 0 : wq->pending--;
1029 : 0 : DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
1030 : 0 : DWC_WAITQ_TRIGGER(wq->waitq);
1031 : 0 : }
1032 : :
1033 : 0 : static int work_done(void *data)
1034 : : {
1035 : : dwc_workq_t *workq = (dwc_workq_t *)data;
1036 : 0 : return workq->pending == 0;
1037 : : }
1038 : :
1039 : 0 : int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout)
1040 : : {
1041 : 0 : return DWC_WAITQ_WAIT_TIMEOUT(workq->waitq, work_done, workq, timeout);
1042 : : }
1043 : :
1044 : 414 : dwc_workq_t *DWC_WORKQ_ALLOC(char *name)
1045 : : {
1046 : : dwc_workq_t *wq = DWC_ALLOC(sizeof(*wq));
1047 : :
1048 [ + - ]: 414 : if (!wq) {
1049 : : return NULL;
1050 : : }
1051 : :
1052 : 414 : wq->wq = create_singlethread_workqueue(name);
1053 [ + - ]: 414 : if (!wq->wq) {
1054 : : goto no_wq;
1055 : : }
1056 : :
1057 : 414 : wq->pending = 0;
1058 : :
1059 : : #if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_SPINLOCK))
1060 : : DWC_SPINLOCK_ALLOC_LINUX_DEBUG(wq->lock);
1061 : : #else
1062 : 414 : wq->lock = DWC_SPINLOCK_ALLOC();
1063 : : #endif
1064 [ + - ]: 414 : if (!wq->lock) {
1065 : : goto no_lock;
1066 : : }
1067 : :
1068 : 414 : wq->waitq = DWC_WAITQ_ALLOC();
1069 [ - + ]: 414 : if (!wq->waitq) {
1070 : : goto no_waitq;
1071 : : }
1072 : :
1073 : : #ifdef DEBUG
1074 : : DWC_CIRCLEQ_INIT(&wq->entries);
1075 : : #endif
1076 : : return wq;
1077 : :
1078 : : no_waitq:
1079 : 0 : DWC_SPINLOCK_FREE(wq->lock);
1080 : : no_lock:
1081 : 0 : destroy_workqueue(wq->wq);
1082 : : no_wq:
1083 : : DWC_FREE(wq);
1084 : :
1085 : 0 : return NULL;
1086 : : }
1087 : :
1088 : 0 : void DWC_WORKQ_FREE(dwc_workq_t *wq)
1089 : : {
1090 : : #ifdef DEBUG
1091 : : if (wq->pending != 0) {
1092 : : struct work_container *wc;
1093 : : DWC_ERROR("Destroying work queue with pending work");
1094 : : DWC_CIRCLEQ_FOREACH(wc, &wq->entries, entry) {
1095 : : DWC_ERROR("Work %s still pending", wc->name);
1096 : : }
1097 : : }
1098 : : #endif
1099 : 0 : destroy_workqueue(wq->wq);
1100 : 0 : DWC_SPINLOCK_FREE(wq->lock);
1101 : 0 : DWC_WAITQ_FREE(wq->waitq);
1102 : : DWC_FREE(wq);
1103 : 0 : }
1104 : :
1105 : 0 : void DWC_WORKQ_SCHEDULE(dwc_workq_t *wq, dwc_work_callback_t cb, void *data,
1106 : : char *format, ...)
1107 : : {
1108 : : dwc_irqflags_t flags;
1109 : : work_container_t *container;
1110 : : static char name[128];
1111 : : va_list args;
1112 : :
1113 : 0 : va_start(args, format);
1114 : : DWC_VSNPRINTF(name, 128, format, args);
1115 : 0 : va_end(args);
1116 : :
1117 : 0 : DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
1118 : 0 : wq->pending++;
1119 : 0 : DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
1120 : 0 : DWC_WAITQ_TRIGGER(wq->waitq);
1121 : :
1122 : : container = DWC_ALLOC_ATOMIC(sizeof(*container));
1123 [ # # ]: 0 : if (!container) {
1124 : 0 : DWC_ERROR("Cannot allocate memory for container\n");
1125 : 0 : return;
1126 : : }
1127 : :
1128 : 0 : container->name = DWC_STRDUP(name);
1129 [ # # ]: 0 : if (!container->name) {
1130 : 0 : DWC_ERROR("Cannot allocate memory for container->name\n");
1131 : : DWC_FREE(container);
1132 : : return;
1133 : : }
1134 : :
1135 : 0 : container->cb = cb;
1136 : 0 : container->data = data;
1137 : 0 : container->wq = wq;
1138 : : DWC_DEBUGC("Queueing work: %s, container=%p", container->name, container);
1139 : 0 : INIT_WORK(&container->work.work, do_work);
1140 : :
1141 : : #ifdef DEBUG
1142 : : DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry);
1143 : : #endif
1144 : 0 : queue_work(wq->wq, &container->work.work);
1145 : : }
1146 : :
1147 : 0 : void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *wq, dwc_work_callback_t cb,
1148 : : void *data, uint32_t time, char *format, ...)
1149 : : {
1150 : : dwc_irqflags_t flags;
1151 : : work_container_t *container;
1152 : : static char name[128];
1153 : : va_list args;
1154 : :
1155 : 0 : va_start(args, format);
1156 : : DWC_VSNPRINTF(name, 128, format, args);
1157 : 0 : va_end(args);
1158 : :
1159 : 0 : DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
1160 : 0 : wq->pending++;
1161 : 0 : DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
1162 : 0 : DWC_WAITQ_TRIGGER(wq->waitq);
1163 : :
1164 : : container = DWC_ALLOC_ATOMIC(sizeof(*container));
1165 [ # # ]: 0 : if (!container) {
1166 : 0 : DWC_ERROR("Cannot allocate memory for container\n");
1167 : 0 : return;
1168 : : }
1169 : :
1170 : 0 : container->name = DWC_STRDUP(name);
1171 [ # # ]: 0 : if (!container->name) {
1172 : 0 : DWC_ERROR("Cannot allocate memory for container->name\n");
1173 : : DWC_FREE(container);
1174 : : return;
1175 : : }
1176 : :
1177 : 0 : container->cb = cb;
1178 : 0 : container->data = data;
1179 : 0 : container->wq = wq;
1180 : : DWC_DEBUGC("Queueing work: %s, container=%p", container->name, container);
1181 : 0 : INIT_DELAYED_WORK(&container->work, do_work);
1182 : :
1183 : : #ifdef DEBUG
1184 : : DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry);
1185 : : #endif
1186 : 0 : queue_delayed_work(wq->wq, &container->work, msecs_to_jiffies(time));
1187 : : }
1188 : :
1189 : 0 : int DWC_WORKQ_PENDING(dwc_workq_t *wq)
1190 : : {
1191 : 0 : return wq->pending;
1192 : : }
1193 : :
1194 : :
1195 : : #ifdef DWC_LIBMODULE
1196 : :
1197 : : #ifdef DWC_CCLIB
1198 : : /* CC */
1199 : : EXPORT_SYMBOL(dwc_cc_if_alloc);
1200 : : EXPORT_SYMBOL(dwc_cc_if_free);
1201 : : EXPORT_SYMBOL(dwc_cc_clear);
1202 : : EXPORT_SYMBOL(dwc_cc_add);
1203 : : EXPORT_SYMBOL(dwc_cc_remove);
1204 : : EXPORT_SYMBOL(dwc_cc_change);
1205 : : EXPORT_SYMBOL(dwc_cc_data_for_save);
1206 : : EXPORT_SYMBOL(dwc_cc_restore_from_data);
1207 : : EXPORT_SYMBOL(dwc_cc_match_chid);
1208 : : EXPORT_SYMBOL(dwc_cc_match_cdid);
1209 : : EXPORT_SYMBOL(dwc_cc_ck);
1210 : : EXPORT_SYMBOL(dwc_cc_chid);
1211 : : EXPORT_SYMBOL(dwc_cc_cdid);
1212 : : EXPORT_SYMBOL(dwc_cc_name);
1213 : : #endif /* DWC_CCLIB */
1214 : :
1215 : : #ifdef DWC_CRYPTOLIB
1216 : : # ifndef CONFIG_MACH_IPMATE
1217 : : /* Modpow */
1218 : : EXPORT_SYMBOL(dwc_modpow);
1219 : :
1220 : : /* DH */
1221 : : EXPORT_SYMBOL(dwc_dh_modpow);
1222 : : EXPORT_SYMBOL(dwc_dh_derive_keys);
1223 : : EXPORT_SYMBOL(dwc_dh_pk);
1224 : : # endif /* CONFIG_MACH_IPMATE */
1225 : :
1226 : : /* Crypto */
1227 : : EXPORT_SYMBOL(dwc_wusb_aes_encrypt);
1228 : : EXPORT_SYMBOL(dwc_wusb_cmf);
1229 : : EXPORT_SYMBOL(dwc_wusb_prf);
1230 : : EXPORT_SYMBOL(dwc_wusb_fill_ccm_nonce);
1231 : : EXPORT_SYMBOL(dwc_wusb_gen_nonce);
1232 : : EXPORT_SYMBOL(dwc_wusb_gen_key);
1233 : : EXPORT_SYMBOL(dwc_wusb_gen_mic);
1234 : : #endif /* DWC_CRYPTOLIB */
1235 : :
1236 : : /* Notification */
1237 : : #ifdef DWC_NOTIFYLIB
1238 : : EXPORT_SYMBOL(dwc_alloc_notification_manager);
1239 : : EXPORT_SYMBOL(dwc_free_notification_manager);
1240 : : EXPORT_SYMBOL(dwc_register_notifier);
1241 : : EXPORT_SYMBOL(dwc_unregister_notifier);
1242 : : EXPORT_SYMBOL(dwc_add_observer);
1243 : : EXPORT_SYMBOL(dwc_remove_observer);
1244 : : EXPORT_SYMBOL(dwc_notify);
1245 : : #endif
1246 : :
1247 : : /* Memory Debugging Routines */
1248 : : #ifdef DWC_DEBUG_MEMORY
1249 : : EXPORT_SYMBOL(dwc_alloc_debug);
1250 : : EXPORT_SYMBOL(dwc_alloc_atomic_debug);
1251 : : EXPORT_SYMBOL(dwc_free_debug);
1252 : : EXPORT_SYMBOL(dwc_dma_alloc_debug);
1253 : : EXPORT_SYMBOL(dwc_dma_free_debug);
1254 : : #endif
1255 : :
1256 : : EXPORT_SYMBOL(DWC_MEMSET);
1257 : : EXPORT_SYMBOL(DWC_MEMCPY);
1258 : : EXPORT_SYMBOL(DWC_MEMMOVE);
1259 : : EXPORT_SYMBOL(DWC_MEMCMP);
1260 : : EXPORT_SYMBOL(DWC_STRNCMP);
1261 : : EXPORT_SYMBOL(DWC_STRCMP);
1262 : : EXPORT_SYMBOL(DWC_STRLEN);
1263 : : EXPORT_SYMBOL(DWC_STRCPY);
1264 : : EXPORT_SYMBOL(DWC_STRDUP);
1265 : : EXPORT_SYMBOL(DWC_ATOI);
1266 : : EXPORT_SYMBOL(DWC_ATOUI);
1267 : :
1268 : : #ifdef DWC_UTFLIB
1269 : : EXPORT_SYMBOL(DWC_UTF8_TO_UTF16LE);
1270 : : #endif /* DWC_UTFLIB */
1271 : :
1272 : : EXPORT_SYMBOL(DWC_IN_IRQ);
1273 : : EXPORT_SYMBOL(DWC_IN_BH);
1274 : : EXPORT_SYMBOL(DWC_VPRINTF);
1275 : : EXPORT_SYMBOL(DWC_VSNPRINTF);
1276 : : EXPORT_SYMBOL(DWC_PRINTF);
1277 : : EXPORT_SYMBOL(DWC_SPRINTF);
1278 : : EXPORT_SYMBOL(DWC_SNPRINTF);
1279 : : EXPORT_SYMBOL(__DWC_WARN);
1280 : : EXPORT_SYMBOL(__DWC_ERROR);
1281 : : EXPORT_SYMBOL(DWC_EXCEPTION);
1282 : :
1283 : : #ifdef DEBUG
1284 : : EXPORT_SYMBOL(__DWC_DEBUG);
1285 : : #endif
1286 : :
1287 : : EXPORT_SYMBOL(__DWC_DMA_ALLOC);
1288 : : EXPORT_SYMBOL(__DWC_DMA_ALLOC_ATOMIC);
1289 : : EXPORT_SYMBOL(__DWC_DMA_FREE);
1290 : : EXPORT_SYMBOL(__DWC_ALLOC);
1291 : : EXPORT_SYMBOL(__DWC_ALLOC_ATOMIC);
1292 : : EXPORT_SYMBOL(__DWC_FREE);
1293 : :
1294 : : #ifdef DWC_CRYPTOLIB
1295 : : EXPORT_SYMBOL(DWC_RANDOM_BYTES);
1296 : : EXPORT_SYMBOL(DWC_AES_CBC);
1297 : : EXPORT_SYMBOL(DWC_SHA256);
1298 : : EXPORT_SYMBOL(DWC_HMAC_SHA256);
1299 : : #endif
1300 : :
1301 : : EXPORT_SYMBOL(DWC_CPU_TO_LE32);
1302 : : EXPORT_SYMBOL(DWC_CPU_TO_BE32);
1303 : : EXPORT_SYMBOL(DWC_LE32_TO_CPU);
1304 : : EXPORT_SYMBOL(DWC_BE32_TO_CPU);
1305 : : EXPORT_SYMBOL(DWC_CPU_TO_LE16);
1306 : : EXPORT_SYMBOL(DWC_CPU_TO_BE16);
1307 : : EXPORT_SYMBOL(DWC_LE16_TO_CPU);
1308 : : EXPORT_SYMBOL(DWC_BE16_TO_CPU);
1309 : : EXPORT_SYMBOL(DWC_READ_REG32);
1310 : : EXPORT_SYMBOL(DWC_WRITE_REG32);
1311 : : EXPORT_SYMBOL(DWC_MODIFY_REG32);
1312 : :
1313 : : #if 0
1314 : : EXPORT_SYMBOL(DWC_READ_REG64);
1315 : : EXPORT_SYMBOL(DWC_WRITE_REG64);
1316 : : EXPORT_SYMBOL(DWC_MODIFY_REG64);
1317 : : #endif
1318 : :
1319 : : EXPORT_SYMBOL(DWC_SPINLOCK_ALLOC);
1320 : : EXPORT_SYMBOL(DWC_SPINLOCK_FREE);
1321 : : EXPORT_SYMBOL(DWC_SPINLOCK);
1322 : : EXPORT_SYMBOL(DWC_SPINUNLOCK);
1323 : : EXPORT_SYMBOL(DWC_SPINLOCK_IRQSAVE);
1324 : : EXPORT_SYMBOL(DWC_SPINUNLOCK_IRQRESTORE);
1325 : : EXPORT_SYMBOL(DWC_MUTEX_ALLOC);
1326 : :
1327 : : #if (!defined(DWC_LINUX) || !defined(CONFIG_DEBUG_MUTEXES))
1328 : : EXPORT_SYMBOL(DWC_MUTEX_FREE);
1329 : : #endif
1330 : :
1331 : : EXPORT_SYMBOL(DWC_MUTEX_LOCK);
1332 : : EXPORT_SYMBOL(DWC_MUTEX_TRYLOCK);
1333 : : EXPORT_SYMBOL(DWC_MUTEX_UNLOCK);
1334 : : EXPORT_SYMBOL(DWC_UDELAY);
1335 : : EXPORT_SYMBOL(DWC_MDELAY);
1336 : : EXPORT_SYMBOL(DWC_MSLEEP);
1337 : : EXPORT_SYMBOL(DWC_TIME);
1338 : : EXPORT_SYMBOL(DWC_TIMER_ALLOC);
1339 : : EXPORT_SYMBOL(DWC_TIMER_FREE);
1340 : : EXPORT_SYMBOL(DWC_TIMER_SCHEDULE);
1341 : : EXPORT_SYMBOL(DWC_TIMER_CANCEL);
1342 : : EXPORT_SYMBOL(DWC_WAITQ_ALLOC);
1343 : : EXPORT_SYMBOL(DWC_WAITQ_FREE);
1344 : : EXPORT_SYMBOL(DWC_WAITQ_WAIT);
1345 : : EXPORT_SYMBOL(DWC_WAITQ_WAIT_TIMEOUT);
1346 : : EXPORT_SYMBOL(DWC_WAITQ_TRIGGER);
1347 : : EXPORT_SYMBOL(DWC_WAITQ_ABORT);
1348 : : EXPORT_SYMBOL(DWC_THREAD_RUN);
1349 : : EXPORT_SYMBOL(DWC_THREAD_STOP);
1350 : : EXPORT_SYMBOL(DWC_THREAD_SHOULD_STOP);
1351 : : EXPORT_SYMBOL(DWC_TASK_ALLOC);
1352 : : EXPORT_SYMBOL(DWC_TASK_FREE);
1353 : : EXPORT_SYMBOL(DWC_TASK_SCHEDULE);
1354 : : EXPORT_SYMBOL(DWC_WORKQ_WAIT_WORK_DONE);
1355 : : EXPORT_SYMBOL(DWC_WORKQ_ALLOC);
1356 : : EXPORT_SYMBOL(DWC_WORKQ_FREE);
1357 : : EXPORT_SYMBOL(DWC_WORKQ_SCHEDULE);
1358 : : EXPORT_SYMBOL(DWC_WORKQ_SCHEDULE_DELAYED);
1359 : : EXPORT_SYMBOL(DWC_WORKQ_PENDING);
1360 : :
1361 : 207 : static int dwc_common_port_init_module(void)
1362 : : {
1363 : : int result = 0;
1364 : :
1365 : 207 : printk(KERN_DEBUG "Module dwc_common_port init\n" );
1366 : :
1367 : : #ifdef DWC_DEBUG_MEMORY
1368 : : result = dwc_memory_debug_start(NULL);
1369 : : if (result) {
1370 : : printk(KERN_ERR
1371 : : "dwc_memory_debug_start() failed with error %d\n",
1372 : : result);
1373 : : return result;
1374 : : }
1375 : : #endif
1376 : :
1377 : : #ifdef DWC_NOTIFYLIB
1378 : 207 : result = dwc_alloc_notification_manager(NULL, NULL);
1379 [ - + ]: 207 : if (result) {
1380 : 0 : printk(KERN_ERR
1381 : : "dwc_alloc_notification_manager() failed with error %d\n",
1382 : : result);
1383 : 0 : return result;
1384 : : }
1385 : : #endif
1386 : : return result;
1387 : : }
1388 : :
1389 : 0 : static void dwc_common_port_exit_module(void)
1390 : : {
1391 : 0 : printk(KERN_DEBUG "Module dwc_common_port exit\n" );
1392 : :
1393 : : #ifdef DWC_NOTIFYLIB
1394 : 0 : dwc_free_notification_manager();
1395 : : #endif
1396 : :
1397 : : #ifdef DWC_DEBUG_MEMORY
1398 : : dwc_memory_debug_stop();
1399 : : #endif
1400 : 0 : }
1401 : :
1402 : : module_init(dwc_common_port_init_module);
1403 : : module_exit(dwc_common_port_exit_module);
1404 : :
1405 : : MODULE_DESCRIPTION("DWC Common Library - Portable version");
1406 : : MODULE_AUTHOR("Synopsys Inc.");
1407 : : MODULE_LICENSE ("GPL");
1408 : :
1409 : : #endif /* DWC_LIBMODULE */
|