Mon Dec 24 08:26:04 2018 UTC ()
this works well enough to start and have basic accel only on GTX 750,
so enable those cards.  maybe can enable some pascal cards too.

thanks to fly for fixing nouveau drm2 so it was worth trying :-)


(mrg)
diff -r1.21 -r1.22 src/sys/external/bsd/drm2/nouveau/nouveau_pci.c

cvs diff -r1.21 -r1.22 src/sys/external/bsd/drm2/nouveau/nouveau_pci.c (switch to unified diff)

--- src/sys/external/bsd/drm2/nouveau/nouveau_pci.c 2018/08/28 03:34:07 1.21
+++ src/sys/external/bsd/drm2/nouveau/nouveau_pci.c 2018/12/24 08:26:04 1.22
@@ -1,316 +1,309 @@ @@ -1,316 +1,309 @@
1/* $NetBSD: nouveau_pci.c,v 1.21 2018/08/28 03:34:07 riastradh Exp $ */ 1/* $NetBSD: nouveau_pci.c,v 1.22 2018/12/24 08:26:04 mrg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2015 The NetBSD Foundation, Inc. 4 * Copyright (c) 2015 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R. Campbell. 8 * by Taylor R. Campbell.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: nouveau_pci.c,v 1.21 2018/08/28 03:34:07 riastradh Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: nouveau_pci.c,v 1.22 2018/12/24 08:26:04 mrg Exp $");
34 34
35#include <sys/types.h> 35#include <sys/types.h>
36#include <sys/device.h> 36#include <sys/device.h>
37#include <sys/queue.h> 37#include <sys/queue.h>
38#include <sys/workqueue.h> 38#include <sys/workqueue.h>
39#include <sys/module.h> 39#include <sys/module.h>
40 40
41#include <drm/drmP.h> 41#include <drm/drmP.h>
42 42
43#include <core/device.h> 43#include <core/device.h>
44#include <core/pci.h> 44#include <core/pci.h>
45 45
46#include "nouveau_drm.h" 46#include "nouveau_drm.h"
47#include "nouveau_pci.h" 47#include "nouveau_pci.h"
48 48
49MODULE(MODULE_CLASS_DRIVER, nouveau_pci, "nouveau,drmkms_pci"); 49MODULE(MODULE_CLASS_DRIVER, nouveau_pci, "nouveau,drmkms_pci");
50 50
51SIMPLEQ_HEAD(nouveau_pci_task_head, nouveau_pci_task); 51SIMPLEQ_HEAD(nouveau_pci_task_head, nouveau_pci_task);
52 52
53struct nouveau_pci_softc { 53struct nouveau_pci_softc {
54 device_t sc_dev; 54 device_t sc_dev;
55 enum { 55 enum {
56 NOUVEAU_TASK_ATTACH, 56 NOUVEAU_TASK_ATTACH,
57 NOUVEAU_TASK_WORKQUEUE, 57 NOUVEAU_TASK_WORKQUEUE,
58 } sc_task_state; 58 } sc_task_state;
59 union { 59 union {
60 struct workqueue *workqueue; 60 struct workqueue *workqueue;
61 struct nouveau_pci_task_head attach; 61 struct nouveau_pci_task_head attach;
62 } sc_task_u; 62 } sc_task_u;
63 struct drm_device *sc_drm_dev; 63 struct drm_device *sc_drm_dev;
64 struct pci_dev sc_pci_dev; 64 struct pci_dev sc_pci_dev;
65 struct nvkm_device *sc_nv_dev; 65 struct nvkm_device *sc_nv_dev;
66}; 66};
67 67
68static int nouveau_pci_match(device_t, cfdata_t, void *); 68static int nouveau_pci_match(device_t, cfdata_t, void *);
69static void nouveau_pci_attach(device_t, device_t, void *); 69static void nouveau_pci_attach(device_t, device_t, void *);
70static int nouveau_pci_detach(device_t, int); 70static int nouveau_pci_detach(device_t, int);
71 71
72static bool nouveau_pci_suspend(device_t, const pmf_qual_t *); 72static bool nouveau_pci_suspend(device_t, const pmf_qual_t *);
73static bool nouveau_pci_resume(device_t, const pmf_qual_t *); 73static bool nouveau_pci_resume(device_t, const pmf_qual_t *);
74 74
75static void nouveau_pci_task_work(struct work *, void *); 75static void nouveau_pci_task_work(struct work *, void *);
76 76
77CFATTACH_DECL_NEW(nouveau_pci, sizeof(struct nouveau_pci_softc), 77CFATTACH_DECL_NEW(nouveau_pci, sizeof(struct nouveau_pci_softc),
78 nouveau_pci_match, nouveau_pci_attach, nouveau_pci_detach, NULL); 78 nouveau_pci_match, nouveau_pci_attach, nouveau_pci_detach, NULL);
79 79
80/* Kludge to get this from nouveau_drm.c. */ 80/* Kludge to get this from nouveau_drm.c. */
81extern struct drm_driver *const nouveau_drm_driver_pci; 81extern struct drm_driver *const nouveau_drm_driver_pci;
82 82
83static int 83static int
84nouveau_pci_match(device_t parent, cfdata_t match, void *aux) 84nouveau_pci_match(device_t parent, cfdata_t match, void *aux)
85{ 85{
86 const struct pci_attach_args *const pa = aux; 86 const struct pci_attach_args *const pa = aux;
87 struct pci_dev pdev; 87 struct pci_dev pdev;
88 struct nvkm_device *device; 88 struct nvkm_device *device;
89 int ret; 89 int ret;
90 90
91 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA && 91 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA &&
92 PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA_SGS) 92 PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA_SGS)
93 return 0; 93 return 0;
94 94
95 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY) 95 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
96 return 0; 96 return 0;
97 97
98#define IS_BETWEEN(x,y) \ 98#define IS_BETWEEN(x,y) \
99 (PCI_PRODUCT(pa->pa_id) >= (x) && PCI_PRODUCT(pa->pa_id) <= (y)) 99 (PCI_PRODUCT(pa->pa_id) >= (x) && PCI_PRODUCT(pa->pa_id) <= (y))
100 /* 100 /*
101 * NetBSD drm2 needs missing-so-far firmware for Maxwell-based cards: 
102 * 0x1380-0x13bf GM107 
103 */ 
104 if (IS_BETWEEN(0x1380, 0x13bf)) 
105 return 0; 
106 
107 /* 
108 * NetBSD drm2 doesn't support Pascal-based cards: 101 * NetBSD drm2 doesn't support Pascal-based cards:
109 * 0x1580-0x15ff GP100 102 * 0x1580-0x15ff GP100
110 * 0x1b00-0x1b7f GP102 103 * 0x1b00-0x1b7f GP102
111 * 0x1b80-0x1bff GP104 104 * 0x1b80-0x1bff GP104
112 * 0x1c00-0x1c7f GP106 105 * 0x1c00-0x1c7f GP106
113 * 0x1c80-0x1cff GP107 106 * 0x1c80-0x1cff GP107
114 * 0x1d00-0x1d7f GP108 107 * 0x1d00-0x1d7f GP108
115 * 0x1d80-0x1dff GV100 108 * 0x1d80-0x1dff GV100
116 */ 109 */
117  110
118 if (IS_BETWEEN(0x1580, 0x15ff) || 111 if (IS_BETWEEN(0x1580, 0x15ff) ||
119 IS_BETWEEN(0x1b00, 0x1b7f) || 112 IS_BETWEEN(0x1b00, 0x1b7f) ||
120 IS_BETWEEN(0x1b80, 0x1bff) || 113 IS_BETWEEN(0x1b80, 0x1bff) ||
121 IS_BETWEEN(0x1c00, 0x1c7f) || 114 IS_BETWEEN(0x1c00, 0x1c7f) ||
122 IS_BETWEEN(0x1c80, 0x1cff) || 115 IS_BETWEEN(0x1c80, 0x1cff) ||
123 IS_BETWEEN(0x1d00, 0x1d7f) || 116 IS_BETWEEN(0x1d00, 0x1d7f) ||
124 IS_BETWEEN(0x1d80, 0x1dff)) 117 IS_BETWEEN(0x1d80, 0x1dff))
125 return 0; 118 return 0;
126#undef IS_BETWEEN 119#undef IS_BETWEEN
127 120
128 linux_pci_dev_init(&pdev, parent /* XXX bogus */, parent, pa, 0); 121 linux_pci_dev_init(&pdev, parent /* XXX bogus */, parent, pa, 0);
129 ret = nvkm_device_pci_new(&pdev, NULL, "error", 122 ret = nvkm_device_pci_new(&pdev, NULL, "error",
130 /* detect */ true, /* mmio */ false, /* subdev_mask */ 0, &device); 123 /* detect */ true, /* mmio */ false, /* subdev_mask */ 0, &device);
131 if (ret == 0) /* don't want to hang onto it */ 124 if (ret == 0) /* don't want to hang onto it */
132 nvkm_device_del(&device); 125 nvkm_device_del(&device);
133 linux_pci_dev_destroy(&pdev); 126 linux_pci_dev_destroy(&pdev);
134 if (ret) /* failure */ 127 if (ret) /* failure */
135 return 0; 128 return 0;
136 129
137 return 6; /* XXX Beat genfb_pci... */ 130 return 6; /* XXX Beat genfb_pci... */
138} 131}
139 132
140extern char *nouveau_config; 133extern char *nouveau_config;
141extern char *nouveau_debug; 134extern char *nouveau_debug;
142 135
143static void 136static void
144nouveau_pci_attach(device_t parent, device_t self, void *aux) 137nouveau_pci_attach(device_t parent, device_t self, void *aux)
145{ 138{
146 struct nouveau_pci_softc *const sc = device_private(self); 139 struct nouveau_pci_softc *const sc = device_private(self);
147 const struct pci_attach_args *const pa = aux; 140 const struct pci_attach_args *const pa = aux;
148 int error; 141 int error;
149 142
150 pci_aprint_devinfo(pa, NULL); 143 pci_aprint_devinfo(pa, NULL);
151 144
152 sc->sc_dev = self; 145 sc->sc_dev = self;
153 146
154 /* Initialize the Linux PCI device descriptor. */ 147 /* Initialize the Linux PCI device descriptor. */
155 linux_pci_dev_init(&sc->sc_pci_dev, self, device_parent(self), pa, 0); 148 linux_pci_dev_init(&sc->sc_pci_dev, self, device_parent(self), pa, 0);
156 149
157 if (!pmf_device_register(self, &nouveau_pci_suspend, 150 if (!pmf_device_register(self, &nouveau_pci_suspend,
158 &nouveau_pci_resume)) 151 &nouveau_pci_resume))
159 aprint_error_dev(self, "unable to establish power handler\n"); 152 aprint_error_dev(self, "unable to establish power handler\n");
160 153
161 sc->sc_task_state = NOUVEAU_TASK_ATTACH; 154 sc->sc_task_state = NOUVEAU_TASK_ATTACH;
162 SIMPLEQ_INIT(&sc->sc_task_u.attach); 155 SIMPLEQ_INIT(&sc->sc_task_u.attach);
163 156
164 /* XXX errno Linux->NetBSD */ 157 /* XXX errno Linux->NetBSD */
165 error = -nvkm_device_pci_new(&sc->sc_pci_dev, 158 error = -nvkm_device_pci_new(&sc->sc_pci_dev,
166 nouveau_config, nouveau_debug, 159 nouveau_config, nouveau_debug,
167 /* detect */ true, /* mmio */ true, /* subdev_mask */ ~0ULL, 160 /* detect */ true, /* mmio */ true, /* subdev_mask */ ~0ULL,
168 &sc->sc_nv_dev); 161 &sc->sc_nv_dev);
169 if (error) { 162 if (error) {
170 aprint_error_dev(self, "unable to create nouveau device: %d\n", 163 aprint_error_dev(self, "unable to create nouveau device: %d\n",
171 error); 164 error);
172 return; 165 return;
173 } 166 }
174 167
175 /* XXX errno Linux->NetBSD */ 168 /* XXX errno Linux->NetBSD */
176 error = -drm_pci_attach(self, pa, &sc->sc_pci_dev, 169 error = -drm_pci_attach(self, pa, &sc->sc_pci_dev,
177 nouveau_drm_driver_pci, 0, &sc->sc_drm_dev); 170 nouveau_drm_driver_pci, 0, &sc->sc_drm_dev);
178 if (error) { 171 if (error) {
179 aprint_error_dev(self, "unable to attach drm: %d\n", error); 172 aprint_error_dev(self, "unable to attach drm: %d\n", error);
180 return; 173 return;
181 } 174 }
182 175
183 while (!SIMPLEQ_EMPTY(&sc->sc_task_u.attach)) { 176 while (!SIMPLEQ_EMPTY(&sc->sc_task_u.attach)) {
184 struct nouveau_pci_task *const task = 177 struct nouveau_pci_task *const task =
185 SIMPLEQ_FIRST(&sc->sc_task_u.attach); 178 SIMPLEQ_FIRST(&sc->sc_task_u.attach);
186 179
187 SIMPLEQ_REMOVE_HEAD(&sc->sc_task_u.attach, nt_u.queue); 180 SIMPLEQ_REMOVE_HEAD(&sc->sc_task_u.attach, nt_u.queue);
188 (*task->nt_fn)(task); 181 (*task->nt_fn)(task);
189 } 182 }
190 183
191 sc->sc_task_state = NOUVEAU_TASK_WORKQUEUE; 184 sc->sc_task_state = NOUVEAU_TASK_WORKQUEUE;
192 error = workqueue_create(&sc->sc_task_u.workqueue, "nouveau_pci", 185 error = workqueue_create(&sc->sc_task_u.workqueue, "nouveau_pci",
193 &nouveau_pci_task_work, NULL, PRI_NONE, IPL_NONE, WQ_MPSAFE); 186 &nouveau_pci_task_work, NULL, PRI_NONE, IPL_NONE, WQ_MPSAFE);
194 if (error) { 187 if (error) {
195 aprint_error_dev(self, "unable to create workqueue: %d\n", 188 aprint_error_dev(self, "unable to create workqueue: %d\n",
196 error); 189 error);
197 sc->sc_task_u.workqueue = NULL; 190 sc->sc_task_u.workqueue = NULL;
198 return; 191 return;
199 } 192 }
200} 193}
201 194
202static int 195static int
203nouveau_pci_detach(device_t self, int flags) 196nouveau_pci_detach(device_t self, int flags)
204{ 197{
205 struct nouveau_pci_softc *const sc = device_private(self); 198 struct nouveau_pci_softc *const sc = device_private(self);
206 int error; 199 int error;
207 200
208 /* XXX Check for in-use before tearing it all down... */ 201 /* XXX Check for in-use before tearing it all down... */
209 error = config_detach_children(self, flags); 202 error = config_detach_children(self, flags);
210 if (error) 203 if (error)
211 return error; 204 return error;
212 205
213 if (sc->sc_task_state == NOUVEAU_TASK_ATTACH) 206 if (sc->sc_task_state == NOUVEAU_TASK_ATTACH)
214 goto out0; 207 goto out0;
215 if (sc->sc_task_u.workqueue != NULL) { 208 if (sc->sc_task_u.workqueue != NULL) {
216 workqueue_destroy(sc->sc_task_u.workqueue); 209 workqueue_destroy(sc->sc_task_u.workqueue);
217 sc->sc_task_u.workqueue = NULL; 210 sc->sc_task_u.workqueue = NULL;
218 } 211 }
219 212
220 if (sc->sc_nv_dev == NULL) 213 if (sc->sc_nv_dev == NULL)
221 goto out0; 214 goto out0;
222 215
223 if (sc->sc_drm_dev == NULL) 216 if (sc->sc_drm_dev == NULL)
224 goto out1; 217 goto out1;
225 /* XXX errno Linux->NetBSD */ 218 /* XXX errno Linux->NetBSD */
226 error = -drm_pci_detach(sc->sc_drm_dev, flags); 219 error = -drm_pci_detach(sc->sc_drm_dev, flags);
227 if (error) 220 if (error)
228 /* XXX Kinda too late to fail now... */ 221 /* XXX Kinda too late to fail now... */
229 return error; 222 return error;
230 sc->sc_drm_dev = NULL; 223 sc->sc_drm_dev = NULL;
231 224
232out1: nvkm_device_del(&sc->sc_nv_dev); 225out1: nvkm_device_del(&sc->sc_nv_dev);
233out0: linux_pci_dev_destroy(&sc->sc_pci_dev); 226out0: linux_pci_dev_destroy(&sc->sc_pci_dev);
234 pmf_device_deregister(self); 227 pmf_device_deregister(self);
235 return 0; 228 return 0;
236} 229}
237 230
238/* 231/*
239 * XXX Synchronize with nouveau_do_suspend in nouveau_drm.c. 232 * XXX Synchronize with nouveau_do_suspend in nouveau_drm.c.
240 */ 233 */
241static bool 234static bool
242nouveau_pci_suspend(device_t self, const pmf_qual_t *qual __unused) 235nouveau_pci_suspend(device_t self, const pmf_qual_t *qual __unused)
243{ 236{
244 struct nouveau_pci_softc *const sc = device_private(self); 237 struct nouveau_pci_softc *const sc = device_private(self);
245 238
246 return nouveau_pmops_suspend(sc->sc_drm_dev) == 0; 239 return nouveau_pmops_suspend(sc->sc_drm_dev) == 0;
247} 240}
248 241
249static bool 242static bool
250nouveau_pci_resume(device_t self, const pmf_qual_t *qual) 243nouveau_pci_resume(device_t self, const pmf_qual_t *qual)
251{ 244{
252 struct nouveau_pci_softc *const sc = device_private(self); 245 struct nouveau_pci_softc *const sc = device_private(self);
253 246
254 return nouveau_pmops_resume(sc->sc_drm_dev) == 0; 247 return nouveau_pmops_resume(sc->sc_drm_dev) == 0;
255} 248}
256 249
257static void 250static void
258nouveau_pci_task_work(struct work *work, void *cookie __unused) 251nouveau_pci_task_work(struct work *work, void *cookie __unused)
259{ 252{
260 struct nouveau_pci_task *const task = container_of(work, 253 struct nouveau_pci_task *const task = container_of(work,
261 struct nouveau_pci_task, nt_u.work); 254 struct nouveau_pci_task, nt_u.work);
262 255
263 (*task->nt_fn)(task); 256 (*task->nt_fn)(task);
264} 257}
265 258
266int 259int
267nouveau_pci_task_schedule(device_t self, struct nouveau_pci_task *task) 260nouveau_pci_task_schedule(device_t self, struct nouveau_pci_task *task)
268{ 261{
269 struct nouveau_pci_softc *const sc = device_private(self); 262 struct nouveau_pci_softc *const sc = device_private(self);
270 263
271 switch (sc->sc_task_state) { 264 switch (sc->sc_task_state) {
272 case NOUVEAU_TASK_ATTACH: 265 case NOUVEAU_TASK_ATTACH:
273 SIMPLEQ_INSERT_TAIL(&sc->sc_task_u.attach, task, nt_u.queue); 266 SIMPLEQ_INSERT_TAIL(&sc->sc_task_u.attach, task, nt_u.queue);
274 return 0; 267 return 0;
275 case NOUVEAU_TASK_WORKQUEUE: 268 case NOUVEAU_TASK_WORKQUEUE:
276 if (sc->sc_task_u.workqueue == NULL) { 269 if (sc->sc_task_u.workqueue == NULL) {
277 aprint_error_dev(self, "unable to schedule task\n"); 270 aprint_error_dev(self, "unable to schedule task\n");
278 return EIO; 271 return EIO;
279 } 272 }
280 workqueue_enqueue(sc->sc_task_u.workqueue, &task->nt_u.work, 273 workqueue_enqueue(sc->sc_task_u.workqueue, &task->nt_u.work,
281 NULL); 274 NULL);
282 return 0; 275 return 0;
283 default: 276 default:
284 panic("nouveau in invalid task state: %d\n", 277 panic("nouveau in invalid task state: %d\n",
285 (int)sc->sc_task_state); 278 (int)sc->sc_task_state);
286 } 279 }
287} 280}
288 281
289extern struct drm_driver *const nouveau_drm_driver_stub; /* XXX */ 282extern struct drm_driver *const nouveau_drm_driver_stub; /* XXX */
290extern struct drm_driver *const nouveau_drm_driver_pci; /* XXX */ 283extern struct drm_driver *const nouveau_drm_driver_pci; /* XXX */
291 284
292static int 285static int
293nouveau_pci_modcmd(modcmd_t cmd, void *arg __unused) 286nouveau_pci_modcmd(modcmd_t cmd, void *arg __unused)
294{ 287{
295 288
296 switch (cmd) { 289 switch (cmd) {
297 case MODULE_CMD_INIT: 290 case MODULE_CMD_INIT:
298 *nouveau_drm_driver_pci = *nouveau_drm_driver_stub; 291 *nouveau_drm_driver_pci = *nouveau_drm_driver_stub;
299 nouveau_drm_driver_pci->set_busid = drm_pci_set_busid; 292 nouveau_drm_driver_pci->set_busid = drm_pci_set_busid;
300 nouveau_drm_driver_pci->request_irq = drm_pci_request_irq; 293 nouveau_drm_driver_pci->request_irq = drm_pci_request_irq;
301 nouveau_drm_driver_pci->free_irq = drm_pci_free_irq; 294 nouveau_drm_driver_pci->free_irq = drm_pci_free_irq;
302#if 0 /* XXX nouveau acpi */ 295#if 0 /* XXX nouveau acpi */
303 nouveau_register_dsm_handler(); 296 nouveau_register_dsm_handler();
304#endif 297#endif
305 break; 298 break;
306 case MODULE_CMD_FINI: 299 case MODULE_CMD_FINI:
307#if 0 /* XXX nouveau acpi */ 300#if 0 /* XXX nouveau acpi */
308 nouveau_unregister_dsm_handler(); 301 nouveau_unregister_dsm_handler();
309#endif 302#endif
310 break; 303 break;
311 default: 304 default:
312 return ENOTTY; 305 return ENOTTY;
313 } 306 }
314 307
315 return 0; 308 return 0;
316} 309}