xref: /NextBSD/sys/dev/scd/scd_isa.c (revision 4bf303e5af1834cdd3092175eeca7676420229c4)
1 /*
2  */
3 
4 #include <sys/cdefs.h>
5 __FBSDID("$FreeBSD$");
6 
7 #include <sys/param.h>
8 #include <sys/systm.h>
9 #include <sys/kernel.h>
10 #include <sys/module.h>
11 #include <sys/conf.h>
12 #include <sys/fcntl.h>
13 #include <sys/bio.h>
14 #include <sys/cdio.h>
15 #include <sys/bus.h>
16 
17 #include <sys/mutex.h>
18 
19 #include <machine/bus.h>
20 #include <machine/resource.h>
21 #include <sys/rman.h>
22 
23 #include <isa/isavar.h>
24 
25 #include <dev/scd/scdreg.h>
26 #include <dev/scd/scdvar.h>
27 
28 static int	scd_isa_probe	(device_t);
29 static int	scd_isa_attach	(device_t);
30 static int	scd_isa_detach	(device_t);
31 
32 static int	scd_alloc_resources	(device_t);
33 static void	scd_release_resources	(device_t);
34 
35 static int
scd_isa_probe(device_t dev)36 scd_isa_probe (device_t dev)
37 {
38 	struct scd_softc *	sc;
39 	int			error;
40 
41 	/* No pnp support */
42 	if (isa_get_vendorid(dev))
43 		return (ENXIO);
44 
45 	/* IO port must be configured. */
46 	if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0)
47 		return (ENXIO);
48 
49 	sc = device_get_softc(dev);
50 	sc->dev = dev;
51 	sc->port_rid = 0;
52 	sc->port_type = SYS_RES_IOPORT;
53 	error = scd_alloc_resources(dev);
54 	if (error)
55 		goto fail;
56 
57 	error = scd_probe(sc);
58 	if (error) {
59 		device_printf(dev, "Probe failed.\n");
60 		goto fail;
61 	}
62 
63 	device_set_desc(dev, sc->data.name);
64 
65 fail:
66 	scd_release_resources(dev);
67 	return (error);
68 }
69 
70 static int
scd_isa_attach(device_t dev)71 scd_isa_attach (device_t dev)
72 {
73 	struct scd_softc *	sc;
74 	int			error;
75 
76 	sc = device_get_softc(dev);
77 	error = 0;
78 
79 	sc->dev = dev;
80 	sc->port_rid = 0;
81 	sc->port_type = SYS_RES_IOPORT;
82 	error = scd_alloc_resources(dev);
83 	if (error)
84 		goto fail;
85 
86 	error = scd_probe(sc);
87 	if (error) {
88 		device_printf(dev, "Re-Probe failed.\n");
89 		goto fail;
90 	}
91 
92 	error = scd_attach(sc);
93 	if (error) {
94 		device_printf(dev, "Attach failed.\n");
95 		goto fail;
96 	}
97 
98 	return (0);
99 fail:
100 	scd_release_resources(dev);
101 	return (error);
102 }
103 
104 static int
scd_isa_detach(device_t dev)105 scd_isa_detach (device_t dev)
106 {
107 	struct scd_softc *	sc;
108 	int			error;
109 
110 	sc = device_get_softc(dev);
111 	error = 0;
112 
113 	destroy_dev(sc->scd_dev_t);
114 
115 	scd_release_resources(dev);
116 
117 	return (error);
118 }
119 
120 static int
scd_alloc_resources(device_t dev)121 scd_alloc_resources (device_t dev)
122 {
123 	struct scd_softc *	sc;
124 	int			error;
125 
126 	sc = device_get_softc(dev);
127 	error = 0;
128 	mtx_init(&sc->mtx, "scd", NULL, MTX_DEF);
129 
130 	if (sc->port_type) {
131 		sc->port = bus_alloc_resource_any(dev, sc->port_type,
132 				&sc->port_rid, RF_ACTIVE);
133 		if (sc->port == NULL) {
134 			device_printf(dev, "Unable to allocate PORT resource.\n");
135 			error = ENOMEM;
136 			goto bad;
137 		}
138 	}
139 
140 bad:
141 	return (error);
142 }
143 
144 void
scd_release_resources(device_t dev)145 scd_release_resources (device_t dev)
146 {
147 	struct scd_softc *	sc;
148 
149 	sc = device_get_softc(dev);
150 
151 	if (sc->port)
152 		bus_release_resource(dev, sc->port_type, sc->port_rid, sc->port);
153 
154 	mtx_destroy(&sc->mtx);
155 
156 	return;
157 }
158 
159 static device_method_t scd_isa_methods[] = {
160 	DEVMETHOD(device_probe,         scd_isa_probe),
161 	DEVMETHOD(device_attach,        scd_isa_attach),
162 	DEVMETHOD(device_detach,        scd_isa_detach),
163 
164 	{ 0, 0 }
165 };
166 
167 static driver_t scd_isa_driver = {
168 	"scd",
169 	scd_isa_methods,
170 	sizeof(struct scd_softc)
171 };
172 
173 static devclass_t	scd_devclass;
174 
175 DRIVER_MODULE(scd, isa, scd_isa_driver, scd_devclass, NULL, 0);
176