Rev 6084 | Rev 6103 | 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 | |||
5060 | serge | 4 | #include |
5 | #include "i915_drv.h" |
||
2338 | Serge | 6 | #include "intel_drv.h" |
7 | #include |
||
8 | #include |
||
9 | #include |
||
10 | |||
11 | |||
12 | |||
13 | |||
2340 | Serge | 14 | #include |
5354 | serge | 15 | |
2338 | Serge | 16 | |
17 | |||
5354 | serge | 18 | struct drm_i915_gem_object *main_fb_obj; |
4560 | Serge | 19 | struct drm_framebuffer *main_framebuffer; |
6084 | serge | 20 | |
2338 | Serge | 21 | |
5354 | serge | 22 | u32 cmd_offset; |
23 | |||
2340 | Serge | 24 | |
2351 | Serge | 25 | int sna_init(); |
26 | |||
27 | |||
2338 | Serge | 28 | static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y); |
29 | |||
30 | |||
31 | {}; |
||
32 | |||
33 | |||
34 | {}; |
||
35 | |||
36 | |||
6088 | serge | 37 | |
4560 | Serge | 38 | |
3031 | serge | 39 | { |
40 | static char name[4]; |
||
41 | |||
42 | |||
43 | name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@'; |
||
44 | name[2] = (x[1] & 0x1F) + '@'; |
||
45 | name[3] = 0; |
||
46 | |||
47 | |||
48 | } |
||
49 | |||
50 | |||
6088 | serge | 51 | { |
52 | struct drm_display_mode *mode; |
||
53 | int count = 0; |
||
54 | |||
55 | |||
56 | count++; |
||
57 | |||
58 | |||
59 | }; |
||
60 | |||
61 | |||
5060 | serge | 62 | struct drm_crtc *crtc, videomode_t *reqmode, bool strict) |
63 | { |
||
3031 | serge | 64 | struct drm_i915_private *dev_priv = dev->dev_private; |
5060 | serge | 65 | |
3031 | serge | 66 | |
67 | struct drm_display_mode *mode = NULL, *tmpmode; |
||
68 | struct drm_connector *tmpc; |
||
6088 | serge | 69 | struct drm_framebuffer *fb = NULL; |
3031 | serge | 70 | struct drm_mode_set set; |
71 | const char *con_name; |
||
4371 | Serge | 72 | unsigned hdisplay, vdisplay; |
3031 | serge | 73 | int stride; |
4557 | Serge | 74 | int ret; |
3031 | serge | 75 | |
76 | |||
6084 | serge | 77 | |
78 | |||
5060 | serge | 79 | |
3031 | serge | 80 | |
6088 | serge | 81 | { |
82 | const struct drm_connector_funcs *f = tmpc->funcs; |
||
83 | if(tmpc == connector) |
||
84 | continue; |
||
85 | f->dpms(tmpc, DRM_MODE_DPMS_OFF); |
||
86 | }; |
||
87 | |||
88 | |||
3031 | serge | 89 | { |
90 | if( (tmpmode->hdisplay == reqmode->width) && |
||
5060 | serge | 91 | (tmpmode->vdisplay == reqmode->height) && |
92 | (drm_mode_vrefresh(tmpmode) == reqmode->freq) ) |
||
3031 | serge | 93 | { |
94 | mode = tmpmode; |
||
95 | goto do_set; |
||
96 | } |
||
97 | }; |
||
98 | |||
99 | |||
100 | { |
||
101 | list_for_each_entry(tmpmode, &connector->modes, head) |
||
102 | { |
||
103 | if( (tmpmode->hdisplay == reqmode->width) && |
||
5060 | serge | 104 | (tmpmode->vdisplay == reqmode->height) ) |
105 | { |
||
3031 | serge | 106 | mode = tmpmode; |
107 | goto do_set; |
||
108 | } |
||
109 | }; |
||
110 | }; |
||
111 | |||
112 | |||
3037 | serge | 113 | |
3031 | serge | 114 | |
115 | |||
116 | |||
117 | |||
118 | |||
6088 | serge | 119 | |
5060 | serge | 120 | |
3031 | serge | 121 | |
6088 | serge | 122 | |
123 | |||
124 | DRM_DEBUG_KMS("Manufacturer: %s Model %x Serial Number %u\n", |
||
125 | manufacturer_name(con_edid + 0x08), |
||
126 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
||
127 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
||
128 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
||
129 | |||
130 | |||
5060 | serge | 131 | reqmode->width, reqmode->height, crtc->base.id, |
3031 | serge | 132 | con_name); |
5060 | serge | 133 | |
3031 | serge | 134 | |
135 | |||
136 | |||
137 | vdisplay = mode->vdisplay; |
||
138 | |||
139 | |||
6084 | serge | 140 | // swap(hdisplay, vdisplay); |
141 | |||
3031 | serge | 142 | |
5060 | serge | 143 | if(fb == NULL) |
6084 | serge | 144 | fb = main_framebuffer; |
145 | |||
3031 | serge | 146 | |
147 | fb->height = reqmode->height; |
||
148 | |||
149 | |||
6084 | serge | 150 | |
4280 | Serge | 151 | |
5060 | serge | 152 | { |
153 | if(IS_GEN3(dev)) |
||
4557 | Serge | 154 | for (stride = 512; stride < reqmode->width * 4; stride <<= 1); |
155 | else |
||
156 | stride = ALIGN(reqmode->width * 4, 512); |
||
157 | } |
||
158 | else |
||
159 | { |
||
160 | stride = ALIGN(reqmode->width * 4, 64); |
||
161 | } |
||
162 | |||
4280 | Serge | 163 | |
4557 | Serge | 164 | fb->pitches[1] = |
165 | fb->pitches[2] = |
||
166 | fb->pitches[3] = stride; |
||
167 | |||
168 | |||
4560 | Serge | 169 | |
4557 | Serge | 170 | |
3031 | serge | 171 | fb->depth = 24; |
172 | |||
173 | |||
174 | os_display->crtc = crtc; |
||
175 | |||
176 | |||
4560 | Serge | 177 | |
4280 | Serge | 178 | |
6084 | serge | 179 | fb,fb->width,fb->height,fb->pitches[0],fb->pixel_format); |
180 | |||
181 | |||
3031 | serge | 182 | set.x = 0; |
183 | set.y = 0; |
||
184 | set.mode = mode; |
||
185 | set.connectors = &connector; |
||
186 | set.num_connectors = 1; |
||
187 | set.fb = fb; |
||
188 | |||
189 | |||
5060 | serge | 190 | |
191 | |||
3031 | serge | 192 | { |
193 | os_display->width = fb->width; |
||
194 | os_display->height = fb->height; |
||
195 | os_display->vrefresh = drm_mode_vrefresh(mode); |
||
196 | |||
197 | |||
198 | |||
199 | |||
3037 | serge | 200 | fb->width, fb->height, fb->pitches[0]); |
3031 | serge | 201 | } |
202 | else |
||
203 | DRM_ERROR("failed to set mode %d_%d on crtc %p\n", |
||
204 | fb->width, fb->height, crtc); |
||
205 | |||
206 | |||
6084 | serge | 207 | |
208 | |||
209 | |||
210 | |||
3031 | serge | 211 | } |
212 | |||
213 | |||
6088 | serge | 214 | struct drm_connector *connector, struct drm_display_mode *mode) |
215 | { |
||
2338 | Serge | 216 | struct drm_i915_private *dev_priv = dev->dev_private; |
6088 | serge | 217 | struct drm_connector *tmpc; |
218 | struct drm_mode_config *config = &dev->mode_config; |
||
219 | struct drm_framebuffer *fb = NULL; |
||
220 | struct drm_mode_set set; |
||
221 | char con_edid[128]; |
||
222 | int stride; |
||
223 | int ret; |
||
224 | |||
2338 | Serge | 225 | |
6088 | serge | 226 | |
227 | |||
228 | |||
229 | |||
230 | { |
||
2338 | Serge | 231 | const struct drm_connector_funcs *f = tmpc->funcs; |
6088 | serge | 232 | if(tmpc == connector) |
233 | continue; |
||
234 | f->dpms(tmpc, DRM_MODE_DPMS_OFF); |
||
235 | }; |
||
2338 | Serge | 236 | |
6088 | serge | 237 | |
238 | |||
239 | |||
240 | if(fb == NULL) |
||
241 | fb = main_framebuffer; |
||
242 | |||
243 | |||
244 | fb->height = mode->vdisplay;; |
||
245 | |||
246 | |||
247 | |||
248 | |||
249 | { |
||
250 | if(IS_GEN3(dev)) |
||
251 | for (stride = 512; stride < mode->hdisplay * 4; stride <<= 1); |
||
252 | else |
||
253 | stride = ALIGN(mode->hdisplay * 4, 512); |
||
254 | } |
||
255 | else |
||
256 | { |
||
257 | stride = ALIGN(mode->hdisplay * 4, 64); |
||
258 | } |
||
259 | |||
260 | |||
261 | fb->pitches[1] = |
||
262 | fb->pitches[2] = |
||
263 | fb->pitches[3] = stride; |
||
264 | |||
265 | |||
266 | |||
267 | |||
268 | fb->depth = 24; |
||
269 | |||
270 | |||
271 | |||
272 | |||
273 | |||
274 | |||
275 | DRM_DEBUG_KMS("set mode %dx%d: crtc %d connector %s\n" |
||
276 | "monitor: %s model %x serial number %u\n", |
||
277 | fb->width, fb->height, |
||
278 | connector->encoder->crtc->base.id, connector->name, |
||
279 | manufacturer_name(con_edid + 0x08), |
||
280 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
||
281 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
||
282 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
||
283 | |||
284 | |||
285 | fb,fb->width,fb->height,fb->pitches[0],fb->pixel_format); |
||
286 | |||
287 | |||
288 | set.x = 0; |
||
289 | set.y = 0; |
||
290 | set.mode = mode; |
||
291 | set.connectors = &connector; |
||
292 | set.num_connectors = 1; |
||
293 | set.fb = fb; |
||
294 | |||
295 | |||
296 | if ( !ret ) |
||
297 | { |
||
298 | struct drm_crtc *crtc = os_display->crtc; |
||
299 | |||
300 | |||
301 | os_display->height = fb->height; |
||
302 | os_display->vrefresh = drm_mode_vrefresh(mode); |
||
303 | |||
304 | |||
305 | |||
306 | |||
307 | os_display->crtc = connector->encoder->crtc; |
||
308 | os_display->supported_modes = count_connector_modes(connector); |
||
309 | |||
310 | |||
311 | crtc->cursor_y = os_display->height/2; |
||
312 | |||
313 | |||
314 | |||
315 | |||
316 | fb->width, fb->height, fb->pitches[0]); |
||
317 | } |
||
318 | else |
||
319 | DRM_ERROR(" failed to set mode %d_%d on crtc %p\n", |
||
320 | fb->width, fb->height, connector->encoder->crtc); |
||
321 | |||
322 | |||
323 | |||
324 | |||
325 | |||
326 | |||
327 | } |
||
328 | |||
329 | |||
330 | { |
||
331 | struct drm_display_mode *mode; |
||
332 | int retval; |
||
333 | |||
334 | |||
335 | if(mode == NULL) |
||
336 | return EINVAL; |
||
337 | |||
338 | |||
339 | |||
340 | |||
341 | return retval; |
||
342 | }; |
||
2338 | Serge | 343 | |
344 | |||
5060 | serge | 345 | { |
3031 | serge | 346 | struct drm_crtc *tmp_crtc; |
5060 | serge | 347 | int crtc_mask = 1; |
348 | |||
3031 | serge | 349 | |
5060 | serge | 350 | { |
3031 | serge | 351 | if (encoder->possible_crtcs & crtc_mask) |
5060 | serge | 352 | { |
6084 | serge | 353 | encoder->crtc = tmp_crtc; |
5060 | serge | 354 | DRM_DEBUG_KMS("use CRTC %p ID %d\n", tmp_crtc, tmp_crtc->base.id); |
355 | return tmp_crtc; |
||
356 | }; |
||
357 | crtc_mask <<= 1; |
||
358 | }; |
||
3031 | serge | 359 | return NULL; |
5060 | serge | 360 | }; |
3031 | serge | 361 | |
362 | |||
6088 | serge | 363 | { |
2338 | Serge | 364 | const struct drm_connector_helper_funcs *connector_funcs; |
6088 | serge | 365 | struct drm_encoder *encoder; |
4560 | Serge | 366 | struct drm_crtc *crtc; |
5060 | serge | 367 | |
2338 | Serge | 368 | |
6088 | serge | 369 | return -EINVAL; |
370 | |||
371 | |||
372 | |||
373 | |||
374 | { |
||
375 | connector_funcs = connector->helper_private; |
||
376 | encoder = connector_funcs->best_encoder(connector); |
||
377 | |||
378 | |||
379 | { |
||
380 | DRM_DEBUG_KMS("CONNECTOR %s ID: %d no active encoders\n", |
||
381 | connector->name, connector->base.id); |
||
382 | return -EINVAL; |
||
383 | }; |
||
384 | } |
||
385 | |||
386 | |||
387 | if(crtc == NULL) |
||
388 | crtc = get_possible_crtc(dev, encoder); |
||
389 | |||
390 | |||
391 | { |
||
392 | encoder->crtc = crtc; |
||
393 | return 0; |
||
394 | } |
||
395 | else |
||
396 | DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id); |
||
397 | return -EINVAL; |
||
398 | } |
||
399 | |||
400 | |||
401 | { |
||
402 | struct drm_connector *connector; |
||
403 | |||
404 | |||
5060 | serge | 405 | { |
2338 | Serge | 406 | int name_len = __builtin_strlen(connector->name); |
6088 | serge | 407 | |
408 | |||
409 | continue; |
||
2338 | Serge | 410 | |
411 | |||
6088 | serge | 412 | continue; |
413 | |||
5060 | serge | 414 | |
6088 | serge | 415 | return connector; |
416 | } |
||
417 | return NULL; |
||
418 | } |
||
419 | |||
5060 | serge | 420 | |
2338 | Serge | 421 | |
6088 | serge | 422 | struct drm_crtc **boot_crtc) |
423 | { |
||
424 | const struct drm_connector_helper_funcs *connector_funcs; |
||
425 | struct drm_connector *connector = NULL; |
||
426 | struct drm_encoder *encoder = NULL; |
||
427 | struct drm_crtc *crtc = NULL; |
||
428 | |||
4371 | Serge | 429 | |
6088 | serge | 430 | { |
431 | connector = get_cmdline_connector(dev, i915.cmdline_mode); |
||
432 | if(connector != NULL) |
||
433 | { |
||
5060 | serge | 434 | *boot_connector = connector; |
435 | *boot_crtc = connector->encoder->crtc; |
||
6088 | serge | 436 | return 0; |
5060 | serge | 437 | } |
438 | } |
||
6088 | serge | 439 | |
5060 | serge | 440 | |
6088 | serge | 441 | { |
442 | if(check_connector(dev, connector) == 0) |
||
443 | { |
||
444 | *boot_connector = connector; |
||
445 | *boot_crtc = connector->encoder->crtc; |
||
446 | return 0; |
||
447 | }; |
||
448 | }; |
||
2338 | Serge | 449 | |
450 | |||
5060 | serge | 451 | }; |
4398 | Serge | 452 | |
2338 | Serge | 453 | |
5060 | serge | 454 | { |
4371 | Serge | 455 | struct drm_display_mode *mode; |
456 | |||
457 | |||
458 | { |
||
459 | if( os_display->width == mode->hdisplay && |
||
5060 | serge | 460 | os_display->height == mode->vdisplay && |
461 | drm_mode_vrefresh(mode) == 60) |
||
4371 | Serge | 462 | { |
463 | usermode->width = os_display->width; |
||
464 | usermode->height = os_display->height; |
||
465 | usermode->freq = 60; |
||
466 | return 1; |
||
467 | } |
||
468 | } |
||
469 | return 0; |
||
470 | } |
||
471 | |||
472 | |||
473 | { |
||
474 | struct drm_connector_helper_funcs *connector_funcs; |
||
475 | struct drm_connector *connector = NULL; |
||
5060 | serge | 476 | struct drm_crtc *crtc = NULL; |
477 | struct drm_framebuffer *fb; |
||
4371 | Serge | 478 | |
479 | |||
480 | u32 ifl; |
||
5354 | serge | 481 | int ret; |
6084 | serge | 482 | |
4371 | Serge | 483 | |
6084 | serge | 484 | |
485 | |||
4371 | Serge | 486 | ret = choose_config(dev, &connector, &crtc); |
5060 | serge | 487 | if(ret) |
488 | { |
||
4371 | Serge | 489 | mutex_unlock(&dev->mode_config.mutex); |
6088 | serge | 490 | DRM_DEBUG_KMS("No active connectors!\n"); |
4371 | Serge | 491 | return -1; |
492 | }; |
||
493 | |||
494 | |||
5060 | serge | 495 | idr_preload(GFP_KERNEL); |
496 | |||
4371 | Serge | 497 | |
5060 | serge | 498 | ret = idr_alloc(&dev->object_name_idr, &main_fb_obj->base, 1, 0, GFP_NOWAIT); |
499 | |||
4371 | Serge | 500 | |
5060 | serge | 501 | main_fb_obj->base.handle_count++; |
6084 | serge | 502 | DRM_DEBUG_KMS("%s allocate fb name %d\n", __FUNCTION__, main_fb_obj->base.name ); |
5060 | serge | 503 | } |
504 | |||
505 | |||
506 | mutex_unlock(&dev->object_name_lock); |
||
507 | |||
508 | |||
2338 | Serge | 509 | os_display->ddev = dev; |
510 | os_display->connector = connector; |
||
511 | os_display->crtc = crtc; |
||
512 | os_display->supported_modes = count_connector_modes(connector); |
||
513 | mutex_unlock(&dev->mode_config.mutex); |
||
6088 | serge | 514 | |
2338 | Serge | 515 | |
6088 | serge | 516 | mutex_lock(&dev->struct_mutex); |
517 | |||
518 | |||
2338 | Serge | 519 | { |
520 | list_for_each_entry(cursor, &os_display->cursors, list) |
||
521 | { |
||
522 | init_cursor(cursor); |
||
523 | }; |
||
524 | |||
525 | |||
526 | os_display->init_cursor = init_cursor; |
||
527 | os_display->select_cursor = select_cursor_kms; |
||
528 | os_display->show_cursor = NULL; |
||
529 | os_display->move_cursor = move_cursor_kms; |
||
530 | os_display->restore_cursor = restore_cursor; |
||
531 | os_display->disable_mouse = disable_mouse; |
||
532 | |||
533 | |||
5060 | serge | 534 | crtc->cursor_y = os_display->height/2; |
535 | |||
2338 | Serge | 536 | |
537 | }; |
||
538 | safe_sti(ifl); |
||
539 | |||
540 | |||
6088 | serge | 541 | |
542 | |||
543 | |||
544 | |||
545 | ret = set_cmdline_mode(dev, connector); |
||
546 | |||
547 | |||
548 | { |
||
4280 | Serge | 549 | mutex_lock(&dev->mode_config.mutex); |
6088 | serge | 550 | |
551 | |||
552 | (usermode->height == 0)) |
||
553 | { |
||
4371 | Serge | 554 | if( !get_boot_mode(connector, usermode)) |
6088 | serge | 555 | { |
556 | struct drm_display_mode *mode; |
||
557 | |||
4280 | Serge | 558 | |
6088 | serge | 559 | usermode->width = mode->hdisplay; |
560 | usermode->height = mode->vdisplay; |
||
561 | usermode->freq = drm_mode_vrefresh(mode); |
||
562 | }; |
||
563 | }; |
||
4280 | Serge | 564 | mutex_unlock(&dev->mode_config.mutex); |
6088 | serge | 565 | |
566 | |||
567 | }; |
||
4280 | Serge | 568 | |
569 | |||
3243 | Serge | 570 | err = init_bitmaps(); |
2342 | Serge | 571 | #endif |
3243 | Serge | 572 | |
2340 | Serge | 573 | |
4280 | Serge | 574 | |
575 | |||
6088 | serge | 576 | }; |
2338 | Serge | 577 | |
578 | |||
579 | |||
6088 | serge | 580 | { |
581 | struct drm_connector_helper_funcs *connector_funcs; |
||
582 | struct drm_connector *connector; |
||
583 | struct drm_cmdline_mode cmd_mode; |
||
584 | struct drm_display_mode *mode; |
||
585 | char *mode_option; |
||
586 | int retval = 0; |
||
587 | char con_edid[128]; |
||
588 | |||
589 | |||
590 | if((cmdline == NULL) || (*cmdline == 0)) |
||
591 | return EINVAL; |
||
592 | |||
593 | |||
594 | connector = get_cmdline_connector(dev, cmdline); |
||
595 | mutex_unlock(&dev->mode_config.mutex); |
||
596 | |||
597 | |||
598 | return EINVAL; |
||
599 | |||
600 | |||
601 | if(mode_option == NULL) |
||
602 | return EINVAL; |
||
603 | |||
604 | |||
605 | |||
606 | |||
607 | |||
608 | |||
609 | return EINVAL; |
||
610 | |||
611 | |||
612 | connector->name, |
||
613 | cmd_mode.xres, cmd_mode.yres, |
||
614 | cmd_mode.refresh_specified ? cmd_mode.refresh : 60, |
||
615 | cmd_mode.rb ? " reduced blanking" : "", |
||
616 | cmd_mode.margins ? " with margins" : "", |
||
617 | cmd_mode.interlace ? " interlaced" : ""); |
||
618 | |||
619 | |||
620 | if(mode == NULL) |
||
621 | return EINVAL; |
||
622 | |||
623 | |||
624 | DRM_DEBUG_KMS("connector: %s monitor: %s model %x serial number %u\n", |
||
625 | connector->name, |
||
626 | manufacturer_name(con_edid + 0x08), |
||
627 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
||
628 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
||
629 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
||
630 | |||
631 | |||
632 | |||
633 | |||
634 | |||
635 | |||
636 | return retval; |
||
637 | } |
||
638 | |||
639 | |||
2338 | Serge | 640 | { |
641 | int err = -1; |
||
642 | |||
643 | |||
3031 | serge | 644 | |
2338 | Serge | 645 | |
646 | { |
||
647 | *count = os_display->supported_modes; |
||
648 | err = 0; |
||
649 | } |
||
650 | else if( mode != NULL ) |
||
651 | { |
||
652 | struct drm_display_mode *drmmode; |
||
653 | int i = 0; |
||
654 | |||
655 | |||
656 | *count = os_display->supported_modes; |
||
657 | |||
658 | |||
659 | { |
||
660 | if( i < *count) |
||
661 | { |
||
662 | mode->width = drmmode->hdisplay; |
||
5060 | serge | 663 | mode->height = drmmode->vdisplay; |
664 | mode->bpp = 32; |
||
2338 | Serge | 665 | mode->freq = drm_mode_vrefresh(drmmode); |
666 | i++; |
||
667 | mode++; |
||
668 | } |
||
669 | else break; |
||
670 | }; |
||
671 | *count = i; |
||
672 | err = 0; |
||
673 | }; |
||
674 | return err; |
||
675 | }; |
||
676 | |||
677 | |||
678 | { |
||
679 | |||
680 | |||
3031 | serge | 681 | // mode->width, mode->height, mode->freq); |
682 | |||
2338 | Serge | 683 | |
684 | (mode->height != 0) && |
||
685 | (mode->freq != 0 ) && |
||
686 | ( (mode->width != os_display->width) || |
||
687 | (mode->height != os_display->height) || |
||
688 | (mode->freq != os_display->vrefresh) ) ) |
||
689 | { |
||
690 | return set_mode(os_display->ddev, os_display->connector, os_display->crtc, mode, true); |
||
5060 | serge | 691 | }; |
2338 | Serge | 692 | |
693 | |||
5060 | serge | 694 | }; |
2338 | Serge | 695 | |
696 | |||
4126 | Serge | 697 | { |
698 | const struct drm_connector_funcs *f = os_display->connector->funcs; |
||
4371 | Serge | 699 | |
4126 | Serge | 700 | |
701 | }; |
||
702 | |||
703 | |||
2338 | Serge | 704 | { |
705 | struct drm_i915_gem_object *obj = cursor->cobj; |
||
5354 | serge | 706 | list_del(&cursor->list); |
3037 | serge | 707 | |
2342 | Serge | 708 | |
5060 | serge | 709 | |
3037 | serge | 710 | |
711 | drm_gem_object_unreference(&obj->base); |
||
5354 | serge | 712 | mutex_unlock(&main_device->struct_mutex); |
3037 | serge | 713 | |
714 | |||
2338 | Serge | 715 | }; |
716 | |||
717 | |||
718 | { |
||
719 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
||
720 | struct drm_i915_gem_object *obj; |
||
721 | uint32_t *bits; |
||
722 | uint32_t *src; |
||
723 | void *mapped; |
||
3037 | serge | 724 | |
2338 | Serge | 725 | |
726 | int ret; |
||
727 | |||
728 | |||
5060 | serge | 729 | { |
2338 | Serge | 730 | bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8); |
6084 | serge | 731 | if (unlikely(bits == NULL)) |
2338 | Serge | 732 | return ENOMEM; |
733 | cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits); |
||
734 | } |
||
735 | else |
||
736 | { |
||
737 | obj = i915_gem_alloc_object(os_display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4); |
||
5060 | serge | 738 | if (unlikely(obj == NULL)) |
2338 | Serge | 739 | return -ENOMEM; |
740 | |||
741 | |||
6084 | serge | 742 | if (ret) { |
2338 | Serge | 743 | drm_gem_object_unreference(&obj->base); |
2344 | Serge | 744 | return ret; |
2338 | Serge | 745 | } |
746 | |||
747 | |||
4104 | Serge | 748 | if (ret) |
749 | { |
||
750 | i915_gem_object_ggtt_unpin(obj); |
||
5060 | serge | 751 | drm_gem_object_unreference(&obj->base); |
4104 | Serge | 752 | return ret; |
753 | } |
||
754 | /* You don't need to worry about fragmentation issues. |
||
2338 | Serge | 755 | * GTT space is continuous. I guarantee it. */ |
756 | |||
757 | |||
4104 | Serge | 758 | KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW); |
5060 | serge | 759 | |
2338 | Serge | 760 | |
761 | { |
||
762 | i915_gem_object_ggtt_unpin(obj); |
||
5060 | serge | 763 | drm_gem_object_unreference(&obj->base); |
2344 | Serge | 764 | return -ENOMEM; |
2338 | Serge | 765 | }; |
766 | cursor->cobj = obj; |
||
767 | }; |
||
768 | |||
769 | |||
770 | |||
771 | |||
772 | { |
||
773 | for(j = 0; j < 32; j++) |
||
774 | *bits++ = *src++; |
||
775 | for(j = 32; j < KMS_CURSOR_WIDTH; j++) |
||
5060 | serge | 776 | *bits++ = 0; |
2338 | Serge | 777 | } |
778 | for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++) |
||
5060 | serge | 779 | *bits++ = 0; |
2338 | Serge | 780 | |
781 | |||
3037 | serge | 782 | |
783 | |||
2338 | Serge | 784 | |
785 | |||
2340 | Serge | 786 | |
2338 | Serge | 787 | |
788 | |||
789 | |||
790 | |||
791 | |||
792 | } |
||
793 | |||
794 | |||
795 | |||
796 | { |
||
797 | struct drm_crtc *crtc = os_display->crtc; |
||
4557 | Serge | 798 | struct drm_plane_state *cursor_state = crtc->cursor->state; |
6084 | serge | 799 | |
800 | |||
4557 | Serge | 801 | y-= cursor->hot_y; |
802 | |||
2338 | Serge | 803 | |
5060 | serge | 804 | crtc->cursor_y = y; |
805 | |||
2338 | Serge | 806 | |
6084 | serge | 807 | cursor_state->crtc_y = y; |
808 | |||
809 | |||
5060 | serge | 810 | |
811 | |||
2338 | Serge | 812 | |
813 | |||
814 | { |
||
815 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
||
816 | struct drm_crtc *crtc = os_display->crtc; |
||
5060 | serge | 817 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
818 | |||
819 | |||
2338 | Serge | 820 | |
821 | |||
822 | |||
6088 | serge | 823 | |
824 | |||
825 | |||
2338 | Serge | 826 | |
827 | |||
5060 | serge | 828 | intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj); |
4104 | Serge | 829 | else |
2338 | Serge | 830 | intel_crtc->cursor_addr = (addr_t)cursor->cobj; |
2352 | Serge | 831 | |
2338 | Serge | 832 | |
6084 | serge | 833 | intel_crtc->base.cursor->state->crtc_h = 64; |
834 | intel_crtc->base.cursor->state->rotation = 0; |
||
835 | mutex_unlock(&cursor_lock); |
||
6088 | serge | 836 | |
2338 | Serge | 837 | |
5060 | serge | 838 | return old; |
2338 | Serge | 839 | }; |
840 | |||
841 | |||
4371 | Serge | 842 | { |
3263 | Serge | 843 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
4389 | Serge | 844 | struct intel_crtc *crtc = to_intel_crtc(os_display->crtc); |
845 | struct drm_i915_gem_object *obj = get_fb_obj(); |
||
4371 | Serge | 846 | |
2340 | Serge | 847 | |
4371 | Serge | 848 | fb->width = os_display->width; |
3263 | Serge | 849 | fb->height = os_display->height; |
850 | fb->pitch = obj->stride; |
||
4371 | Serge | 851 | fb->tiling = obj->tiling_mode; |
852 | fb->crtc = crtc->base.base.id; |
||
4389 | Serge | 853 | fb->pipe = crtc->pipe; |
854 | |||
2340 | Serge | 855 | |
3263 | Serge | 856 | } |
4371 | Serge | 857 | |
3263 | Serge | 858 | |
4371 | Serge | 859 | |
3277 | Serge | 860 | { |
861 | int left; |
||
862 | int top; |
||
863 | int right; |
||
864 | int bottom; |
||
865 | }rect_t; |
||
866 | |||
3263 | Serge | 867 | |
3277 | Serge | 868 | |
869 | |||
870 | |||
871 | |||
872 | |||
873 | struct drm_file *file) |
||
874 | { |
||
875 | struct drm_i915_mask *mask = data; |
||
876 | struct drm_gem_object *obj; |
||
877 | static unsigned int mask_seqno[256]; |
||
878 | rect_t winrc; |
||
879 | u32 slot; |
||
880 | int ret=0; |
||
4371 | Serge | 881 | |
3277 | Serge | 882 | |
883 | if (obj == NULL) |
||
884 | return -ENOENT; |
||
885 | |||
886 | |||
887 | drm_gem_object_unreference_unlocked(obj); |
||
888 | return -EINVAL; |
||
889 | } |
||
890 | |||
891 | |||
892 | { |
||
893 | // static warn_count; |
||
3298 | Serge | 894 | |
3277 | Serge | 895 | |
3290 | Serge | 896 | mask->height = winrc.bottom - winrc.top + 1; |
897 | mask->bo_pitch = (mask->width+15) & ~15; |
||
898 | |||
899 | |||
3298 | Serge | 900 | if(warn_count < 1) |
3277 | Serge | 901 | { |
902 | printf("left %d top %d right %d bottom %d\n", |
||
903 | winrc.left, winrc.top, winrc.right, winrc.bottom); |
||
904 | printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_map); |
||
5060 | serge | 905 | warn_count++; |
3277 | Serge | 906 | }; |
907 | #endif |
||
3298 | Serge | 908 | |
909 | |||
4104 | Serge | 910 | |
3277 | Serge | 911 | |
3290 | Serge | 912 | |
3277 | Serge | 913 | |
914 | |||
915 | { |
||
916 | u8* src_offset; |
||
917 | u8* dst_offset; |
||
918 | u32 ifl; |
||
919 | |||
920 | |||
921 | if (ret) |
||
922 | goto err1; |
||
4371 | Serge | 923 | |
3277 | Serge | 924 | |
925 | if(ret != 0 ) |
||
4398 | Serge | 926 | { |
3277 | Serge | 927 | dbgprintf("%s: i915_gem_object_set_to_cpu_domain failed\n", __FUNCTION__); |
4371 | Serge | 928 | goto err2; |
929 | }; |
||
3277 | Serge | 930 | |
931 | |||
932 | |||
933 | |||
934 | |||
935 | |||
5354 | serge | 936 | src_offset+= winrc.top*os_display->width + winrc.left; |
937 | |||
3277 | Serge | 938 | |
939 | |||
940 | |||
5354 | serge | 941 | |
3277 | Serge | 942 | |
943 | { |
||
944 | mask_seqno[slot] = os_display->mask_seqno; |
||
945 | |||
946 | |||
947 | |||
948 | |||
949 | "movd %[slot], %%xmm6 \n" |
||
4560 | Serge | 950 | "punpckldq %%xmm6, %%xmm6 \n" |
3277 | Serge | 951 | "punpcklqdq %%xmm6, %%xmm6 \n" |
952 | :: [slot] "m" (slot) |
||
953 | :"xmm6"); |
||
954 | |||
955 | |||
956 | { |
||
957 | int tmp_w = mask->width; |
||
4398 | Serge | 958 | |
3277 | Serge | 959 | |
960 | u8* tmp_dst = dst_offset; |
||
961 | |||
962 | |||
963 | dst_offset+= mask->bo_pitch; |
||
964 | |||
965 | |||
966 | { |
||
967 | __asm__ __volatile__ ( |
||
968 | "movdqu (%0), %%xmm0 \n" |
||
969 | "movdqu 16(%0), %%xmm1 \n" |
||
970 | "movdqu 32(%0), %%xmm2 \n" |
||
971 | "movdqu 48(%0), %%xmm3 \n" |
||
972 | "pcmpeqb %%xmm6, %%xmm0 \n" |
||
973 | "pcmpeqb %%xmm6, %%xmm1 \n" |
||
974 | "pcmpeqb %%xmm6, %%xmm2 \n" |
||
975 | "pcmpeqb %%xmm6, %%xmm3 \n" |
||
976 | "movdqa %%xmm0, (%%edi) \n" |
||
977 | "movdqa %%xmm1, 16(%%edi) \n" |
||
978 | "movdqa %%xmm2, 32(%%edi) \n" |
||
979 | "movdqa %%xmm3, 48(%%edi) \n" |
||
980 | |||
981 | |||
982 | :"xmm0","xmm1","xmm2","xmm3"); |
||
983 | tmp_w -= 64; |
||
984 | tmp_src += 64; |
||
985 | tmp_dst += 64; |
||
986 | } |
||
987 | |||
988 | |||
989 | { |
||
990 | __asm__ __volatile__ ( |
||
991 | "movdqu (%0), %%xmm0 \n" |
||
992 | "movdqu 16(%0), %%xmm1 \n" |
||
993 | "pcmpeqb %%xmm6, %%xmm0 \n" |
||
994 | "pcmpeqb %%xmm6, %%xmm1 \n" |
||
995 | "movdqa %%xmm0, (%%edi) \n" |
||
996 | "movdqa %%xmm1, 16(%%edi) \n" |
||
997 | |||
998 | |||
999 | :"xmm0","xmm1"); |
||
1000 | tmp_w -= 32; |
||
1001 | tmp_src += 32; |
||
1002 | tmp_dst += 32; |
||
1003 | } |
||
1004 | |||
1005 | |||
4398 | Serge | 1006 | { |
3277 | Serge | 1007 | __asm__ __volatile__ ( |
1008 | "movdqu (%0), %%xmm0 \n" |
||
1009 | "pcmpeqb %%xmm6, %%xmm0 \n" |
||
1010 | "movdqa %%xmm0, (%%edi) \n" |
||
1011 | :: "r" (tmp_src), "D" (tmp_dst) |
||
1012 | :"xmm0"); |
||
1013 | tmp_w -= 16; |
||
1014 | tmp_src += 16; |
||
1015 | tmp_dst += 16; |
||
1016 | } |
||
1017 | |||
4398 | Serge | 1018 | |
1019 | { |
||
1020 | __asm__ __volatile__ ( |
||
1021 | "movq (%0), %%xmm0 \n" |
||
1022 | "pcmpeqb %%xmm6, %%xmm0 \n" |
||
1023 | "movq %%xmm0, (%%edi) \n" |
||
1024 | :: "r" (tmp_src), "D" (tmp_dst) |
||
1025 | :"xmm0"); |
||
1026 | tmp_w -= 8; |
||
1027 | tmp_src += 8; |
||
1028 | tmp_dst += 8; |
||
1029 | } |
||
1030 | if( tmp_w >= 4 ) |
||
1031 | { |
||
1032 | __asm__ __volatile__ ( |
||
1033 | "movd (%0), %%xmm0 \n" |
||
1034 | "pcmpeqb %%xmm6, %%xmm0 \n" |
||
1035 | "movd %%xmm0, (%%edi) \n" |
||
1036 | :: "r" (tmp_src), "D" (tmp_dst) |
||
1037 | :"xmm0"); |
||
1038 | tmp_w -= 4; |
||
1039 | tmp_src += 4; |
||
1040 | tmp_dst += 4; |
||
1041 | } |
||
1042 | while(tmp_w--) |
||
1043 | *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00; |
||
1044 | }; |
||
3277 | Serge | 1045 | }; |
1046 | safe_sti(ifl); |
||
1047 | |||
4371 | Serge | 1048 | |
1049 | } |
||
4539 | Serge | 1050 | |
1051 | |||
1052 | mutex_unlock(&dev->struct_mutex); |
||
1053 | err1: |
||
1054 | drm_gem_object_unreference(obj); |
||
1055 | |||
1056 | |||
1057 | } |
||
1058 | |||
1059 | |||
1060 | struct drm_file *file) |
||
1061 | { |
||
1062 | struct drm_i915_mask_update *mask = data; |
||
1063 | struct drm_gem_object *obj; |
||
1064 | static unsigned int mask_seqno[256]; |
||
1065 | static warn_count; |
||
1066 | |||
1067 | |||
1068 | u32 winw,winh; |
||
1069 | u32 ml,mt,mr,mb; |
||
1070 | u32 slot; |
||
1071 | int ret = 0; |
||
1072 | slot = *((u8*)CURRENT_TASK); |
||
1073 | |||
1074 | |||
6084 | serge | 1075 | return 0; |
4539 | Serge | 1076 | |
1077 | |||
6084 | serge | 1078 | memset((void*)mask->bo_map,0,mask->width * mask->height); |
1079 | |||
5367 | serge | 1080 | |
4539 | Serge | 1081 | win.right+= 1; |
1082 | win.bottom+= 1; |
||
1083 | |||
1084 | |||
1085 | winh = win.bottom - win.top; |
||
1086 | |||
1087 | |||
1088 | mask->dy >= winh) |
||
1089 | return 1; |
||
1090 | |||
1091 | |||
1092 | mt = win.top + mask->dy; |
||
1093 | mr = ml + mask->width; |
||
1094 | mb = mt + mask->height; |
||
1095 | |||
1096 | |||
1097 | mr < win.left || mb < win.top ) |
||
1098 | return 1; |
||
1099 | |||
1100 | |||
1101 | mr = win.right; |
||
1102 | |||
1103 | |||
1104 | mb = win.bottom; |
||
1105 | |||
1106 | |||
1107 | mask->height = mb - mt; |
||
1108 | |||
1109 | |||
1110 | mask->height== 0 ) |
||
1111 | return 1; |
||
1112 | |||
1113 | |||
1114 | if (obj == NULL) |
||
1115 | return -ENOENT; |
||
1116 | |||
1117 | |||
1118 | drm_gem_object_unreference_unlocked(obj); |
||
1119 | return -EINVAL; |
||
1120 | } |
||
1121 | |||
1122 | |||
6084 | serge | 1123 | if(warn_count < 100) |
1124 | { |
||
4539 | Serge | 1125 | printf("left %d top %d right %d bottom %d\n", |
1126 | ml, mt, mr, mb); |
||
1127 | warn_count++; |
||
1128 | }; |
||
1129 | #endif |
||
1130 | |||
1131 | |||
1132 | |||
1133 | |||
1134 | |||
1135 | u8* src_offset; |
||
1136 | u8* dst_offset; |
||
1137 | u32 ifl; |
||
1138 | |||
1139 | |||
1140 | if (ret) |
||
1141 | goto err1; |
||
1142 | |||
1143 | |||
1144 | |||
1145 | |||
5354 | serge | 1146 | src_offset+= mt*os_display->width + ml; |
1147 | dst_offset = (u8*)mask->bo_map; |
||
4539 | Serge | 1148 | |
1149 | |||
5354 | serge | 1150 | |
4539 | Serge | 1151 | |
1152 | { |
||
4371 | Serge | 1153 | mask_seqno[slot] = os_display->mask_seqno; |
4539 | Serge | 1154 | |
1155 | |||
1156 | |||
1157 | |||
1158 | "movd %[slot], %%xmm6 \n" |
||
1159 | "punpckldq %%xmm6, %%xmm6 \n" |
||
1160 | "punpcklqdq %%xmm6, %%xmm6 \n" |
||
1161 | :: [slot] "m" (slot) |
||
1162 | :"xmm6"); |
||
1163 | |||
1164 | |||
1165 | { |
||
1166 | int tmp_w = mask->width; |
||
1167 | |||
1168 | |||
1169 | u8* tmp_dst = dst_offset; |
||
1170 | |||
1171 | |||
1172 | dst_offset+= mask->bo_pitch; |
||
1173 | |||
1174 | |||
1175 | { |
||
1176 | __asm__ __volatile__ ( |
||
1177 | "movdqu (%0), %%xmm0 \n" |
||
1178 | "movdqu 16(%0), %%xmm1 \n" |
||
1179 | "movdqu 32(%0), %%xmm2 \n" |
||
1180 | "movdqu 48(%0), %%xmm3 \n" |
||
1181 | "pcmpeqb %%xmm6, %%xmm0 \n" |
||
1182 | "pcmpeqb %%xmm6, %%xmm1 \n" |
||
1183 | "pcmpeqb %%xmm6, %%xmm2 \n" |
||
1184 | "pcmpeqb %%xmm6, %%xmm3 \n" |
||
1185 | "movdqa %%xmm0, (%%edi) \n" |
||
1186 | "movdqa %%xmm1, 16(%%edi) \n" |
||
1187 | "movdqa %%xmm2, 32(%%edi) \n" |
||
1188 | "movdqa %%xmm3, 48(%%edi) \n" |
||
1189 | |||
1190 | |||
1191 | :"xmm0","xmm1","xmm2","xmm3"); |
||
1192 | tmp_w -= 64; |
||
1193 | tmp_src += 64; |
||
1194 | tmp_dst += 64; |
||
1195 | } |
||
1196 | |||
1197 | |||
1198 | { |
||
1199 | __asm__ __volatile__ ( |
||
1200 | "movdqu (%0), %%xmm0 \n" |
||
1201 | "movdqu 16(%0), %%xmm1 \n" |
||
1202 | "pcmpeqb %%xmm6, %%xmm0 \n" |
||
1203 | "pcmpeqb %%xmm6, %%xmm1 \n" |
||
1204 | "movdqa %%xmm0, (%%edi) \n" |
||
1205 | "movdqa %%xmm1, 16(%%edi) \n" |
||
1206 | |||
1207 | |||
1208 | :"xmm0","xmm1"); |
||
1209 | tmp_w -= 32; |
||
1210 | tmp_src += 32; |
||
1211 | tmp_dst += 32; |
||
1212 | } |
||
1213 | |||
1214 | |||
1215 | { |
||
1216 | __asm__ __volatile__ ( |
||
1217 | "movdqu (%0), %%xmm0 \n" |
||
1218 | "pcmpeqb %%xmm6, %%xmm0 \n" |
||
1219 | "movdqa %%xmm0, (%%edi) \n" |
||
1220 | :: "r" (tmp_src), "D" (tmp_dst) |
||
1221 | :"xmm0"); |
||
1222 | tmp_w -= 16; |
||
1223 | tmp_src += 16; |
||
1224 | tmp_dst += 16; |
||
1225 | } |
||
1226 | |||
1227 | |||
1228 | { |
||
1229 | __asm__ __volatile__ ( |
||
1230 | "movq (%0), %%xmm0 \n" |
||
1231 | "pcmpeqb %%xmm6, %%xmm0 \n" |
||
1232 | "movq %%xmm0, (%%edi) \n" |
||
1233 | :: "r" (tmp_src), "D" (tmp_dst) |
||
1234 | :"xmm0"); |
||
1235 | tmp_w -= 8; |
||
1236 | tmp_src += 8; |
||
1237 | tmp_dst += 8; |
||
1238 | } |
||
1239 | if( tmp_w >= 4 ) |
||
1240 | { |
||
4560 | Serge | 1241 | __asm__ __volatile__ ( |
4539 | Serge | 1242 | "movd (%0), %%xmm0 \n" |
1243 | "pcmpeqb %%xmm6, %%xmm0 \n" |
||
1244 | "movd %%xmm0, (%%edi) \n" |
||
1245 | :: "r" (tmp_src), "D" (tmp_dst) |
||
1246 | :"xmm0"); |
||
1247 | tmp_w -= 4; |
||
1248 | tmp_src += 4; |
||
1249 | tmp_dst += 4; |
||
1250 | } |
||
1251 | while(tmp_w--) |
||
1252 | *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00; |
||
1253 | }; |
||
1254 | }; |
||
4371 | Serge | 1255 | safe_sti(ifl); |
4539 | Serge | 1256 | |
1257 | |||
1258 | } |
||
3277 | Serge | 1259 | #endif |
4539 | Serge | 1260 | |
3277 | Serge | 1261 | |
4371 | Serge | 1262 | mutex_unlock(&dev->struct_mutex); |
1263 | err1: |
||
1264 | drm_gem_object_unreference(obj); |
||
3277 | Serge | 1265 | |
1266 | |||
4371 | Serge | 1267 | } |
3277 | Serge | 1268 | |
1269 | |||
1270 | |||
1271 | |||
2360 | Serge | 1272 | |
3031 | serge | 1273 | |
2360 | Serge | 1274 | |
3031 | serge | 1275 | { |
1276 | u32 tmp = GetTimerTicks(); |
||
1277 | |||
2360 | Serge | 1278 | |
3031 | serge | 1279 | ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000; |
1280 | } |
||
1281 | |||
2360 | Serge | 1282 | |
6084 | serge | 1283 | { |
3031 | serge | 1284 | unsigned long flags; |
3480 | Serge | 1285 | |
3031 | serge | 1286 | |
3480 | Serge | 1287 | spin_lock_irqsave(&q->lock, flags); |
1288 | if (list_empty(&wait->task_list)) |
||
1289 | __add_wait_queue(q, wait); |
||
1290 | spin_unlock_irqrestore(&q->lock, flags); |
||
1291 | } |
||
1292 | |||
1293 | |||
1294 | * finish_wait - clean up after waiting in a queue |
||
1295 | * @q: waitqueue waited on |
||
1296 | * @wait: wait descriptor |
||
1297 | * |
||
1298 | * Sets current thread back to running state and removes |
||
1299 | * the wait descriptor from the given waitqueue if still |
||
1300 | * queued. |
||
1301 | */ |
||
1302 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) |
||
1303 | { |
||
1304 | unsigned long flags; |
||
1305 | |||
1306 | |||
1307 | /* |
||
1308 | * We can check for list emptiness outside the lock |
||
1309 | * IFF: |
||
1310 | * - we use the "careful" check that verifies both |
||
1311 | * the next and prev pointers, so that there cannot |
||
1312 | * be any half-pending updates in progress on other |
||
1313 | * CPU's that we haven't seen yet (and that might |
||
1314 | * still change the stack area. |
||
1315 | * and |
||
1316 | * - all other users take the lock (ie we can only |
||
1317 | * have _one_ other CPU that looks at or modifies |
||
1318 | * the list). |
||
1319 | */ |
||
1320 | if (!list_empty_careful(&wait->task_list)) { |
||
1321 | spin_lock_irqsave(&q->lock, flags); |
||
1322 | list_del_init(&wait->task_list); |
||
1323 | spin_unlock_irqrestore(&q->lock, flags); |
||
1324 | } |
||
1325 | |||
1326 | |||
1327 | } |
||
1328 | |||
1329 | |||
1330 | { |
||
1331 | list_del_init(&wait->task_list); |
||
1332 | return 1; |
||
1333 | }24); |
||
1334 | |||
1335 | |||
1336 | |||
1337 |