Subversion Repositories Kolibri OS

Rev

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