xref: /gfx-drm/usr/src/uts/intel/io/agpgart/amd64_gart.c (revision 829150b0)
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