Deleted Added
full compact
proto_core.c (265055) proto_core.c (284079)
1/*-
2 * Copyright (c) 2014 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *

--- 11 unchanged lines hidden (view full) ---

20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2014 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *

--- 11 unchanged lines hidden (view full) ---

20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/proto/proto_core.c 265055 2014-04-28 17:58:40Z marcel $");
28__FBSDID("$FreeBSD: head/sys/dev/proto/proto_core.c 284079 2015-06-06 16:09:25Z marcel $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/conf.h>
34#include <sys/cons.h>
35#include <sys/fcntl.h>
36#include <sys/interrupt.h>

--- 9 unchanged lines hidden (view full) ---

46#include <sys/uio.h>
47#include <machine/resource.h>
48#include <machine/stdarg.h>
49
50#include <dev/pci/pcivar.h>
51
52#include <dev/proto/proto.h>
53#include <dev/proto/proto_dev.h>
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/conf.h>
34#include <sys/cons.h>
35#include <sys/fcntl.h>
36#include <sys/interrupt.h>

--- 9 unchanged lines hidden (view full) ---

46#include <sys/uio.h>
47#include <machine/resource.h>
48#include <machine/stdarg.h>
49
50#include <dev/pci/pcivar.h>
51
52#include <dev/proto/proto.h>
53#include <dev/proto/proto_dev.h>
54#include <dev/proto/proto_busdma.h>
54
55CTASSERT(SYS_RES_IRQ != PROTO_RES_UNUSED &&
56 SYS_RES_MEMORY != PROTO_RES_UNUSED &&
57 SYS_RES_IOPORT != PROTO_RES_UNUSED);
58CTASSERT(SYS_RES_IRQ != PROTO_RES_PCICFG &&
59 SYS_RES_MEMORY != PROTO_RES_PCICFG &&
60 SYS_RES_IOPORT != PROTO_RES_PCICFG);
55
56CTASSERT(SYS_RES_IRQ != PROTO_RES_UNUSED &&
57 SYS_RES_MEMORY != PROTO_RES_UNUSED &&
58 SYS_RES_IOPORT != PROTO_RES_UNUSED);
59CTASSERT(SYS_RES_IRQ != PROTO_RES_PCICFG &&
60 SYS_RES_MEMORY != PROTO_RES_PCICFG &&
61 SYS_RES_IOPORT != PROTO_RES_PCICFG);
62CTASSERT(SYS_RES_IRQ != PROTO_RES_BUSDMA &&
63 SYS_RES_MEMORY != PROTO_RES_BUSDMA &&
64 SYS_RES_IOPORT != PROTO_RES_BUSDMA);
61
62devclass_t proto_devclass;
63char proto_driver_name[] = "proto";
64
65static d_open_t proto_open;
66static d_close_t proto_close;
67static d_read_t proto_read;
68static d_write_t proto_write;

--- 23 unchanged lines hidden (view full) ---

92 if (type == PROTO_RES_UNUSED)
93 return (EINVAL);
94 if (sc->sc_rescnt == PROTO_RES_MAX)
95 return (ENOSPC);
96
97 r = sc->sc_res + sc->sc_rescnt++;
98 r->r_type = type;
99 r->r_rid = rid;
65
66devclass_t proto_devclass;
67char proto_driver_name[] = "proto";
68
69static d_open_t proto_open;
70static d_close_t proto_close;
71static d_read_t proto_read;
72static d_write_t proto_write;

--- 23 unchanged lines hidden (view full) ---

96 if (type == PROTO_RES_UNUSED)
97 return (EINVAL);
98 if (sc->sc_rescnt == PROTO_RES_MAX)
99 return (ENOSPC);
100
101 r = sc->sc_res + sc->sc_rescnt++;
102 r->r_type = type;
103 r->r_rid = rid;
100 r->r_res = res;
104 r->r_d.res = res;
101 return (0);
102}
103
104#ifdef notyet
105static int
106proto_intr(void *arg)
107{
108 struct proto_softc *sc = arg;

--- 16 unchanged lines hidden (view full) ---

125 for (res = 0; res < sc->sc_rescnt; res++) {
126 r = sc->sc_res + res;
127 switch (r->r_type) {
128 case SYS_RES_IRQ:
129 /* XXX TODO */
130 break;
131 case SYS_RES_MEMORY:
132 case SYS_RES_IOPORT:
105 return (0);
106}
107
108#ifdef notyet
109static int
110proto_intr(void *arg)
111{
112 struct proto_softc *sc = arg;

--- 16 unchanged lines hidden (view full) ---

129 for (res = 0; res < sc->sc_rescnt; res++) {
130 r = sc->sc_res + res;
131 switch (r->r_type) {
132 case SYS_RES_IRQ:
133 /* XXX TODO */
134 break;
135 case SYS_RES_MEMORY:
136 case SYS_RES_IOPORT:
133 r->r_size = rman_get_size(r->r_res);
137 r->r_size = rman_get_size(r->r_d.res);
134 r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666,
135 "proto/%s/%02x.%s", device_get_desc(dev), r->r_rid,
136 (r->r_type == SYS_RES_IOPORT) ? "io" : "mem");
137 r->r_u.cdev->si_drv1 = sc;
138 r->r_u.cdev->si_drv2 = r;
139 break;
140 case PROTO_RES_PCICFG:
141 r->r_size = 4096;
142 r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666,
143 "proto/%s/pcicfg", device_get_desc(dev));
144 r->r_u.cdev->si_drv1 = sc;
145 r->r_u.cdev->si_drv2 = r;
146 break;
138 r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666,
139 "proto/%s/%02x.%s", device_get_desc(dev), r->r_rid,
140 (r->r_type == SYS_RES_IOPORT) ? "io" : "mem");
141 r->r_u.cdev->si_drv1 = sc;
142 r->r_u.cdev->si_drv2 = r;
143 break;
144 case PROTO_RES_PCICFG:
145 r->r_size = 4096;
146 r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666,
147 "proto/%s/pcicfg", device_get_desc(dev));
148 r->r_u.cdev->si_drv1 = sc;
149 r->r_u.cdev->si_drv2 = r;
150 break;
151 case PROTO_RES_BUSDMA:
152 r->r_d.busdma = proto_busdma_attach(sc);
153 r->r_size = 0; /* no read(2) nor write(2) */
154 r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666,
155 "proto/%s/busdma", device_get_desc(dev));
156 r->r_u.cdev->si_drv1 = sc;
157 r->r_u.cdev->si_drv2 = r;
158 break;
147 }
148 }
149 return (0);
150}
151
152int
153proto_detach(device_t dev)
154{
155 struct proto_softc *sc;
156 struct proto_res *r;
157 u_int res;
158
159 sc = device_get_softc(dev);
160
159 }
160 }
161 return (0);
162}
163
164int
165proto_detach(device_t dev)
166{
167 struct proto_softc *sc;
168 struct proto_res *r;
169 u_int res;
170
171 sc = device_get_softc(dev);
172
161 /* Don't detach if we have open device filess. */
173 /* Don't detach if we have open device files. */
162 for (res = 0; res < sc->sc_rescnt; res++) {
163 r = sc->sc_res + res;
164 if (r->r_opened)
165 return (EBUSY);
166 }
167
168 for (res = 0; res < sc->sc_rescnt; res++) {
169 r = sc->sc_res + res;
170 switch (r->r_type) {
171 case SYS_RES_IRQ:
172 /* XXX TODO */
174 for (res = 0; res < sc->sc_rescnt; res++) {
175 r = sc->sc_res + res;
176 if (r->r_opened)
177 return (EBUSY);
178 }
179
180 for (res = 0; res < sc->sc_rescnt; res++) {
181 r = sc->sc_res + res;
182 switch (r->r_type) {
183 case SYS_RES_IRQ:
184 /* XXX TODO */
185 bus_release_resource(dev, r->r_type, r->r_rid,
186 r->r_d.res);
173 break;
174 case SYS_RES_MEMORY:
175 case SYS_RES_IOPORT:
187 break;
188 case SYS_RES_MEMORY:
189 case SYS_RES_IOPORT:
190 bus_release_resource(dev, r->r_type, r->r_rid,
191 r->r_d.res);
192 destroy_dev(r->r_u.cdev);
193 break;
176 case PROTO_RES_PCICFG:
177 destroy_dev(r->r_u.cdev);
178 break;
194 case PROTO_RES_PCICFG:
195 destroy_dev(r->r_u.cdev);
196 break;
197 case PROTO_RES_BUSDMA:
198 proto_busdma_detach(sc, r->r_d.busdma);
199 destroy_dev(r->r_u.cdev);
200 break;
179 }
201 }
180 if (r->r_res != NULL) {
181 bus_release_resource(dev, r->r_type, r->r_rid,
182 r->r_res);
183 r->r_res = NULL;
184 }
185 r->r_type = PROTO_RES_UNUSED;
186 }
187 sc->sc_rescnt = 0;
188 return (0);
189}
190
191/*
192 * Device functions

--- 9 unchanged lines hidden (view full) ---

202 return (EBUSY);
203 return (0);
204}
205
206static int
207proto_close(struct cdev *cdev, int fflag, int devtype, struct thread *td)
208{
209 struct proto_res *r;
202 r->r_type = PROTO_RES_UNUSED;
203 }
204 sc->sc_rescnt = 0;
205 return (0);
206}
207
208/*
209 * Device functions

--- 9 unchanged lines hidden (view full) ---

219 return (EBUSY);
220 return (0);
221}
222
223static int
224proto_close(struct cdev *cdev, int fflag, int devtype, struct thread *td)
225{
226 struct proto_res *r;
227 struct proto_softc *sc;
210
228
229 sc = cdev->si_drv1;
211 r = cdev->si_drv2;
212 if (!atomic_cmpset_acq_ptr(&r->r_opened, (uintptr_t)td->td_proc, 0UL))
213 return (ENXIO);
230 r = cdev->si_drv2;
231 if (!atomic_cmpset_acq_ptr(&r->r_opened, (uintptr_t)td->td_proc, 0UL))
232 return (ENXIO);
233 if (r->r_type == PROTO_RES_BUSDMA)
234 proto_busdma_cleanup(sc, r->r_d.busdma);
214 return (0);
215}
216
217static int
218proto_read(struct cdev *cdev, struct uio *uio, int ioflag)
219{
220 union {
221 uint8_t x1[8];

--- 17 unchanged lines hidden (view full) ---

239 return (EIO);
240 ofs = uio->uio_offset;
241 if (ofs + width > r->r_size)
242 return (EIO);
243
244 switch (width) {
245 case 1:
246 buf.x1[0] = (r->r_type == PROTO_RES_PCICFG) ?
235 return (0);
236}
237
238static int
239proto_read(struct cdev *cdev, struct uio *uio, int ioflag)
240{
241 union {
242 uint8_t x1[8];

--- 17 unchanged lines hidden (view full) ---

260 return (EIO);
261 ofs = uio->uio_offset;
262 if (ofs + width > r->r_size)
263 return (EIO);
264
265 switch (width) {
266 case 1:
267 buf.x1[0] = (r->r_type == PROTO_RES_PCICFG) ?
247 pci_read_config(dev, ofs, 1) : bus_read_1(r->r_res, ofs);
268 pci_read_config(dev, ofs, 1) : bus_read_1(r->r_d.res, ofs);
248 break;
249 case 2:
250 buf.x2[0] = (r->r_type == PROTO_RES_PCICFG) ?
269 break;
270 case 2:
271 buf.x2[0] = (r->r_type == PROTO_RES_PCICFG) ?
251 pci_read_config(dev, ofs, 2) : bus_read_2(r->r_res, ofs);
272 pci_read_config(dev, ofs, 2) : bus_read_2(r->r_d.res, ofs);
252 break;
253 case 4:
254 buf.x4[0] = (r->r_type == PROTO_RES_PCICFG) ?
273 break;
274 case 4:
275 buf.x4[0] = (r->r_type == PROTO_RES_PCICFG) ?
255 pci_read_config(dev, ofs, 4) : bus_read_4(r->r_res, ofs);
276 pci_read_config(dev, ofs, 4) : bus_read_4(r->r_d.res, ofs);
256 break;
257#ifndef __i386__
258 case 8:
259 if (r->r_type == PROTO_RES_PCICFG)
260 return (EINVAL);
277 break;
278#ifndef __i386__
279 case 8:
280 if (r->r_type == PROTO_RES_PCICFG)
281 return (EINVAL);
261 buf.x8[0] = bus_read_8(r->r_res, ofs);
282 buf.x8[0] = bus_read_8(r->r_d.res, ofs);
262 break;
263#endif
264 default:
265 return (EIO);
266 }
267
268 error = uiomove(&buf, width, uio);
269 return (error);

--- 30 unchanged lines hidden (view full) ---

300 if (error)
301 return (error);
302
303 switch (width) {
304 case 1:
305 if (r->r_type == PROTO_RES_PCICFG)
306 pci_write_config(dev, ofs, buf.x1[0], 1);
307 else
283 break;
284#endif
285 default:
286 return (EIO);
287 }
288
289 error = uiomove(&buf, width, uio);
290 return (error);

--- 30 unchanged lines hidden (view full) ---

321 if (error)
322 return (error);
323
324 switch (width) {
325 case 1:
326 if (r->r_type == PROTO_RES_PCICFG)
327 pci_write_config(dev, ofs, buf.x1[0], 1);
328 else
308 bus_write_1(r->r_res, ofs, buf.x1[0]);
329 bus_write_1(r->r_d.res, ofs, buf.x1[0]);
309 break;
310 case 2:
311 if (r->r_type == PROTO_RES_PCICFG)
312 pci_write_config(dev, ofs, buf.x2[0], 2);
313 else
330 break;
331 case 2:
332 if (r->r_type == PROTO_RES_PCICFG)
333 pci_write_config(dev, ofs, buf.x2[0], 2);
334 else
314 bus_write_2(r->r_res, ofs, buf.x2[0]);
335 bus_write_2(r->r_d.res, ofs, buf.x2[0]);
315 break;
316 case 4:
317 if (r->r_type == PROTO_RES_PCICFG)
318 pci_write_config(dev, ofs, buf.x4[0], 4);
319 else
336 break;
337 case 4:
338 if (r->r_type == PROTO_RES_PCICFG)
339 pci_write_config(dev, ofs, buf.x4[0], 4);
340 else
320 bus_write_4(r->r_res, ofs, buf.x4[0]);
341 bus_write_4(r->r_d.res, ofs, buf.x4[0]);
321 break;
322#ifndef __i386__
323 case 8:
324 if (r->r_type == PROTO_RES_PCICFG)
325 return (EINVAL);
342 break;
343#ifndef __i386__
344 case 8:
345 if (r->r_type == PROTO_RES_PCICFG)
346 return (EINVAL);
326 bus_write_8(r->r_res, ofs, buf.x8[0]);
347 bus_write_8(r->r_d.res, ofs, buf.x8[0]);
327 break;
328#endif
329 default:
330 return (EIO);
331 }
332
333 return (0);
334}
335
336static int
337proto_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
338 struct thread *td)
339{
340 struct proto_ioc_region *region;
348 break;
349#endif
350 default:
351 return (EIO);
352 }
353
354 return (0);
355}
356
357static int
358proto_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
359 struct thread *td)
360{
361 struct proto_ioc_region *region;
362 struct proto_ioc_busdma *busdma;
341 struct proto_res *r;
363 struct proto_res *r;
364 struct proto_softc *sc;
342 int error;
343
365 int error;
366
367 sc = cdev->si_drv1;
344 r = cdev->si_drv2;
345
346 error = 0;
347 switch (cmd) {
348 case PROTO_IOC_REGION:
349 region = (struct proto_ioc_region *)data;
350 region->size = r->r_size;
351 if (r->r_type == PROTO_RES_PCICFG)
352 region->address = 0;
353 else
368 r = cdev->si_drv2;
369
370 error = 0;
371 switch (cmd) {
372 case PROTO_IOC_REGION:
373 region = (struct proto_ioc_region *)data;
374 region->size = r->r_size;
375 if (r->r_type == PROTO_RES_PCICFG)
376 region->address = 0;
377 else
354 region->address = rman_get_start(r->r_res);
378 region->address = rman_get_start(r->r_d.res);
355 break;
379 break;
380 case PROTO_IOC_BUSDMA:
381 busdma = (struct proto_ioc_busdma *)data;
382 error = proto_busdma_ioctl(sc, r->r_d.busdma, busdma);
383 break;
356 default:
357 error = ENOIOCTL;
358 break;
359 }
360 return (error);
361}
362
363static int

--- 7 unchanged lines hidden (view full) ---

371 if (r->r_type != SYS_RES_MEMORY)
372 return (ENXIO);
373 if (offset & PAGE_MASK)
374 return (EINVAL);
375 if (prot & PROT_EXEC)
376 return (EACCES);
377 if (offset >= r->r_size)
378 return (EINVAL);
384 default:
385 error = ENOIOCTL;
386 break;
387 }
388 return (error);
389}
390
391static int

--- 7 unchanged lines hidden (view full) ---

399 if (r->r_type != SYS_RES_MEMORY)
400 return (ENXIO);
401 if (offset & PAGE_MASK)
402 return (EINVAL);
403 if (prot & PROT_EXEC)
404 return (EACCES);
405 if (offset >= r->r_size)
406 return (EINVAL);
379 *paddr = rman_get_start(r->r_res) + offset;
407 *paddr = rman_get_start(r->r_d.res) + offset;
380#ifndef __sparc64__
381 *memattr = VM_MEMATTR_UNCACHEABLE;
382#endif
383 return (0);
384}
408#ifndef __sparc64__
409 *memattr = VM_MEMATTR_UNCACHEABLE;
410#endif
411 return (0);
412}