Subversion Repositories Kolibri OS

Rev

Rev 6084 | Rev 6103 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3263 Serge 1
#include 
2
#include 
3260 Serge 3
#include 
4
#include 
5
#include "i915_drv.h"
6
#include "intel_drv.h"
3480 Serge 7
#include 
6084 serge 8
#include 
9
#include 
6088 serge 10
#include "i915_kos32.h"
3260 Serge 11
 
12
struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
13
{
14
    struct file *filep;
15
    int count;
16
 
5354 serge 17
    filep = __builtin_malloc(sizeof(*filep));
3260 Serge 18
 
19
    if(unlikely(filep == NULL))
20
        return ERR_PTR(-ENOMEM);
21
 
22
    count = size / PAGE_SIZE;
23
 
24
    filep->pages = kzalloc(sizeof(struct page *) * count, 0);
25
    if(unlikely(filep->pages == NULL))
26
    {
27
        kfree(filep);
28
        return ERR_PTR(-ENOMEM);
29
    };
30
 
31
    filep->count     = count;
32
    filep->allocated = 0;
33
    filep->vma       = NULL;
34
 
3298 Serge 35
//    printf("%s file %p pages %p count %d\n",
36
//              __FUNCTION__,filep, filep->pages, count);
3260 Serge 37
 
38
    return filep;
39
}
40
 
41
struct page *shmem_read_mapping_page_gfp(struct file *filep,
42
                                         pgoff_t index, gfp_t gfp)
43
{
44
    struct page *page;
45
 
46
    if(unlikely(index >= filep->count))
47
        return ERR_PTR(-EINVAL);
48
 
49
    page = filep->pages[index];
50
 
51
    if(unlikely(page == NULL))
52
    {
53
        page = (struct page *)AllocPage();
54
 
55
        if(unlikely(page == NULL))
56
            return ERR_PTR(-ENOMEM);
57
 
58
        filep->pages[index] = page;
4246 Serge 59
//        printf("file %p index %d page %x\n", filep, index, page);
60
//        delay(1);
61
 
3260 Serge 62
    };
63
 
64
    return page;
65
};
3263 Serge 66
 
67
unsigned long vm_mmap(struct file *file, unsigned long addr,
68
         unsigned long len, unsigned long prot,
69
         unsigned long flag, unsigned long offset)
70
{
71
    char *mem, *ptr;
72
    int i;
73
 
74
    if (unlikely(offset + PAGE_ALIGN(len) < offset))
75
        return -EINVAL;
76
    if (unlikely(offset & ~PAGE_MASK))
77
        return -EINVAL;
78
 
79
    mem = UserAlloc(len);
80
    if(unlikely(mem == NULL))
81
        return -ENOMEM;
82
 
83
    for(i = offset, ptr = mem; i < offset+len; i+= 4096, ptr+= 4096)
84
    {
85
        struct page *page;
86
 
87
        page = shmem_read_mapping_page_gfp(file, i/PAGE_SIZE,0);
88
 
89
        if (unlikely(IS_ERR(page)))
90
            goto err;
91
 
92
        MapPage(ptr, (addr_t)page, PG_SHARED|PG_UW);
93
    }
94
 
95
    return (unsigned long)mem;
96
err:
97
    UserFree(mem);
98
    return -ENOMEM;
99
};
100
 
3290 Serge 101
void shmem_file_delete(struct file *filep)
102
{
3298 Serge 103
//    printf("%s file %p pages %p count %d\n",
104
//            __FUNCTION__, filep, filep->pages, filep->count);
3263 Serge 105
 
3290 Serge 106
    if(filep->pages)
107
        kfree(filep->pages);
108
}
3480 Serge 109
 
110
 
111
 
112
static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
113
{
114
        while (bytes) {
115
                if (*start != value)
116
                        return (void *)start;
117
                start++;
118
                bytes--;
119
        }
120
        return NULL;
121
}
122
 
123
/**
124
 * memchr_inv - Find an unmatching character in an area of memory.
125
 * @start: The memory area
126
 * @c: Find a character other than c
127
 * @bytes: The size of the area.
128
 *
129
 * returns the address of the first character other than @c, or %NULL
130
 * if the whole buffer contains just @c.
131
 */
132
void *memchr_inv(const void *start, int c, size_t bytes)
133
{
134
        u8 value = c;
135
        u64 value64;
136
        unsigned int words, prefix;
137
 
138
        if (bytes <= 16)
139
                return check_bytes8(start, value, bytes);
140
 
141
        value64 = value;
142
#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
143
        value64 *= 0x0101010101010101;
144
#elif defined(ARCH_HAS_FAST_MULTIPLIER)
145
        value64 *= 0x01010101;
146
        value64 |= value64 << 32;
147
#else
148
        value64 |= value64 << 8;
149
        value64 |= value64 << 16;
150
        value64 |= value64 << 32;
151
#endif
152
 
153
        prefix = (unsigned long)start % 8;
154
        if (prefix) {
155
                u8 *r;
156
 
157
                prefix = 8 - prefix;
158
                r = check_bytes8(start, value, prefix);
159
                if (r)
160
                        return r;
161
                start += prefix;
162
                bytes -= prefix;
163
        }
164
 
165
        words = bytes / 8;
166
 
167
        while (words) {
168
                if (*(u64 *)start != value64)
169
                        return check_bytes8(start, value, 8);
170
                start += 8;
171
                words--;
172
        }
173
 
174
        return check_bytes8(start, value, bytes % 8);
175
}
176
 
177
 
178
 
179
int dma_map_sg(struct device *dev, struct scatterlist *sglist,
180
                           int nelems, int dir)
181
{
182
    struct scatterlist *s;
183
    int i;
184
 
185
    for_each_sg(sglist, s, nelems, i) {
186
        s->dma_address = (dma_addr_t)sg_phys(s);
187
#ifdef CONFIG_NEED_SG_DMA_LENGTH
188
        s->dma_length  = s->length;
189
#endif
190
    }
191
 
192
    return nelems;
193
}
194
 
195
 
196
 
197
#define _U  0x01    /* upper */
198
#define _L  0x02    /* lower */
199
#define _D  0x04    /* digit */
200
#define _C  0x08    /* cntrl */
201
#define _P  0x10    /* punct */
202
#define _S  0x20    /* white space (space/lf/tab) */
203
#define _X  0x40    /* hex digit */
204
#define _SP 0x80    /* hard space (0x20) */
205
 
206
extern const unsigned char _ctype[];
207
 
208
#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
209
 
210
#define isalnum(c)  ((__ismask(c)&(_U|_L|_D)) != 0)
211
#define isalpha(c)  ((__ismask(c)&(_U|_L)) != 0)
212
#define iscntrl(c)  ((__ismask(c)&(_C)) != 0)
213
#define isdigit(c)  ((__ismask(c)&(_D)) != 0)
214
#define isgraph(c)  ((__ismask(c)&(_P|_U|_L|_D)) != 0)
215
#define islower(c)  ((__ismask(c)&(_L)) != 0)
216
#define isprint(c)  ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
217
#define ispunct(c)  ((__ismask(c)&(_P)) != 0)
218
/* Note: isspace() must return false for %NUL-terminator */
219
#define isspace(c)  ((__ismask(c)&(_S)) != 0)
220
#define isupper(c)  ((__ismask(c)&(_U)) != 0)
221
#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
222
 
223
#define isascii(c) (((unsigned char)(c))<=0x7f)
224
#define toascii(c) (((unsigned char)(c))&0x7f)
225
 
226
static inline unsigned char __tolower(unsigned char c)
227
{
228
    if (isupper(c))
229
        c -= 'A'-'a';
230
    return c;
231
}
232
 
233
static inline unsigned char __toupper(unsigned char c)
234
{
235
    if (islower(c))
236
        c -= 'a'-'A';
237
    return c;
238
}
239
 
240
#define tolower(c) __tolower(c)
241
#define toupper(c) __toupper(c)
242
 
243
/*
244
 * Fast implementation of tolower() for internal usage. Do not use in your
245
 * code.
246
 */
247
static inline char _tolower(const char c)
248
{
249
    return c | 0x20;
250
}
251
 
252
 
253
//const char hex_asc[] = "0123456789abcdef";
254
 
255
/**
256
 * hex_to_bin - convert a hex digit to its real value
257
 * @ch: ascii character represents hex digit
258
 *
259
 * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad
260
 * input.
261
 */
262
int hex_to_bin(char ch)
263
{
264
    if ((ch >= '0') && (ch <= '9'))
265
        return ch - '0';
266
    ch = tolower(ch);
267
    if ((ch >= 'a') && (ch <= 'f'))
268
        return ch - 'a' + 10;
269
    return -1;
270
}
271
EXPORT_SYMBOL(hex_to_bin);
272
 
273
/**
274
 * hex2bin - convert an ascii hexadecimal string to its binary representation
275
 * @dst: binary result
276
 * @src: ascii hexadecimal string
277
 * @count: result length
278
 *
279
 * Return 0 on success, -1 in case of bad input.
280
 */
281
int hex2bin(u8 *dst, const char *src, size_t count)
282
{
283
    while (count--) {
284
        int hi = hex_to_bin(*src++);
285
        int lo = hex_to_bin(*src++);
286
 
287
        if ((hi < 0) || (lo < 0))
288
            return -1;
289
 
290
        *dst++ = (hi << 4) | lo;
291
    }
292
    return 0;
293
}
294
EXPORT_SYMBOL(hex2bin);
295
 
296
/**
297
 * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
298
 * @buf: data blob to dump
299
 * @len: number of bytes in the @buf
300
 * @rowsize: number of bytes to print per line; must be 16 or 32
301
 * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
302
 * @linebuf: where to put the converted data
303
 * @linebuflen: total size of @linebuf, including space for terminating NUL
304
 * @ascii: include ASCII after the hex output
305
 *
306
 * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
307
 * 16 or 32 bytes of input data converted to hex + ASCII output.
308
 *
309
 * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
310
 * to a hex + ASCII dump at the supplied memory location.
311
 * The converted output is always NUL-terminated.
312
 *
313
 * E.g.:
314
 *   hex_dump_to_buffer(frame->data, frame->len, 16, 1,
315
 *          linebuf, sizeof(linebuf), true);
316
 *
317
 * example output buffer:
318
 * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
319
 */
6084 serge 320
int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize,
321
               char *linebuf, size_t linebuflen, bool ascii)
3480 Serge 322
{
323
    const u8 *ptr = buf;
6084 serge 324
    int ngroups;
3480 Serge 325
    u8 ch;
326
    int j, lx = 0;
327
    int ascii_column;
6084 serge 328
    int ret;
3480 Serge 329
 
330
    if (rowsize != 16 && rowsize != 32)
331
        rowsize = 16;
332
 
333
    if (len > rowsize)      /* limit to one line at a time */
334
        len = rowsize;
6084 serge 335
    if (!is_power_of_2(groupsize) || groupsize > 8)
336
        groupsize = 1;
3480 Serge 337
    if ((len % groupsize) != 0) /* no mixed size output */
338
        groupsize = 1;
339
 
6084 serge 340
    ngroups = len / groupsize;
341
    ascii_column = rowsize * 2 + rowsize / groupsize + 1;
342
 
343
    if (!linebuflen)
344
        goto overflow1;
345
 
346
    if (!len)
347
        goto nil;
348
 
349
    if (groupsize == 8) {
3480 Serge 350
        const u64 *ptr8 = buf;
351
 
6084 serge 352
        for (j = 0; j < ngroups; j++) {
353
            ret = snprintf(linebuf + lx, linebuflen - lx,
354
                       "%s%16.16llx", j ? " " : "",
355
                       (unsigned long long)*(ptr8 + j));
356
            if (ret >= linebuflen - lx)
357
                goto overflow1;
358
            lx += ret;
359
        }
360
    } else if (groupsize == 4) {
3480 Serge 361
        const u32 *ptr4 = buf;
362
 
6084 serge 363
        for (j = 0; j < ngroups; j++) {
364
            ret = snprintf(linebuf + lx, linebuflen - lx,
365
                       "%s%8.8x", j ? " " : "",
366
                       *(ptr4 + j));
367
            if (ret >= linebuflen - lx)
368
                goto overflow1;
369
            lx += ret;
370
        }
371
    } else if (groupsize == 2) {
3480 Serge 372
        const u16 *ptr2 = buf;
373
 
6084 serge 374
        for (j = 0; j < ngroups; j++) {
375
            ret = snprintf(linebuf + lx, linebuflen - lx,
376
                       "%s%4.4x", j ? " " : "",
377
                       *(ptr2 + j));
378
            if (ret >= linebuflen - lx)
379
                goto overflow1;
380
            lx += ret;
381
        }
382
    } else {
383
        for (j = 0; j < len; j++) {
384
            if (linebuflen < lx + 3)
385
                goto overflow2;
3480 Serge 386
            ch = ptr[j];
387
            linebuf[lx++] = hex_asc_hi(ch);
388
            linebuf[lx++] = hex_asc_lo(ch);
389
            linebuf[lx++] = ' ';
390
        }
391
        if (j)
392
            lx--;
393
    }
394
    if (!ascii)
395
        goto nil;
396
 
6084 serge 397
    while (lx < ascii_column) {
398
        if (linebuflen < lx + 2)
399
            goto overflow2;
3480 Serge 400
        linebuf[lx++] = ' ';
6084 serge 401
    }
402
    for (j = 0; j < len; j++) {
403
        if (linebuflen < lx + 2)
404
            goto overflow2;
3480 Serge 405
        ch = ptr[j];
406
        linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.';
407
    }
408
nil:
6084 serge 409
    linebuf[lx] = '\0';
410
    return lx;
411
overflow2:
3480 Serge 412
    linebuf[lx++] = '\0';
6084 serge 413
overflow1:
414
    return ascii ? ascii_column + len : (groupsize * 2 + 1) * ngroups - 1;
3480 Serge 415
}
416
/**
417
 * print_hex_dump - print a text hex dump to syslog for a binary blob of data
418
 * @level: kernel log level (e.g. KERN_DEBUG)
419
 * @prefix_str: string to prefix each line with;
420
 *  caller supplies trailing spaces for alignment if desired
421
 * @prefix_type: controls whether prefix of an offset, address, or none
422
 *  is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
423
 * @rowsize: number of bytes to print per line; must be 16 or 32
424
 * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
425
 * @buf: data blob to dump
426
 * @len: number of bytes in the @buf
427
 * @ascii: include ASCII after the hex output
428
 *
429
 * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump
430
 * to the kernel log at the specified kernel log level, with an optional
431
 * leading prefix.
432
 *
433
 * print_hex_dump() works on one "line" of output at a time, i.e.,
434
 * 16 or 32 bytes of input data converted to hex + ASCII output.
435
 * print_hex_dump() iterates over the entire input @buf, breaking it into
436
 * "line size" chunks to format and print.
437
 *
438
 * E.g.:
439
 *   print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS,
440
 *          16, 1, frame->data, frame->len, true);
441
 *
442
 * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode:
443
 * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
444
 * Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode:
445
 * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c  pqrstuvwxyz{|}~.
446
 */
447
void print_hex_dump(const char *level, const char *prefix_str, int prefix_type,
448
            int rowsize, int groupsize,
449
            const void *buf, size_t len, bool ascii)
450
{
451
    const u8 *ptr = buf;
452
    int i, linelen, remaining = len;
453
    unsigned char linebuf[32 * 3 + 2 + 32 + 1];
454
 
455
    if (rowsize != 16 && rowsize != 32)
456
        rowsize = 16;
457
 
458
    for (i = 0; i < len; i += rowsize) {
459
        linelen = min(remaining, rowsize);
460
        remaining -= rowsize;
461
 
462
        hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
463
                   linebuf, sizeof(linebuf), ascii);
464
 
465
        switch (prefix_type) {
466
        case DUMP_PREFIX_ADDRESS:
467
            printk("%s%s%p: %s\n",
468
                   level, prefix_str, ptr + i, linebuf);
469
            break;
470
        case DUMP_PREFIX_OFFSET:
471
            printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf);
472
            break;
473
        default:
474
            printk("%s%s%s\n", level, prefix_str, linebuf);
475
            break;
476
        }
477
    }
478
}
479
 
480
void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
481
                          const void *buf, size_t len)
482
{
483
    print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1,
484
                       buf, len, true);
485
}
486
 
4104 Serge 487
void *kmemdup(const void *src, size_t len, gfp_t gfp)
488
{
489
    void *p;
3480 Serge 490
 
4104 Serge 491
    p = kmalloc(len, gfp);
492
    if (p)
493
        memcpy(p, src, len);
494
    return p;
495
}
496
 
497
 
5354 serge 498
#define KMAP_MAX    256
5060 serge 499
 
5354 serge 500
static struct mutex kmap_mutex;
501
static struct page* kmap_table[KMAP_MAX];
502
static int kmap_av;
503
static int kmap_first;
504
static void* kmap_base;
505
 
506
 
507
int kmap_init()
508
{
509
    kmap_base = AllocKernelSpace(KMAP_MAX*4096);
510
    if(kmap_base == NULL)
511
        return -1;
512
 
513
    kmap_av = KMAP_MAX;
514
    MutexInit(&kmap_mutex);
515
    return 0;
516
};
517
 
5060 serge 518
void *kmap(struct page *page)
519
{
5354 serge 520
    void *vaddr = NULL;
521
    int i;
522
 
523
    do
524
    {
525
        MutexLock(&kmap_mutex);
526
        if(kmap_av != 0)
527
        {
528
            for(i = kmap_first; i < KMAP_MAX; i++)
529
            {
530
                if(kmap_table[i] == NULL)
531
                {
532
                    kmap_av--;
533
                    kmap_first = i;
534
                    kmap_table[i] = page;
535
                    vaddr = kmap_base + (i<<12);
536
                    MapPage(vaddr,(addr_t)page,3);
537
                    break;
538
                };
539
            };
540
        };
541
        MutexUnlock(&kmap_mutex);
542
    }while(vaddr == NULL);
543
 
544
    return vaddr;
545
};
546
 
547
void *kmap_atomic(struct page *page) __attribute__ ((alias ("kmap")));
548
 
549
void kunmap(struct page *page)
550
{
5060 serge 551
    void *vaddr;
5354 serge 552
    int   i;
5060 serge 553
 
5354 serge 554
    MutexLock(&kmap_mutex);
5060 serge 555
 
5354 serge 556
    for(i = 0; i < KMAP_MAX; i++)
557
    {
558
        if(kmap_table[i] == page)
559
        {
560
            kmap_av++;
561
            if(i < kmap_first)
562
                kmap_first = i;
563
            kmap_table[i] = NULL;
564
            vaddr = kmap_base + (i<<12);
565
            MapPage(vaddr,0,0);
566
            break;
567
        };
568
    };
569
 
570
    MutexUnlock(&kmap_mutex);
571
};
572
 
573
void kunmap_atomic(void *vaddr)
574
{
575
    int i;
576
 
577
    MapPage(vaddr,0,0);
578
 
579
    i = (vaddr - kmap_base) >> 12;
580
 
581
    MutexLock(&kmap_mutex);
582
 
583
    kmap_av++;
584
    if(i < kmap_first)
585
        kmap_first = i;
586
    kmap_table[i] = NULL;
587
 
588
    MutexUnlock(&kmap_mutex);
5060 serge 589
}
590
 
5354 serge 591
size_t strlcat(char *dest, const char *src, size_t count)
5060 serge 592
{
5354 serge 593
        size_t dsize = strlen(dest);
594
        size_t len = strlen(src);
595
        size_t res = dsize + len;
5060 serge 596
 
5354 serge 597
        /* This would be a bug */
598
        BUG_ON(dsize >= count);
5060 serge 599
 
5354 serge 600
        dest += dsize;
601
        count -= dsize;
602
        if (len >= count)
603
                len = count-1;
604
        memcpy(dest, src, len);
605
        dest[len] = 0;
606
        return res;
5060 serge 607
}
5354 serge 608
EXPORT_SYMBOL(strlcat);
5060 serge 609
 
5354 serge 610
void msleep(unsigned int msecs)
611
{
612
    msecs /= 10;
613
    if(!msecs) msecs = 1;
614
 
615
     __asm__ __volatile__ (
616
     "call *__imp__Delay"
617
     ::"b" (msecs));
618
     __asm__ __volatile__ (
619
     "":::"ebx");
620
 
621
};
622
 
623
 
624
/* simple loop based delay: */
625
static void delay_loop(unsigned long loops)
626
{
627
        asm volatile(
628
                "       test %0,%0      \n"
629
                "       jz 3f           \n"
630
                "       jmp 1f          \n"
631
 
632
                ".align 16              \n"
633
                "1:     jmp 2f          \n"
634
 
635
                ".align 16              \n"
636
                "2:     dec %0          \n"
637
                "       jnz 2b          \n"
638
                "3:     dec %0          \n"
639
 
640
                : /* we don't need output */
641
                :"a" (loops)
642
        );
643
}
644
 
645
 
646
static void (*delay_fn)(unsigned long) = delay_loop;
647
 
648
void __delay(unsigned long loops)
649
{
650
        delay_fn(loops);
651
}
652
 
653
 
654
inline void __const_udelay(unsigned long xloops)
655
{
656
        int d0;
657
 
658
        xloops *= 4;
659
        asm("mull %%edx"
660
                : "=d" (xloops), "=&a" (d0)
661
                : "1" (xloops), ""
662
                (loops_per_jiffy * (HZ/4)));
663
 
664
        __delay(++xloops);
665
}
666
 
667
void __udelay(unsigned long usecs)
668
{
669
        __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
670
}
671
 
672
unsigned int _sw_hweight32(unsigned int w)
673
{
674
#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
675
        w -= (w >> 1) & 0x55555555;
676
        w =  (w & 0x33333333) + ((w >> 2) & 0x33333333);
677
        w =  (w + (w >> 4)) & 0x0f0f0f0f;
678
        return (w * 0x01010101) >> 24;
679
#else
680
        unsigned int res = w - ((w >> 1) & 0x55555555);
681
        res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
682
        res = (res + (res >> 4)) & 0x0F0F0F0F;
683
        res = res + (res >> 8);
684
        return (res + (res >> 16)) & 0x000000FF;
685
#endif
686
}
687
EXPORT_SYMBOL(_sw_hweight32);
688
 
689
 
690
void usleep_range(unsigned long min, unsigned long max)
691
{
692
    udelay(max);
693
}
694
EXPORT_SYMBOL(usleep_range);
695
 
696
 
697
static unsigned long round_jiffies_common(unsigned long j, int cpu,
698
                bool force_up)
699
{
700
        int rem;
701
        unsigned long original = j;
702
 
703
        /*
704
         * We don't want all cpus firing their timers at once hitting the
705
         * same lock or cachelines, so we skew each extra cpu with an extra
706
         * 3 jiffies. This 3 jiffies came originally from the mm/ code which
707
         * already did this.
708
         * The skew is done by adding 3*cpunr, then round, then subtract this
709
         * extra offset again.
710
         */
711
        j += cpu * 3;
712
 
713
        rem = j % HZ;
714
 
715
        /*
716
         * If the target jiffie is just after a whole second (which can happen
717
         * due to delays of the timer irq, long irq off times etc etc) then
718
         * we should round down to the whole second, not up. Use 1/4th second
719
         * as cutoff for this rounding as an extreme upper bound for this.
720
         * But never round down if @force_up is set.
721
         */
722
        if (rem < HZ/4 && !force_up) /* round down */
723
                j = j - rem;
724
        else /* round up */
725
                j = j - rem + HZ;
726
 
727
        /* now that we have rounded, subtract the extra skew again */
728
        j -= cpu * 3;
729
 
730
        /*
731
         * Make sure j is still in the future. Otherwise return the
732
         * unmodified value.
733
         */
734
        return time_is_after_jiffies(j) ? j : original;
735
}
736
 
737
 
738
unsigned long round_jiffies_up_relative(unsigned long j, int cpu)
739
{
740
        unsigned long j0 = jiffies;
741
 
742
        /* Use j0 because jiffies might change while we run */
743
        return round_jiffies_common(j + j0, 0, true) - j0;
744
}
745
EXPORT_SYMBOL_GPL(__round_jiffies_up_relative);
746
 
747
 
748
#include 
749
 
750
struct rcu_ctrlblk {
751
        struct rcu_head *rcucblist;     /* List of pending callbacks (CBs). */
752
        struct rcu_head **donetail;     /* ->next pointer of last "done" CB. */
753
        struct rcu_head **curtail;      /* ->next pointer of last CB. */
754
//        RCU_TRACE(long qlen);           /* Number of pending CBs. */
755
//        RCU_TRACE(unsigned long gp_start); /* Start time for stalls. */
756
//        RCU_TRACE(unsigned long ticks_this_gp); /* Statistic for stalls. */
757
//        RCU_TRACE(unsigned long jiffies_stall); /* Jiffies at next stall. */
758
//        RCU_TRACE(const char *name);    /* Name of RCU type. */
759
};
760
 
761
/* Definition for rcupdate control block. */
762
static struct rcu_ctrlblk rcu_sched_ctrlblk = {
763
        .donetail       = &rcu_sched_ctrlblk.rcucblist,
764
        .curtail        = &rcu_sched_ctrlblk.rcucblist,
765
//        RCU_TRACE(.name = "rcu_sched")
766
};
767
 
768
static void __call_rcu(struct rcu_head *head,
769
                       void (*func)(struct rcu_head *rcu),
770
                       struct rcu_ctrlblk *rcp)
771
{
772
        unsigned long flags;
773
 
774
//        debug_rcu_head_queue(head);
775
        head->func = func;
776
        head->next = NULL;
777
 
778
        local_irq_save(flags);
779
        *rcp->curtail = head;
780
        rcp->curtail = &head->next;
781
//        RCU_TRACE(rcp->qlen++);
782
        local_irq_restore(flags);
783
}
784
 
785
/*
786
 * Post an RCU callback to be invoked after the end of an RCU-sched grace
787
 * period.  But since we have but one CPU, that would be after any
788
 * quiescent state.
789
 */
790
void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
791
{
792
        __call_rcu(head, func, &rcu_sched_ctrlblk);
793
}
794
 
6084 serge 795
int seq_puts(struct seq_file *m, const char *s)
796
{
797
    return 0;
798
};
5354 serge 799
 
6084 serge 800
__printf(2, 3) int seq_printf(struct seq_file *m, const char *f, ...)
801
{
802
    return 0;
803
}
5354 serge 804
 
6084 serge 805
 
806
signed long
807
fence_wait_timeout(struct fence *fence, bool intr, signed long timeout)
808
{
809
        signed long ret;
810
 
811
        if (WARN_ON(timeout < 0))
812
                return -EINVAL;
813
 
814
//        trace_fence_wait_start(fence);
815
        ret = fence->ops->wait(fence, intr, timeout);
816
//        trace_fence_wait_end(fence);
817
        return ret;
818
}
819
 
820
void fence_release(struct kref *kref)
821
{
822
        struct fence *fence =
823
                        container_of(kref, struct fence, refcount);
824
 
825
//        trace_fence_destroy(fence);
826
 
827
        BUG_ON(!list_empty(&fence->cb_list));
828
 
829
        if (fence->ops->release)
830
                fence->ops->release(fence);
831
        else
832
                fence_free(fence);
833
}
834
 
835
void fence_free(struct fence *fence)
836
{
837
        kfree_rcu(fence, rcu);
838
}
839
EXPORT_SYMBOL(fence_free);
840
 
841
 
842
ktime_t ktime_get(void)
843
{
844
    ktime_t t;
845
 
846
    t.tv64 = GetClockNs();
847
 
848
    return t;
849
}
850
 
6088 serge 851
char *strdup(const char *str)
852
{
853
    size_t len = strlen(str) + 1;
854
    char *copy = __builtin_malloc(len);
855
    if (copy)
856
    {
857
        memcpy (copy, str, len);
858
    }
859
    return copy;
860
}
861
 
862
int split_cmdline(char *cmdline, char **argv)
863
{
864
    enum quote_state
865
    {
866
        QUOTE_NONE,         /* no " active in current parm       */
867
        QUOTE_DELIMITER,    /* " was first char and must be last */
868
        QUOTE_STARTED       /* " was seen, look for a match      */
869
    };
870
 
871
    enum quote_state state;
872
    unsigned int argc;
873
    char *p = cmdline;
874
    char *new_arg, *start;
875
 
876
    argc = 0;
877
 
878
    for(;;)
879
    {
880
        /* skip over spaces and tabs */
881
        if ( *p )
882
        {
883
            while (*p == ' ' || *p == '\t')
884
                ++p;
885
        }
886
 
887
        if (*p == '\0')
888
            break;
889
 
890
        state = QUOTE_NONE;
891
        if( *p == '\"' )
892
        {
893
            p++;
894
            state = QUOTE_DELIMITER;
895
        }
896
        new_arg = start = p;
897
        for (;;)
898
        {
899
            if( *p == '\"' )
900
            {
901
                p++;
902
                if( state == QUOTE_NONE )
903
                {
904
                    state = QUOTE_STARTED;
905
                }
906
                else
907
                {
908
                    state = QUOTE_NONE;
909
                }
910
                continue;
911
            }
912
 
913
            if( *p == ' ' || *p == '\t' )
914
            {
915
                if( state == QUOTE_NONE )
916
                {
917
                    break;
918
                }
919
            }
920
 
921
            if( *p == '\0' )
922
                break;
923
 
924
            if( *p == '\\' )
925
            {
926
                if( p[1] == '\"' )
927
                {
928
                    ++p;
929
                    if( p[-2] == '\\' )
930
                    {
931
                        continue;
932
                    }
933
                }
934
            }
935
            if( argv )
936
            {
937
                *(new_arg++) = *p;
938
            }
939
            ++p;
940
        };
941
 
942
        if( argv )
943
        {
944
            argv[ argc ] = start;
945
            ++argc;
946
 
947
            /*
948
              The *new = '\0' is req'd in case there was a \" to "
949
              translation. It must be after the *p check against
950
              '\0' because new and p could point to the same char
951
              in which case the scan would be terminated too soon.
952
            */
953
 
954
            if( *p == '\0' )
955
            {
956
                *new_arg = '\0';
957
                break;
958
            }
959
            *new_arg = '\0';
960
            ++p;
961
        }
962
        else
963
        {
964
            ++argc;
965
            if( *p == '\0' )
966
            {
967
                break;
968
            }
969
            ++p;
970
        }
971
    }
972
 
973
    return argc;
974
};
975
 
976
char *strstr(const char *cs, const char *ct)
977
{
978
int d0, d1;
979
register char *__res;
980
__asm__ __volatile__(
981
    "movl %6,%%edi\n\t"
982
    "repne\n\t"
983
    "scasb\n\t"
984
    "notl %%ecx\n\t"
985
    "decl %%ecx\n\t"    /* NOTE! This also sets Z if searchstring='' */
986
    "movl %%ecx,%%edx\n"
987
    "1:\tmovl %6,%%edi\n\t"
988
    "movl %%esi,%%eax\n\t"
989
    "movl %%edx,%%ecx\n\t"
990
    "repe\n\t"
991
    "cmpsb\n\t"
992
    "je 2f\n\t"     /* also works for empty string, see above */
993
    "xchgl %%eax,%%esi\n\t"
994
    "incl %%esi\n\t"
995
    "cmpb $0,-1(%%eax)\n\t"
996
    "jne 1b\n\t"
997
    "xorl %%eax,%%eax\n\t"
998
    "2:"
999
    : "=a" (__res), "=&c" (d0), "=&S" (d1)
1000
    : "0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
1001
    : "dx", "di");
1002
return __res;
1003
}
1004
 
1005
fb_get_options(const char *name, char **option)
1006
{
1007
    char *opt, *options = NULL;
1008
    int retval = 1;
1009
    int name_len;
1010
 
1011
    if(i915.cmdline_mode == NULL)
1012
        return 1;
1013
 
1014
    name_len = __builtin_strlen(name);
1015
 
1016
    if (name_len )
1017
    {
1018
        opt = i915.cmdline_mode;
1019
        if (!__builtin_strncmp(name, opt, name_len) &&
1020
             opt[name_len] == ':')
1021
        {
1022
             options = opt + name_len + 1;
1023
             retval = 0;
1024
        }
1025
    }
1026
 
1027
    if (option)
1028
        *option = options;
1029
 
1030
    return retval;
1031
}