Sat Oct 5 22:37:50 2019 UTC ()
list the PCI ID range for new nvidia TU117 and TU116.
adjust the check to simply be >= 0x1580, which is the
first pciid not support.

should fix PR#54600.


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

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

--- src/sys/external/bsd/drm2/nouveau/nouveau_pci.c 2019/07/03 20:47:22 1.24
+++ src/sys/external/bsd/drm2/nouveau/nouveau_pci.c 2019/10/05 22:37:49 1.25
@@ -1,336 +1,330 @@ @@ -1,336 +1,330 @@
1/* $NetBSD: nouveau_pci.c,v 1.24 2019/07/03 20:47:22 wiz Exp $ */ 1/* $NetBSD: nouveau_pci.c,v 1.25 2019/10/05 22:37:49 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.24 2019/07/03 20:47:22 wiz Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: nouveau_pci.c,v 1.25 2019/10/05 22:37:49 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 struct pci_attach_args sc_pa; 55 struct pci_attach_args sc_pa;
56 enum { 56 enum {
57 NOUVEAU_TASK_ATTACH, 57 NOUVEAU_TASK_ATTACH,
58 NOUVEAU_TASK_WORKQUEUE, 58 NOUVEAU_TASK_WORKQUEUE,
59 } sc_task_state; 59 } sc_task_state;
60 union { 60 union {
61 struct workqueue *workqueue; 61 struct workqueue *workqueue;
62 struct nouveau_pci_task_head attach; 62 struct nouveau_pci_task_head attach;
63 } sc_task_u; 63 } sc_task_u;
64 struct drm_device *sc_drm_dev; 64 struct drm_device *sc_drm_dev;
65 struct pci_dev sc_pci_dev; 65 struct pci_dev sc_pci_dev;
66 struct nvkm_device *sc_nv_dev; 66 struct nvkm_device *sc_nv_dev;
67}; 67};
68 68
69static int nouveau_pci_match(device_t, cfdata_t, void *); 69static int nouveau_pci_match(device_t, cfdata_t, void *);
70static void nouveau_pci_attach(device_t, device_t, void *); 70static void nouveau_pci_attach(device_t, device_t, void *);
71static void nouveau_pci_attach_real(device_t); 71static void nouveau_pci_attach_real(device_t);
72static int nouveau_pci_detach(device_t, int); 72static int nouveau_pci_detach(device_t, int);
73 73
74static bool nouveau_pci_suspend(device_t, const pmf_qual_t *); 74static bool nouveau_pci_suspend(device_t, const pmf_qual_t *);
75static bool nouveau_pci_resume(device_t, const pmf_qual_t *); 75static bool nouveau_pci_resume(device_t, const pmf_qual_t *);
76 76
77static void nouveau_pci_task_work(struct work *, void *); 77static void nouveau_pci_task_work(struct work *, void *);
78 78
79CFATTACH_DECL_NEW(nouveau_pci, sizeof(struct nouveau_pci_softc), 79CFATTACH_DECL_NEW(nouveau_pci, sizeof(struct nouveau_pci_softc),
80 nouveau_pci_match, nouveau_pci_attach, nouveau_pci_detach, NULL); 80 nouveau_pci_match, nouveau_pci_attach, nouveau_pci_detach, NULL);
81 81
82/* Kludge to get this from nouveau_drm.c. */ 82/* Kludge to get this from nouveau_drm.c. */
83extern struct drm_driver *const nouveau_drm_driver_pci; 83extern struct drm_driver *const nouveau_drm_driver_pci;
84 84
85static int 85static int
86nouveau_pci_match(device_t parent, cfdata_t match, void *aux) 86nouveau_pci_match(device_t parent, cfdata_t match, void *aux)
87{ 87{
88 const struct pci_attach_args *const pa = aux; 88 const struct pci_attach_args *const pa = aux;
89 struct pci_dev pdev; 89 struct pci_dev pdev;
90 struct nvkm_device *device; 90 struct nvkm_device *device;
91 int ret; 91 int ret;
92 92
93 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA && 93 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA &&
94 PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA_SGS) 94 PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA_SGS)
95 return 0; 95 return 0;
96 96
97 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY) 97 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
98 return 0; 98 return 0;
99 99
100#define IS_BETWEEN(x,y) \ 
101 (PCI_PRODUCT(pa->pa_id) >= (x) && PCI_PRODUCT(pa->pa_id) <= (y)) 
102 /* 100 /*
103 * NetBSD drm2 doesn't support Pascal, Volta or Turing based cards: 101 * NetBSD drm2 doesn't support Pascal, Volta or Turing based cards:
104 * 0x1580-0x15ff GP100 102 * 0x1580-0x15ff GP100
105 * 0x1b00-0x1b7f GP102 103 * 0x1b00-0x1b7f GP102
106 * 0x1b80-0x1bff GP104 104 * 0x1b80-0x1bff GP104
107 * 0x1c00-0x1c7f GP106 105 * 0x1c00-0x1c7f GP106
108 * 0x1c80-0x1cff GP107 106 * 0x1c80-0x1cff GP107
109 * 0x1d00-0x1d7f GP108 107 * 0x1d00-0x1d7f GP108
110 * 0x1d80-0x1dff GV100 108 * 0x1d80-0x1dff GV100
111 * 0x1e00-0x1e7f TU102 109 * 0x1e00-0x1e7f TU102
112 * 0x1e80-0x1eff TU104 110 * 0x1e80-0x1eff TU104
113 * 0x1f00-0x1f7f TU106 111 * 0x1f00-0x1f7f TU106
 112 * 0x1f80-0x1fff TU117
 113 * 0x2180-0x21ff TU116
 114 *
 115 * reduce this to >= 1580, so that new chipsets not explictly
 116 * listed above will be picked up.
 117 *
 118 * XXX perhaps switch this to explicitly match known list.
114 */ 119 */
115 120 if (PCI_PRODUCT(pa->pa_id) >= 0x1580)
116 if (IS_BETWEEN(0x1580, 0x15ff) || 
117 IS_BETWEEN(0x1b00, 0x1b7f) || 
118 IS_BETWEEN(0x1b80, 0x1bff) || 
119 IS_BETWEEN(0x1c00, 0x1c7f) || 
120 IS_BETWEEN(0x1c80, 0x1cff) || 
121 IS_BETWEEN(0x1d00, 0x1d7f) || 
122 IS_BETWEEN(0x1d80, 0x1dff) || 
123 IS_BETWEEN(0x1e00, 0x1e7f) || 
124 IS_BETWEEN(0x1e80, 0x1eff) || 
125 IS_BETWEEN(0x1f00, 0x1f7f)) 
126 return 0; 121 return 0;
127#undef IS_BETWEEN 
128 122
129 linux_pci_dev_init(&pdev, parent /* XXX bogus */, parent, pa, 0); 123 linux_pci_dev_init(&pdev, parent /* XXX bogus */, parent, pa, 0);
130 ret = nvkm_device_pci_new(&pdev, NULL, "error", 124 ret = nvkm_device_pci_new(&pdev, NULL, "error",
131 /* detect */ true, /* mmio */ false, /* subdev_mask */ 0, &device); 125 /* detect */ true, /* mmio */ false, /* subdev_mask */ 0, &device);
132 if (ret == 0) /* don't want to hang onto it */ 126 if (ret == 0) /* don't want to hang onto it */
133 nvkm_device_del(&device); 127 nvkm_device_del(&device);
134 linux_pci_dev_destroy(&pdev); 128 linux_pci_dev_destroy(&pdev);
135 if (ret) /* failure */ 129 if (ret) /* failure */
136 return 0; 130 return 0;
137 131
138 return 6; /* XXX Beat genfb_pci... */ 132 return 6; /* XXX Beat genfb_pci... */
139} 133}
140 134
141extern char *nouveau_config; 135extern char *nouveau_config;
142extern char *nouveau_debug; 136extern char *nouveau_debug;
143 137
144static void 138static void
145nouveau_pci_attach(device_t parent, device_t self, void *aux) 139nouveau_pci_attach(device_t parent, device_t self, void *aux)
146{ 140{
147 struct nouveau_pci_softc *const sc = device_private(self); 141 struct nouveau_pci_softc *const sc = device_private(self);
148 const struct pci_attach_args *const pa = aux; 142 const struct pci_attach_args *const pa = aux;
149 143
150 pci_aprint_devinfo(pa, NULL); 144 pci_aprint_devinfo(pa, NULL);
151 145
152 if (!pmf_device_register(self, &nouveau_pci_suspend, &nouveau_pci_resume)) 146 if (!pmf_device_register(self, &nouveau_pci_suspend, &nouveau_pci_resume))
153 aprint_error_dev(self, "unable to establish power handler\n"); 147 aprint_error_dev(self, "unable to establish power handler\n");
154 148
155 /* 149 /*
156 * Trivial initialization first; the rest will come after we 150 * Trivial initialization first; the rest will come after we
157 * have mounted the root file system and can load firmware 151 * have mounted the root file system and can load firmware
158 * images. 152 * images.
159 */ 153 */
160 sc->sc_dev = NULL; 154 sc->sc_dev = NULL;
161 sc->sc_pa = *pa; 155 sc->sc_pa = *pa;
162 156
163 config_mountroot(self, &nouveau_pci_attach_real); 157 config_mountroot(self, &nouveau_pci_attach_real);
164} 158}
165 159
166static void 160static void
167nouveau_pci_attach_real(device_t self) 161nouveau_pci_attach_real(device_t self)
168{ 162{
169 struct nouveau_pci_softc *const sc = device_private(self); 163 struct nouveau_pci_softc *const sc = device_private(self);
170 const struct pci_attach_args *const pa = &sc->sc_pa; 164 const struct pci_attach_args *const pa = &sc->sc_pa;
171 int error; 165 int error;
172 166
173 sc->sc_dev = self; 167 sc->sc_dev = self;
174 sc->sc_task_state = NOUVEAU_TASK_ATTACH; 168 sc->sc_task_state = NOUVEAU_TASK_ATTACH;
175 SIMPLEQ_INIT(&sc->sc_task_u.attach); 169 SIMPLEQ_INIT(&sc->sc_task_u.attach);
176 170
177 /* Initialize the Linux PCI device descriptor. */ 171 /* Initialize the Linux PCI device descriptor. */
178 linux_pci_dev_init(&sc->sc_pci_dev, self, device_parent(self), pa, 0); 172 linux_pci_dev_init(&sc->sc_pci_dev, self, device_parent(self), pa, 0);
179 173
180 /* XXX errno Linux->NetBSD */ 174 /* XXX errno Linux->NetBSD */
181 error = -nvkm_device_pci_new(&sc->sc_pci_dev, 175 error = -nvkm_device_pci_new(&sc->sc_pci_dev,
182 nouveau_config, nouveau_debug, 176 nouveau_config, nouveau_debug,
183 /* detect */ true, /* mmio */ true, /* subdev_mask */ ~0ULL, 177 /* detect */ true, /* mmio */ true, /* subdev_mask */ ~0ULL,
184 &sc->sc_nv_dev); 178 &sc->sc_nv_dev);
185 if (error) { 179 if (error) {
186 aprint_error_dev(self, "unable to create nouveau device: %d\n", 180 aprint_error_dev(self, "unable to create nouveau device: %d\n",
187 error); 181 error);
188 return; 182 return;
189 } 183 }
190 184
191 /* XXX errno Linux->NetBSD */ 185 /* XXX errno Linux->NetBSD */
192 error = -drm_pci_attach(self, pa, &sc->sc_pci_dev, 186 error = -drm_pci_attach(self, pa, &sc->sc_pci_dev,
193 nouveau_drm_driver_pci, 0, &sc->sc_drm_dev); 187 nouveau_drm_driver_pci, 0, &sc->sc_drm_dev);
194 if (error) { 188 if (error) {
195 aprint_error_dev(self, "unable to attach drm: %d\n", error); 189 aprint_error_dev(self, "unable to attach drm: %d\n", error);
196 return; 190 return;
197 } 191 }
198 192
199 while (!SIMPLEQ_EMPTY(&sc->sc_task_u.attach)) { 193 while (!SIMPLEQ_EMPTY(&sc->sc_task_u.attach)) {
200 struct nouveau_pci_task *const task = 194 struct nouveau_pci_task *const task =
201 SIMPLEQ_FIRST(&sc->sc_task_u.attach); 195 SIMPLEQ_FIRST(&sc->sc_task_u.attach);
202 196
203 SIMPLEQ_REMOVE_HEAD(&sc->sc_task_u.attach, nt_u.queue); 197 SIMPLEQ_REMOVE_HEAD(&sc->sc_task_u.attach, nt_u.queue);
204 (*task->nt_fn)(task); 198 (*task->nt_fn)(task);
205 } 199 }
206 200
207 sc->sc_task_state = NOUVEAU_TASK_WORKQUEUE; 201 sc->sc_task_state = NOUVEAU_TASK_WORKQUEUE;
208 error = workqueue_create(&sc->sc_task_u.workqueue, "nouveau_pci", 202 error = workqueue_create(&sc->sc_task_u.workqueue, "nouveau_pci",
209 &nouveau_pci_task_work, NULL, PRI_NONE, IPL_NONE, WQ_MPSAFE); 203 &nouveau_pci_task_work, NULL, PRI_NONE, IPL_NONE, WQ_MPSAFE);
210 if (error) { 204 if (error) {
211 aprint_error_dev(self, "unable to create workqueue: %d\n", 205 aprint_error_dev(self, "unable to create workqueue: %d\n",
212 error); 206 error);
213 sc->sc_task_u.workqueue = NULL; 207 sc->sc_task_u.workqueue = NULL;
214 return; 208 return;
215 } 209 }
216} 210}
217 211
218static int 212static int
219nouveau_pci_detach(device_t self, int flags) 213nouveau_pci_detach(device_t self, int flags)
220{ 214{
221 struct nouveau_pci_softc *const sc = device_private(self); 215 struct nouveau_pci_softc *const sc = device_private(self);
222 int error; 216 int error;
223 217
224 if (sc->sc_dev == NULL) 218 if (sc->sc_dev == NULL)
225 /* Not done attaching. */ 219 /* Not done attaching. */
226 return EBUSY; 220 return EBUSY;
227 221
228 /* XXX Check for in-use before tearing it all down... */ 222 /* XXX Check for in-use before tearing it all down... */
229 error = config_detach_children(self, flags); 223 error = config_detach_children(self, flags);
230 if (error) 224 if (error)
231 return error; 225 return error;
232 226
233 if (sc->sc_task_state == NOUVEAU_TASK_ATTACH) 227 if (sc->sc_task_state == NOUVEAU_TASK_ATTACH)
234 goto out0; 228 goto out0;
235 if (sc->sc_task_u.workqueue != NULL) { 229 if (sc->sc_task_u.workqueue != NULL) {
236 workqueue_destroy(sc->sc_task_u.workqueue); 230 workqueue_destroy(sc->sc_task_u.workqueue);
237 sc->sc_task_u.workqueue = NULL; 231 sc->sc_task_u.workqueue = NULL;
238 } 232 }
239 233
240 if (sc->sc_nv_dev == NULL) 234 if (sc->sc_nv_dev == NULL)
241 goto out0; 235 goto out0;
242 236
243 if (sc->sc_drm_dev == NULL) 237 if (sc->sc_drm_dev == NULL)
244 goto out1; 238 goto out1;
245 /* XXX errno Linux->NetBSD */ 239 /* XXX errno Linux->NetBSD */
246 error = -drm_pci_detach(sc->sc_drm_dev, flags); 240 error = -drm_pci_detach(sc->sc_drm_dev, flags);
247 if (error) 241 if (error)
248 /* XXX Kinda too late to fail now... */ 242 /* XXX Kinda too late to fail now... */
249 return error; 243 return error;
250 sc->sc_drm_dev = NULL; 244 sc->sc_drm_dev = NULL;
251 245
252out1: nvkm_device_del(&sc->sc_nv_dev); 246out1: nvkm_device_del(&sc->sc_nv_dev);
253out0: linux_pci_dev_destroy(&sc->sc_pci_dev); 247out0: linux_pci_dev_destroy(&sc->sc_pci_dev);
254 pmf_device_deregister(self); 248 pmf_device_deregister(self);
255 return 0; 249 return 0;
256} 250}
257 251
258/* 252/*
259 * XXX Synchronize with nouveau_do_suspend in nouveau_drm.c. 253 * XXX Synchronize with nouveau_do_suspend in nouveau_drm.c.
260 */ 254 */
261static bool 255static bool
262nouveau_pci_suspend(device_t self, const pmf_qual_t *qual __unused) 256nouveau_pci_suspend(device_t self, const pmf_qual_t *qual __unused)
263{ 257{
264 struct nouveau_pci_softc *const sc = device_private(self); 258 struct nouveau_pci_softc *const sc = device_private(self);
265 259
266 return nouveau_pmops_suspend(sc->sc_drm_dev) == 0; 260 return nouveau_pmops_suspend(sc->sc_drm_dev) == 0;
267} 261}
268 262
269static bool 263static bool
270nouveau_pci_resume(device_t self, const pmf_qual_t *qual) 264nouveau_pci_resume(device_t self, const pmf_qual_t *qual)
271{ 265{
272 struct nouveau_pci_softc *const sc = device_private(self); 266 struct nouveau_pci_softc *const sc = device_private(self);
273 267
274 return nouveau_pmops_resume(sc->sc_drm_dev) == 0; 268 return nouveau_pmops_resume(sc->sc_drm_dev) == 0;
275} 269}
276 270
277static void 271static void
278nouveau_pci_task_work(struct work *work, void *cookie __unused) 272nouveau_pci_task_work(struct work *work, void *cookie __unused)
279{ 273{
280 struct nouveau_pci_task *const task = container_of(work, 274 struct nouveau_pci_task *const task = container_of(work,
281 struct nouveau_pci_task, nt_u.work); 275 struct nouveau_pci_task, nt_u.work);
282 276
283 (*task->nt_fn)(task); 277 (*task->nt_fn)(task);
284} 278}
285 279
286int 280int
287nouveau_pci_task_schedule(device_t self, struct nouveau_pci_task *task) 281nouveau_pci_task_schedule(device_t self, struct nouveau_pci_task *task)
288{ 282{
289 struct nouveau_pci_softc *const sc = device_private(self); 283 struct nouveau_pci_softc *const sc = device_private(self);
290 284
291 switch (sc->sc_task_state) { 285 switch (sc->sc_task_state) {
292 case NOUVEAU_TASK_ATTACH: 286 case NOUVEAU_TASK_ATTACH:
293 SIMPLEQ_INSERT_TAIL(&sc->sc_task_u.attach, task, nt_u.queue); 287 SIMPLEQ_INSERT_TAIL(&sc->sc_task_u.attach, task, nt_u.queue);
294 return 0; 288 return 0;
295 case NOUVEAU_TASK_WORKQUEUE: 289 case NOUVEAU_TASK_WORKQUEUE:
296 if (sc->sc_task_u.workqueue == NULL) { 290 if (sc->sc_task_u.workqueue == NULL) {
297 aprint_error_dev(self, "unable to schedule task\n"); 291 aprint_error_dev(self, "unable to schedule task\n");
298 return EIO; 292 return EIO;
299 } 293 }
300 workqueue_enqueue(sc->sc_task_u.workqueue, &task->nt_u.work, 294 workqueue_enqueue(sc->sc_task_u.workqueue, &task->nt_u.work,
301 NULL); 295 NULL);
302 return 0; 296 return 0;
303 default: 297 default:
304 panic("nouveau in invalid task state: %d\n", 298 panic("nouveau in invalid task state: %d\n",
305 (int)sc->sc_task_state); 299 (int)sc->sc_task_state);
306 } 300 }
307} 301}
308 302
309extern struct drm_driver *const nouveau_drm_driver_stub; /* XXX */ 303extern struct drm_driver *const nouveau_drm_driver_stub; /* XXX */
310extern struct drm_driver *const nouveau_drm_driver_pci; /* XXX */ 304extern struct drm_driver *const nouveau_drm_driver_pci; /* XXX */
311 305
312static int 306static int
313nouveau_pci_modcmd(modcmd_t cmd, void *arg __unused) 307nouveau_pci_modcmd(modcmd_t cmd, void *arg __unused)
314{ 308{
315 309
316 switch (cmd) { 310 switch (cmd) {
317 case MODULE_CMD_INIT: 311 case MODULE_CMD_INIT:
318 *nouveau_drm_driver_pci = *nouveau_drm_driver_stub; 312 *nouveau_drm_driver_pci = *nouveau_drm_driver_stub;
319 nouveau_drm_driver_pci->set_busid = drm_pci_set_busid; 313 nouveau_drm_driver_pci->set_busid = drm_pci_set_busid;
320 nouveau_drm_driver_pci->request_irq = drm_pci_request_irq; 314 nouveau_drm_driver_pci->request_irq = drm_pci_request_irq;
321 nouveau_drm_driver_pci->free_irq = drm_pci_free_irq; 315 nouveau_drm_driver_pci->free_irq = drm_pci_free_irq;
322#if 0 /* XXX nouveau acpi */ 316#if 0 /* XXX nouveau acpi */
323 nouveau_register_dsm_handler(); 317 nouveau_register_dsm_handler();
324#endif 318#endif
325 break; 319 break;
326 case MODULE_CMD_FINI: 320 case MODULE_CMD_FINI:
327#if 0 /* XXX nouveau acpi */ 321#if 0 /* XXX nouveau acpi */
328 nouveau_unregister_dsm_handler(); 322 nouveau_unregister_dsm_handler();
329#endif 323#endif
330 break; 324 break;
331 default: 325 default:
332 return ENOTTY; 326 return ENOTTY;
333 } 327 }
334 328
335 return 0; 329 return 0;
336} 330}