Print this page
7217 Buffer overflow in i915 driver
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Toomas Soome <tsoome@me.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/drm/i915_drv.c
+++ new/usr/src/uts/intel/io/drm/i915_drv.c
1 1 /* BEGIN CSTYLED */
2 2
3 3 /*
4 4 * i915_drv.c -- Intel i915 driver -*- linux-c -*-
5 5 * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com
6 6 */
7 7
8 8 /*
9 9 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
10 10 * Copyright (c) 2009, Intel Corporation.
11 11 * All Rights Reserved.
12 12 *
13 13 * Permission is hereby granted, free of charge, to any person obtaining a
14 14 * copy of this software and associated documentation files (the "Software"),
15 15 * to deal in the Software without restriction, including without limitation
16 16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 17 * and/or sell copies of the Software, and to permit persons to whom the
18 18 * Software is furnished to do so, subject to the following conditions:
19 19 *
20 20 * The above copyright notice and this permission notice (including the next
21 21 * paragraph) shall be included in all copies or substantial portions of the
22 22 * Software.
23 23 *
24 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 27 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
28 28 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
29 29 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30 30 * OTHER DEALINGS IN THE SOFTWARE.
31 31 *
32 32 * Authors:
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
33 33 * Gareth Hughes <gareth@valinux.com>
34 34 *
35 35 */
36 36
37 37 /*
38 38 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
39 39 * Use is subject to license terms.
40 40 */
41 41
42 42 /*
43 + * Copyright 2014 RackTop Systems.
44 + */
45 +
46 +/*
43 47 * I915 DRM Driver for Solaris
44 48 *
45 49 * This driver provides the hardware 3D acceleration support for Intel
46 50 * integrated video devices (e.g. i8xx/i915/i945 series chipsets), under the
47 51 * DRI (Direct Rendering Infrastructure). DRM (Direct Rendering Manager) here
48 52 * means the kernel device driver in DRI.
49 53 *
50 54 * I915 driver is a device dependent driver only, it depends on a misc module
51 55 * named drm for generic DRM operations.
52 56 */
53 57
54 58 #include "drmP.h"
55 59 #include "i915_drm.h"
56 60 #include "i915_drv.h"
57 61 #include "drm_pciids.h"
58 62
59 63 /*
60 64 * copied from vgasubr.h
61 65 */
62 66
63 67 struct vgaregmap {
64 68 uint8_t *addr;
65 69 ddi_acc_handle_t handle;
66 70 boolean_t mapped;
67 71 };
68 72
69 73 enum pipe {
70 74 PIPE_A = 0,
71 75 PIPE_B,
72 76 };
73 77
74 78
75 79 /*
76 80 * cb_ops entrypoint
77 81 */
78 82 extern struct cb_ops drm_cb_ops;
79 83
80 84 /*
81 85 * module entrypoint
82 86 */
83 87 static int i915_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
84 88 static int i915_attach(dev_info_t *, ddi_attach_cmd_t);
85 89 static int i915_detach(dev_info_t *, ddi_detach_cmd_t);
86 90
87 91
88 92 /* drv_PCI_IDs comes from drm_pciids.h */
89 93 static drm_pci_id_list_t i915_pciidlist[] = {
90 94 i915_PCI_IDS
91 95 };
92 96
93 97 /*
94 98 * Local routines
95 99 */
96 100 static void i915_configure(drm_driver_t *);
97 101 static int i915_quiesce(dev_info_t *dip);
98 102
99 103 /*
100 104 * DRM driver
101 105 */
102 106 static drm_driver_t i915_driver = {0};
103 107
104 108
105 109 static struct dev_ops i915_dev_ops = {
106 110 DEVO_REV, /* devo_rev */
107 111 0, /* devo_refcnt */
108 112 i915_info, /* devo_getinfo */
109 113 nulldev, /* devo_identify */
110 114 nulldev, /* devo_probe */
111 115 i915_attach, /* devo_attach */
112 116 i915_detach, /* devo_detach */
113 117 nodev, /* devo_reset */
114 118 &drm_cb_ops, /* devo_cb_ops */
115 119 NULL, /* devo_bus_ops */
116 120 NULL, /* power */
117 121 i915_quiesce, /* devo_quiesce */
118 122 };
119 123
120 124 static struct modldrv modldrv = {
121 125 &mod_driverops, /* drv_modops */
122 126 "I915 DRM driver", /* drv_linkinfo */
123 127 &i915_dev_ops, /* drv_dev_ops */
124 128 };
125 129
126 130 static struct modlinkage modlinkage = {
127 131 MODREV_1, (void *) &modldrv, NULL
128 132 };
129 133
130 134 static ddi_device_acc_attr_t s3_attr = {
131 135 DDI_DEVICE_ATTR_V0,
132 136 DDI_NEVERSWAP_ACC,
133 137 DDI_STRICTORDER_ACC /* must be DDI_STRICTORDER_ACC */
134 138 };
135 139
136 140 /*
137 141 * softstate head
138 142 */
139 143 static void *i915_statep;
140 144
141 145 int
142 146 _init(void)
143 147 {
144 148 int error;
145 149
146 150 i915_configure(&i915_driver);
147 151
148 152 if ((error = ddi_soft_state_init(&i915_statep,
149 153 sizeof (drm_device_t), DRM_MAX_INSTANCES)) != 0)
150 154 return (error);
151 155
152 156 if ((error = mod_install(&modlinkage)) != 0) {
153 157 ddi_soft_state_fini(&i915_statep);
154 158 return (error);
155 159 }
156 160
157 161 return (error);
158 162
159 163 } /* _init() */
160 164
161 165 int
162 166 _fini(void)
163 167 {
164 168 int error;
165 169
166 170 if ((error = mod_remove(&modlinkage)) != 0)
167 171 return (error);
168 172
169 173 (void) ddi_soft_state_fini(&i915_statep);
170 174
171 175 return (0);
172 176
173 177 } /* _fini() */
174 178
175 179 int
176 180 _info(struct modinfo *modinfop)
177 181 {
178 182 return (mod_info(&modlinkage, modinfop));
179 183
180 184 } /* _info() */
181 185
182 186 /*
183 187 * off range: 0x3b0 ~ 0x3ff
184 188 */
185 189
186 190 static void
187 191 vga_reg_put8(struct vgaregmap *regmap, uint16_t off, uint8_t val)
188 192 {
189 193 ASSERT((off >= 0x3b0) && (off <= 0x3ff));
190 194
191 195 ddi_put8(regmap->handle, regmap->addr + off, val);
192 196 }
193 197
194 198 /*
195 199 * off range: 0x3b0 ~ 0x3ff
196 200 */
197 201 static uint8_t
198 202 vga_reg_get8(struct vgaregmap *regmap, uint16_t off)
199 203 {
200 204
201 205 ASSERT((off >= 0x3b0) && (off <= 0x3ff));
202 206
203 207 return (ddi_get8(regmap->handle, regmap->addr + off));
204 208 }
205 209
206 210 static void
207 211 i915_write_indexed(struct vgaregmap *regmap,
208 212 uint16_t index_port, uint16_t data_port, uint8_t index, uint8_t val)
209 213 {
210 214 vga_reg_put8(regmap, index_port, index);
211 215 vga_reg_put8(regmap, data_port, val);
212 216 }
213 217
214 218 static uint8_t
215 219 i915_read_indexed(struct vgaregmap *regmap,
216 220 uint16_t index_port, uint16_t data_port, uint8_t index)
217 221 {
218 222 vga_reg_put8(regmap, index_port, index);
219 223 return (vga_reg_get8(regmap, data_port));
220 224 }
221 225
222 226 static void
223 227 i915_write_ar(struct vgaregmap *regmap, uint16_t st01,
224 228 uint8_t reg, uint8_t val, uint8_t palette_enable)
225 229 {
226 230 (void) vga_reg_get8(regmap, st01);
227 231 vga_reg_put8(regmap, VGA_AR_INDEX, palette_enable | reg);
228 232 vga_reg_put8(regmap, VGA_AR_DATA_WRITE, val);
229 233 }
230 234
231 235 static uint8_t
232 236 i915_read_ar(struct vgaregmap *regmap, uint16_t st01,
233 237 uint8_t index, uint8_t palette_enable)
234 238 {
235 239 (void) vga_reg_get8(regmap, st01);
236 240 vga_reg_put8(regmap, VGA_AR_INDEX, index | palette_enable);
237 241 return (vga_reg_get8(regmap, VGA_AR_DATA_READ));
238 242 }
239 243
240 244 static int
241 245 i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
242 246 {
243 247 struct s3_i915_private *s3_priv = dev->s3_private;
244 248
245 249 if (pipe == PIPE_A)
246 250 return (S3_READ(DPLL_A) & DPLL_VCO_ENABLE);
247 251 else
248 252 return (S3_READ(DPLL_B) & DPLL_VCO_ENABLE);
249 253 }
250 254
251 255 static void
252 256 i915_save_palette(struct drm_device *dev, enum pipe pipe)
253 257 {
254 258 struct s3_i915_private *s3_priv = dev->s3_private;
255 259 unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
256 260 uint32_t *array;
257 261 int i;
258 262
259 263 if (!i915_pipe_enabled(dev, pipe))
260 264 return;
261 265
262 266 if (pipe == PIPE_A)
263 267 array = s3_priv->save_palette_a;
264 268 else
265 269 array = s3_priv->save_palette_b;
266 270
267 271 for(i = 0; i < 256; i++)
268 272 array[i] = S3_READ(reg + (i << 2));
269 273
270 274 }
271 275
272 276 static void
273 277 i915_restore_palette(struct drm_device *dev, enum pipe pipe)
274 278 {
275 279 struct s3_i915_private *s3_priv = dev->s3_private;
276 280 unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
277 281 uint32_t *array;
278 282 int i;
279 283
280 284 if (!i915_pipe_enabled(dev, pipe))
281 285 return;
282 286
283 287 if (pipe == PIPE_A)
284 288 array = s3_priv->save_palette_a;
285 289 else
286 290 array = s3_priv->save_palette_b;
287 291
288 292 for(i = 0; i < 256; i++)
289 293 S3_WRITE(reg + (i << 2), array[i]);
290 294 }
291 295
292 296 static void
293 297 i915_save_vga(struct drm_device *dev)
294 298 {
295 299 struct s3_i915_private *s3_priv = dev->s3_private;
296 300 int i;
297 301 uint16_t cr_index, cr_data, st01;
298 302 struct vgaregmap regmap;
299 303
300 304 regmap.addr = (uint8_t *)s3_priv->saveAddr;
301 305 regmap.handle = s3_priv->saveHandle;
302 306
303 307 /* VGA color palette registers */
304 308 s3_priv->saveDACMASK = vga_reg_get8(®map, VGA_DACMASK);
305 309 /* DACCRX automatically increments during read */
306 310 vga_reg_put8(®map, VGA_DACRX, 0);
307 311 /* Read 3 bytes of color data from each index */
308 312 for (i = 0; i < 256 * 3; i++)
309 313 s3_priv->saveDACDATA[i] = vga_reg_get8(®map, VGA_DACDATA);
310 314
311 315 /* MSR bits */
312 316 s3_priv->saveMSR = vga_reg_get8(®map, VGA_MSR_READ);
313 317 if (s3_priv->saveMSR & VGA_MSR_CGA_MODE) {
314 318 cr_index = VGA_CR_INDEX_CGA;
315 319 cr_data = VGA_CR_DATA_CGA;
316 320 st01 = VGA_ST01_CGA;
317 321 } else {
318 322 cr_index = VGA_CR_INDEX_MDA;
319 323 cr_data = VGA_CR_DATA_MDA;
320 324 st01 = VGA_ST01_MDA;
321 325 }
322 326
323 327 /* CRT controller regs */
324 328 i915_write_indexed(®map, cr_index, cr_data, 0x11,
325 329 i915_read_indexed(®map, cr_index, cr_data, 0x11) & (~0x80));
326 330 for (i = 0; i <= 0x24; i++)
327 331 s3_priv->saveCR[i] =
328 332 i915_read_indexed(®map, cr_index, cr_data, i);
329 333 /* Make sure we don't turn off CR group 0 writes */
330 334 s3_priv->saveCR[0x11] &= ~0x80;
331 335
332 336 /* Attribute controller registers */
333 337 (void) vga_reg_get8(®map, st01);
334 338 s3_priv->saveAR_INDEX = vga_reg_get8(®map, VGA_AR_INDEX);
335 339 for (i = 0; i <= 0x14; i++)
336 340 s3_priv->saveAR[i] = i915_read_ar(®map, st01, i, 0);
337 341 (void) vga_reg_get8(®map, st01);
338 342 vga_reg_put8(®map, VGA_AR_INDEX, s3_priv->saveAR_INDEX);
339 343 (void) vga_reg_get8(®map, st01);
340 344
341 345 /* Graphics controller registers */
342 346 for (i = 0; i < 9; i++)
343 347 s3_priv->saveGR[i] =
344 348 i915_read_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, i);
345 349
346 350 s3_priv->saveGR[0x10] =
347 351 i915_read_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x10);
348 352 s3_priv->saveGR[0x11] =
349 353 i915_read_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x11);
350 354 s3_priv->saveGR[0x18] =
351 355 i915_read_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x18);
352 356
353 357 /* Sequencer registers */
354 358 for (i = 0; i < 8; i++)
355 359 s3_priv->saveSR[i] =
356 360 i915_read_indexed(®map, VGA_SR_INDEX, VGA_SR_DATA, i);
357 361 }
358 362
359 363 static void
360 364 i915_restore_vga(struct drm_device *dev)
361 365 {
362 366 struct s3_i915_private *s3_priv = dev->s3_private;
363 367 int i;
364 368 uint16_t cr_index, cr_data, st01;
365 369 struct vgaregmap regmap;
366 370
367 371 regmap.addr = (uint8_t *)s3_priv->saveAddr;
368 372 regmap.handle = s3_priv->saveHandle;
369 373
370 374 /*
371 375 * I/O Address Select. This bit selects 3Bxh or 3Dxh as the
372 376 * I/O address for the CRT Controller registers,
373 377 * the Feature Control Register (FCR), and Input Status Register
374 378 * 1 (ST01). Presently ignored (whole range is claimed), but
375 379 * will "ignore" 3Bx for color configuration or 3Dx for monochrome.
376 380 * Note that it is typical in AGP chipsets to shadow this bit
377 381 * and properly steer I/O cycles to the proper bus for operation
378 382 * where a MDA exists on another bus such as ISA.
379 383 * 0 = Select 3Bxh I/O address (MDA emulation) (default).
380 384 * 1 = Select 3Dxh I/O address (CGA emulation).
381 385 */
382 386 vga_reg_put8(®map, VGA_MSR_WRITE, s3_priv->saveMSR);
383 387
384 388 if (s3_priv->saveMSR & VGA_MSR_CGA_MODE) {
385 389 cr_index = VGA_CR_INDEX_CGA;
386 390 cr_data = VGA_CR_DATA_CGA;
387 391 st01 = VGA_ST01_CGA;
388 392 } else {
389 393 cr_index = VGA_CR_INDEX_MDA;
390 394 cr_data = VGA_CR_DATA_MDA;
391 395 st01 = VGA_ST01_MDA;
392 396 }
393 397
394 398 /* Sequencer registers, don't write SR07 */
395 399 for (i = 0; i < 7; i++)
396 400 i915_write_indexed(®map, VGA_SR_INDEX, VGA_SR_DATA, i,
397 401 s3_priv->saveSR[i]);
398 402 /* CRT controller regs */
399 403 /* Enable CR group 0 writes */
400 404 i915_write_indexed(®map, cr_index, cr_data,
401 405 0x11, s3_priv->saveCR[0x11]);
402 406 for (i = 0; i <= 0x24; i++)
403 407 i915_write_indexed(®map, cr_index,
404 408 cr_data, i, s3_priv->saveCR[i]);
405 409
406 410 /* Graphics controller regs */
407 411 for (i = 0; i < 9; i++)
408 412 i915_write_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, i,
409 413 s3_priv->saveGR[i]);
410 414
411 415 i915_write_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x10,
412 416 s3_priv->saveGR[0x10]);
413 417 i915_write_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x11,
414 418 s3_priv->saveGR[0x11]);
415 419 i915_write_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x18,
416 420 s3_priv->saveGR[0x18]);
417 421
418 422 /* Attribute controller registers */
419 423 (void) vga_reg_get8(®map, st01); /* switch back to index mode */
420 424 for (i = 0; i <= 0x14; i++)
421 425 i915_write_ar(®map, st01, i, s3_priv->saveAR[i], 0);
422 426 (void) vga_reg_get8(®map, st01); /* switch back to index mode */
423 427 vga_reg_put8(®map, VGA_AR_INDEX, s3_priv->saveAR_INDEX | 0x20);
424 428 (void) vga_reg_get8(®map, st01); /* switch back to index mode */
425 429
426 430 /* VGA color palette registers */
427 431 vga_reg_put8(®map, VGA_DACMASK, s3_priv->saveDACMASK);
428 432 /* DACCRX automatically increments during read */
429 433 vga_reg_put8(®map, VGA_DACWX, 0);
430 434 /* Read 3 bytes of color data from each index */
431 435 for (i = 0; i < 256 * 3; i++)
432 436 vga_reg_put8(®map, VGA_DACDATA, s3_priv->saveDACDATA[i]);
433 437 }
434 438
435 439 /**
436 440 * i915_save_display - save display & mode info
437 441 * @dev: DRM device
438 442 *
439 443 * Save mode timings and display info.
440 444 */
441 445 void i915_save_display(struct drm_device *dev)
442 446 {
443 447 struct s3_i915_private *s3_priv = dev->s3_private;
444 448
445 449 /* Display arbitration control */
446 450 s3_priv->saveDSPARB = S3_READ(DSPARB);
447 451
448 452 /*
449 453 * Pipe & plane A info.
450 454 */
451 455 s3_priv->savePIPEACONF = S3_READ(PIPEACONF);
452 456 s3_priv->savePIPEASRC = S3_READ(PIPEASRC);
453 457 s3_priv->saveFPA0 = S3_READ(FPA0);
454 458 s3_priv->saveFPA1 = S3_READ(FPA1);
455 459 s3_priv->saveDPLL_A = S3_READ(DPLL_A);
456 460 if (IS_I965G(dev))
457 461 s3_priv->saveDPLL_A_MD = S3_READ(DPLL_A_MD);
458 462 s3_priv->saveHTOTAL_A = S3_READ(HTOTAL_A);
459 463 s3_priv->saveHBLANK_A = S3_READ(HBLANK_A);
460 464 s3_priv->saveHSYNC_A = S3_READ(HSYNC_A);
461 465 s3_priv->saveVTOTAL_A = S3_READ(VTOTAL_A);
462 466 s3_priv->saveVBLANK_A = S3_READ(VBLANK_A);
463 467 s3_priv->saveVSYNC_A = S3_READ(VSYNC_A);
464 468 s3_priv->saveBCLRPAT_A = S3_READ(BCLRPAT_A);
465 469
466 470 s3_priv->saveDSPACNTR = S3_READ(DSPACNTR);
467 471 s3_priv->saveDSPASTRIDE = S3_READ(DSPASTRIDE);
468 472 s3_priv->saveDSPASIZE = S3_READ(DSPASIZE);
469 473 s3_priv->saveDSPAPOS = S3_READ(DSPAPOS);
470 474 s3_priv->saveDSPABASE = S3_READ(DSPABASE);
471 475 if (IS_I965G(dev)) {
472 476 s3_priv->saveDSPASURF = S3_READ(DSPASURF);
473 477 s3_priv->saveDSPATILEOFF = S3_READ(DSPATILEOFF);
474 478 }
475 479 i915_save_palette(dev, PIPE_A);
476 480 s3_priv->savePIPEASTAT = S3_READ(PIPEASTAT);
477 481
478 482 /*
479 483 * Pipe & plane B info
480 484 */
481 485 s3_priv->savePIPEBCONF = S3_READ(PIPEBCONF);
482 486 s3_priv->savePIPEBSRC = S3_READ(PIPEBSRC);
483 487 s3_priv->saveFPB0 = S3_READ(FPB0);
484 488 s3_priv->saveFPB1 = S3_READ(FPB1);
485 489 s3_priv->saveDPLL_B = S3_READ(DPLL_B);
486 490 if (IS_I965G(dev))
487 491 s3_priv->saveDPLL_B_MD = S3_READ(DPLL_B_MD);
488 492 s3_priv->saveHTOTAL_B = S3_READ(HTOTAL_B);
489 493 s3_priv->saveHBLANK_B = S3_READ(HBLANK_B);
490 494 s3_priv->saveHSYNC_B = S3_READ(HSYNC_B);
491 495 s3_priv->saveVTOTAL_B = S3_READ(VTOTAL_B);
492 496 s3_priv->saveVBLANK_B = S3_READ(VBLANK_B);
493 497 s3_priv->saveVSYNC_B = S3_READ(VSYNC_B);
494 498 s3_priv->saveBCLRPAT_A = S3_READ(BCLRPAT_A);
495 499
496 500 s3_priv->saveDSPBCNTR = S3_READ(DSPBCNTR);
497 501 s3_priv->saveDSPBSTRIDE = S3_READ(DSPBSTRIDE);
498 502 s3_priv->saveDSPBSIZE = S3_READ(DSPBSIZE);
499 503 s3_priv->saveDSPBPOS = S3_READ(DSPBPOS);
500 504 s3_priv->saveDSPBBASE = S3_READ(DSPBBASE);
501 505 if (IS_I965GM(dev) || IS_GM45(dev)) {
502 506 s3_priv->saveDSPBSURF = S3_READ(DSPBSURF);
503 507 s3_priv->saveDSPBTILEOFF = S3_READ(DSPBTILEOFF);
504 508 }
505 509 i915_save_palette(dev, PIPE_B);
506 510 s3_priv->savePIPEBSTAT = S3_READ(PIPEBSTAT);
507 511
508 512 /*
509 513 * CRT state
510 514 */
511 515 s3_priv->saveADPA = S3_READ(ADPA);
512 516
513 517 /*
514 518 * LVDS state
515 519 */
516 520 s3_priv->savePP_CONTROL = S3_READ(PP_CONTROL);
517 521 s3_priv->savePFIT_PGM_RATIOS = S3_READ(PFIT_PGM_RATIOS);
518 522 s3_priv->saveBLC_PWM_CTL = S3_READ(BLC_PWM_CTL);
519 523 if (IS_I965G(dev))
520 524 s3_priv->saveBLC_PWM_CTL2 = S3_READ(BLC_PWM_CTL2);
521 525 if (IS_MOBILE(dev) && !IS_I830(dev))
522 526 s3_priv->saveLVDS = S3_READ(LVDS);
523 527 if (!IS_I830(dev) && !IS_845G(dev))
524 528 s3_priv->savePFIT_CONTROL = S3_READ(PFIT_CONTROL);
525 529 s3_priv->saveLVDSPP_ON = S3_READ(LVDSPP_ON);
526 530 s3_priv->saveLVDSPP_OFF = S3_READ(LVDSPP_OFF);
527 531 s3_priv->savePP_CYCLE = S3_READ(PP_CYCLE);
528 532
529 533 /* FIXME: save TV & SDVO state */
530 534
531 535 /* FBC state */
532 536 s3_priv->saveFBC_CFB_BASE = S3_READ(FBC_CFB_BASE);
533 537 s3_priv->saveFBC_LL_BASE = S3_READ(FBC_LL_BASE);
534 538 s3_priv->saveFBC_CONTROL2 = S3_READ(FBC_CONTROL2);
535 539 s3_priv->saveFBC_CONTROL = S3_READ(FBC_CONTROL);
536 540
537 541 /* VGA state */
538 542 s3_priv->saveVCLK_DIVISOR_VGA0 = S3_READ(VCLK_DIVISOR_VGA0);
539 543 s3_priv->saveVCLK_DIVISOR_VGA1 = S3_READ(VCLK_DIVISOR_VGA1);
540 544 s3_priv->saveVCLK_POST_DIV = S3_READ(VCLK_POST_DIV);
541 545 s3_priv->saveVGACNTRL = S3_READ(VGACNTRL);
542 546
543 547 i915_save_vga(dev);
544 548 }
545 549
546 550 void i915_restore_display(struct drm_device *dev)
547 551 {
548 552 struct s3_i915_private *s3_priv = dev->s3_private;
549 553
550 554 S3_WRITE(DSPARB, s3_priv->saveDSPARB);
551 555
552 556 /*
553 557 * Pipe & plane A info
554 558 * Prime the clock
555 559 */
556 560 if (s3_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
557 561 S3_WRITE(DPLL_A, s3_priv->saveDPLL_A &
558 562 ~DPLL_VCO_ENABLE);
559 563 drv_usecwait(150);
560 564 }
561 565 S3_WRITE(FPA0, s3_priv->saveFPA0);
562 566 S3_WRITE(FPA1, s3_priv->saveFPA1);
563 567 /* Actually enable it */
564 568 S3_WRITE(DPLL_A, s3_priv->saveDPLL_A);
565 569 drv_usecwait(150);
566 570 if (IS_I965G(dev))
567 571 S3_WRITE(DPLL_A_MD, s3_priv->saveDPLL_A_MD);
568 572 drv_usecwait(150);
569 573
570 574 /* Restore mode */
571 575 S3_WRITE(HTOTAL_A, s3_priv->saveHTOTAL_A);
572 576 S3_WRITE(HBLANK_A, s3_priv->saveHBLANK_A);
573 577 S3_WRITE(HSYNC_A, s3_priv->saveHSYNC_A);
574 578 S3_WRITE(VTOTAL_A, s3_priv->saveVTOTAL_A);
575 579 S3_WRITE(VBLANK_A, s3_priv->saveVBLANK_A);
576 580 S3_WRITE(VSYNC_A, s3_priv->saveVSYNC_A);
577 581 S3_WRITE(BCLRPAT_A, s3_priv->saveBCLRPAT_A);
578 582
579 583 /* Restore plane info */
580 584 S3_WRITE(DSPASIZE, s3_priv->saveDSPASIZE);
581 585 S3_WRITE(DSPAPOS, s3_priv->saveDSPAPOS);
582 586 S3_WRITE(PIPEASRC, s3_priv->savePIPEASRC);
583 587 S3_WRITE(DSPABASE, s3_priv->saveDSPABASE);
584 588 S3_WRITE(DSPASTRIDE, s3_priv->saveDSPASTRIDE);
585 589 if (IS_I965G(dev)) {
586 590 S3_WRITE(DSPASURF, s3_priv->saveDSPASURF);
587 591 S3_WRITE(DSPATILEOFF, s3_priv->saveDSPATILEOFF);
588 592 }
589 593 S3_WRITE(PIPEACONF, s3_priv->savePIPEACONF);
590 594 i915_restore_palette(dev, PIPE_A);
591 595 /* Enable the plane */
592 596 S3_WRITE(DSPACNTR, s3_priv->saveDSPACNTR);
593 597 S3_WRITE(DSPABASE, S3_READ(DSPABASE));
594 598
595 599 /* Pipe & plane B info */
596 600 if (s3_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
597 601 S3_WRITE(DPLL_B, s3_priv->saveDPLL_B &
598 602 ~DPLL_VCO_ENABLE);
599 603 drv_usecwait(150);
600 604 }
601 605 S3_WRITE(FPB0, s3_priv->saveFPB0);
602 606 S3_WRITE(FPB1, s3_priv->saveFPB1);
603 607 /* Actually enable it */
604 608 S3_WRITE(DPLL_B, s3_priv->saveDPLL_B);
605 609 drv_usecwait(150);
606 610 if (IS_I965G(dev))
607 611 S3_WRITE(DPLL_B_MD, s3_priv->saveDPLL_B_MD);
608 612 drv_usecwait(150);
609 613
610 614 /* Restore mode */
611 615 S3_WRITE(HTOTAL_B, s3_priv->saveHTOTAL_B);
612 616 S3_WRITE(HBLANK_B, s3_priv->saveHBLANK_B);
613 617 S3_WRITE(HSYNC_B, s3_priv->saveHSYNC_B);
614 618 S3_WRITE(VTOTAL_B, s3_priv->saveVTOTAL_B);
615 619 S3_WRITE(VBLANK_B, s3_priv->saveVBLANK_B);
616 620 S3_WRITE(VSYNC_B, s3_priv->saveVSYNC_B);
617 621 S3_WRITE(BCLRPAT_B, s3_priv->saveBCLRPAT_B);
618 622
619 623 /* Restore plane info */
620 624 S3_WRITE(DSPBSIZE, s3_priv->saveDSPBSIZE);
621 625 S3_WRITE(DSPBPOS, s3_priv->saveDSPBPOS);
622 626 S3_WRITE(PIPEBSRC, s3_priv->savePIPEBSRC);
623 627 S3_WRITE(DSPBBASE, s3_priv->saveDSPBBASE);
624 628 S3_WRITE(DSPBSTRIDE, s3_priv->saveDSPBSTRIDE);
625 629 if (IS_I965G(dev)) {
626 630 S3_WRITE(DSPBSURF, s3_priv->saveDSPBSURF);
627 631 S3_WRITE(DSPBTILEOFF, s3_priv->saveDSPBTILEOFF);
628 632 }
629 633 S3_WRITE(PIPEBCONF, s3_priv->savePIPEBCONF);
630 634 i915_restore_palette(dev, PIPE_B);
631 635 /* Enable the plane */
632 636 S3_WRITE(DSPBCNTR, s3_priv->saveDSPBCNTR);
633 637 S3_WRITE(DSPBBASE, S3_READ(DSPBBASE));
634 638
635 639 /* CRT state */
636 640 S3_WRITE(ADPA, s3_priv->saveADPA);
637 641
638 642 /* LVDS state */
639 643 if (IS_I965G(dev))
640 644 S3_WRITE(BLC_PWM_CTL2, s3_priv->saveBLC_PWM_CTL2);
641 645 if (IS_MOBILE(dev) && !IS_I830(dev))
642 646 S3_WRITE(LVDS, s3_priv->saveLVDS);
643 647 if (!IS_I830(dev) && !IS_845G(dev))
644 648 S3_WRITE(PFIT_CONTROL, s3_priv->savePFIT_CONTROL);
645 649
646 650 S3_WRITE(PFIT_PGM_RATIOS, s3_priv->savePFIT_PGM_RATIOS);
647 651 S3_WRITE(BLC_PWM_CTL, s3_priv->saveBLC_PWM_CTL);
648 652 S3_WRITE(LVDSPP_ON, s3_priv->saveLVDSPP_ON);
649 653 S3_WRITE(LVDSPP_OFF, s3_priv->saveLVDSPP_OFF);
650 654 S3_WRITE(PP_CYCLE, s3_priv->savePP_CYCLE);
651 655 S3_WRITE(PP_CONTROL, s3_priv->savePP_CONTROL);
652 656
653 657 /* FIXME: restore TV & SDVO state */
654 658
655 659 /* FBC info */
656 660 S3_WRITE(FBC_CFB_BASE, s3_priv->saveFBC_CFB_BASE);
657 661 S3_WRITE(FBC_LL_BASE, s3_priv->saveFBC_LL_BASE);
658 662 S3_WRITE(FBC_CONTROL2, s3_priv->saveFBC_CONTROL2);
659 663 S3_WRITE(FBC_CONTROL, s3_priv->saveFBC_CONTROL);
660 664
661 665 /* VGA state */
662 666 S3_WRITE(VGACNTRL, s3_priv->saveVGACNTRL);
663 667 S3_WRITE(VCLK_DIVISOR_VGA0, s3_priv->saveVCLK_DIVISOR_VGA0);
664 668 S3_WRITE(VCLK_DIVISOR_VGA1, s3_priv->saveVCLK_DIVISOR_VGA1);
665 669 S3_WRITE(VCLK_POST_DIV, s3_priv->saveVCLK_POST_DIV);
666 670 drv_usecwait(150);
667 671
668 672 i915_restore_vga(dev);
669 673 }
670 674 static int
671 675 i915_resume(struct drm_device *dev)
672 676 {
673 677 ddi_acc_handle_t conf_hdl;
674 678 struct s3_i915_private *s3_priv = dev->s3_private;
675 679 int i;
676 680
677 681 if (pci_config_setup(dev->dip, &conf_hdl) != DDI_SUCCESS) {
678 682 DRM_ERROR(("i915_resume: pci_config_setup fail"));
679 683 return (DDI_FAILURE);
680 684 }
681 685 /*
682 686 * Nexus driver will resume pci config space and set the power state
683 687 * for its children. So we needn't resume them explicitly here.
684 688 * see pci_pre_resume for detail.
685 689 */
686 690 pci_config_put8(conf_hdl, LBB, s3_priv->saveLBB);
687 691
688 692 if (IS_I965G(dev) && IS_MOBILE(dev))
689 693 S3_WRITE(MCHBAR_RENDER_STANDBY, s3_priv->saveRENDERSTANDBY);
690 694 if (IS_I965GM(dev))
691 695 (void) S3_READ(MCHBAR_RENDER_STANDBY);
692 696
693 697 S3_WRITE(HWS_PGA, s3_priv->saveHWS);
694 698 if (IS_I965GM(dev))
695 699 (void) S3_READ(HWS_PGA);
696 700
697 701 i915_restore_display(dev);
698 702
699 703 /* Clock gating state */
700 704 S3_WRITE (D_STATE, s3_priv->saveD_STATE);
↓ open down ↓ |
648 lines elided |
↑ open up ↑ |
701 705 S3_WRITE (CG_2D_DIS, s3_priv->saveCG_2D_DIS);
702 706
703 707 /* Cache mode state */
704 708 S3_WRITE (CACHE_MODE_0, s3_priv->saveCACHE_MODE_0 | 0xffff0000);
705 709
706 710 /* Memory arbitration state */
707 711 S3_WRITE (MI_ARB_STATE, s3_priv->saveMI_ARB_STATE | 0xffff0000);
708 712
709 713 for (i = 0; i < 16; i++) {
710 714 S3_WRITE(SWF0 + (i << 2), s3_priv->saveSWF0[i]);
711 - S3_WRITE(SWF10 + (i << 2), s3_priv->saveSWF1[i+7]);
715 + S3_WRITE(SWF10 + (i << 2), s3_priv->saveSWF1[i]);
712 716 }
713 717 for (i = 0; i < 3; i++)
714 718 S3_WRITE(SWF30 + (i << 2), s3_priv->saveSWF2[i]);
715 719
716 720 S3_WRITE(I915REG_PGTBL_CTRL, s3_priv->pgtbl_ctl);
717 721
718 722 (void) pci_config_teardown(&conf_hdl);
719 723
720 724 drm_agp_rebind(dev);
721 725
722 726 return (DDI_SUCCESS);
723 727 }
724 728
725 729 static int
726 730 i915_suspend(struct drm_device *dev)
727 731 {
728 732 ddi_acc_handle_t conf_hdl;
729 733 struct s3_i915_private *s3_priv = dev->s3_private;
730 734 int i;
731 735
732 736 if (pci_config_setup(dev->dip, &conf_hdl) != DDI_SUCCESS) {
733 737 DRM_ERROR(("i915_suspend: pci_config_setup fail"));
734 738 return (DDI_FAILURE);
735 739 }
736 740
737 741 /*
738 742 * Nexus driver will resume pci config space for its children.
739 743 * So pci config registers are not saved here.
740 744 */
741 745 s3_priv->saveLBB = pci_config_get8(conf_hdl, LBB);
742 746
743 747 if (IS_I965G(dev) && IS_MOBILE(dev))
744 748 s3_priv->saveRENDERSTANDBY = S3_READ(MCHBAR_RENDER_STANDBY);
745 749
746 750 /* Hardware status page */
747 751 s3_priv->saveHWS = S3_READ(HWS_PGA);
748 752
749 753 i915_save_display(dev);
750 754
751 755 /* Interrupt state */
752 756 s3_priv->saveIIR = S3_READ(IIR);
753 757 s3_priv->saveIER = S3_READ(IER);
754 758 s3_priv->saveIMR = S3_READ(IMR);
755 759
756 760 /* Clock gating state */
757 761 s3_priv->saveD_STATE = S3_READ(D_STATE);
758 762 s3_priv->saveCG_2D_DIS = S3_READ(CG_2D_DIS);
759 763
760 764 /* Cache mode state */
761 765 s3_priv->saveCACHE_MODE_0 = S3_READ(CACHE_MODE_0);
762 766
763 767 /* Memory Arbitration state */
764 768 s3_priv->saveMI_ARB_STATE = S3_READ(MI_ARB_STATE);
765 769
766 770 /* Scratch space */
767 771 for (i = 0; i < 16; i++) {
768 772 s3_priv->saveSWF0[i] = S3_READ(SWF0 + (i << 2));
769 773 s3_priv->saveSWF1[i] = S3_READ(SWF10 + (i << 2));
770 774 }
771 775 for (i = 0; i < 3; i++)
772 776 s3_priv->saveSWF2[i] = S3_READ(SWF30 + (i << 2));
773 777
774 778 /*
775 779 * Save page table control register
776 780 */
777 781 s3_priv->pgtbl_ctl = S3_READ(I915REG_PGTBL_CTRL);
778 782
779 783 (void) pci_config_teardown(&conf_hdl);
780 784
781 785 return (DDI_SUCCESS);
782 786 }
783 787
784 788 /*
785 789 * This funtion check the length of memory mapped IO space to get the right bar. * And There are two possibilities here.
786 790 * 1. The MMIO registers is in memory map IO bar with 1M size. The bottom half
787 791 * of the 1M space is the MMIO registers.
788 792 * 2. The MMIO register is in memory map IO with 512K size. The whole 512K
789 793 * space is the MMIO registers.
790 794 */
791 795 static int
792 796 i915_map_regs(dev_info_t *dip, caddr_t *save_addr, ddi_acc_handle_t *handlep)
793 797 {
794 798 int rnumber;
795 799 int nregs;
796 800 off_t size = 0;
797 801
798 802 if (ddi_dev_nregs(dip, &nregs)) {
799 803 cmn_err(CE_WARN, "i915_map_regs: failed to get nregs");
800 804 return (DDI_FAILURE);
801 805 }
802 806
803 807 for (rnumber = 1; rnumber < nregs; rnumber++) {
804 808 (void) ddi_dev_regsize(dip, rnumber, &size);
805 809 if ((size == 0x80000) ||
806 810 (size == 0x100000) ||
807 811 (size == 0x400000))
808 812 break;
809 813 }
810 814
811 815 if (rnumber >= nregs) {
812 816 cmn_err(CE_WARN,
813 817 "i915_map_regs: failed to find MMIO registers");
814 818 return (DDI_FAILURE);
815 819 }
816 820
817 821 if (ddi_regs_map_setup(dip, rnumber, save_addr,
818 822 0, 0x80000, &s3_attr, handlep)) {
819 823 cmn_err(CE_WARN,
820 824 "i915_map_regs: failed to map bar %d", rnumber);
821 825 return (DDI_FAILURE);
822 826 }
823 827
824 828 return (DDI_SUCCESS);
825 829 }
826 830 static void
827 831 i915_unmap_regs(ddi_acc_handle_t *handlep)
828 832 {
829 833 ddi_regs_map_free(handlep);
830 834 }
831 835 static int
832 836 i915_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
833 837 {
834 838 drm_device_t *statep;
835 839 s3_i915_private_t *s3_private;
836 840 void *handle;
837 841 int unit;
838 842
839 843 unit = ddi_get_instance(dip);
840 844 switch (cmd) {
841 845 case DDI_ATTACH:
842 846 break;
843 847 case DDI_RESUME:
844 848 statep = ddi_get_soft_state(i915_statep, unit);
845 849 return (i915_resume(statep));
846 850 default:
847 851 DRM_ERROR("i915_attach: attach and resume ops are supported");
848 852 return (DDI_FAILURE);
849 853
850 854 }
851 855
852 856 if (ddi_soft_state_zalloc(i915_statep, unit) != DDI_SUCCESS) {
853 857 cmn_err(CE_WARN,
854 858 "i915_attach: failed to alloc softstate");
855 859 return (DDI_FAILURE);
856 860 }
857 861 statep = ddi_get_soft_state(i915_statep, unit);
858 862 statep->dip = dip;
859 863 statep->driver = &i915_driver;
860 864
861 865 statep->s3_private = drm_alloc(sizeof(s3_i915_private_t),
862 866 DRM_MEM_DRIVER);
863 867
864 868 if (statep->s3_private == NULL) {
865 869 cmn_err(CE_WARN, "i915_attach: failed to allocate s3 priv");
866 870 goto err_exit1;
867 871 }
868 872
869 873 /*
870 874 * Map in the mmio register space for s3.
871 875 */
872 876 s3_private = (s3_i915_private_t *)statep->s3_private;
873 877
874 878 if (i915_map_regs(dip, &s3_private->saveAddr,
875 879 &s3_private->saveHandle)) {
876 880 cmn_err(CE_WARN, "i915_attach: failed to map MMIO");
877 881 goto err_exit2;
878 882 }
879 883
880 884 /*
881 885 * Call drm_supp_register to create minor nodes for us
882 886 */
883 887 handle = drm_supp_register(dip, statep);
884 888 if ( handle == NULL) {
885 889 DRM_ERROR("i915_attach: drm_supp_register failed");
886 890 goto err_exit3;
887 891 }
888 892 statep->drm_handle = handle;
889 893
890 894 /*
891 895 * After drm_supp_register, we can call drm_xxx routine
892 896 */
893 897 statep->drm_supported = DRM_UNSUPPORT;
894 898 if (
895 899 drm_probe(statep, i915_pciidlist) != DDI_SUCCESS) {
896 900 DRM_ERROR("i915_open: "
897 901 "DRM current don't support this graphics card");
898 902 goto err_exit4;
899 903 }
900 904 statep->drm_supported = DRM_SUPPORT;
901 905
902 906 /* call common attach code */
903 907 if (drm_attach(statep) != DDI_SUCCESS) {
904 908 DRM_ERROR("i915_attach: drm_attach failed");
905 909 goto err_exit4;
906 910 }
907 911 return (DDI_SUCCESS);
908 912 err_exit4:
909 913 (void) drm_supp_unregister(handle);
910 914 err_exit3:
911 915 i915_unmap_regs(&s3_private->saveHandle);
912 916 err_exit2:
913 917 drm_free(statep->s3_private, sizeof(s3_i915_private_t),
914 918 DRM_MEM_DRIVER);
915 919 err_exit1:
916 920 (void) ddi_soft_state_free(i915_statep, unit);
917 921
918 922 return (DDI_FAILURE);
919 923
920 924 } /* i915_attach() */
921 925
922 926 static int
923 927 i915_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
924 928 {
925 929 drm_device_t *statep;
926 930 int unit;
927 931 s3_i915_private_t *s3_private;
928 932
929 933 if ((cmd != DDI_SUSPEND) && (cmd != DDI_DETACH)) {
930 934 DRM_ERROR("i915_detach: "
931 935 "only detach and resume ops are supported");
932 936 return (DDI_FAILURE);
933 937 }
934 938
935 939 unit = ddi_get_instance(dip);
936 940 statep = ddi_get_soft_state(i915_statep, unit);
937 941 if (statep == NULL) {
938 942 DRM_ERROR("i915_detach: can not get soft state");
939 943 return (DDI_FAILURE);
940 944 }
941 945
942 946 if (cmd == DDI_SUSPEND)
943 947 return (i915_suspend(statep));
944 948
945 949 s3_private = (s3_i915_private_t *)statep->s3_private;
946 950 ddi_regs_map_free(&s3_private->saveHandle);
947 951
948 952 /*
949 953 * Free the struct for context saving in S3
950 954 */
951 955 drm_free(statep->s3_private, sizeof(s3_i915_private_t),
952 956 DRM_MEM_DRIVER);
953 957
954 958 (void) drm_detach(statep);
955 959 (void) drm_supp_unregister(statep->drm_handle);
956 960 (void) ddi_soft_state_free(i915_statep, unit);
957 961
958 962 return (DDI_SUCCESS);
959 963
960 964 } /* i915_detach() */
961 965
962 966
963 967 /*ARGSUSED*/
964 968 static int
965 969 i915_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
966 970 {
967 971 drm_device_t *statep;
968 972 int error = DDI_SUCCESS;
969 973 int unit;
970 974
971 975 unit = drm_dev_to_instance((dev_t)arg);
972 976 switch (infocmd) {
973 977 case DDI_INFO_DEVT2DEVINFO:
974 978 statep = ddi_get_soft_state(i915_statep, unit);
975 979 if (statep == NULL || statep->dip == NULL) {
976 980 error = DDI_FAILURE;
977 981 } else {
978 982 *result = (void *) statep->dip;
979 983 error = DDI_SUCCESS;
980 984 }
981 985 break;
982 986 case DDI_INFO_DEVT2INSTANCE:
983 987 *result = (void *)(uintptr_t)unit;
984 988 error = DDI_SUCCESS;
985 989 break;
986 990 default:
987 991 error = DDI_FAILURE;
988 992 break;
989 993 }
990 994 return (error);
991 995
992 996 } /* i915_info() */
993 997
994 998
995 999 static void i915_configure(drm_driver_t *driver)
996 1000 {
997 1001 driver->buf_priv_size = 1; /* No dev_priv */
998 1002 driver->load = i915_driver_load;
999 1003 driver->unload = i915_driver_unload;
1000 1004 driver->open = i915_driver_open;
1001 1005 driver->preclose = i915_driver_preclose;
1002 1006 driver->postclose = i915_driver_postclose;
1003 1007 driver->lastclose = i915_driver_lastclose;
1004 1008 driver->device_is_agp = i915_driver_device_is_agp;
1005 1009 driver->enable_vblank = i915_enable_vblank;
1006 1010 driver->disable_vblank = i915_disable_vblank;
1007 1011 driver->irq_preinstall = i915_driver_irq_preinstall;
1008 1012 driver->irq_postinstall = i915_driver_irq_postinstall;
1009 1013 driver->irq_uninstall = i915_driver_irq_uninstall;
1010 1014 driver->irq_handler = i915_driver_irq_handler;
1011 1015
1012 1016 driver->gem_init_object = i915_gem_init_object;
1013 1017 driver->gem_free_object = i915_gem_free_object;
1014 1018
1015 1019 driver->driver_ioctls = i915_ioctls;
1016 1020 driver->max_driver_ioctl = i915_max_ioctl;
1017 1021
1018 1022 driver->driver_name = DRIVER_NAME;
1019 1023 driver->driver_desc = DRIVER_DESC;
1020 1024 driver->driver_date = DRIVER_DATE;
1021 1025 driver->driver_major = DRIVER_MAJOR;
1022 1026 driver->driver_minor = DRIVER_MINOR;
1023 1027 driver->driver_patchlevel = DRIVER_PATCHLEVEL;
1024 1028
1025 1029 driver->use_agp = 1;
1026 1030 driver->require_agp = 1;
1027 1031 driver->use_irq = 1;
1028 1032 }
1029 1033
1030 1034 static int i915_quiesce(dev_info_t *dip)
1031 1035 {
1032 1036 drm_device_t *statep;
1033 1037 int unit;
1034 1038
1035 1039 unit = ddi_get_instance(dip);
1036 1040 statep = ddi_get_soft_state(i915_statep, unit);
1037 1041 if (statep == NULL) {
1038 1042 return (DDI_FAILURE);
1039 1043 }
1040 1044 i915_driver_irq_uninstall(statep);
1041 1045
1042 1046 return (DDI_SUCCESS);
1043 1047 }
↓ open down ↓ |
322 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX