Subversion Repositories Kolibri OS

Rev

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