1*829150b0SGordon Ross /*
2*829150b0SGordon Ross * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3*829150b0SGordon Ross * Use is subject to license terms.
4*829150b0SGordon Ross */
5*829150b0SGordon Ross
6*829150b0SGordon Ross #include <sys/conf.h>
7*829150b0SGordon Ross #include <sys/ddi.h>
8*829150b0SGordon Ross #include <sys/sunddi.h>
9*829150b0SGordon Ross #include <sys/modctl.h>
10*829150b0SGordon Ross #include <sys/stat.h>
11*829150b0SGordon Ross #include <sys/sunldi.h>
12*829150b0SGordon Ross #include <sys/file.h>
13*829150b0SGordon Ross #include <sys/agpgart.h>
14*829150b0SGordon Ross #include <sys/agp/agpdefs.h>
15*829150b0SGordon Ross #include <sys/agp/agpamd64gart_io.h>
16*829150b0SGordon Ross
17*829150b0SGordon Ross #define MAX_GART_INSTS 8
18*829150b0SGordon Ross #define GETSOFTC(instance) ((amd64_gart_softstate_t *) \
19*829150b0SGordon Ross ddi_get_soft_state(amd64_gart_glob_soft_handle, (instance)));
20*829150b0SGordon Ross #define DEV2INST(dev) (getminor(dev))
21*829150b0SGordon Ross #define INST2NODENUM(inst) (inst)
22*829150b0SGordon Ross
23*829150b0SGordon Ross int amd64_debug_var = 0;
24*829150b0SGordon Ross #define AMD64DB_PRINT1(fmt) if (amd64_debug_var == 1) cmn_err fmt
25*829150b0SGordon Ross #define AMD64DB_PRINT2(fmt) if (amd64_debug_var >= 1) cmn_err fmt
26*829150b0SGordon Ross
27*829150b0SGordon Ross typedef struct amd64_gart_softstate {
28*829150b0SGordon Ross dev_info_t *gsoft_dip;
29*829150b0SGordon Ross ddi_acc_handle_t gsoft_pcihdl;
30*829150b0SGordon Ross kmutex_t gsoft_lock;
31*829150b0SGordon Ross }amd64_gart_softstate_t;
32*829150b0SGordon Ross
33*829150b0SGordon Ross static void *amd64_gart_glob_soft_handle;
34*829150b0SGordon Ross
35*829150b0SGordon Ross static uint64_t
amd64_get_aperbase(amd64_gart_softstate_t * sc)36*829150b0SGordon Ross amd64_get_aperbase(amd64_gart_softstate_t *sc)
37*829150b0SGordon Ross {
38*829150b0SGordon Ross uint32_t value;
39*829150b0SGordon Ross uint64_t aper_base;
40*829150b0SGordon Ross
41*829150b0SGordon Ross /* amd64 aperture base support 40 bits and 32M aligned */
42*829150b0SGordon Ross value = pci_config_get32(sc->gsoft_pcihdl,
43*829150b0SGordon Ross AMD64_APERTURE_BASE) & AMD64_APERBASE_MASK;
44*829150b0SGordon Ross aper_base = (uint64_t)value << AMD64_APERBASE_SHIFT;
45*829150b0SGordon Ross return (aper_base);
46*829150b0SGordon Ross }
47*829150b0SGordon Ross
48*829150b0SGordon Ross static size_t
amd64_get_apersize(amd64_gart_softstate_t * sc)49*829150b0SGordon Ross amd64_get_apersize(amd64_gart_softstate_t *sc)
50*829150b0SGordon Ross {
51*829150b0SGordon Ross uint32_t value;
52*829150b0SGordon Ross size_t size;
53*829150b0SGordon Ross
54*829150b0SGordon Ross value = pci_config_get32(sc->gsoft_pcihdl, AMD64_APERTURE_CONTROL);
55*829150b0SGordon Ross
56*829150b0SGordon Ross value = (value & AMD64_APERSIZE_MASK) >> 1;
57*829150b0SGordon Ross
58*829150b0SGordon Ross /* aper size = 2^value x 32 */
59*829150b0SGordon Ross switch (value) {
60*829150b0SGordon Ross case 0x0:
61*829150b0SGordon Ross size = 32;
62*829150b0SGordon Ross break;
63*829150b0SGordon Ross case 0x1:
64*829150b0SGordon Ross size = 64;
65*829150b0SGordon Ross break;
66*829150b0SGordon Ross case 0x2:
67*829150b0SGordon Ross size = 128;
68*829150b0SGordon Ross break;
69*829150b0SGordon Ross case 0x3:
70*829150b0SGordon Ross size = 256;
71*829150b0SGordon Ross break;
72*829150b0SGordon Ross case 0x4:
73*829150b0SGordon Ross size = 512;
74*829150b0SGordon Ross break;
75*829150b0SGordon Ross case 0x5:
76*829150b0SGordon Ross size = 1024;
77*829150b0SGordon Ross break;
78*829150b0SGordon Ross case 0x6:
79*829150b0SGordon Ross size = 2048;
80*829150b0SGordon Ross break;
81*829150b0SGordon Ross default: /* reserved */
82*829150b0SGordon Ross size = 0;
83*829150b0SGordon Ross };
84*829150b0SGordon Ross
85*829150b0SGordon Ross return (size);
86*829150b0SGordon Ross }
87*829150b0SGordon Ross
88*829150b0SGordon Ross static void
amd64_invalidate_gtlb(amd64_gart_softstate_t * sc)89*829150b0SGordon Ross amd64_invalidate_gtlb(amd64_gart_softstate_t *sc)
90*829150b0SGordon Ross {
91*829150b0SGordon Ross uint32_t value;
92*829150b0SGordon Ross
93*829150b0SGordon Ross value = pci_config_get32(sc->gsoft_pcihdl, AMD64_GART_CACHE_CTL);
94*829150b0SGordon Ross value |= AMD64_INVALID_CACHE;
95*829150b0SGordon Ross
96*829150b0SGordon Ross pci_config_put32(sc->gsoft_pcihdl, AMD64_GART_CACHE_CTL, value);
97*829150b0SGordon Ross }
98*829150b0SGordon Ross
99*829150b0SGordon Ross static void
amd64_enable_gart(amd64_gart_softstate_t * sc,int enable)100*829150b0SGordon Ross amd64_enable_gart(amd64_gart_softstate_t *sc, int enable)
101*829150b0SGordon Ross {
102*829150b0SGordon Ross uint32_t aper_ctl;
103*829150b0SGordon Ross uint32_t aper_base;
104*829150b0SGordon Ross uint32_t gart_ctl;
105*829150b0SGordon Ross uint32_t gart_base;
106*829150b0SGordon Ross
107*829150b0SGordon Ross aper_ctl = pci_config_get32(sc->gsoft_pcihdl, AMD64_APERTURE_CONTROL);
108*829150b0SGordon Ross AMD64DB_PRINT1((CE_NOTE, "before: aper_ctl = %x", aper_ctl));
109*829150b0SGordon Ross aper_base = pci_config_get32(sc->gsoft_pcihdl, AMD64_APERTURE_BASE);
110*829150b0SGordon Ross gart_ctl = pci_config_get32(sc->gsoft_pcihdl, AMD64_GART_CACHE_CTL);
111*829150b0SGordon Ross gart_base = pci_config_get32(sc->gsoft_pcihdl, AMD64_GART_BASE);
112*829150b0SGordon Ross #ifdef lint
113*829150b0SGordon Ross aper_base = aper_base;
114*829150b0SGordon Ross gart_ctl = gart_ctl;
115*829150b0SGordon Ross gart_base = gart_base;
116*829150b0SGordon Ross #endif /* lint */
117*829150b0SGordon Ross AMD64DB_PRINT1((CE_NOTE, "before: aper_base = %x", aper_base));
118*829150b0SGordon Ross AMD64DB_PRINT1((CE_NOTE, "before: gart_ctl = %x", gart_ctl));
119*829150b0SGordon Ross AMD64DB_PRINT1((CE_NOTE, "before: gart_base = %x", gart_base));
120*829150b0SGordon Ross if (enable) {
121*829150b0SGordon Ross aper_ctl |= AMD64_GARTEN;
122*829150b0SGordon Ross aper_ctl &= ~(AMD64_DISGARTCPU | AMD64_DISGARTIO);
123*829150b0SGordon Ross } else
124*829150b0SGordon Ross aper_ctl &= (~AMD64_GARTEN);
125*829150b0SGordon Ross
126*829150b0SGordon Ross pci_config_put32(sc->gsoft_pcihdl, AMD64_APERTURE_CONTROL, aper_ctl);
127*829150b0SGordon Ross }
128*829150b0SGordon Ross
129*829150b0SGordon Ross /*ARGSUSED*/
130*829150b0SGordon Ross static int
amd64_gart_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** resultp)131*829150b0SGordon Ross amd64_gart_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd,
132*829150b0SGordon Ross void *arg, void **resultp)
133*829150b0SGordon Ross {
134*829150b0SGordon Ross amd64_gart_softstate_t *st;
135*829150b0SGordon Ross int instance, rval = DDI_FAILURE;
136*829150b0SGordon Ross dev_t dev;
137*829150b0SGordon Ross
138*829150b0SGordon Ross switch (cmd) {
139*829150b0SGordon Ross case DDI_INFO_DEVT2DEVINFO:
140*829150b0SGordon Ross dev = (dev_t)arg;
141*829150b0SGordon Ross instance = DEV2INST(dev);
142*829150b0SGordon Ross st = ddi_get_soft_state(amd64_gart_glob_soft_handle, instance);
143*829150b0SGordon Ross if (st != NULL) {
144*829150b0SGordon Ross mutex_enter(&st->gsoft_lock);
145*829150b0SGordon Ross *resultp = st->gsoft_dip;
146*829150b0SGordon Ross mutex_exit(&st->gsoft_lock);
147*829150b0SGordon Ross rval = DDI_SUCCESS;
148*829150b0SGordon Ross } else {
149*829150b0SGordon Ross *resultp = NULL;
150*829150b0SGordon Ross }
151*829150b0SGordon Ross
152*829150b0SGordon Ross break;
153*829150b0SGordon Ross case DDI_INFO_DEVT2INSTANCE:
154*829150b0SGordon Ross dev = (dev_t)arg;
155*829150b0SGordon Ross instance = DEV2INST(dev);
156*829150b0SGordon Ross *resultp = (void *)(uintptr_t)instance;
157*829150b0SGordon Ross rval = DDI_SUCCESS;
158*829150b0SGordon Ross break;
159*829150b0SGordon Ross default:
160*829150b0SGordon Ross break;
161*829150b0SGordon Ross }
162*829150b0SGordon Ross
163*829150b0SGordon Ross return (rval);
164*829150b0SGordon Ross }
165*829150b0SGordon Ross
166*829150b0SGordon Ross static int
amd64_gart_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)167*829150b0SGordon Ross amd64_gart_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
168*829150b0SGordon Ross {
169*829150b0SGordon Ross int instance;
170*829150b0SGordon Ross amd64_gart_softstate_t *sc;
171*829150b0SGordon Ross int status;
172*829150b0SGordon Ross char buf[80];
173*829150b0SGordon Ross
174*829150b0SGordon Ross switch (cmd) {
175*829150b0SGordon Ross default:
176*829150b0SGordon Ross return (DDI_FAILURE);
177*829150b0SGordon Ross
178*829150b0SGordon Ross case DDI_RESUME:
179*829150b0SGordon Ross /* Nothing special is needed for resume. */
180*829150b0SGordon Ross return (DDI_SUCCESS);
181*829150b0SGordon Ross
182*829150b0SGordon Ross case DDI_ATTACH:
183*829150b0SGordon Ross break;
184*829150b0SGordon Ross }
185*829150b0SGordon Ross
186*829150b0SGordon Ross instance = ddi_get_instance(dip);
187*829150b0SGordon Ross
188*829150b0SGordon Ross if (ddi_soft_state_zalloc(amd64_gart_glob_soft_handle, instance) !=
189*829150b0SGordon Ross DDI_SUCCESS)
190*829150b0SGordon Ross return (DDI_FAILURE);
191*829150b0SGordon Ross
192*829150b0SGordon Ross sc = ddi_get_soft_state(amd64_gart_glob_soft_handle, instance);
193*829150b0SGordon Ross mutex_init(&sc->gsoft_lock, NULL, MUTEX_DRIVER, NULL);
194*829150b0SGordon Ross sc->gsoft_dip = dip;
195*829150b0SGordon Ross status = pci_config_setup(dip, &sc->gsoft_pcihdl);
196*829150b0SGordon Ross if (status != DDI_SUCCESS) {
197*829150b0SGordon Ross ddi_soft_state_free(amd64_gart_glob_soft_handle, instance);
198*829150b0SGordon Ross return (DDI_FAILURE);
199*829150b0SGordon Ross }
200*829150b0SGordon Ross (void) sprintf(buf, "%s-%d", AMD64GART_NAME, instance);
201*829150b0SGordon Ross status = ddi_create_minor_node(dip, buf, S_IFCHR,
202*829150b0SGordon Ross INST2NODENUM(instance), DDI_NT_AGP_CPUGART, 0);
203*829150b0SGordon Ross if (status != DDI_SUCCESS) {
204*829150b0SGordon Ross pci_config_teardown(&sc->gsoft_pcihdl);
205*829150b0SGordon Ross ddi_soft_state_free(amd64_gart_glob_soft_handle, instance);
206*829150b0SGordon Ross return (DDI_FAILURE);
207*829150b0SGordon Ross }
208*829150b0SGordon Ross return (DDI_SUCCESS);
209*829150b0SGordon Ross }
210*829150b0SGordon Ross
211*829150b0SGordon Ross /*ARGSUSED*/
212*829150b0SGordon Ross static int
amd64_gart_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)213*829150b0SGordon Ross amd64_gart_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
214*829150b0SGordon Ross {
215*829150b0SGordon Ross int instance;
216*829150b0SGordon Ross amd64_gart_softstate_t *sc;
217*829150b0SGordon Ross char buf[80];
218*829150b0SGordon Ross
219*829150b0SGordon Ross switch (cmd) {
220*829150b0SGordon Ross default:
221*829150b0SGordon Ross return (DDI_FAILURE);
222*829150b0SGordon Ross
223*829150b0SGordon Ross case DDI_SUSPEND:
224*829150b0SGordon Ross /* Nothing special is needed for suspend */
225*829150b0SGordon Ross return (DDI_SUCCESS);
226*829150b0SGordon Ross
227*829150b0SGordon Ross case DDI_DETACH:
228*829150b0SGordon Ross break;
229*829150b0SGordon Ross }
230*829150b0SGordon Ross
231*829150b0SGordon Ross instance = ddi_get_instance(dip);
232*829150b0SGordon Ross sc = ddi_get_soft_state(amd64_gart_glob_soft_handle, instance);
233*829150b0SGordon Ross
234*829150b0SGordon Ross (void) sprintf(buf, "%s-%d", AMD64GART_NAME, instance);
235*829150b0SGordon Ross ddi_remove_minor_node(dip, buf);
236*829150b0SGordon Ross pci_config_teardown(&sc->gsoft_pcihdl);
237*829150b0SGordon Ross mutex_destroy(&sc->gsoft_lock);
238*829150b0SGordon Ross ddi_soft_state_free(amd64_gart_glob_soft_handle, instance);
239*829150b0SGordon Ross
240*829150b0SGordon Ross return (DDI_SUCCESS);
241*829150b0SGordon Ross }
242*829150b0SGordon Ross
243*829150b0SGordon Ross /*ARGSUSED*/
244*829150b0SGordon Ross static int
amd64_gart_ioctl(dev_t dev,int cmd,intptr_t data,int mode,cred_t * cred,int * rval)245*829150b0SGordon Ross amd64_gart_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
246*829150b0SGordon Ross cred_t *cred, int *rval)
247*829150b0SGordon Ross {
248*829150b0SGordon Ross int instance;
249*829150b0SGordon Ross amd64_gart_softstate_t *sc;
250*829150b0SGordon Ross static char kernel_only[] =
251*829150b0SGordon Ross "amd64_gart_ioctl: is a kernel only ioctl";
252*829150b0SGordon Ross
253*829150b0SGordon Ross if (!(mode & FKIOCTL)) {
254*829150b0SGordon Ross AMD64DB_PRINT2((CE_CONT, kernel_only));
255*829150b0SGordon Ross return (ENXIO);
256*829150b0SGordon Ross }
257*829150b0SGordon Ross instance = DEV2INST(dev);
258*829150b0SGordon Ross sc = GETSOFTC(instance);
259*829150b0SGordon Ross
260*829150b0SGordon Ross if (sc == NULL)
261*829150b0SGordon Ross return (ENXIO);
262*829150b0SGordon Ross mutex_enter(&sc->gsoft_lock);
263*829150b0SGordon Ross
264*829150b0SGordon Ross switch (cmd) {
265*829150b0SGordon Ross case AMD64_GET_INFO:
266*829150b0SGordon Ross {
267*829150b0SGordon Ross amdgart_info_t info;
268*829150b0SGordon Ross
269*829150b0SGordon Ross info.cgart_aperbase = amd64_get_aperbase(sc);
270*829150b0SGordon Ross info.cgart_apersize = amd64_get_apersize(sc);
271*829150b0SGordon Ross
272*829150b0SGordon Ross if (ddi_copyout(&info, (void *)data,
273*829150b0SGordon Ross sizeof (amdgart_info_t), mode)) {
274*829150b0SGordon Ross mutex_exit(&sc->gsoft_lock);
275*829150b0SGordon Ross return (EFAULT);
276*829150b0SGordon Ross }
277*829150b0SGordon Ross break;
278*829150b0SGordon Ross }
279*829150b0SGordon Ross case AMD64_SET_GART_ADDR:
280*829150b0SGordon Ross {
281*829150b0SGordon Ross uint32_t addr;
282*829150b0SGordon Ross
283*829150b0SGordon Ross if (ddi_copyin((void *)data, &addr, sizeof (uint32_t), mode)) {
284*829150b0SGordon Ross mutex_exit(&sc->gsoft_lock);
285*829150b0SGordon Ross return (EFAULT);
286*829150b0SGordon Ross }
287*829150b0SGordon Ross
288*829150b0SGordon Ross pci_config_put32(sc->gsoft_pcihdl, AMD64_GART_BASE, addr);
289*829150b0SGordon Ross amd64_enable_gart(sc, 1);
290*829150b0SGordon Ross
291*829150b0SGordon Ross break;
292*829150b0SGordon Ross }
293*829150b0SGordon Ross case AMD64_FLUSH_GTLB:
294*829150b0SGordon Ross {
295*829150b0SGordon Ross amd64_invalidate_gtlb(sc);
296*829150b0SGordon Ross
297*829150b0SGordon Ross break;
298*829150b0SGordon Ross }
299*829150b0SGordon Ross case AMD64_CONFIGURE:
300*829150b0SGordon Ross {
301*829150b0SGordon Ross /* reserved */
302*829150b0SGordon Ross break;
303*829150b0SGordon Ross }
304*829150b0SGordon Ross case AMD64_UNCONFIG:
305*829150b0SGordon Ross {
306*829150b0SGordon Ross amd64_enable_gart(sc, 0);
307*829150b0SGordon Ross pci_config_put32(sc->gsoft_pcihdl, AMD64_GART_BASE, 0x00000000);
308*829150b0SGordon Ross
309*829150b0SGordon Ross break;
310*829150b0SGordon Ross }
311*829150b0SGordon Ross default:
312*829150b0SGordon Ross mutex_exit(&sc->gsoft_lock);
313*829150b0SGordon Ross return (ENXIO);
314*829150b0SGordon Ross
315*829150b0SGordon Ross }
316*829150b0SGordon Ross
317*829150b0SGordon Ross mutex_exit(&sc->gsoft_lock);
318*829150b0SGordon Ross
319*829150b0SGordon Ross return (0);
320*829150b0SGordon Ross }
321*829150b0SGordon Ross
322*829150b0SGordon Ross /*ARGSUSED*/
323*829150b0SGordon Ross static int
amd64_gart_open(dev_t * dev,int flag,int otyp,cred_t * cred)324*829150b0SGordon Ross amd64_gart_open(dev_t *dev, int flag, int otyp, cred_t *cred)
325*829150b0SGordon Ross {
326*829150b0SGordon Ross int instance;
327*829150b0SGordon Ross amd64_gart_softstate_t *sc;
328*829150b0SGordon Ross
329*829150b0SGordon Ross if (!(flag & FKLYR))
330*829150b0SGordon Ross return (ENXIO);
331*829150b0SGordon Ross
332*829150b0SGordon Ross instance = DEV2INST(*dev);
333*829150b0SGordon Ross sc = GETSOFTC(instance);
334*829150b0SGordon Ross
335*829150b0SGordon Ross if (sc == NULL)
336*829150b0SGordon Ross return (ENXIO);
337*829150b0SGordon Ross
338*829150b0SGordon Ross return (0);
339*829150b0SGordon Ross }
340*829150b0SGordon Ross
341*829150b0SGordon Ross /*ARGSUSED*/
342*829150b0SGordon Ross static int
amd64_gart_close(dev_t dev,int flag,int otyp,cred_t * cred)343*829150b0SGordon Ross amd64_gart_close(dev_t dev, int flag, int otyp, cred_t *cred)
344*829150b0SGordon Ross {
345*829150b0SGordon Ross int instance;
346*829150b0SGordon Ross amd64_gart_softstate_t *sc;
347*829150b0SGordon Ross
348*829150b0SGordon Ross instance = DEV2INST(dev);
349*829150b0SGordon Ross sc = GETSOFTC(instance);
350*829150b0SGordon Ross
351*829150b0SGordon Ross if (sc == NULL)
352*829150b0SGordon Ross return (ENXIO);
353*829150b0SGordon Ross
354*829150b0SGordon Ross return (0);
355*829150b0SGordon Ross }
356*829150b0SGordon Ross
357*829150b0SGordon Ross static struct cb_ops amd64_gart_cb_ops = {
358*829150b0SGordon Ross amd64_gart_open, /* cb_open() */
359*829150b0SGordon Ross amd64_gart_close, /* cb_close() */
360*829150b0SGordon Ross nodev, /* cb_strategy() */
361*829150b0SGordon Ross nodev, /* cb_print */
362*829150b0SGordon Ross nodev, /* cb_dump */
363*829150b0SGordon Ross nodev, /* cb_read() */
364*829150b0SGordon Ross nodev, /* cb_write() */
365*829150b0SGordon Ross amd64_gart_ioctl, /* cb_ioctl */
366*829150b0SGordon Ross nodev, /* cb_devmap */
367*829150b0SGordon Ross nodev, /* cb_mmap */
368*829150b0SGordon Ross nodev, /* cb_segmap */
369*829150b0SGordon Ross nochpoll, /* cb_chpoll */
370*829150b0SGordon Ross ddi_prop_op, /* cb_prop_op */
371*829150b0SGordon Ross 0, /* cb_stream */
372*829150b0SGordon Ross D_NEW | D_MP, /* cb_flag */
373*829150b0SGordon Ross CB_REV, /* cb_ops version? */
374*829150b0SGordon Ross nodev, /* cb_aread() */
375*829150b0SGordon Ross nodev, /* cb_awrite() */
376*829150b0SGordon Ross };
377*829150b0SGordon Ross
378*829150b0SGordon Ross /* device operations */
379*829150b0SGordon Ross static struct dev_ops amd64_gart_ops = {
380*829150b0SGordon Ross DEVO_REV, /* devo_rev */
381*829150b0SGordon Ross 0, /* devo_refcnt */
382*829150b0SGordon Ross amd64_gart_getinfo, /* devo_getinfo */
383*829150b0SGordon Ross nulldev, /* devo_identify */
384*829150b0SGordon Ross nulldev, /* devo_probe */
385*829150b0SGordon Ross amd64_gart_attach, /* devo_attach */
386*829150b0SGordon Ross amd64_gart_detach, /* devo_detach */
387*829150b0SGordon Ross nodev, /* devo_reset */
388*829150b0SGordon Ross &amd64_gart_cb_ops, /* devo_cb_ops */
389*829150b0SGordon Ross 0, /* devo_bus_ops */
390*829150b0SGordon Ross 0, /* devo_power */
391*829150b0SGordon Ross ddi_quiesce_not_needed, /* devo_quiesce */
392*829150b0SGordon Ross };
393*829150b0SGordon Ross
394*829150b0SGordon Ross static struct modldrv modldrv = {
395*829150b0SGordon Ross &mod_driverops,
396*829150b0SGordon Ross "AGP AMD gart driver",
397*829150b0SGordon Ross &amd64_gart_ops,
398*829150b0SGordon Ross };
399*829150b0SGordon Ross
400*829150b0SGordon Ross static struct modlinkage modlinkage = {
401*829150b0SGordon Ross MODREV_1, /* MODREV_1 is indicated by manual */
402*829150b0SGordon Ross &modldrv,
403*829150b0SGordon Ross NULL
404*829150b0SGordon Ross };
405*829150b0SGordon Ross
406*829150b0SGordon Ross
407*829150b0SGordon Ross int
_init(void)408*829150b0SGordon Ross _init(void)
409*829150b0SGordon Ross {
410*829150b0SGordon Ross int ret = DDI_SUCCESS;
411*829150b0SGordon Ross
412*829150b0SGordon Ross ret = ddi_soft_state_init(&amd64_gart_glob_soft_handle,
413*829150b0SGordon Ross sizeof (amd64_gart_softstate_t),
414*829150b0SGordon Ross MAX_GART_INSTS);
415*829150b0SGordon Ross
416*829150b0SGordon Ross if (ret)
417*829150b0SGordon Ross return (ret);
418*829150b0SGordon Ross if ((ret = mod_install(&modlinkage)) != 0) {
419*829150b0SGordon Ross ddi_soft_state_fini(&amd64_gart_glob_soft_handle);
420*829150b0SGordon Ross return (ret);
421*829150b0SGordon Ross }
422*829150b0SGordon Ross return (DDI_SUCCESS);
423*829150b0SGordon Ross }
424*829150b0SGordon Ross
425*829150b0SGordon Ross int
_info(struct modinfo * modinfop)426*829150b0SGordon Ross _info(struct modinfo *modinfop)
427*829150b0SGordon Ross {
428*829150b0SGordon Ross return (mod_info(&modlinkage, modinfop));
429*829150b0SGordon Ross }
430*829150b0SGordon Ross
431*829150b0SGordon Ross int
_fini(void)432*829150b0SGordon Ross _fini(void)
433*829150b0SGordon Ross {
434*829150b0SGordon Ross int ret;
435*829150b0SGordon Ross if ((ret = mod_remove(&modlinkage)) == 0) {
436*829150b0SGordon Ross ddi_soft_state_fini(&amd64_gart_glob_soft_handle);
437*829150b0SGordon Ross }
438*829150b0SGordon Ross return (ret);
439*829150b0SGordon Ross }
440