Merge tag 'v5.15.57' into rpi-5.15.y
[platform/kernel/linux-rpi.git] / drivers / usb / host / dwc_common_port / dwc_common_nbsd.c
1 #include "dwc_os.h"
2 #include "dwc_list.h"
3
4 #ifdef DWC_CCLIB
5 # include "dwc_cc.h"
6 #endif
7
8 #ifdef DWC_CRYPTOLIB
9 # include "dwc_modpow.h"
10 # include "dwc_dh.h"
11 # include "dwc_crypto.h"
12 #endif
13
14 #ifdef DWC_NOTIFYLIB
15 # include "dwc_notifier.h"
16 #endif
17
18 /* OS-Level Implementations */
19
20 /* This is the NetBSD 4.0.1 kernel implementation of the DWC platform library. */
21
22
23 /* MISC */
24
25 void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size)
26 {
27         return memset(dest, byte, size);
28 }
29
30 void *DWC_MEMCPY(void *dest, void const *src, uint32_t size)
31 {
32         return memcpy(dest, src, size);
33 }
34
35 void *DWC_MEMMOVE(void *dest, void *src, uint32_t size)
36 {
37         bcopy(src, dest, size);
38         return dest;
39 }
40
41 int DWC_MEMCMP(void *m1, void *m2, uint32_t size)
42 {
43         return memcmp(m1, m2, size);
44 }
45
46 int DWC_STRNCMP(void *s1, void *s2, uint32_t size)
47 {
48         return strncmp(s1, s2, size);
49 }
50
51 int DWC_STRCMP(void *s1, void *s2)
52 {
53         return strcmp(s1, s2);
54 }
55
56 int DWC_STRLEN(char const *str)
57 {
58         return strlen(str);
59 }
60
61 char *DWC_STRCPY(char *to, char const *from)
62 {
63         return strcpy(to, from);
64 }
65
66 char *DWC_STRDUP(char const *str)
67 {
68         int len = DWC_STRLEN(str) + 1;
69         char *new = DWC_ALLOC_ATOMIC(len);
70
71         if (!new) {
72                 return NULL;
73         }
74
75         DWC_MEMCPY(new, str, len);
76         return new;
77 }
78
79 int DWC_ATOI(char *str, int32_t *value)
80 {
81         char *end = NULL;
82
83         /* NetBSD doesn't have 'strtol' in the kernel, but 'strtoul'
84          * should be equivalent on 2's complement machines
85          */
86         *value = strtoul(str, &end, 0);
87         if (*end == '\0') {
88                 return 0;
89         }
90
91         return -1;
92 }
93
94 int DWC_ATOUI(char *str, uint32_t *value)
95 {
96         char *end = NULL;
97
98         *value = strtoul(str, &end, 0);
99         if (*end == '\0') {
100                 return 0;
101         }
102
103         return -1;
104 }
105
106
107 #ifdef DWC_UTFLIB
108 /* From usbstring.c */
109
110 int DWC_UTF8_TO_UTF16LE(uint8_t const *s, uint16_t *cp, unsigned len)
111 {
112         int     count = 0;
113         u8      c;
114         u16     uchar;
115
116         /* this insists on correct encodings, though not minimal ones.
117          * BUT it currently rejects legit 4-byte UTF-8 code points,
118          * which need surrogate pairs.  (Unicode 3.1 can use them.)
119          */
120         while (len != 0 && (c = (u8) *s++) != 0) {
121                 if (unlikely(c & 0x80)) {
122                         // 2-byte sequence:
123                         // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
124                         if ((c & 0xe0) == 0xc0) {
125                                 uchar = (c & 0x1f) << 6;
126
127                                 c = (u8) *s++;
128                                 if ((c & 0xc0) != 0xc0)
129                                         goto fail;
130                                 c &= 0x3f;
131                                 uchar |= c;
132
133                         // 3-byte sequence (most CJKV characters):
134                         // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
135                         } else if ((c & 0xf0) == 0xe0) {
136                                 uchar = (c & 0x0f) << 12;
137
138                                 c = (u8) *s++;
139                                 if ((c & 0xc0) != 0xc0)
140                                         goto fail;
141                                 c &= 0x3f;
142                                 uchar |= c << 6;
143
144                                 c = (u8) *s++;
145                                 if ((c & 0xc0) != 0xc0)
146                                         goto fail;
147                                 c &= 0x3f;
148                                 uchar |= c;
149
150                                 /* no bogus surrogates */
151                                 if (0xd800 <= uchar && uchar <= 0xdfff)
152                                         goto fail;
153
154                         // 4-byte sequence (surrogate pairs, currently rare):
155                         // 11101110wwwwzzzzyy + 110111yyyyxxxxxx
156                         //     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
157                         // (uuuuu = wwww + 1)
158                         // FIXME accept the surrogate code points (only)
159                         } else
160                                 goto fail;
161                 } else
162                         uchar = c;
163                 put_unaligned (cpu_to_le16 (uchar), cp++);
164                 count++;
165                 len--;
166         }
167         return count;
168 fail:
169         return -1;
170 }
171
172 #endif  /* DWC_UTFLIB */
173
174
175 /* dwc_debug.h */
176
177 dwc_bool_t DWC_IN_IRQ(void)
178 {
179 //      return in_irq();
180         return 0;
181 }
182
183 dwc_bool_t DWC_IN_BH(void)
184 {
185 //      return in_softirq();
186         return 0;
187 }
188
189 void DWC_VPRINTF(char *format, va_list args)
190 {
191         vprintf(format, args);
192 }
193
194 int DWC_VSNPRINTF(char *str, int size, char *format, va_list args)
195 {
196         return vsnprintf(str, size, format, args);
197 }
198
199 void DWC_PRINTF(char *format, ...)
200 {
201         va_list args;
202
203         va_start(args, format);
204         DWC_VPRINTF(format, args);
205         va_end(args);
206 }
207
208 int DWC_SPRINTF(char *buffer, char *format, ...)
209 {
210         int retval;
211         va_list args;
212
213         va_start(args, format);
214         retval = vsprintf(buffer, format, args);
215         va_end(args);
216         return retval;
217 }
218
219 int DWC_SNPRINTF(char *buffer, int size, char *format, ...)
220 {
221         int retval;
222         va_list args;
223
224         va_start(args, format);
225         retval = vsnprintf(buffer, size, format, args);
226         va_end(args);
227         return retval;
228 }
229
230 void __DWC_WARN(char *format, ...)
231 {
232         va_list args;
233
234         va_start(args, format);
235         DWC_VPRINTF(format, args);
236         va_end(args);
237 }
238
239 void __DWC_ERROR(char *format, ...)
240 {
241         va_list args;
242
243         va_start(args, format);
244         DWC_VPRINTF(format, args);
245         va_end(args);
246 }
247
248 void DWC_EXCEPTION(char *format, ...)
249 {
250         va_list args;
251
252         va_start(args, format);
253         DWC_VPRINTF(format, args);
254         va_end(args);
255 //      BUG_ON(1);      ???
256 }
257
258 #ifdef DEBUG
259 void __DWC_DEBUG(char *format, ...)
260 {
261         va_list args;
262
263         va_start(args, format);
264         DWC_VPRINTF(format, args);
265         va_end(args);
266 }
267 #endif
268
269
270 /* dwc_mem.h */
271
272 #if 0
273 dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size,
274                                 uint32_t align,
275                                 uint32_t alloc)
276 {
277         struct dma_pool *pool = dma_pool_create("Pool", NULL,
278                                                 size, align, alloc);
279         return (dwc_pool_t *)pool;
280 }
281
282 void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool)
283 {
284         dma_pool_destroy((struct dma_pool *)pool);
285 }
286
287 void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
288 {
289 //      return dma_pool_alloc((struct dma_pool *)pool, GFP_KERNEL, dma_addr);
290         return dma_pool_alloc((struct dma_pool *)pool, M_WAITOK, dma_addr);
291 }
292
293 void *DWC_DMA_POOL_ZALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
294 {
295         void *vaddr = DWC_DMA_POOL_ALLOC(pool, dma_addr);
296         memset(..);
297 }
298
299 void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr)
300 {
301         dma_pool_free(pool, vaddr, daddr);
302 }
303 #endif
304
305 void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
306 {
307         dwc_dmactx_t *dma = (dwc_dmactx_t *)dma_ctx;
308         int error;
309
310         error = bus_dmamem_alloc(dma->dma_tag, size, 1, size, dma->segs,
311                                  sizeof(dma->segs) / sizeof(dma->segs[0]),
312                                  &dma->nsegs, BUS_DMA_NOWAIT);
313         if (error) {
314                 printf("%s: bus_dmamem_alloc(%ju) failed: %d\n", __func__,
315                        (uintmax_t)size, error);
316                 goto fail_0;
317         }
318
319         error = bus_dmamem_map(dma->dma_tag, dma->segs, dma->nsegs, size,
320                                (caddr_t *)&dma->dma_vaddr,
321                                BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
322         if (error) {
323                 printf("%s: bus_dmamem_map failed: %d\n", __func__, error);
324                 goto fail_1;
325         }
326
327         error = bus_dmamap_create(dma->dma_tag, size, 1, size, 0,
328                                   BUS_DMA_NOWAIT, &dma->dma_map);
329         if (error) {
330                 printf("%s: bus_dmamap_create failed: %d\n", __func__, error);
331                 goto fail_2;
332         }
333
334         error = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr,
335                                 size, NULL, BUS_DMA_NOWAIT);
336         if (error) {
337                 printf("%s: bus_dmamap_load failed: %d\n", __func__, error);
338                 goto fail_3;
339         }
340
341         dma->dma_paddr = (bus_addr_t)dma->segs[0].ds_addr;
342         *dma_addr = dma->dma_paddr;
343         return dma->dma_vaddr;
344
345 fail_3:
346         bus_dmamap_destroy(dma->dma_tag, dma->dma_map);
347 fail_2:
348         bus_dmamem_unmap(dma->dma_tag, dma->dma_vaddr, size);
349 fail_1:
350         bus_dmamem_free(dma->dma_tag, dma->segs, dma->nsegs);
351 fail_0:
352         dma->dma_map = NULL;
353         dma->dma_vaddr = NULL;
354         dma->nsegs = 0;
355
356         return NULL;
357 }
358
359 void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr)
360 {
361         dwc_dmactx_t *dma = (dwc_dmactx_t *)dma_ctx;
362
363         if (dma->dma_map != NULL) {
364                 bus_dmamap_sync(dma->dma_tag, dma->dma_map, 0, size,
365                                 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
366                 bus_dmamap_unload(dma->dma_tag, dma->dma_map);
367                 bus_dmamap_destroy(dma->dma_tag, dma->dma_map);
368                 bus_dmamem_unmap(dma->dma_tag, dma->dma_vaddr, size);
369                 bus_dmamem_free(dma->dma_tag, dma->segs, dma->nsegs);
370                 dma->dma_paddr = 0;
371                 dma->dma_map = NULL;
372                 dma->dma_vaddr = NULL;
373                 dma->nsegs = 0;
374         }
375 }
376
377 void *__DWC_ALLOC(void *mem_ctx, uint32_t size)
378 {
379         return malloc(size, M_DEVBUF, M_WAITOK | M_ZERO);
380 }
381
382 void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size)
383 {
384         return malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
385 }
386
387 void __DWC_FREE(void *mem_ctx, void *addr)
388 {
389         free(addr, M_DEVBUF);
390 }
391
392
393 #ifdef DWC_CRYPTOLIB
394 /* dwc_crypto.h */
395
396 void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length)
397 {
398         get_random_bytes(buffer, length);
399 }
400
401 int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out)
402 {
403         struct crypto_blkcipher *tfm;
404         struct blkcipher_desc desc;
405         struct scatterlist sgd;
406         struct scatterlist sgs;
407
408         tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
409         if (tfm == NULL) {
410                 printk("failed to load transform for aes CBC\n");
411                 return -1;
412         }
413
414         crypto_blkcipher_setkey(tfm, key, keylen);
415         crypto_blkcipher_set_iv(tfm, iv, 16);
416
417         sg_init_one(&sgd, out, messagelen);
418         sg_init_one(&sgs, message, messagelen);
419
420         desc.tfm = tfm;
421         desc.flags = 0;
422
423         if (crypto_blkcipher_encrypt(&desc, &sgd, &sgs, messagelen)) {
424                 crypto_free_blkcipher(tfm);
425                 DWC_ERROR("AES CBC encryption failed");
426                 return -1;
427         }
428
429         crypto_free_blkcipher(tfm);
430         return 0;
431 }
432
433 int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out)
434 {
435         struct crypto_hash *tfm;
436         struct hash_desc desc;
437         struct scatterlist sg;
438
439         tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
440         if (IS_ERR(tfm)) {
441                 DWC_ERROR("Failed to load transform for sha256: %ld", PTR_ERR(tfm));
442                 return 0;
443         }
444         desc.tfm = tfm;
445         desc.flags = 0;
446
447         sg_init_one(&sg, message, len);
448         crypto_hash_digest(&desc, &sg, len, out);
449         crypto_free_hash(tfm);
450
451         return 1;
452 }
453
454 int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen,
455                     uint8_t *key, uint32_t keylen, uint8_t *out)
456 {
457         struct crypto_hash *tfm;
458         struct hash_desc desc;
459         struct scatterlist sg;
460
461         tfm = crypto_alloc_hash("hmac(sha256)", 0, CRYPTO_ALG_ASYNC);
462         if (IS_ERR(tfm)) {
463                 DWC_ERROR("Failed to load transform for hmac(sha256): %ld", PTR_ERR(tfm));
464                 return 0;
465         }
466         desc.tfm = tfm;
467         desc.flags = 0;
468
469         sg_init_one(&sg, message, messagelen);
470         crypto_hash_setkey(tfm, key, keylen);
471         crypto_hash_digest(&desc, &sg, messagelen, out);
472         crypto_free_hash(tfm);
473
474         return 1;
475 }
476
477 #endif  /* DWC_CRYPTOLIB */
478
479
480 /* Byte Ordering Conversions */
481
482 uint32_t DWC_CPU_TO_LE32(uint32_t *p)
483 {
484 #ifdef __LITTLE_ENDIAN
485         return *p;
486 #else
487         uint8_t *u_p = (uint8_t *)p;
488
489         return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
490 #endif
491 }
492
493 uint32_t DWC_CPU_TO_BE32(uint32_t *p)
494 {
495 #ifdef __BIG_ENDIAN
496         return *p;
497 #else
498         uint8_t *u_p = (uint8_t *)p;
499
500         return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
501 #endif
502 }
503
504 uint32_t DWC_LE32_TO_CPU(uint32_t *p)
505 {
506 #ifdef __LITTLE_ENDIAN
507         return *p;
508 #else
509         uint8_t *u_p = (uint8_t *)p;
510
511         return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
512 #endif
513 }
514
515 uint32_t DWC_BE32_TO_CPU(uint32_t *p)
516 {
517 #ifdef __BIG_ENDIAN
518         return *p;
519 #else
520         uint8_t *u_p = (uint8_t *)p;
521
522         return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
523 #endif
524 }
525
526 uint16_t DWC_CPU_TO_LE16(uint16_t *p)
527 {
528 #ifdef __LITTLE_ENDIAN
529         return *p;
530 #else
531         uint8_t *u_p = (uint8_t *)p;
532         return (u_p[1] | (u_p[0] << 8));
533 #endif
534 }
535
536 uint16_t DWC_CPU_TO_BE16(uint16_t *p)
537 {
538 #ifdef __BIG_ENDIAN
539         return *p;
540 #else
541         uint8_t *u_p = (uint8_t *)p;
542         return (u_p[1] | (u_p[0] << 8));
543 #endif
544 }
545
546 uint16_t DWC_LE16_TO_CPU(uint16_t *p)
547 {
548 #ifdef __LITTLE_ENDIAN
549         return *p;
550 #else
551         uint8_t *u_p = (uint8_t *)p;
552         return (u_p[1] | (u_p[0] << 8));
553 #endif
554 }
555
556 uint16_t DWC_BE16_TO_CPU(uint16_t *p)
557 {
558 #ifdef __BIG_ENDIAN
559         return *p;
560 #else
561         uint8_t *u_p = (uint8_t *)p;
562         return (u_p[1] | (u_p[0] << 8));
563 #endif
564 }
565
566
567 /* Registers */
568
569 uint32_t DWC_READ_REG32(void *io_ctx, uint32_t volatile *reg)
570 {
571         dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
572         bus_size_t ior = (bus_size_t)reg;
573
574         return bus_space_read_4(io->iot, io->ioh, ior);
575 }
576
577 #if 0
578 uint64_t DWC_READ_REG64(void *io_ctx, uint64_t volatile *reg)
579 {
580         dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
581         bus_size_t ior = (bus_size_t)reg;
582
583         return bus_space_read_8(io->iot, io->ioh, ior);
584 }
585 #endif
586
587 void DWC_WRITE_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t value)
588 {
589         dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
590         bus_size_t ior = (bus_size_t)reg;
591
592         bus_space_write_4(io->iot, io->ioh, ior, value);
593 }
594
595 #if 0
596 void DWC_WRITE_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t value)
597 {
598         dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
599         bus_size_t ior = (bus_size_t)reg;
600
601         bus_space_write_8(io->iot, io->ioh, ior, value);
602 }
603 #endif
604
605 void DWC_MODIFY_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t clear_mask,
606                       uint32_t set_mask)
607 {
608         dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
609         bus_size_t ior = (bus_size_t)reg;
610
611         bus_space_write_4(io->iot, io->ioh, ior,
612                           (bus_space_read_4(io->iot, io->ioh, ior) &
613                            ~clear_mask) | set_mask);
614 }
615
616 #if 0
617 void DWC_MODIFY_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t clear_mask,
618                       uint64_t set_mask)
619 {
620         dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
621         bus_size_t ior = (bus_size_t)reg;
622
623         bus_space_write_8(io->iot, io->ioh, ior,
624                           (bus_space_read_8(io->iot, io->ioh, ior) &
625                            ~clear_mask) | set_mask);
626 }
627 #endif
628
629
630 /* Locking */
631
632 dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void)
633 {
634         struct simplelock *sl = DWC_ALLOC(sizeof(*sl));
635
636         if (!sl) {
637                 DWC_ERROR("Cannot allocate memory for spinlock");
638                 return NULL;
639         }
640
641         simple_lock_init(sl);
642         return (dwc_spinlock_t *)sl;
643 }
644
645 void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock)
646 {
647         struct simplelock *sl = (struct simplelock *)lock;
648
649         DWC_FREE(sl);
650 }
651
652 void DWC_SPINLOCK(dwc_spinlock_t *lock)
653 {
654         simple_lock((struct simplelock *)lock);
655 }
656
657 void DWC_SPINUNLOCK(dwc_spinlock_t *lock)
658 {
659         simple_unlock((struct simplelock *)lock);
660 }
661
662 void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags)
663 {
664         simple_lock((struct simplelock *)lock);
665         *flags = splbio();
666 }
667
668 void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags)
669 {
670         splx(flags);
671         simple_unlock((struct simplelock *)lock);
672 }
673
674 dwc_mutex_t *DWC_MUTEX_ALLOC(void)
675 {
676         dwc_mutex_t *mutex = DWC_ALLOC(sizeof(struct lock));
677
678         if (!mutex) {
679                 DWC_ERROR("Cannot allocate memory for mutex");
680                 return NULL;
681         }
682
683         lockinit((struct lock *)mutex, 0, "dw3mtx", 0, 0);
684         return mutex;
685 }
686
687 #if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES))
688 #else
689 void DWC_MUTEX_FREE(dwc_mutex_t *mutex)
690 {
691         DWC_FREE(mutex);
692 }
693 #endif
694
695 void DWC_MUTEX_LOCK(dwc_mutex_t *mutex)
696 {
697         lockmgr((struct lock *)mutex, LK_EXCLUSIVE, NULL);
698 }
699
700 int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex)
701 {
702         int status;
703
704         status = lockmgr((struct lock *)mutex, LK_EXCLUSIVE | LK_NOWAIT, NULL);
705         return status == 0;
706 }
707
708 void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex)
709 {
710         lockmgr((struct lock *)mutex, LK_RELEASE, NULL);
711 }
712
713
714 /* Timing */
715
716 void DWC_UDELAY(uint32_t usecs)
717 {
718         DELAY(usecs);
719 }
720
721 void DWC_MDELAY(uint32_t msecs)
722 {
723         do {
724                 DELAY(1000);
725         } while (--msecs);
726 }
727
728 void DWC_MSLEEP(uint32_t msecs)
729 {
730         struct timeval tv;
731
732         tv.tv_sec = msecs / 1000;
733         tv.tv_usec = (msecs - tv.tv_sec * 1000) * 1000;
734         tsleep(&tv, 0, "dw3slp", tvtohz(&tv));
735 }
736
737 uint32_t DWC_TIME(void)
738 {
739         struct timeval tv;
740
741         microuptime(&tv);       // or getmicrouptime? (less precise, but faster)
742         return tv.tv_sec * 1000 + tv.tv_usec / 1000;
743 }
744
745
746 /* Timers */
747
748 struct dwc_timer {
749         struct callout t;
750         char *name;
751         dwc_spinlock_t *lock;
752         dwc_timer_callback_t cb;
753         void *data;
754 };
755
756 dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data)
757 {
758         dwc_timer_t *t = DWC_ALLOC(sizeof(*t));
759
760         if (!t) {
761                 DWC_ERROR("Cannot allocate memory for timer");
762                 return NULL;
763         }
764
765         callout_init(&t->t);
766
767         t->name = DWC_STRDUP(name);
768         if (!t->name) {
769                 DWC_ERROR("Cannot allocate memory for timer->name");
770                 goto no_name;
771         }
772
773         t->lock = DWC_SPINLOCK_ALLOC();
774         if (!t->lock) {
775                 DWC_ERROR("Cannot allocate memory for timer->lock");
776                 goto no_lock;
777         }
778
779         t->cb = cb;
780         t->data = data;
781
782         return t;
783
784  no_lock:
785         DWC_FREE(t->name);
786  no_name:
787         DWC_FREE(t);
788
789         return NULL;
790 }
791
792 void DWC_TIMER_FREE(dwc_timer_t *timer)
793 {
794         callout_stop(&timer->t);
795         DWC_SPINLOCK_FREE(timer->lock);
796         DWC_FREE(timer->name);
797         DWC_FREE(timer);
798 }
799
800 void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time)
801 {
802         struct timeval tv;
803
804         tv.tv_sec = time / 1000;
805         tv.tv_usec = (time - tv.tv_sec * 1000) * 1000;
806         callout_reset(&timer->t, tvtohz(&tv), timer->cb, timer->data);
807 }
808
809 void DWC_TIMER_CANCEL(dwc_timer_t *timer)
810 {
811         callout_stop(&timer->t);
812 }
813
814
815 /* Wait Queues */
816
817 struct dwc_waitq {
818         struct simplelock lock;
819         int abort;
820 };
821
822 dwc_waitq_t *DWC_WAITQ_ALLOC(void)
823 {
824         dwc_waitq_t *wq = DWC_ALLOC(sizeof(*wq));
825
826         if (!wq) {
827                 DWC_ERROR("Cannot allocate memory for waitqueue");
828                 return NULL;
829         }
830
831         simple_lock_init(&wq->lock);
832         wq->abort = 0;
833
834         return wq;
835 }
836
837 void DWC_WAITQ_FREE(dwc_waitq_t *wq)
838 {
839         DWC_FREE(wq);
840 }
841
842 int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data)
843 {
844         int ipl;
845         int result = 0;
846
847         simple_lock(&wq->lock);
848         ipl = splbio();
849
850         /* Skip the sleep if already aborted or triggered */
851         if (!wq->abort && !cond(data)) {
852                 splx(ipl);
853                 result = ltsleep(wq, PCATCH, "dw3wat", 0, &wq->lock); // infinite timeout
854                 ipl = splbio();
855         }
856
857         if (result == 0) {                      // awoken
858                 if (wq->abort) {
859                         wq->abort = 0;
860                         result = -DWC_E_ABORT;
861                 } else {
862                         result = 0;
863                 }
864
865                 splx(ipl);
866                 simple_unlock(&wq->lock);
867         } else {
868                 wq->abort = 0;
869                 splx(ipl);
870                 simple_unlock(&wq->lock);
871
872                 if (result == ERESTART) {       // signaled - restart
873                         result = -DWC_E_RESTART;
874                 } else {                        // signaled - must be EINTR
875                         result = -DWC_E_ABORT;
876                 }
877         }
878
879         return result;
880 }
881
882 int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond,
883                                void *data, int32_t msecs)
884 {
885         struct timeval tv, tv1, tv2;
886         int ipl;
887         int result = 0;
888
889         tv.tv_sec = msecs / 1000;
890         tv.tv_usec = (msecs - tv.tv_sec * 1000) * 1000;
891
892         simple_lock(&wq->lock);
893         ipl = splbio();
894
895         /* Skip the sleep if already aborted or triggered */
896         if (!wq->abort && !cond(data)) {
897                 splx(ipl);
898                 getmicrouptime(&tv1);
899                 result = ltsleep(wq, PCATCH, "dw3wto", tvtohz(&tv), &wq->lock);
900                 getmicrouptime(&tv2);
901                 ipl = splbio();
902         }
903
904         if (result == 0) {                      // awoken
905                 if (wq->abort) {
906                         wq->abort = 0;
907                         splx(ipl);
908                         simple_unlock(&wq->lock);
909                         result = -DWC_E_ABORT;
910                 } else {
911                         splx(ipl);
912                         simple_unlock(&wq->lock);
913
914                         tv2.tv_usec -= tv1.tv_usec;
915                         if (tv2.tv_usec < 0) {
916                                 tv2.tv_usec += 1000000;
917                                 tv2.tv_sec--;
918                         }
919
920                         tv2.tv_sec -= tv1.tv_sec;
921                         result = tv2.tv_sec * 1000 + tv2.tv_usec / 1000;
922                         result = msecs - result;
923                         if (result <= 0)
924                                 result = 1;
925                 }
926         } else {
927                 wq->abort = 0;
928                 splx(ipl);
929                 simple_unlock(&wq->lock);
930
931                 if (result == ERESTART) {       // signaled - restart
932                         result = -DWC_E_RESTART;
933
934                 } else if (result == EINTR) {           // signaled - interrupt
935                         result = -DWC_E_ABORT;
936
937                 } else {                                // timed out
938                         result = -DWC_E_TIMEOUT;
939                 }
940         }
941
942         return result;
943 }
944
945 void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq)
946 {
947         wakeup(wq);
948 }
949
950 void DWC_WAITQ_ABORT(dwc_waitq_t *wq)
951 {
952         int ipl;
953
954         simple_lock(&wq->lock);
955         ipl = splbio();
956         wq->abort = 1;
957         wakeup(wq);
958         splx(ipl);
959         simple_unlock(&wq->lock);
960 }
961
962
963 /* Threading */
964
965 struct dwc_thread {
966         struct proc *proc;
967         int abort;
968 };
969
970 dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data)
971 {
972         int retval;
973         dwc_thread_t *thread = DWC_ALLOC(sizeof(*thread));
974
975         if (!thread) {
976                 return NULL;
977         }
978
979         thread->abort = 0;
980         retval = kthread_create1((void (*)(void *))func, data, &thread->proc,
981                                  "%s", name);
982         if (retval) {
983                 DWC_FREE(thread);
984                 return NULL;
985         }
986
987         return thread;
988 }
989
990 int DWC_THREAD_STOP(dwc_thread_t *thread)
991 {
992         int retval;
993
994         thread->abort = 1;
995         retval = tsleep(&thread->abort, 0, "dw3stp", 60 * hz);
996
997         if (retval == 0) {
998                 /* DWC_THREAD_EXIT() will free the thread struct */
999                 return 0;
1000         }
1001
1002         /* NOTE: We leak the thread struct if thread doesn't die */
1003
1004         if (retval == EWOULDBLOCK) {
1005                 return -DWC_E_TIMEOUT;
1006         }
1007
1008         return -DWC_E_UNKNOWN;
1009 }
1010
1011 dwc_bool_t DWC_THREAD_SHOULD_STOP(dwc_thread_t *thread)
1012 {
1013         return thread->abort;
1014 }
1015
1016 void DWC_THREAD_EXIT(dwc_thread_t *thread)
1017 {
1018         wakeup(&thread->abort);
1019         DWC_FREE(thread);
1020         kthread_exit(0);
1021 }
1022
1023 /* tasklets
1024  - Runs in interrupt context (cannot sleep)
1025  - Each tasklet runs on a single CPU
1026  - Different tasklets can be running simultaneously on different CPUs
1027  [ On NetBSD there is no corresponding mechanism, drivers don't have bottom-
1028    halves. So we just call the callback directly from DWC_TASK_SCHEDULE() ]
1029  */
1030 struct dwc_tasklet {
1031         dwc_tasklet_callback_t cb;
1032         void *data;
1033 };
1034
1035 static void tasklet_callback(void *data)
1036 {
1037         dwc_tasklet_t *task = (dwc_tasklet_t *)data;
1038
1039         task->cb(task->data);
1040 }
1041
1042 dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data)
1043 {
1044         dwc_tasklet_t *task = DWC_ALLOC(sizeof(*task));
1045
1046         if (task) {
1047                 task->cb = cb;
1048                 task->data = data;
1049         } else {
1050                 DWC_ERROR("Cannot allocate memory for tasklet");
1051         }
1052
1053         return task;
1054 }
1055
1056 void DWC_TASK_FREE(dwc_tasklet_t *task)
1057 {
1058         DWC_FREE(task);
1059 }
1060
1061 void DWC_TASK_SCHEDULE(dwc_tasklet_t *task)
1062 {
1063         tasklet_callback(task);
1064 }
1065
1066
1067 /* workqueues
1068  - Runs in process context (can sleep)
1069  */
1070 typedef struct work_container {
1071         dwc_work_callback_t cb;
1072         void *data;
1073         dwc_workq_t *wq;
1074         char *name;
1075         int hz;
1076         struct work task;
1077 } work_container_t;
1078
1079 struct dwc_workq {
1080         struct workqueue *taskq;
1081         dwc_spinlock_t *lock;
1082         dwc_waitq_t *waitq;
1083         int pending;
1084         struct work_container *container;
1085 };
1086
1087 static void do_work(struct work *task, void *data)
1088 {
1089         dwc_workq_t *wq = (dwc_workq_t *)data;
1090         work_container_t *container = wq->container;
1091         dwc_irqflags_t flags;
1092
1093         if (container->hz) {
1094                 tsleep(container, 0, "dw3wrk", container->hz);
1095         }
1096
1097         container->cb(container->data);
1098         DWC_DEBUG("Work done: %s, container=%p", container->name, container);
1099
1100         DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
1101         if (container->name)
1102                 DWC_FREE(container->name);
1103         DWC_FREE(container);
1104         wq->pending--;
1105         DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
1106         DWC_WAITQ_TRIGGER(wq->waitq);
1107 }
1108
1109 static int work_done(void *data)
1110 {
1111         dwc_workq_t *workq = (dwc_workq_t *)data;
1112
1113         return workq->pending == 0;
1114 }
1115
1116 int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout)
1117 {
1118         return DWC_WAITQ_WAIT_TIMEOUT(workq->waitq, work_done, workq, timeout);
1119 }
1120
1121 dwc_workq_t *DWC_WORKQ_ALLOC(char *name)
1122 {
1123         int result;
1124         dwc_workq_t *wq = DWC_ALLOC(sizeof(*wq));
1125
1126         if (!wq) {
1127                 DWC_ERROR("Cannot allocate memory for workqueue");
1128                 return NULL;
1129         }
1130
1131         result = workqueue_create(&wq->taskq, name, do_work, wq, 0 /*PWAIT*/,
1132                                   IPL_BIO, 0);
1133         if (result) {
1134                 DWC_ERROR("Cannot create workqueue");
1135                 goto no_taskq;
1136         }
1137
1138         wq->pending = 0;
1139
1140         wq->lock = DWC_SPINLOCK_ALLOC();
1141         if (!wq->lock) {
1142                 DWC_ERROR("Cannot allocate memory for spinlock");
1143                 goto no_lock;
1144         }
1145
1146         wq->waitq = DWC_WAITQ_ALLOC();
1147         if (!wq->waitq) {
1148                 DWC_ERROR("Cannot allocate memory for waitqueue");
1149                 goto no_waitq;
1150         }
1151
1152         return wq;
1153
1154  no_waitq:
1155         DWC_SPINLOCK_FREE(wq->lock);
1156  no_lock:
1157         workqueue_destroy(wq->taskq);
1158  no_taskq:
1159         DWC_FREE(wq);
1160
1161         return NULL;
1162 }
1163
1164 void DWC_WORKQ_FREE(dwc_workq_t *wq)
1165 {
1166 #ifdef DEBUG
1167         dwc_irqflags_t flags;
1168
1169         DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
1170
1171         if (wq->pending != 0) {
1172                 struct work_container *container = wq->container;
1173
1174                 DWC_ERROR("Destroying work queue with pending work");
1175
1176                 if (container && container->name) {
1177                         DWC_ERROR("Work %s still pending", container->name);
1178                 }
1179         }
1180
1181         DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
1182 #endif
1183         DWC_WAITQ_FREE(wq->waitq);
1184         DWC_SPINLOCK_FREE(wq->lock);
1185         workqueue_destroy(wq->taskq);
1186         DWC_FREE(wq);
1187 }
1188
1189 void DWC_WORKQ_SCHEDULE(dwc_workq_t *wq, dwc_work_callback_t cb, void *data,
1190                         char *format, ...)
1191 {
1192         dwc_irqflags_t flags;
1193         work_container_t *container;
1194         static char name[128];
1195         va_list args;
1196
1197         va_start(args, format);
1198         DWC_VSNPRINTF(name, 128, format, args);
1199         va_end(args);
1200
1201         DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
1202         wq->pending++;
1203         DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
1204         DWC_WAITQ_TRIGGER(wq->waitq);
1205
1206         container = DWC_ALLOC_ATOMIC(sizeof(*container));
1207         if (!container) {
1208                 DWC_ERROR("Cannot allocate memory for container");
1209                 return;
1210         }
1211
1212         container->name = DWC_STRDUP(name);
1213         if (!container->name) {
1214                 DWC_ERROR("Cannot allocate memory for container->name");
1215                 DWC_FREE(container);
1216                 return;
1217         }
1218
1219         container->cb = cb;
1220         container->data = data;
1221         container->wq = wq;
1222         container->hz = 0;
1223         wq->container = container;
1224
1225         DWC_DEBUG("Queueing work: %s, container=%p", container->name, container);
1226         workqueue_enqueue(wq->taskq, &container->task);
1227 }
1228
1229 void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *wq, dwc_work_callback_t cb,
1230                                 void *data, uint32_t time, char *format, ...)
1231 {
1232         dwc_irqflags_t flags;
1233         work_container_t *container;
1234         static char name[128];
1235         struct timeval tv;
1236         va_list args;
1237
1238         va_start(args, format);
1239         DWC_VSNPRINTF(name, 128, format, args);
1240         va_end(args);
1241
1242         DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
1243         wq->pending++;
1244         DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
1245         DWC_WAITQ_TRIGGER(wq->waitq);
1246
1247         container = DWC_ALLOC_ATOMIC(sizeof(*container));
1248         if (!container) {
1249                 DWC_ERROR("Cannot allocate memory for container");
1250                 return;
1251         }
1252
1253         container->name = DWC_STRDUP(name);
1254         if (!container->name) {
1255                 DWC_ERROR("Cannot allocate memory for container->name");
1256                 DWC_FREE(container);
1257                 return;
1258         }
1259
1260         container->cb = cb;
1261         container->data = data;
1262         container->wq = wq;
1263         tv.tv_sec = time / 1000;
1264         tv.tv_usec = (time - tv.tv_sec * 1000) * 1000;
1265         container->hz = tvtohz(&tv);
1266         wq->container = container;
1267
1268         DWC_DEBUG("Queueing work: %s, container=%p", container->name, container);
1269         workqueue_enqueue(wq->taskq, &container->task);
1270 }
1271
1272 int DWC_WORKQ_PENDING(dwc_workq_t *wq)
1273 {
1274         return wq->pending;
1275 }