xref: /freebsd/sys/dev/nfsmb/nfsmb.c (revision 271b33a6fdb9a444fa31b1f3e945d8a93ba7b5bc)
1*271b33a6SRui Paulo /*-
2*271b33a6SRui Paulo  * Copyright (c) 2005 Ruslan Ermilov
3*271b33a6SRui Paulo  * All rights reserved.
4*271b33a6SRui Paulo  *
5*271b33a6SRui Paulo  * Redistribution and use in source and binary forms, with or without
6*271b33a6SRui Paulo  * modification, are permitted provided that the following conditions
7*271b33a6SRui Paulo  * are met:
8*271b33a6SRui Paulo  * 1. Redistributions of source code must retain the above copyright
9*271b33a6SRui Paulo  *    notice, this list of conditions and the following disclaimer.
10*271b33a6SRui Paulo  * 2. Redistributions in binary form must reproduce the above copyright
11*271b33a6SRui Paulo  *    notice, this list of conditions and the following disclaimer in the
12*271b33a6SRui Paulo  *    documentation and/or other materials provided with the distribution.
13*271b33a6SRui Paulo  *
14*271b33a6SRui Paulo  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*271b33a6SRui Paulo  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*271b33a6SRui Paulo  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*271b33a6SRui Paulo  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*271b33a6SRui Paulo  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*271b33a6SRui Paulo  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*271b33a6SRui Paulo  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*271b33a6SRui Paulo  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*271b33a6SRui Paulo  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*271b33a6SRui Paulo  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*271b33a6SRui Paulo  * SUCH DAMAGE.
25*271b33a6SRui Paulo  */
26*271b33a6SRui Paulo 
27*271b33a6SRui Paulo #include <sys/cdefs.h>
28*271b33a6SRui Paulo __FBSDID("$FreeBSD$");
29*271b33a6SRui Paulo 
30*271b33a6SRui Paulo #include <sys/param.h>
31*271b33a6SRui Paulo #include <sys/bus.h>
32*271b33a6SRui Paulo #include <sys/kernel.h>
33*271b33a6SRui Paulo #include <sys/lock.h>
34*271b33a6SRui Paulo #include <sys/module.h>
35*271b33a6SRui Paulo #include <sys/mutex.h>
36*271b33a6SRui Paulo #include <sys/systm.h>
37*271b33a6SRui Paulo 
38*271b33a6SRui Paulo #include <machine/bus.h>
39*271b33a6SRui Paulo #include <machine/resource.h>
40*271b33a6SRui Paulo #include <sys/rman.h>
41*271b33a6SRui Paulo 
42*271b33a6SRui Paulo #include <dev/pci/pcivar.h>
43*271b33a6SRui Paulo #include <dev/pci/pcireg.h>
44*271b33a6SRui Paulo 
45*271b33a6SRui Paulo #include <dev/smbus/smbconf.h>
46*271b33a6SRui Paulo #include "smbus_if.h"
47*271b33a6SRui Paulo 
48*271b33a6SRui Paulo #define	NFSMB_DEBUG(x)	if (nfsmb_debug) (x)
49*271b33a6SRui Paulo 
50*271b33a6SRui Paulo #ifdef DEBUG
51*271b33a6SRui Paulo static int nfsmb_debug = 1;
52*271b33a6SRui Paulo #else
53*271b33a6SRui Paulo static int nfsmb_debug = 0;
54*271b33a6SRui Paulo #endif
55*271b33a6SRui Paulo 
56*271b33a6SRui Paulo /* NVIDIA nForce2/3/4 MCP */
57*271b33a6SRui Paulo #define	NFSMB_VENDORID_NVIDIA		0x10de
58*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF2_SMB		0x0064
59*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF2_ULTRA_SMB	0x0084
60*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF3_PRO150_SMB	0x00d4
61*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF3_250GB_SMB	0x00e4
62*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF4_SMB		0x0052
63*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF4_04_SMB	0x0034
64*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF4_51_SMB	0x0264
65*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF4_55_SMB	0x0368
66*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF4_61_SMB	0x03eb
67*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF4_65_SMB	0x0446
68*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF4_67_SMB	0x0542
69*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF4_73_SMB	0x07d8
70*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF4_78S_SMB	0x0752
71*271b33a6SRui Paulo #define	NFSMB_DEVICEID_NF4_79_SMB	0x0aa2
72*271b33a6SRui Paulo 
73*271b33a6SRui Paulo /* PCI Configuration space registers */
74*271b33a6SRui Paulo #define	NF2PCI_SMBASE_1		PCIR_BAR(4)
75*271b33a6SRui Paulo #define	NF2PCI_SMBASE_2		PCIR_BAR(5)
76*271b33a6SRui Paulo 
77*271b33a6SRui Paulo /*
78*271b33a6SRui Paulo  * ACPI 3.0, Chapter 12, SMBus Host Controller Interface.
79*271b33a6SRui Paulo  */
80*271b33a6SRui Paulo #define	SMB_PRTCL		0x00	/* protocol */
81*271b33a6SRui Paulo #define	SMB_STS			0x01	/* status */
82*271b33a6SRui Paulo #define	SMB_ADDR		0x02	/* address */
83*271b33a6SRui Paulo #define	SMB_CMD			0x03	/* command */
84*271b33a6SRui Paulo #define	SMB_DATA		0x04	/* 32 data registers */
85*271b33a6SRui Paulo #define	SMB_BCNT		0x24	/* number of data bytes */
86*271b33a6SRui Paulo #define	SMB_ALRM_A		0x25	/* alarm address */
87*271b33a6SRui Paulo #define	SMB_ALRM_D		0x26	/* 2 bytes alarm data */
88*271b33a6SRui Paulo 
89*271b33a6SRui Paulo #define	SMB_STS_DONE		0x80
90*271b33a6SRui Paulo #define	SMB_STS_ALRM		0x40
91*271b33a6SRui Paulo #define	SMB_STS_RES		0x20
92*271b33a6SRui Paulo #define	SMB_STS_STATUS		0x1f
93*271b33a6SRui Paulo #define	SMB_STS_OK		0x00	/* OK */
94*271b33a6SRui Paulo #define	SMB_STS_UF		0x07	/* Unknown Failure */
95*271b33a6SRui Paulo #define	SMB_STS_DANA		0x10	/* Device Address Not Acknowledged */
96*271b33a6SRui Paulo #define	SMB_STS_DED		0x11	/* Device Error Detected */
97*271b33a6SRui Paulo #define	SMB_STS_DCAD		0x12	/* Device Command Access Denied */
98*271b33a6SRui Paulo #define	SMB_STS_UE		0x13	/* Unknown Error */
99*271b33a6SRui Paulo #define	SMB_STS_DAD		0x17	/* Device Access Denied */
100*271b33a6SRui Paulo #define	SMB_STS_T		0x18	/* Timeout */
101*271b33a6SRui Paulo #define	SMB_STS_HUP		0x19	/* Host Unsupported Protocol */
102*271b33a6SRui Paulo #define	SMB_STS_B		0x1A	/* Busy */
103*271b33a6SRui Paulo #define	SMB_STS_PEC		0x1F	/* PEC (CRC-8) Error */
104*271b33a6SRui Paulo 
105*271b33a6SRui Paulo #define	SMB_PRTCL_WRITE		0x00
106*271b33a6SRui Paulo #define	SMB_PRTCL_READ		0x01
107*271b33a6SRui Paulo #define	SMB_PRTCL_QUICK		0x02
108*271b33a6SRui Paulo #define	SMB_PRTCL_BYTE		0x04
109*271b33a6SRui Paulo #define	SMB_PRTCL_BYTE_DATA	0x06
110*271b33a6SRui Paulo #define	SMB_PRTCL_WORD_DATA	0x08
111*271b33a6SRui Paulo #define	SMB_PRTCL_BLOCK_DATA	0x0a
112*271b33a6SRui Paulo #define	SMB_PRTCL_PROC_CALL	0x0c
113*271b33a6SRui Paulo #define	SMB_PRTCL_BLOCK_PROC_CALL 0x0d
114*271b33a6SRui Paulo #define	SMB_PRTCL_PEC		0x80
115*271b33a6SRui Paulo 
116*271b33a6SRui Paulo struct nfsmb_softc {
117*271b33a6SRui Paulo 	int rid;
118*271b33a6SRui Paulo 	struct resource *res;
119*271b33a6SRui Paulo 	device_t smbus;
120*271b33a6SRui Paulo 	device_t subdev;
121*271b33a6SRui Paulo 	struct mtx lock;
122*271b33a6SRui Paulo };
123*271b33a6SRui Paulo 
124*271b33a6SRui Paulo #define	NFSMB_LOCK(nfsmb)		mtx_lock(&(nfsmb)->lock)
125*271b33a6SRui Paulo #define	NFSMB_UNLOCK(nfsmb)		mtx_unlock(&(nfsmb)->lock)
126*271b33a6SRui Paulo #define	NFSMB_LOCK_ASSERT(nfsmb)	mtx_assert(&(nfsmb)->lock, MA_OWNED)
127*271b33a6SRui Paulo 
128*271b33a6SRui Paulo #define	NFSMB_SMBINB(nfsmb, register)					\
129*271b33a6SRui Paulo 	(bus_read_1(nfsmb->res, register))
130*271b33a6SRui Paulo #define	NFSMB_SMBOUTB(nfsmb, register, value) \
131*271b33a6SRui Paulo 	(bus_write_1(nfsmb->res, register, value))
132*271b33a6SRui Paulo 
133*271b33a6SRui Paulo static int	nfsmb_detach(device_t dev);
134*271b33a6SRui Paulo static int	nfsmbsub_detach(device_t dev);
135*271b33a6SRui Paulo 
136*271b33a6SRui Paulo static int
137*271b33a6SRui Paulo nfsmbsub_probe(device_t dev)
138*271b33a6SRui Paulo {
139*271b33a6SRui Paulo 
140*271b33a6SRui Paulo 	device_set_desc(dev, "nForce2/3/4 MCP SMBus Controller");
141*271b33a6SRui Paulo 	return (BUS_PROBE_DEFAULT);
142*271b33a6SRui Paulo }
143*271b33a6SRui Paulo 
144*271b33a6SRui Paulo static int
145*271b33a6SRui Paulo nfsmb_probe(device_t dev)
146*271b33a6SRui Paulo {
147*271b33a6SRui Paulo 	u_int16_t vid;
148*271b33a6SRui Paulo 	u_int16_t did;
149*271b33a6SRui Paulo 
150*271b33a6SRui Paulo 	vid = pci_get_vendor(dev);
151*271b33a6SRui Paulo 	did = pci_get_device(dev);
152*271b33a6SRui Paulo 
153*271b33a6SRui Paulo 	if (vid == NFSMB_VENDORID_NVIDIA) {
154*271b33a6SRui Paulo 		switch(did) {
155*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF2_SMB:
156*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF2_ULTRA_SMB:
157*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF3_PRO150_SMB:
158*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF3_250GB_SMB:
159*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF4_SMB:
160*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF4_04_SMB:
161*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF4_51_SMB:
162*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF4_55_SMB:
163*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF4_61_SMB:
164*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF4_65_SMB:
165*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF4_67_SMB:
166*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF4_73_SMB:
167*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF4_78S_SMB:
168*271b33a6SRui Paulo 		case NFSMB_DEVICEID_NF4_79_SMB:
169*271b33a6SRui Paulo 			device_set_desc(dev, "nForce2/3/4 MCP SMBus Controller");
170*271b33a6SRui Paulo 			return (BUS_PROBE_DEFAULT);
171*271b33a6SRui Paulo 		}
172*271b33a6SRui Paulo 	}
173*271b33a6SRui Paulo 
174*271b33a6SRui Paulo 	return (ENXIO);
175*271b33a6SRui Paulo }
176*271b33a6SRui Paulo 
177*271b33a6SRui Paulo static int
178*271b33a6SRui Paulo nfsmbsub_attach(device_t dev)
179*271b33a6SRui Paulo {
180*271b33a6SRui Paulo 	device_t parent;
181*271b33a6SRui Paulo 	struct nfsmb_softc *nfsmbsub_sc = device_get_softc(dev);
182*271b33a6SRui Paulo 
183*271b33a6SRui Paulo 	parent = device_get_parent(dev);
184*271b33a6SRui Paulo 
185*271b33a6SRui Paulo 	nfsmbsub_sc->rid = NF2PCI_SMBASE_2;
186*271b33a6SRui Paulo 
187*271b33a6SRui Paulo 	nfsmbsub_sc->res = bus_alloc_resource_any(parent, SYS_RES_IOPORT,
188*271b33a6SRui Paulo 	    &nfsmbsub_sc->rid, RF_ACTIVE);
189*271b33a6SRui Paulo 	if (nfsmbsub_sc->res == NULL) {
190*271b33a6SRui Paulo 		/* Older incarnations of the device used non-standard BARs. */
191*271b33a6SRui Paulo 		nfsmbsub_sc->rid = 0x54;
192*271b33a6SRui Paulo 		nfsmbsub_sc->res = bus_alloc_resource_any(parent,
193*271b33a6SRui Paulo 		    SYS_RES_IOPORT, &nfsmbsub_sc->rid, RF_ACTIVE);
194*271b33a6SRui Paulo 		if (nfsmbsub_sc->res == NULL) {
195*271b33a6SRui Paulo 			device_printf(dev, "could not map i/o space\n");
196*271b33a6SRui Paulo 			return (ENXIO);
197*271b33a6SRui Paulo 		}
198*271b33a6SRui Paulo 	}
199*271b33a6SRui Paulo 	mtx_init(&nfsmbsub_sc->lock, device_get_nameunit(dev), "nfsmb",
200*271b33a6SRui Paulo 	    MTX_DEF);
201*271b33a6SRui Paulo 
202*271b33a6SRui Paulo 	nfsmbsub_sc->smbus = device_add_child(dev, "smbus", -1);
203*271b33a6SRui Paulo 	if (nfsmbsub_sc->smbus == NULL) {
204*271b33a6SRui Paulo 		nfsmbsub_detach(dev);
205*271b33a6SRui Paulo 		return (EINVAL);
206*271b33a6SRui Paulo 	}
207*271b33a6SRui Paulo 
208*271b33a6SRui Paulo 	bus_generic_attach(dev);
209*271b33a6SRui Paulo 
210*271b33a6SRui Paulo 	return (0);
211*271b33a6SRui Paulo }
212*271b33a6SRui Paulo 
213*271b33a6SRui Paulo static int
214*271b33a6SRui Paulo nfsmb_attach(device_t dev)
215*271b33a6SRui Paulo {
216*271b33a6SRui Paulo 	struct nfsmb_softc *nfsmb_sc = device_get_softc(dev);
217*271b33a6SRui Paulo 
218*271b33a6SRui Paulo 	/* Allocate I/O space */
219*271b33a6SRui Paulo 	nfsmb_sc->rid = NF2PCI_SMBASE_1;
220*271b33a6SRui Paulo 
221*271b33a6SRui Paulo 	nfsmb_sc->res = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
222*271b33a6SRui Paulo 		&nfsmb_sc->rid, RF_ACTIVE);
223*271b33a6SRui Paulo 
224*271b33a6SRui Paulo 	if (nfsmb_sc->res == NULL) {
225*271b33a6SRui Paulo 		/* Older incarnations of the device used non-standard BARs. */
226*271b33a6SRui Paulo 		nfsmb_sc->rid = 0x50;
227*271b33a6SRui Paulo 		nfsmb_sc->res = bus_alloc_resource_any(dev,
228*271b33a6SRui Paulo 		    SYS_RES_IOPORT, &nfsmb_sc->rid, RF_ACTIVE);
229*271b33a6SRui Paulo 		if (nfsmb_sc->res == NULL) {
230*271b33a6SRui Paulo 			device_printf(dev, "could not map i/o space\n");
231*271b33a6SRui Paulo 			return (ENXIO);
232*271b33a6SRui Paulo 		}
233*271b33a6SRui Paulo 	}
234*271b33a6SRui Paulo 
235*271b33a6SRui Paulo 	mtx_init(&nfsmb_sc->lock, device_get_nameunit(dev), "nfsmb", MTX_DEF);
236*271b33a6SRui Paulo 
237*271b33a6SRui Paulo 	/* Allocate a new smbus device */
238*271b33a6SRui Paulo 	nfsmb_sc->smbus = device_add_child(dev, "smbus", -1);
239*271b33a6SRui Paulo 	if (!nfsmb_sc->smbus) {
240*271b33a6SRui Paulo 		nfsmb_detach(dev);
241*271b33a6SRui Paulo 		return (EINVAL);
242*271b33a6SRui Paulo 	}
243*271b33a6SRui Paulo 
244*271b33a6SRui Paulo 	nfsmb_sc->subdev = NULL;
245*271b33a6SRui Paulo 	switch (pci_get_device(dev)) {
246*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF2_SMB:
247*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF2_ULTRA_SMB:
248*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF3_PRO150_SMB:
249*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF3_250GB_SMB:
250*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF4_SMB:
251*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF4_04_SMB:
252*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF4_51_SMB:
253*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF4_55_SMB:
254*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF4_61_SMB:
255*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF4_65_SMB:
256*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF4_67_SMB:
257*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF4_73_SMB:
258*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF4_78S_SMB:
259*271b33a6SRui Paulo 	case NFSMB_DEVICEID_NF4_79_SMB:
260*271b33a6SRui Paulo 		/* Trying to add secondary device as slave */
261*271b33a6SRui Paulo 		nfsmb_sc->subdev = device_add_child(dev, "nfsmb", -1);
262*271b33a6SRui Paulo 		if (!nfsmb_sc->subdev) {
263*271b33a6SRui Paulo 			nfsmb_detach(dev);
264*271b33a6SRui Paulo 			return (EINVAL);
265*271b33a6SRui Paulo 		}
266*271b33a6SRui Paulo 		break;
267*271b33a6SRui Paulo 	default:
268*271b33a6SRui Paulo 		break;
269*271b33a6SRui Paulo 	}
270*271b33a6SRui Paulo 
271*271b33a6SRui Paulo 	bus_generic_attach(dev);
272*271b33a6SRui Paulo 
273*271b33a6SRui Paulo 	return (0);
274*271b33a6SRui Paulo }
275*271b33a6SRui Paulo 
276*271b33a6SRui Paulo static int
277*271b33a6SRui Paulo nfsmbsub_detach(device_t dev)
278*271b33a6SRui Paulo {
279*271b33a6SRui Paulo 	device_t parent;
280*271b33a6SRui Paulo 	struct nfsmb_softc *nfsmbsub_sc = device_get_softc(dev);
281*271b33a6SRui Paulo 
282*271b33a6SRui Paulo 	parent = device_get_parent(dev);
283*271b33a6SRui Paulo 
284*271b33a6SRui Paulo 	if (nfsmbsub_sc->smbus) {
285*271b33a6SRui Paulo 		device_delete_child(dev, nfsmbsub_sc->smbus);
286*271b33a6SRui Paulo 		nfsmbsub_sc->smbus = NULL;
287*271b33a6SRui Paulo 	}
288*271b33a6SRui Paulo 	mtx_destroy(&nfsmbsub_sc->lock);
289*271b33a6SRui Paulo 	if (nfsmbsub_sc->res) {
290*271b33a6SRui Paulo 		bus_release_resource(parent, SYS_RES_IOPORT, nfsmbsub_sc->rid,
291*271b33a6SRui Paulo 		    nfsmbsub_sc->res);
292*271b33a6SRui Paulo 		nfsmbsub_sc->res = NULL;
293*271b33a6SRui Paulo 	}
294*271b33a6SRui Paulo 	return (0);
295*271b33a6SRui Paulo }
296*271b33a6SRui Paulo 
297*271b33a6SRui Paulo static int
298*271b33a6SRui Paulo nfsmb_detach(device_t dev)
299*271b33a6SRui Paulo {
300*271b33a6SRui Paulo 	struct nfsmb_softc *nfsmb_sc = device_get_softc(dev);
301*271b33a6SRui Paulo 
302*271b33a6SRui Paulo 	if (nfsmb_sc->subdev) {
303*271b33a6SRui Paulo 		device_delete_child(dev, nfsmb_sc->subdev);
304*271b33a6SRui Paulo 		nfsmb_sc->subdev = NULL;
305*271b33a6SRui Paulo 	}
306*271b33a6SRui Paulo 
307*271b33a6SRui Paulo 	if (nfsmb_sc->smbus) {
308*271b33a6SRui Paulo 		device_delete_child(dev, nfsmb_sc->smbus);
309*271b33a6SRui Paulo 		nfsmb_sc->smbus = NULL;
310*271b33a6SRui Paulo 	}
311*271b33a6SRui Paulo 
312*271b33a6SRui Paulo 	mtx_destroy(&nfsmb_sc->lock);
313*271b33a6SRui Paulo 	if (nfsmb_sc->res) {
314*271b33a6SRui Paulo 		bus_release_resource(dev, SYS_RES_IOPORT, nfsmb_sc->rid,
315*271b33a6SRui Paulo 		    nfsmb_sc->res);
316*271b33a6SRui Paulo 		nfsmb_sc->res = NULL;
317*271b33a6SRui Paulo 	}
318*271b33a6SRui Paulo 
319*271b33a6SRui Paulo 	return (0);
320*271b33a6SRui Paulo }
321*271b33a6SRui Paulo 
322*271b33a6SRui Paulo static int
323*271b33a6SRui Paulo nfsmb_callback(device_t dev, int index, void *data)
324*271b33a6SRui Paulo {
325*271b33a6SRui Paulo 	int error = 0;
326*271b33a6SRui Paulo 
327*271b33a6SRui Paulo 	switch (index) {
328*271b33a6SRui Paulo 	case SMB_REQUEST_BUS:
329*271b33a6SRui Paulo 	case SMB_RELEASE_BUS:
330*271b33a6SRui Paulo 		break;
331*271b33a6SRui Paulo 	default:
332*271b33a6SRui Paulo 		error = EINVAL;
333*271b33a6SRui Paulo 	}
334*271b33a6SRui Paulo 
335*271b33a6SRui Paulo 	return (error);
336*271b33a6SRui Paulo }
337*271b33a6SRui Paulo 
338*271b33a6SRui Paulo static int
339*271b33a6SRui Paulo nfsmb_wait(struct nfsmb_softc *sc)
340*271b33a6SRui Paulo {
341*271b33a6SRui Paulo 	u_char sts;
342*271b33a6SRui Paulo 	int error, count;
343*271b33a6SRui Paulo 
344*271b33a6SRui Paulo 	NFSMB_LOCK_ASSERT(sc);
345*271b33a6SRui Paulo 	if (NFSMB_SMBINB(sc, SMB_PRTCL) != 0)
346*271b33a6SRui Paulo 	{
347*271b33a6SRui Paulo 		count = 10000;
348*271b33a6SRui Paulo 		do {
349*271b33a6SRui Paulo 			DELAY(500);
350*271b33a6SRui Paulo 		} while (NFSMB_SMBINB(sc, SMB_PRTCL) != 0 && count--);
351*271b33a6SRui Paulo 		if (count == 0)
352*271b33a6SRui Paulo 			return (SMB_ETIMEOUT);
353*271b33a6SRui Paulo 	}
354*271b33a6SRui Paulo 
355*271b33a6SRui Paulo 	sts = NFSMB_SMBINB(sc, SMB_STS) & SMB_STS_STATUS;
356*271b33a6SRui Paulo 	NFSMB_DEBUG(printf("nfsmb: STS=0x%x\n", sts));
357*271b33a6SRui Paulo 
358*271b33a6SRui Paulo 	switch (sts) {
359*271b33a6SRui Paulo 	case SMB_STS_OK:
360*271b33a6SRui Paulo 		error = SMB_ENOERR;
361*271b33a6SRui Paulo 		break;
362*271b33a6SRui Paulo 	case SMB_STS_DANA:
363*271b33a6SRui Paulo 		error = SMB_ENOACK;
364*271b33a6SRui Paulo 		break;
365*271b33a6SRui Paulo 	case SMB_STS_B:
366*271b33a6SRui Paulo 		error = SMB_EBUSY;
367*271b33a6SRui Paulo 		break;
368*271b33a6SRui Paulo 	case SMB_STS_T:
369*271b33a6SRui Paulo 		error = SMB_ETIMEOUT;
370*271b33a6SRui Paulo 		break;
371*271b33a6SRui Paulo 	case SMB_STS_DCAD:
372*271b33a6SRui Paulo 	case SMB_STS_DAD:
373*271b33a6SRui Paulo 	case SMB_STS_HUP:
374*271b33a6SRui Paulo 		error = SMB_ENOTSUPP;
375*271b33a6SRui Paulo 		break;
376*271b33a6SRui Paulo 	default:
377*271b33a6SRui Paulo 		error = SMB_EBUSERR;
378*271b33a6SRui Paulo 		break;
379*271b33a6SRui Paulo 	}
380*271b33a6SRui Paulo 
381*271b33a6SRui Paulo 	return (error);
382*271b33a6SRui Paulo }
383*271b33a6SRui Paulo 
384*271b33a6SRui Paulo static int
385*271b33a6SRui Paulo nfsmb_quick(device_t dev, u_char slave, int how)
386*271b33a6SRui Paulo {
387*271b33a6SRui Paulo 	struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
388*271b33a6SRui Paulo 	u_char protocol;
389*271b33a6SRui Paulo 	int error;
390*271b33a6SRui Paulo 
391*271b33a6SRui Paulo 	protocol = SMB_PRTCL_QUICK;
392*271b33a6SRui Paulo 
393*271b33a6SRui Paulo 	switch (how) {
394*271b33a6SRui Paulo 	case SMB_QWRITE:
395*271b33a6SRui Paulo 		protocol |= SMB_PRTCL_WRITE;
396*271b33a6SRui Paulo 		NFSMB_DEBUG(printf("nfsmb: QWRITE to 0x%x", slave));
397*271b33a6SRui Paulo 		break;
398*271b33a6SRui Paulo 	case SMB_QREAD:
399*271b33a6SRui Paulo 		protocol |= SMB_PRTCL_READ;
400*271b33a6SRui Paulo 		NFSMB_DEBUG(printf("nfsmb: QREAD to 0x%x", slave));
401*271b33a6SRui Paulo 		break;
402*271b33a6SRui Paulo 	default:
403*271b33a6SRui Paulo 		panic("%s: unknown QUICK command (%x)!", __func__, how);
404*271b33a6SRui Paulo 	}
405*271b33a6SRui Paulo 
406*271b33a6SRui Paulo 	NFSMB_LOCK(sc);
407*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
408*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_PRTCL, protocol);
409*271b33a6SRui Paulo 
410*271b33a6SRui Paulo 	error = nfsmb_wait(sc);
411*271b33a6SRui Paulo 
412*271b33a6SRui Paulo 	NFSMB_DEBUG(printf(", error=0x%x\n", error));
413*271b33a6SRui Paulo 	NFSMB_UNLOCK(sc);
414*271b33a6SRui Paulo 
415*271b33a6SRui Paulo 	return (error);
416*271b33a6SRui Paulo }
417*271b33a6SRui Paulo 
418*271b33a6SRui Paulo static int
419*271b33a6SRui Paulo nfsmb_sendb(device_t dev, u_char slave, char byte)
420*271b33a6SRui Paulo {
421*271b33a6SRui Paulo 	struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
422*271b33a6SRui Paulo 	int error;
423*271b33a6SRui Paulo 
424*271b33a6SRui Paulo 	NFSMB_LOCK(sc);
425*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_CMD, byte);
426*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
427*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BYTE);
428*271b33a6SRui Paulo 
429*271b33a6SRui Paulo 	error = nfsmb_wait(sc);
430*271b33a6SRui Paulo 
431*271b33a6SRui Paulo 	NFSMB_DEBUG(printf("nfsmb: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
432*271b33a6SRui Paulo 	NFSMB_UNLOCK(sc);
433*271b33a6SRui Paulo 
434*271b33a6SRui Paulo 	return (error);
435*271b33a6SRui Paulo }
436*271b33a6SRui Paulo 
437*271b33a6SRui Paulo static int
438*271b33a6SRui Paulo nfsmb_recvb(device_t dev, u_char slave, char *byte)
439*271b33a6SRui Paulo {
440*271b33a6SRui Paulo 	struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
441*271b33a6SRui Paulo 	int error;
442*271b33a6SRui Paulo 
443*271b33a6SRui Paulo 	NFSMB_LOCK(sc);
444*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
445*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BYTE);
446*271b33a6SRui Paulo 
447*271b33a6SRui Paulo 	if ((error = nfsmb_wait(sc)) == SMB_ENOERR)
448*271b33a6SRui Paulo 		*byte = NFSMB_SMBINB(sc, SMB_DATA);
449*271b33a6SRui Paulo 
450*271b33a6SRui Paulo 	NFSMB_DEBUG(printf("nfsmb: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
451*271b33a6SRui Paulo 	NFSMB_UNLOCK(sc);
452*271b33a6SRui Paulo 
453*271b33a6SRui Paulo 	return (error);
454*271b33a6SRui Paulo }
455*271b33a6SRui Paulo 
456*271b33a6SRui Paulo static int
457*271b33a6SRui Paulo nfsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
458*271b33a6SRui Paulo {
459*271b33a6SRui Paulo 	struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
460*271b33a6SRui Paulo 	int error;
461*271b33a6SRui Paulo 
462*271b33a6SRui Paulo 	NFSMB_LOCK(sc);
463*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
464*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_DATA, byte);
465*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
466*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BYTE_DATA);
467*271b33a6SRui Paulo 
468*271b33a6SRui Paulo 	error = nfsmb_wait(sc);
469*271b33a6SRui Paulo 
470*271b33a6SRui Paulo 	NFSMB_DEBUG(printf("nfsmb: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
471*271b33a6SRui Paulo 	NFSMB_UNLOCK(sc);
472*271b33a6SRui Paulo 
473*271b33a6SRui Paulo 	return (error);
474*271b33a6SRui Paulo }
475*271b33a6SRui Paulo 
476*271b33a6SRui Paulo static int
477*271b33a6SRui Paulo nfsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
478*271b33a6SRui Paulo {
479*271b33a6SRui Paulo 	struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
480*271b33a6SRui Paulo 	int error;
481*271b33a6SRui Paulo 
482*271b33a6SRui Paulo 	NFSMB_LOCK(sc);
483*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
484*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
485*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BYTE_DATA);
486*271b33a6SRui Paulo 
487*271b33a6SRui Paulo 	if ((error = nfsmb_wait(sc)) == SMB_ENOERR)
488*271b33a6SRui Paulo 		*byte = NFSMB_SMBINB(sc, SMB_DATA);
489*271b33a6SRui Paulo 
490*271b33a6SRui Paulo 	NFSMB_DEBUG(printf("nfsmb: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, (unsigned char)*byte, error));
491*271b33a6SRui Paulo 	NFSMB_UNLOCK(sc);
492*271b33a6SRui Paulo 
493*271b33a6SRui Paulo 	return (error);
494*271b33a6SRui Paulo }
495*271b33a6SRui Paulo 
496*271b33a6SRui Paulo static int
497*271b33a6SRui Paulo nfsmb_writew(device_t dev, u_char slave, char cmd, short word)
498*271b33a6SRui Paulo {
499*271b33a6SRui Paulo 	struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
500*271b33a6SRui Paulo 	int error;
501*271b33a6SRui Paulo 
502*271b33a6SRui Paulo 	NFSMB_LOCK(sc);
503*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
504*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_DATA, word);
505*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_DATA + 1, word >> 8);
506*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
507*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_WORD_DATA);
508*271b33a6SRui Paulo 
509*271b33a6SRui Paulo 	error = nfsmb_wait(sc);
510*271b33a6SRui Paulo 
511*271b33a6SRui Paulo 	NFSMB_DEBUG(printf("nfsmb: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
512*271b33a6SRui Paulo 	NFSMB_UNLOCK(sc);
513*271b33a6SRui Paulo 
514*271b33a6SRui Paulo 	return (error);
515*271b33a6SRui Paulo }
516*271b33a6SRui Paulo 
517*271b33a6SRui Paulo static int
518*271b33a6SRui Paulo nfsmb_readw(device_t dev, u_char slave, char cmd, short *word)
519*271b33a6SRui Paulo {
520*271b33a6SRui Paulo 	struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
521*271b33a6SRui Paulo 	int error;
522*271b33a6SRui Paulo 
523*271b33a6SRui Paulo 	NFSMB_LOCK(sc);
524*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
525*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
526*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_WORD_DATA);
527*271b33a6SRui Paulo 
528*271b33a6SRui Paulo 	if ((error = nfsmb_wait(sc)) == SMB_ENOERR)
529*271b33a6SRui Paulo 		*word = NFSMB_SMBINB(sc, SMB_DATA) |
530*271b33a6SRui Paulo 		    (NFSMB_SMBINB(sc, SMB_DATA + 1) << 8);
531*271b33a6SRui Paulo 
532*271b33a6SRui Paulo 	NFSMB_DEBUG(printf("nfsmb: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, (unsigned short)*word, error));
533*271b33a6SRui Paulo 	NFSMB_UNLOCK(sc);
534*271b33a6SRui Paulo 
535*271b33a6SRui Paulo 	return (error);
536*271b33a6SRui Paulo }
537*271b33a6SRui Paulo 
538*271b33a6SRui Paulo static int
539*271b33a6SRui Paulo nfsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
540*271b33a6SRui Paulo {
541*271b33a6SRui Paulo 	struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
542*271b33a6SRui Paulo 	u_char i;
543*271b33a6SRui Paulo 	int error;
544*271b33a6SRui Paulo 
545*271b33a6SRui Paulo 	if (count < 1 || count > 32)
546*271b33a6SRui Paulo 		return (SMB_EINVAL);
547*271b33a6SRui Paulo 
548*271b33a6SRui Paulo 	NFSMB_LOCK(sc);
549*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
550*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_BCNT, count);
551*271b33a6SRui Paulo 	for (i = 0; i < count; i++)
552*271b33a6SRui Paulo 		NFSMB_SMBOUTB(sc, SMB_DATA + i, buf[i]);
553*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
554*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BLOCK_DATA);
555*271b33a6SRui Paulo 
556*271b33a6SRui Paulo 	error = nfsmb_wait(sc);
557*271b33a6SRui Paulo 
558*271b33a6SRui Paulo 	NFSMB_DEBUG(printf("nfsmb: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
559*271b33a6SRui Paulo 	NFSMB_UNLOCK(sc);
560*271b33a6SRui Paulo 
561*271b33a6SRui Paulo 	return (error);
562*271b33a6SRui Paulo }
563*271b33a6SRui Paulo 
564*271b33a6SRui Paulo static int
565*271b33a6SRui Paulo nfsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
566*271b33a6SRui Paulo {
567*271b33a6SRui Paulo 	struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
568*271b33a6SRui Paulo 	u_char data, len, i;
569*271b33a6SRui Paulo 	int error;
570*271b33a6SRui Paulo 
571*271b33a6SRui Paulo 	if (*count < 1 || *count > 32)
572*271b33a6SRui Paulo 		return (SMB_EINVAL);
573*271b33a6SRui Paulo 
574*271b33a6SRui Paulo 	NFSMB_LOCK(sc);
575*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
576*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
577*271b33a6SRui Paulo 	NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BLOCK_DATA);
578*271b33a6SRui Paulo 
579*271b33a6SRui Paulo 	if ((error = nfsmb_wait(sc)) == SMB_ENOERR) {
580*271b33a6SRui Paulo 		len = NFSMB_SMBINB(sc, SMB_BCNT);
581*271b33a6SRui Paulo 		for (i = 0; i < len; i++) {
582*271b33a6SRui Paulo 			data = NFSMB_SMBINB(sc, SMB_DATA + i);
583*271b33a6SRui Paulo 			if (i < *count)
584*271b33a6SRui Paulo 				buf[i] = data;
585*271b33a6SRui Paulo 		}
586*271b33a6SRui Paulo 		*count = len;
587*271b33a6SRui Paulo 	}
588*271b33a6SRui Paulo 
589*271b33a6SRui Paulo 	NFSMB_DEBUG(printf("nfsmb: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error));
590*271b33a6SRui Paulo 	NFSMB_UNLOCK(sc);
591*271b33a6SRui Paulo 
592*271b33a6SRui Paulo 	return (error);
593*271b33a6SRui Paulo }
594*271b33a6SRui Paulo 
595*271b33a6SRui Paulo static device_method_t nfsmb_methods[] = {
596*271b33a6SRui Paulo 	/* Device interface */
597*271b33a6SRui Paulo 	DEVMETHOD(device_probe,		nfsmb_probe),
598*271b33a6SRui Paulo 	DEVMETHOD(device_attach,	nfsmb_attach),
599*271b33a6SRui Paulo 	DEVMETHOD(device_detach,	nfsmb_detach),
600*271b33a6SRui Paulo 
601*271b33a6SRui Paulo 	/* SMBus interface */
602*271b33a6SRui Paulo 	DEVMETHOD(smbus_callback,	nfsmb_callback),
603*271b33a6SRui Paulo 	DEVMETHOD(smbus_quick,		nfsmb_quick),
604*271b33a6SRui Paulo 	DEVMETHOD(smbus_sendb,		nfsmb_sendb),
605*271b33a6SRui Paulo 	DEVMETHOD(smbus_recvb,		nfsmb_recvb),
606*271b33a6SRui Paulo 	DEVMETHOD(smbus_writeb,		nfsmb_writeb),
607*271b33a6SRui Paulo 	DEVMETHOD(smbus_readb,		nfsmb_readb),
608*271b33a6SRui Paulo 	DEVMETHOD(smbus_writew,		nfsmb_writew),
609*271b33a6SRui Paulo 	DEVMETHOD(smbus_readw,		nfsmb_readw),
610*271b33a6SRui Paulo 	DEVMETHOD(smbus_bwrite,		nfsmb_bwrite),
611*271b33a6SRui Paulo 	DEVMETHOD(smbus_bread,		nfsmb_bread),
612*271b33a6SRui Paulo 
613*271b33a6SRui Paulo 	{ 0, 0 }
614*271b33a6SRui Paulo };
615*271b33a6SRui Paulo 
616*271b33a6SRui Paulo static device_method_t nfsmbsub_methods[] = {
617*271b33a6SRui Paulo 	/* Device interface */
618*271b33a6SRui Paulo 	DEVMETHOD(device_probe,		nfsmbsub_probe),
619*271b33a6SRui Paulo 	DEVMETHOD(device_attach,	nfsmbsub_attach),
620*271b33a6SRui Paulo 	DEVMETHOD(device_detach,	nfsmbsub_detach),
621*271b33a6SRui Paulo 
622*271b33a6SRui Paulo 	/* SMBus interface */
623*271b33a6SRui Paulo 	DEVMETHOD(smbus_callback,	nfsmb_callback),
624*271b33a6SRui Paulo 	DEVMETHOD(smbus_quick,		nfsmb_quick),
625*271b33a6SRui Paulo 	DEVMETHOD(smbus_sendb,		nfsmb_sendb),
626*271b33a6SRui Paulo 	DEVMETHOD(smbus_recvb,		nfsmb_recvb),
627*271b33a6SRui Paulo 	DEVMETHOD(smbus_writeb,		nfsmb_writeb),
628*271b33a6SRui Paulo 	DEVMETHOD(smbus_readb,		nfsmb_readb),
629*271b33a6SRui Paulo 	DEVMETHOD(smbus_writew,		nfsmb_writew),
630*271b33a6SRui Paulo 	DEVMETHOD(smbus_readw,		nfsmb_readw),
631*271b33a6SRui Paulo 	DEVMETHOD(smbus_bwrite,		nfsmb_bwrite),
632*271b33a6SRui Paulo 	DEVMETHOD(smbus_bread,		nfsmb_bread),
633*271b33a6SRui Paulo 
634*271b33a6SRui Paulo 	{ 0, 0 }
635*271b33a6SRui Paulo };
636*271b33a6SRui Paulo 
637*271b33a6SRui Paulo static devclass_t nfsmb_devclass;
638*271b33a6SRui Paulo 
639*271b33a6SRui Paulo static driver_t nfsmb_driver = {
640*271b33a6SRui Paulo 	"nfsmb",
641*271b33a6SRui Paulo 	nfsmb_methods,
642*271b33a6SRui Paulo 	sizeof(struct nfsmb_softc),
643*271b33a6SRui Paulo };
644*271b33a6SRui Paulo 
645*271b33a6SRui Paulo static driver_t nfsmbsub_driver = {
646*271b33a6SRui Paulo 	"nfsmb",
647*271b33a6SRui Paulo 	nfsmbsub_methods,
648*271b33a6SRui Paulo 	sizeof(struct nfsmb_softc),
649*271b33a6SRui Paulo };
650*271b33a6SRui Paulo 
651*271b33a6SRui Paulo DRIVER_MODULE(nfsmb, pci, nfsmb_driver, nfsmb_devclass, 0, 0);
652*271b33a6SRui Paulo DRIVER_MODULE(nfsmb, nfsmb, nfsmbsub_driver, nfsmb_devclass, 0, 0);
653*271b33a6SRui Paulo DRIVER_MODULE(smbus, nfsmb, smbus_driver, smbus_devclass, 0, 0);
654*271b33a6SRui Paulo 
655*271b33a6SRui Paulo MODULE_DEPEND(nfsmb, pci, 1, 1, 1);
656*271b33a6SRui Paulo MODULE_DEPEND(nfsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
657*271b33a6SRui Paulo MODULE_VERSION(nfsmb, 1);
658