Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2340 Serge 1
 
2
3
 
2338 Serge 4
#include "drm.h"
5
#include "i915_drm.h"
6
#include "i915_drv.h"
7
#include "intel_drv.h"
8
9
 
10
#include 
11
#include 
12
#include 
13
#include 
14
15
 
16
17
 
2340 Serge 18
2338 Serge 19
 
20
{
21
    kobj_t     header;
22
23
 
24
    uint32_t   hot_x;
25
    uint32_t   hot_y;
26
27
 
28
    struct drm_i915_gem_object  *cobj;
29
}cursor_t;
30
31
 
32
#define CURSOR_HEIGHT 64
33
34
 
35
 
36
{
37
    int  x;
38
    int  y;
39
    int  width;
40
    int  height;
41
    int  bpp;
42
    int  vrefresh;
43
    int  pitch;
44
    int  lfb;
45
46
 
47
    struct drm_device    *ddev;
48
    struct drm_connector *connector;
49
    struct drm_crtc      *crtc;
50
51
 
52
53
 
54
    int       (*init_cursor)(cursor_t*);
55
    cursor_t* (__stdcall *select_cursor)(cursor_t*);
56
    void      (*show_cursor)(int show);
57
    void      (__stdcall *move_cursor)(cursor_t *cursor, int x, int y);
58
    void      (__stdcall *restore_cursor)(int x, int y);
59
    void      (*disable_mouse)(void);
60
    u32  mask_seqno;
2361 Serge 61
    u32  check_mouse;
3031 serge 62
    u32  check_m_pixel;
63
64
 
2338 Serge 65
66
 
67
 
68
69
 
2340 Serge 70
u32_t cmd_offset;
71
72
 
2351 Serge 73
int  sna_init();
74
75
 
2338 Serge 76
static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
77
static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
78
79
 
80
{};
81
82
 
83
{};
84
85
 
3031 serge 86
{
87
    static char name[4];
88
89
 
90
    name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
91
    name[2] = (x[1] & 0x1F) + '@';
92
    name[3] = 0;
93
94
 
95
}
96
97
 
98
              videomode_t *reqmode, bool strict)
99
{
100
    drm_i915_private_t      *dev_priv   = dev->dev_private;
101
    struct drm_fb_helper    *fb_helper  = &dev_priv->fbdev->helper;
102
103
 
104
    struct drm_display_mode *mode       = NULL, *tmpmode;
105
    struct drm_framebuffer  *fb         = NULL;
106
    struct drm_crtc         *crtc;
107
    struct drm_encoder      *encoder;
108
    struct drm_i915_gem_object *fb_obj;
4280 Serge 109
    struct drm_mode_set     set;
3031 serge 110
    char *con_name;
111
    char *enc_name;
112
    unsigned hdisplay, vdisplay;
113
    int ret;
114
115
 
116
117
 
118
    {
119
        if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
120
            (drm_mode_height(tmpmode)   == reqmode->height) &&
121
            (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
122
        {
123
            mode = tmpmode;
124
            goto do_set;
125
        }
126
    };
127
128
 
129
    {
130
        list_for_each_entry(tmpmode, &connector->modes, head)
131
        {
132
            if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
133
                (drm_mode_height(tmpmode) == reqmode->height) )
134
            {
135
                mode = tmpmode;
136
                goto do_set;
137
            }
138
        };
139
    };
140
141
 
3037 serge 142
3031 serge 143
 
144
145
 
146
147
 
148
    crtc = encoder->crtc;
149
150
 
151
    enc_name = drm_get_encoder_name(encoder);
152
153
 
154
              reqmode->width, reqmode->height, crtc->base.id,
155
              con_name, enc_name);
156
157
 
158
159
 
160
    vdisplay = mode->vdisplay;
161
162
 
163
        swap(hdisplay, vdisplay);
164
165
 
4280 Serge 166
    fb = fb_helper->fb;
3031 serge 167
168
 
169
    fb->height = reqmode->height;
170
171
 
4280 Serge 172
                      fb->pitches[3]  = ALIGN(reqmode->width * 4, 512);
173
174
 
175
176
 
3031 serge 177
    fb->depth = 24;
178
179
 
180
    crtc->enabled = true;
181
    os_display->crtc = crtc;
182
183
 
4280 Serge 184
185
 
3031 serge 186
    set.x = 0;
187
    set.y = 0;
188
    set.mode = mode;
189
    set.connectors = &connector;
190
    set.num_connectors = 1;
191
    set.fb = fb;
192
    ret = crtc->funcs->set_config(&set);
193
    mutex_unlock(&dev->mode_config.mutex);
194
195
 
196
    {
197
        os_display->width    = fb->width;
198
        os_display->height   = fb->height;
199
        os_display->vrefresh = drm_mode_vrefresh(mode);
200
201
 
202
203
 
3037 serge 204
                       fb->width, fb->height, fb->pitches[0]);
3031 serge 205
    }
206
    else
207
        DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
208
                   fb->width, fb->height, crtc);
209
210
 
211
}
212
213
 
2338 Serge 214
{
215
    struct drm_display_mode  *mode;
216
    int count = 0;
217
218
 
219
    {
220
        count++;
221
    };
222
    return count;
223
};
224
225
 
3031 serge 226
{
227
    struct drm_connector  *connector;
228
    struct drm_connector_helper_funcs *connector_funcs;
229
230
 
231
232
 
233
    {
234
        struct drm_encoder  *encoder;
235
        struct drm_crtc     *crtc;
236
237
 
238
            continue;
239
240
 
241
        encoder = connector_funcs->best_encoder(connector);
242
        if( encoder == NULL)
243
            continue;
244
245
 
246
247
 
248
249
 
3037 serge 250
                   connector, connector->base.id,
3031 serge 251
                   connector->status, connector->encoder,
252
                   crtc);
253
254
 
255
//            continue;
256
257
 
258
259
 
260
    };
261
262
 
263
};
264
265
 
266
 
4280 Serge 267
{
2338 Serge 268
    struct drm_connector    *connector;
269
    struct drm_connector_helper_funcs *connector_funcs;
270
    struct drm_encoder      *encoder;
271
    struct drm_crtc         *crtc = NULL;
272
    struct drm_framebuffer  *fb;
273
274
 
275
    u32_t      ifl;
276
    int        err;
3033 serge 277
2338 Serge 278
 
4280 Serge 279
280
 
281
282
 
2338 Serge 283
    {
284
        if( connector->status != connector_status_connected)
285
            continue;
286
287
 
288
        encoder = connector_funcs->best_encoder(connector);
289
        if( encoder == NULL)
290
        {
291
            DRM_DEBUG_KMS("CONNECTOR %x ID: %d no active encoders\n",
3037 serge 292
                      connector, connector->base.id);
2338 Serge 293
            continue;
294
        }
295
        connector->encoder = encoder;
296
        crtc = encoder->crtc;
3031 serge 297
2338 Serge 298
 
4280 Serge 299
               connector, connector->base.id,
2338 Serge 300
               connector->status, connector->encoder,
301
               crtc, crtc->base.id );
3031 serge 302
        break;
2338 Serge 303
    };
304
305
 
306
    {
307
        DRM_DEBUG_KMS("No active connectors!\n");
4280 Serge 308
        mutex_unlock(&dev->mode_config.mutex);
309
        return -1;
2338 Serge 310
    };
311
312
 
4280 Serge 313
314
 
2338 Serge 315
    {
316
        struct drm_crtc *tmp_crtc;
317
        int crtc_mask = 1;
318
319
 
320
        {
321
            dbgprintf("tmp_crtc %p\n", tmp_crtc);
4280 Serge 322
            if (encoder->possible_crtcs & crtc_mask)
2338 Serge 323
            {
324
                crtc = tmp_crtc;
325
                encoder->crtc = crtc;
326
                dbgprintf("CRTC %p\n", crtc);
4280 Serge 327
                break;
2338 Serge 328
            };
329
            crtc_mask <<= 1;
330
        };
331
    };
332
333
 
4280 Serge 334
335
 
2338 Serge 336
    {
337
        DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id);
4280 Serge 338
        mutex_unlock(&dev->mode_config.mutex);
339
        return -1;
2338 Serge 340
    };
341
342
 
4280 Serge 343
2338 Serge 344
 
345
    os_display->ddev = dev;
346
    os_display->connector = connector;
347
    os_display->crtc = crtc;
348
349
 
350
351
 
352
 
353
    {
354
        struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
355
356
 
357
        {
358
            init_cursor(cursor);
359
        };
360
361
 
362
        os_display->init_cursor    = init_cursor;
363
        os_display->select_cursor  = select_cursor_kms;
364
        os_display->show_cursor    = NULL;
365
        os_display->move_cursor    = move_cursor_kms;
366
        os_display->restore_cursor = restore_cursor;
367
        os_display->disable_mouse  = disable_mouse;
368
369
 
370
        intel_crtc->cursor_y = os_display->height/2;
371
372
 
373
    };
374
    safe_sti(ifl);
375
376
 
4280 Serge 377
        (usermode->height == 0))
378
    {
379
        struct drm_display_mode *mode;
380
381
 
382
        {
383
            dbgprintf("check mode w:%d h:%d %dHz\n",
4293 Serge 384
                    drm_mode_width(mode), drm_mode_height(mode),
4280 Serge 385
                    drm_mode_vrefresh(mode));
386
387
 
388
                os_display->height == drm_mode_height(mode) &&
389
                drm_mode_vrefresh(mode) == 60)
390
            {
391
                usermode->width  = os_display->width;
392
                usermode->height = os_display->height;
393
                usermode->freq   = 60;
394
                break;
395
396
 
397
        }
398
399
 
400
            usermode->height == 0)
401
        {
402
            mode = list_entry(connector->modes.next, typeof(*mode), head);
403
404
 
405
            usermode->height = drm_mode_height(mode);
406
            usermode->freq   = drm_mode_vrefresh(mode);
407
        };
408
    };
409
410
 
411
412
 
413
414
 
3243 Serge 415
    err = init_bitmaps();
2342 Serge 416
#endif
3243 Serge 417
2340 Serge 418
 
4280 Serge 419
420
 
2338 Serge 421
};
422
423
 
424
 
425
{
426
    int err = -1;
427
428
 
3031 serge 429
2338 Serge 430
 
431
    {
432
        *count = os_display->supported_modes;
433
        err = 0;
434
    }
435
    else if( mode != NULL )
436
    {
437
        struct drm_display_mode  *drmmode;
438
        int i = 0;
439
440
 
441
            *count = os_display->supported_modes;
442
443
 
444
        {
445
            if( i < *count)
446
            {
447
                mode->width  = drm_mode_width(drmmode);
448
                mode->height = drm_mode_height(drmmode);
449
                mode->bpp    = 32;
450
                mode->freq   = drm_mode_vrefresh(drmmode);
451
                i++;
452
                mode++;
453
            }
454
            else break;
455
        };
456
        *count = i;
457
        err = 0;
458
    };
459
    return err;
460
};
461
462
 
463
{
464
    int err = -1;
465
466
 
3031 serge 467
//               mode->width, mode->height, mode->freq);
468
2338 Serge 469
 
470
        (mode->height != 0)  &&
471
        (mode->freq   != 0 ) &&
472
        ( (mode->width   != os_display->width)  ||
473
          (mode->height  != os_display->height) ||
474
          (mode->freq    != os_display->vrefresh) ) )
475
    {
476
        if( set_mode(os_display->ddev, os_display->connector, mode, true) )
477
            err = 0;
478
    };
479
480
 
481
};
482
483
 
4126 Serge 484
{
485
    struct drm_connector_funcs *f = os_display->connector->funcs;
486
487
 
488
};
489
490
 
2338 Serge 491
{
492
    list_del(&cursor->list);
3037 serge 493
2342 Serge 494
 
3037 serge 495
496
 
497
    drm_gem_object_unreference(&cursor->cobj->base);
498
    mutex_unlock(&main_device->struct_mutex);
499
500
 
2338 Serge 501
};
502
503
 
504
{
505
    struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
506
    struct drm_i915_gem_object *obj;
507
    uint32_t *bits;
508
    uint32_t *src;
509
    void     *mapped;
3037 serge 510
2338 Serge 511
 
512
    int       ret;
513
514
 
515
    {
516
        bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4);
517
        if (unlikely(bits == NULL))
518
            return ENOMEM;
519
        cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
520
    }
521
    else
522
    {
523
        obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4);
524
        if (unlikely(obj == NULL))
525
            return -ENOMEM;
526
527
 
4104 Serge 528
        if (ret) {
2338 Serge 529
            drm_gem_object_unreference(&obj->base);
2344 Serge 530
            return ret;
2338 Serge 531
        }
532
533
 
4104 Serge 534
        if (ret)
535
        {
536
            i915_gem_object_unpin(obj);
537
            drm_gem_object_unreference(&obj->base);
538
            return ret;
539
        }
540
/* You don't need to worry about fragmentation issues.
2338 Serge 541
 * GTT space is continuous. I guarantee it.                           */
542
543
 
4104 Serge 544
                    CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW);
2338 Serge 545
546
 
547
        {
548
            i915_gem_object_unpin(obj);
2344 Serge 549
            drm_gem_object_unreference(&obj->base);
550
            return -ENOMEM;
2338 Serge 551
        };
552
        cursor->cobj = obj;
553
    };
554
555
 
556
557
 
558
    {
559
        for(j = 0; j < 32; j++)
560
            *bits++ = *src++;
561
        for(j = 32; j < CURSOR_WIDTH; j++)
562
            *bits++ = 0;
563
    }
564
    for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
565
        *bits++ = 0;
566
567
 
3037 serge 568
569
 
2338 Serge 570
571
 
2340 Serge 572
2338 Serge 573
 
574
575
 
576
577
 
578
}
579
580
 
581
 
582
{
583
    struct drm_device *dev = crtc->dev;
584
    struct drm_i915_private *dev_priv = dev->dev_private;
585
    struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
586
    int pipe = intel_crtc->pipe;
587
    bool visible = base != 0;
588
589
 
590
        uint32_t cntl = I915_READ(CURCNTR(pipe));
591
        if (base) {
592
            cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
593
            cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
594
            cntl |= pipe << 28; /* Connect to correct pipe */
595
        } else {
596
            cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
597
            cntl |= CURSOR_MODE_DISABLE;
598
        }
599
        I915_WRITE(CURCNTR(pipe), cntl);
600
601
 
602
    }
603
    /* and commit changes on next vblank */
604
    I915_WRITE(CURBASE(pipe), base);
605
}
606
607
 
608
{
609
    struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
610
    struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
611
    u32 base, pos;
612
    bool visible;
613
614
 
615
616
 
617
    intel_crtc->cursor_y = y;
618
619
 
620
    y = y - cursor->hot_y;
621
622
 
623
 
624
625
 
626
    if (x >= os_display->width)
627
        base = 0;
628
629
 
630
        base = 0;
631
632
 
633
    {
634
        if (x + intel_crtc->cursor_width < 0)
635
            base = 0;
636
637
 
638
        x = -x;
639
    }
640
    pos |= x << CURSOR_X_SHIFT;
641
642
 
643
    {
644
        if (y + intel_crtc->cursor_height < 0)
645
            base = 0;
646
647
 
648
        y = -y;
649
    }
650
    pos |= y << CURSOR_Y_SHIFT;
651
652
 
653
    if (!visible && !intel_crtc->cursor_visible)
654
        return;
655
656
 
657
//    if (IS_845G(dev) || IS_I865G(dev))
658
//        i845_update_cursor(crtc, base);
659
//    else
660
        i9xx_update_cursor(os_display->crtc, base);
661
662
 
663
664
 
665
 
666
{
667
    struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
668
    struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
669
    cursor_t *old;
670
671
 
672
    os_display->cursor = cursor;
673
674
 
675
       intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj);
4104 Serge 676
    else
2338 Serge 677
        intel_crtc->cursor_addr = (addr_t)cursor->cobj;
2352 Serge 678
2338 Serge 679
 
680
    intel_crtc->cursor_height = 32;
681
682
 
683
    return old;
684
};
685
686
 
3263 Serge 687
{
688
    uint32_t  width;
689
    uint32_t  height;
690
    uint32_t  pitch;
691
    uint32_t  tiling;
692
};
693
2340 Serge 694
 
3263 Serge 695
{
696
    fb->width  = os_display->width;
697
    fb->height = os_display->height;
698
    fb->pitch  = os_display->pitch;
699
    fb->tiling = 0;
700
2340 Serge 701
 
3263 Serge 702
};
703
704
 
3277 Serge 705
{
706
    int left;
707
    int top;
708
    int right;
709
    int bottom;
710
}rect_t;
711
3263 Serge 712
 
3277 Serge 713
    __u32 handle;
714
    __u32 width;
3290 Serge 715
    __u32 height;
716
    __u32 bo_size;
3277 Serge 717
    __u32 bo_pitch;
718
    __u32 bo_map;
719
};
720
721
 
722
723
 
724
{
725
    u32_t   addr;
726
727
 
728
    addr+= sizeof(display_t);            /*  shoot me  */
729
    return *(u32_t*)addr;
730
}
731
732
 
733
734
 
735
            struct drm_file *file)
736
{
737
    struct drm_i915_mask *mask = data;
738
    struct drm_gem_object *obj;
739
    static unsigned int mask_seqno[256];
740
    rect_t winrc;
741
    u32    slot;
742
    int    ret;
743
744
 
3480 Serge 745
     {
746
        printf("%s handle %d\n", __FUNCTION__, mask->handle);
747
        return 0;
748
     }
749
750
 
3277 Serge 751
    if (obj == NULL)
752
        return -ENOENT;
753
754
 
755
        drm_gem_object_unreference_unlocked(obj);
756
        return -EINVAL;
757
    }
758
759
 
760
    {
761
//        static warn_count;
3298 Serge 762
3277 Serge 763
 
3290 Serge 764
        mask->height   = winrc.bottom - winrc.top + 1;
765
        mask->bo_pitch = (mask->width+15) & ~15;
766
767
 
3298 Serge 768
        if(warn_count < 1)
3277 Serge 769
        {
770
            printf("left %d top %d right %d bottom %d\n",
771
                    winrc.left, winrc.top, winrc.right, winrc.bottom);
772
            printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_size);
773
            warn_count++;
774
        };
775
#endif
3298 Serge 776
777
 
4104 Serge 778
3277 Serge 779
 
3290 Serge 780
 
3277 Serge 781
782
 
783
    {
784
        u8* src_offset;
785
        u8* dst_offset;
786
        u32 ifl;
787
788
 
789
        if (ret)
790
            return ret;
791
792
 
793
        if(ret !=0 )
794
        {
795
            dbgprintf("%s fail\n", __FUNCTION__);
796
            return ret;
797
        };
798
799
 
800
801
 
802
803
 
804
 
805
        src_offset+= get_display_map();
806
        dst_offset = (u8*)mask->bo_map;
807
808
 
3290 Serge 809
3277 Serge 810
 
811
        {
812
            mask_seqno[slot] = os_display->mask_seqno;
813
814
 
815
816
 
817
                "movd       %[slot],   %%xmm6    \n"
818
            "punpckldq  %%xmm6, %%xmm6            \n"
819
            "punpcklqdq %%xmm6, %%xmm6            \n"
820
            :: [slot]  "m" (slot)
821
            :"xmm6");
822
823
 
824
            {
825
                int tmp_w = mask->bo_pitch;
826
827
 
828
                u8* tmp_dst = dst_offset;
829
830
 
831
                dst_offset+= mask->bo_pitch;
832
833
 
834
                {
835
                    __asm__ __volatile__ (
836
                    "movdqu     (%0),   %%xmm0            \n"
837
                    "movdqu   16(%0),   %%xmm1            \n"
838
                    "movdqu   32(%0),   %%xmm2            \n"
839
                    "movdqu   48(%0),   %%xmm3            \n"
840
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
841
                    "pcmpeqb    %%xmm6, %%xmm1            \n"
842
                    "pcmpeqb    %%xmm6, %%xmm2            \n"
843
                    "pcmpeqb    %%xmm6, %%xmm3            \n"
844
                    "movdqa     %%xmm0,   (%%edi)         \n"
845
                    "movdqa     %%xmm1, 16(%%edi)         \n"
846
                    "movdqa     %%xmm2, 32(%%edi)         \n"
847
                    "movdqa     %%xmm3, 48(%%edi)         \n"
848
849
 
850
                    :"xmm0","xmm1","xmm2","xmm3");
851
                    tmp_w -= 64;
852
                    tmp_src += 64;
853
                    tmp_dst += 64;
854
                }
855
856
 
857
                {
858
                    __asm__ __volatile__ (
859
                    "movdqu     (%0),   %%xmm0            \n"
860
                    "movdqu   16(%0),   %%xmm1            \n"
861
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
862
                    "pcmpeqb    %%xmm6, %%xmm1            \n"
863
                    "movdqa     %%xmm0,   (%%edi)         \n"
864
                    "movdqa     %%xmm1, 16(%%edi)         \n"
865
866
 
867
                    :"xmm0","xmm1");
868
                    tmp_w -= 32;
869
                    tmp_src += 32;
870
                    tmp_dst += 32;
871
                }
872
873
 
874
                {
875
                    __asm__ __volatile__ (
876
                    "movdqu     (%0),   %%xmm0            \n"
877
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
878
                    "movdqa     %%xmm0,   (%%edi)         \n"
879
                    :: "r" (tmp_src), "D" (tmp_dst)
880
                    :"xmm0");
881
                    tmp_w -= 16;
882
                    tmp_src += 16;
883
                    tmp_dst += 16;
884
                }
885
            };
886
        };
887
        safe_sti(ifl);
888
    }
889
890
 
891
892
 
893
894
 
895
}
896
897
 
898
 
899
 
2360 Serge 900
 
901
 
902
 
903
 
904
 
905
 
906
 
907
 
908
 
3031 serge 909
2360 Serge 910
 
3031 serge 911
{
912
    u32 tmp = GetTimerTicks();
913
2360 Serge 914
 
3031 serge 915
    ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000;
916
}
917
2360 Serge 918
 
4104 Serge 919
{
3031 serge 920
    while (nsec >= NSEC_PER_SEC) {
4104 Serge 921
        /*
922
         * The following asm() prevents the compiler from
923
         * optimising this loop into a modulo operation. See
924
         * also __iter_div_u64_rem() in include/linux/time.h
925
         */
926
        asm("" : "+rm"(nsec));
927
        nsec -= NSEC_PER_SEC;
928
        ++sec;
929
    }
930
    while (nsec < 0) {
931
        asm("" : "+rm"(nsec));
932
        nsec += NSEC_PER_SEC;
933
        --sec;
934
    }
935
    ts->tv_sec = sec;
936
    ts->tv_nsec = nsec;
937
}
3031 serge 938
2360 Serge 939
 
3480 Serge 940
prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
941
{
942
    unsigned long flags;
943
3031 serge 944
 
3480 Serge 945
    spin_lock_irqsave(&q->lock, flags);
946
    if (list_empty(&wait->task_list))
947
            __add_wait_queue(q, wait);
948
    spin_unlock_irqrestore(&q->lock, flags);
949
}
950
951
 
952
 * finish_wait - clean up after waiting in a queue
953
 * @q: waitqueue waited on
954
 * @wait: wait descriptor
955
 *
956
 * Sets current thread back to running state and removes
957
 * the wait descriptor from the given waitqueue if still
958
 * queued.
959
 */
960
void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
961
{
962
    unsigned long flags;
963
964
 
965
    /*
966
     * We can check for list emptiness outside the lock
967
     * IFF:
968
     *  - we use the "careful" check that verifies both
969
     *    the next and prev pointers, so that there cannot
970
     *    be any half-pending updates in progress on other
971
     *    CPU's that we haven't seen yet (and that might
972
     *    still change the stack area.
973
     * and
974
     *  - all other users take the lock (ie we can only
975
     *    have _one_ other CPU that looks at or modifies
976
     *    the list).
977
     */
978
    if (!list_empty_careful(&wait->task_list)) {
979
            spin_lock_irqsave(&q->lock, flags);
980
            list_del_init(&wait->task_list);
981
            spin_unlock_irqrestore(&q->lock, flags);
982
    }
983
984
 
985
}
986
987
 
988
{
989
    list_del_init(&wait->task_list);
990
    return 1;
991
}
992
993
 
3482 Serge 994
{
995
    unsigned int res = w - ((w >> 1) & 0x5555);
996
    res = (res & 0x3333) + ((res >> 2) & 0x3333);
997
    res = (res + (res >> 4)) & 0x0F0F;
998
    return (res + (res >> 8)) & 0x00FF;
999
}
1000
3480 Serge 1001
 
1002
 
3482 Serge 1003
{
1004
    unsigned long j0 = GetTimerTicks();
1005
3480 Serge 1006
 
3482 Serge 1007
    return round_jiffies_common(j + j0, true) - j0;
1008
}
1009
3480 Serge 1010
 
3482 Serge 1011