1 /* $NetBSD: btvmei.c,v 1.30 2014/03/29 19:28:24 christos Exp $ */
2 
3 /*
4  * Copyright (c) 1999
5  *	Matthias Drochner.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  */
30 
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: btvmei.c,v 1.30 2014/03/29 19:28:24 christos Exp $");
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/device.h>
38 #include <sys/proc.h>
39 #include <sys/malloc.h>
40 
41 #include <sys/bus.h>
42 #include <sys/extent.h>
43 
44 #include <dev/pci/pcireg.h>
45 #include <dev/pci/pcivar.h>
46 #include <dev/pci/pcidevs.h>
47 
48 #include <dev/vme/vmereg.h>
49 #include <dev/vme/vmevar.h>
50 
51 #include <dev/pci/btvmeireg.h>
52 #include <dev/pci/btvmeivar.h>
53 
54 static int b3_617_match(device_t, cfdata_t, void *);
55 static void b3_617_attach(device_t, device_t, void *);
56 #ifdef notyet
57 static int b3_617_detach(device_t);
58 #endif
59 void b3_617_slaveconfig(device_t, struct vme_attach_args *);
60 
61 static void b3_617_vmeintr(struct b3_617_softc *, unsigned char);
62 
63 /*
64  * mapping ressources, needed for deallocation
65  */
66 struct b3_617_vmeresc {
67 	bus_space_handle_t handle;
68 	bus_size_t len;
69 	int firstpage, maplen;
70 };
71 
72 CFATTACH_DECL_NEW(btvmei, sizeof(struct b3_617_softc),
73     b3_617_match, b3_617_attach, NULL, NULL);
74 
75 static int
b3_617_match(device_t parent,cfdata_t match,void * aux)76 b3_617_match(device_t parent, cfdata_t match, void *aux)
77 {
78 	struct pci_attach_args *pa = aux;
79 
80 	if ((PCI_VENDOR(pa->pa_id) != PCI_VENDOR_BIT3)
81 	    || (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_BIT3_PCIVME617))
82 		return (0);
83 	return (1);
84 }
85 
86 static void
b3_617_attach(device_t parent,device_t self,void * aux)87 b3_617_attach(device_t parent, device_t self, void *aux)
88 {
89 	struct b3_617_softc *sc = device_private(self);
90 	struct pci_attach_args *pa = aux;
91 	pci_chipset_tag_t pc = pa->pa_pc;
92 
93 	pci_intr_handle_t ih;
94 	const char *intrstr;
95 	struct vmebus_attach_args vaa;
96 	char intrbuf[PCI_INTRSTR_LEN];
97 
98 	sc->sc_dev = self;
99 	sc->sc_pc = pc;
100 	sc->sc_dmat = pa->pa_dmat;
101 
102 	pci_aprint_devinfo_fancy(pa, "VME bus adapter", "BIT3 PCI-VME 617", 1);
103 
104 	/*
105 	 * Map CSR and mapping table spaces.
106 	 * Don't map VME window; parts are mapped as needed to
107 	 * save kernel virtual memory space
108 	 */
109 	if (pci_mapreg_map(pa, 0x14,
110 			   PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
111 			   0, &sc->csrt, &sc->csrh, NULL, NULL) &&
112 	    pci_mapreg_map(pa, 0x10,
113 			   PCI_MAPREG_TYPE_IO,
114 			   0, &sc->csrt, &sc->csrh, NULL, NULL)) {
115 		aprint_error_dev(self, "can't map CSR space\n");
116 		return;
117 	}
118 
119 	if (pci_mapreg_map(pa, 0x18,
120 			   PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
121 			   0, &sc->mapt, &sc->maph, NULL, NULL)) {
122 		aprint_error_dev(self, "can't map map space\n");
123 		return;
124 	}
125 
126 	if (pci_mapreg_info(pc, pa->pa_tag, 0x1c,
127 			    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
128 			    &sc->vmepbase, 0, 0)) {
129 		aprint_error_dev(self, "can't get VME range\n");
130 		return;
131 	}
132 	sc->sc_vmet = pa->pa_memt; /* XXX needed for VME mappings */
133 
134 	/* Map and establish the interrupt. */
135 	if (pci_intr_map(pa, &ih)) {
136 		aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n");
137 		return;
138 	}
139 	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
140 	/*
141 	 * Use a low interrupt level (the lowest?).
142 	 * We will raise before calling a subdevice's handler.
143 	 */
144 	sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, b3_617_intr, sc);
145 	if (sc->sc_ih == NULL) {
146 		aprint_error_dev(sc->sc_dev, "couldn't establish interrupt");
147 		if (intrstr != NULL)
148 			aprint_error(" at %s", intrstr);
149 		aprint_error("\n");
150 		return;
151 	}
152 	aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);
153 
154 	if (b3_617_init(sc))
155 		return;
156 
157 	/*
158 	 * set up all the tags for use by VME devices
159 	 */
160 	sc->sc_vct.cookie = self;
161 	sc->sc_vct.vct_probe = b3_617_vme_probe;
162 	sc->sc_vct.vct_map = b3_617_map_vme;
163 	sc->sc_vct.vct_unmap = b3_617_unmap_vme;
164 	sc->sc_vct.vct_int_map = b3_617_map_vmeint;
165 	sc->sc_vct.vct_int_establish = b3_617_establish_vmeint;
166 	sc->sc_vct.vct_int_disestablish = b3_617_disestablish_vmeint;
167 	sc->sc_vct.vct_dmamap_create = b3_617_dmamap_create;
168 	sc->sc_vct.vct_dmamap_destroy = b3_617_dmamap_destroy;
169 	sc->sc_vct.vct_dmamem_alloc = b3_617_dmamem_alloc;
170 	sc->sc_vct.vct_dmamem_free = b3_617_dmamem_free;
171 
172 	vaa.va_vct = &(sc->sc_vct);
173 	vaa.va_bdt = pa->pa_dmat;
174 	vaa.va_slaveconfig = b3_617_slaveconfig;
175 
176 	sc->csrwindow.offset = -1;
177 	sc->dmawindow24.offset = -1;
178 	sc->dmawindow32.offset = -1;
179 	config_found(self, &vaa, 0);
180 }
181 
182 #ifdef notyet
183 static int
b3_617_detach(device_t dev)184 b3_617_detach(device_t dev)
185 {
186 	struct b3_617_softc *sc = device_private(dev);
187 
188 	b3_617_halt(sc);
189 
190 	if (sc->sc_ih)
191 		pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
192 
193 	bus_space_unmap(sc->sc_bc, sc->csrbase, 32);
194 	bus_space_unmap(sc->sc_bc, sc->mapbase, 64*1024);
195 
196 	return(0);
197 }
198 #endif
199 
200 void
b3_617_slaveconfig(device_t dev,struct vme_attach_args * va)201 b3_617_slaveconfig(device_t dev, struct vme_attach_args *va)
202 {
203 	struct b3_617_softc *sc = device_private(dev);
204 	vme_chipset_tag_t vmect;
205 	int i, res;
206 	const char *name = 0; /* XXX gcc! */
207 
208 	vmect = &sc->sc_vct;
209 	if (!va)
210 		goto freeit;
211 
212 #ifdef DIAGNOSTIC
213 	if (vmect != va->va_vct)
214 		panic("pcivme_slaveconfig: chipset tag?");
215 #endif
216 
217 	for (i = 0; i < va->numcfranges; i++) {
218 		res = vme_space_alloc(vmect, va->r[i].offset,
219 				      va->r[i].size, va->r[i].am);
220 		if (res)
221 			panic("%s: can't alloc slave window %x/%x/%x",
222 			       device_xname(dev), va->r[i].offset,
223 			       va->r[i].size, va->r[i].am);
224 
225 		switch (va->r[i].am & VME_AM_ADRSIZEMASK) {
226 			/* structure assignments! */
227 		    case VME_AM_A16:
228 			sc->csrwindow = va->r[i];
229 			name = "VME CSR";
230 			break;
231 		    case VME_AM_A24:
232 			sc->dmawindow24 = va->r[i];
233 			name = "A24 DMA";
234 			break;
235 		    case VME_AM_A32:
236 			sc->dmawindow32 = va->r[i];
237 			name = "A32 DMA";
238 			break;
239 		}
240 		printf("%s: %s window: %x-%x\n", device_xname(dev),
241 		       name, va->r[i].offset,
242 		       va->r[i].offset + va->r[i].size - 1);
243 	}
244 	return;
245 
246 freeit:
247 	if (sc->csrwindow.offset != -1)
248 		vme_space_free(vmect, sc->csrwindow.offset,
249 			       sc->csrwindow.size, sc->csrwindow.am);
250 	if (sc->dmawindow32.offset != -1)
251 		vme_space_free(vmect, sc->dmawindow32.offset,
252 			       sc->dmawindow32.size, sc->dmawindow32.am);
253 	if (sc->dmawindow24.offset != -1)
254 		vme_space_free(vmect, sc->dmawindow24.offset,
255 			       sc->dmawindow24.size, sc->dmawindow24.am);
256 }
257 
258 int
b3_617_reset(struct b3_617_softc * sc)259 b3_617_reset(struct b3_617_softc *sc)
260 {
261 	unsigned char status;
262 
263 	/* reset sequence, ch 5.2 */
264 	status = read_csr_byte(sc, LOC_STATUS);
265 	if (status & LSR_NO_CONNECT) {
266 		printf("%s: not connected\n", device_xname(sc->sc_dev));
267 		return (-1);
268 	}
269 	status = read_csr_byte(sc, REM_STATUS); /* discard */
270 	write_csr_byte(sc, LOC_CMD1, LC1_CLR_ERROR);
271 	status = read_csr_byte(sc, LOC_STATUS);
272 	if (status & LSR_CERROR_MASK) {
273 		char sbuf[sizeof(BIT3_LSR_BITS) + 64];
274 
275 		snprintb(sbuf, sizeof(sbuf), BIT3_LSR_BITS, status);
276 		printf("%s: interface error, lsr=%s\n", device_xname(sc->sc_dev),
277 		       sbuf);
278 		return (-1);
279 	}
280 	return (0);
281 }
282 
283 int
b3_617_init(struct b3_617_softc * sc)284 b3_617_init(struct b3_617_softc *sc)
285 {
286 	unsigned int i;
287 
288 	if (b3_617_reset(sc))
289 		return (-1);
290 
291 	/* all maps invalid */
292 	for (i = MR_PCI_VME; i < MR_PCI_VME + MR_PCI_VME_SIZE; i += 4)
293 		write_mapmem(sc, i, MR_RAM_INVALID);
294 	for (i = MR_VME_PCI; i < MR_VME_PCI + MR_VME_PCI_SIZE; i += 4)
295 		write_mapmem(sc, i, MR_RAM_INVALID);
296 	for (i = MR_DMA_PCI; i < MR_DMA_PCI + MR_DMA_PCI_SIZE; i += 4)
297 		write_mapmem(sc, i, MR_RAM_INVALID);
298 
299 	/*
300 	 * set up scatter page allocation control
301 	 */
302 	sc->vmeext = extent_create("pcivme", MR_PCI_VME,
303 				   MR_PCI_VME + MR_PCI_VME_SIZE - 1,
304 				   sc->vmemap, sizeof(sc->vmemap),
305 				   EX_NOCOALESCE);
306 #if 0
307 	sc->pciext = extent_create("vmepci", MR_VME_PCI,
308 				   MR_VME_PCI + MR_VME_PCI_SIZE - 1,
309 				   sc->pcimap, sizeof(sc->pcimap),
310 				   EX_NOCOALESCE);
311 	sc->dmaext = extent_create("dmapci", MR_DMA_PCI,
312 				   MR_DMA_PCI + MR_DMA_PCI_SIZE - 1,
313 				   sc->dmamap, sizeof(sc->dmamap),
314 				   EX_NOCOALESCE);
315 #endif
316 
317 	/*
318 	 * init int handler queue,
319 	 * enable interrupts if PCI interrupt available
320 	 */
321 	TAILQ_INIT(&(sc->intrhdls));
322 	sc->strayintrs = 0;
323 
324 	if (sc->sc_ih)
325 		write_csr_byte(sc, LOC_INT_CTRL, LIC_INT_ENABLE);
326 	/* no error ints */
327 	write_csr_byte(sc, REM_CMD2, 0); /* enables VME IRQ */
328 
329 	return (0);
330 }
331 
332 #ifdef notyet /* for detach */
333 void
b3_617_halt(struct b3_617_softc * sc)334 b3_617_halt(struct b3_617_softc *sc)
335 {
336 	/*
337 	 * because detach code checks for existence of children,
338 	 * all ressources (mappings, VME IRQs, DMA requests)
339 	 * should be deallocated at this point
340 	 */
341 
342 	/* disable IRQ */
343 	write_csr_byte(sc, LOC_INT_CTRL, 0);
344 }
345 #endif
346 
347 static void
b3_617_vmeintr(struct b3_617_softc * sc,unsigned char lstat)348 b3_617_vmeintr(struct b3_617_softc *sc, unsigned char lstat)
349 {
350 	int level;
351 
352 	for (level = 7; level >= 1; level--) {
353 		unsigned char vector;
354 		struct b3_617_vmeintrhand *ih;
355 		int found;
356 
357 		if (!(lstat & (1 << level)))
358 			continue;
359 
360 		write_csr_byte(sc, REM_CMD1, level);
361 		vector = read_csr_byte(sc, REM_IACK);
362 
363 		found = 0;
364 
365 		for (ih = sc->intrhdls.tqh_first; ih;
366 		     ih = ih->ih_next.tqe_next) {
367 			if ((ih->ih_level == level) &&
368 			    ((ih->ih_vector == -1) ||
369 			     (ih->ih_vector == vector))) {
370 				int s, res;
371 				/*
372 				 * We should raise the interrupt level
373 				 * to ih->ih_prior here. How to do this
374 				 * machine-independently?
375 				 * To be safe, raise to the maximum.
376 				 */
377 				s = splhigh();
378 				found |= (res = (*(ih->ih_fun))(ih->ih_arg));
379 				splx(s);
380 				if (res)
381 					ih->ih_count++;
382 				if (res == 1)
383 					break;
384 			}
385 		}
386 		if (!found)
387 			sc->strayintrs++;
388 	}
389 }
390 
391 #define sc ((struct b3_617_softc*)vsc)
392 
393 int
b3_617_map_vme(void * vsc,vme_addr_t vmeaddr,vme_size_t len,vme_am_t am,vme_datasize_t datasizes,vme_swap_t swap,bus_space_tag_t * tag,bus_space_handle_t * handle,vme_mapresc_t * resc)394 b3_617_map_vme(void *vsc, vme_addr_t vmeaddr, vme_size_t len, vme_am_t am, vme_datasize_t datasizes, vme_swap_t swap, bus_space_tag_t *tag, bus_space_handle_t *handle, vme_mapresc_t *resc)
395 {
396 	vme_addr_t vmebase, vmeend, va;
397 	unsigned long maplen, first, i;
398 	u_int32_t mapreg;
399 	bus_addr_t pcibase;
400 	int res;
401 	struct b3_617_vmeresc *r;
402 
403 	/* first mapped address */
404 	vmebase = vmeaddr & ~(VME_PAGESIZE - 1);
405 	/* base of last mapped page */
406 	vmeend = (vmeaddr + len - 1) & ~(VME_PAGESIZE - 1);
407 	/* bytes in scatter table required */
408 	maplen = ((vmeend - vmebase) / VME_PAGESIZE + 1) * 4;
409 
410 	if (extent_alloc(sc->vmeext, maplen, 4, 0, EX_FAST, &first))
411 		return (ENOMEM);
412 
413 	/*
414 	 * set up adapter mapping registers
415 	 */
416 	mapreg = (am << MR_AMOD_SHIFT) | MR_FC_RRAM | swap;
417 
418 	for (i = first, va = vmebase;
419 	     i < first + maplen;
420 	     i += 4, va += VME_PAGESIZE) {
421 		write_mapmem(sc, i, mapreg | va);
422 #ifdef BIT3DEBUG
423 		printf("mapreg@%lx=%x\n", i, read_mapmem(sc, i));
424 #endif
425 	}
426 
427 #ifdef DIAGNOSTIC
428 	if (va != vmeend + VME_PAGESIZE)
429 		panic("b3_617_map_pci_vme: botch");
430 #endif
431 	/*
432 	 * map needed range in PCI space
433 	 */
434 	pcibase = sc->vmepbase + (first - MR_PCI_VME) / 4 * VME_PAGESIZE
435 	    + (vmeaddr & (VME_PAGESIZE - 1));
436 
437 	if ((res = bus_space_map(sc->sc_vmet, pcibase, len, 0, handle))) {
438 		for (i = first; i < first + maplen; i += 4)
439 			write_mapmem(sc, i, MR_RAM_INVALID);
440 		extent_free(sc->vmeext, first, maplen, 0);
441 		return (res);
442 	}
443 
444 	*tag = sc->sc_vmet;
445 
446 	/*
447 	 * save all data needed for later unmapping
448 	 */
449 	r = malloc(sizeof(*r), M_DEVBUF, M_NOWAIT); /* XXX check! */
450 	r->handle = *handle;
451 	r->len = len;
452 	r->firstpage = first;
453 	r->maplen = maplen;
454 	*resc = r;
455 	return (0);
456 }
457 
458 void
b3_617_unmap_vme(void * vsc,vme_mapresc_t resc)459 b3_617_unmap_vme(void *vsc, vme_mapresc_t resc)
460 {
461 	unsigned long i;
462 	struct b3_617_vmeresc *r = resc;
463 
464 	/* unmap PCI window */
465 	bus_space_unmap(sc->sc_vmet, r->handle, r->len);
466 
467 	for (i = r->firstpage; i < r->firstpage + r->maplen; i += 4)
468 		write_mapmem(sc, i, MR_RAM_INVALID);
469 
470 	extent_free(sc->vmeext, r->firstpage, r->maplen, 0);
471 
472 	free(r, M_DEVBUF);
473 }
474 
475 int
b3_617_vme_probe(void * vsc,vme_addr_t addr,vme_size_t len,vme_am_t am,vme_datasize_t datasize,int (* callback)(void *,bus_space_tag_t,bus_space_handle_t),void * cbarg)476 b3_617_vme_probe(void *vsc, vme_addr_t addr, vme_size_t len, vme_am_t am, vme_datasize_t datasize, int (*callback)(void *, bus_space_tag_t, bus_space_handle_t), void *cbarg)
477 {
478 	bus_space_tag_t tag;
479 	bus_space_handle_t handle;
480 	vme_mapresc_t resc;
481 	int res, i;
482 	volatile u_int32_t dummy;
483 	int status;
484 
485 	res = b3_617_map_vme(vsc, addr, len, am, 0, 0,
486 			     &tag, &handle, &resc);
487 	if (res)
488 		return (res);
489 
490 	if (read_csr_byte(sc, LOC_STATUS) & LSR_ERROR_MASK) {
491 		printf("b3_617_vme_badaddr: error bit not clean - resetting\n");
492 		write_csr_byte(sc, LOC_CMD1, LC1_CLR_ERROR);
493 	}
494 
495 	if (callback)
496 		res = (*callback)(cbarg, tag, handle);
497 	else {
498 		for (i = 0; i < len;) {
499 			switch (datasize) {
500 			    case VME_D8:
501 				dummy = bus_space_read_1(tag, handle, i);
502 				i++;
503 				break;
504 			    case VME_D16:
505 				dummy = bus_space_read_2(tag, handle, i);
506 				i += 2;
507 				break;
508 			    case VME_D32:
509 				dummy = bus_space_read_4(tag, handle, i);
510 				i += 4;
511 				break;
512 			    default:
513 				panic("b3_617_vme_probe: invalid datasize %x",
514 				      datasize);
515 			}
516 		}
517 	}
518 
519 	if ((status = read_csr_byte(sc, LOC_STATUS)) & LSR_ERROR_MASK) {
520 #ifdef BIT3DEBUG
521 		printf("b3_617_vme_badaddr: caught error %x\n", status);
522 #endif
523 		write_csr_byte(sc, LOC_CMD1, LC1_CLR_ERROR);
524 		res = EIO;
525 	}
526 
527 	b3_617_unmap_vme(vsc, resc);
528 	return (res);
529 }
530 
531 int
b3_617_map_vmeint(void * vsc,int level,int vector,vme_intr_handle_t * handlep)532 b3_617_map_vmeint(void *vsc, int level, int vector, vme_intr_handle_t *handlep)
533 {
534 	if (!sc->sc_ih) {
535 		printf("%s: b3_617_map_vmeint: no IRQ\n",
536 		       device_xname(sc->sc_dev));
537 		return (ENXIO);
538 	}
539 	/*
540 	 * We should check whether the interface can pass this interrupt
541 	 * level at all, but we don't know much about the jumper setting.
542 	 */
543 	*handlep = (void *)(long)((level << 8) | vector); /* XXX */
544 	return (0);
545 }
546 
547 void *
b3_617_establish_vmeint(void * vsc,vme_intr_handle_t handle,int prior,int (* func)(void *),void * arg)548 b3_617_establish_vmeint(void *vsc, vme_intr_handle_t handle, int prior, int (*func)(void *), void *arg)
549 {
550 	struct b3_617_vmeintrhand *ih;
551 	long lv;
552 	int s;
553 
554 	/* no point in sleeping unless someone can free memory. */
555 	ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
556 	if (ih == NULL)
557 		panic("b3_617_map_vmeint: can't malloc handler info");
558 
559 	lv = (long)handle; /* XXX */
560 
561 	ih->ih_fun = func;
562 	ih->ih_arg = arg;
563 	ih->ih_level = lv >> 8;
564 	ih->ih_vector = lv & 0xff;
565 	ih->ih_prior = prior;
566 	ih->ih_count = 0;
567 
568 	s = splhigh();
569 	TAILQ_INSERT_TAIL(&(sc->intrhdls), ih, ih_next);
570 	splx(s);
571 
572 	return (ih);
573 }
574 
575 void
b3_617_disestablish_vmeint(void * vsc,void * cookie)576 b3_617_disestablish_vmeint(void *vsc, void *cookie)
577 {
578 	struct b3_617_vmeintrhand *ih = cookie;
579 	int s;
580 
581 	if (!ih) {
582 		printf("b3_617_unmap_vmeint: NULL arg\n");
583 		return;
584 	}
585 
586 	s = splhigh();
587 	TAILQ_REMOVE(&(sc->intrhdls), ih, ih_next);
588 	splx(s);
589 
590 	free(ih, M_DEVBUF);
591 }
592 
593 int
b3_617_intr(void * vsc)594 b3_617_intr(void *vsc)
595 {
596 	int handled = 0;
597 
598 	/* follows ch. 5.5.5 (reordered for speed) */
599 	while (read_csr_byte(sc, LOC_INT_CTRL) & LIC_INT_PENDING) {
600 		unsigned char lstat;
601 
602 		handled = 1;
603 
604 		/* no error interrupts! */
605 
606 		lstat = read_csr_byte(sc, LDMA_CMD);
607 		if ((lstat & LDC_DMA_DONE) && (lstat & LDC_DMA_INT_ENABLE)) {
608 			/* DMA done indicator flag */
609 			write_csr_byte(sc, LDMA_CMD, lstat & (~LDC_DMA_DONE));
610 #if 0
611 			b3_617_cntlrdma_done(sc);
612 #endif
613 			continue;
614 		}
615 
616 		lstat = read_csr_byte(sc, LOC_INT_STATUS);
617 		if (lstat & LIS_CINT_MASK) {
618 			/* VME backplane interrupt, ch. 5.5.3 */
619 			b3_617_vmeintr(sc, lstat);
620 		}
621 
622 		/* for now, ignore "mailbox interrupts" */
623 
624 		lstat = read_csr_byte(sc, LOC_STATUS);
625 		if (lstat & LSR_PR_STATUS) {
626 			/* PR interrupt received from REMOTE  */
627 			write_csr_byte(sc, LOC_CMD1, LC1_CLR_PR_INT);
628 			continue;
629 		}
630 
631 		lstat = read_csr_byte(sc, REM_STATUS);
632 		if (lstat & RSR_PT_STATUS) {
633 			/* PT interrupt is set */
634 			write_csr_byte(sc, REM_CMD1, RC1_CLR_PT_INT);
635 			continue;
636 		}
637 	}
638 	return (handled);
639 }
640 
641 int
b3_617_dmamap_create(vsc,len,am,datasize,swap,nsegs,segsz,bound,flags,mapp)642 b3_617_dmamap_create(vsc, len, am, datasize, swap,
643 		   nsegs, segsz, bound,
644 		   flags, mapp)
645 	void *vsc;
646 	vme_size_t len;
647 	vme_am_t am;
648 	vme_datasize_t datasize;
649 	vme_swap_t swap;
650 	int nsegs;
651 	vme_size_t segsz;
652 	vme_addr_t bound;
653 	int flags;
654 	bus_dmamap_t *mapp;
655 {
656 	return (EINVAL);
657 }
658 
659 void
b3_617_dmamap_destroy(void * vsc,bus_dmamap_t map)660 b3_617_dmamap_destroy(void *vsc, bus_dmamap_t map)
661 {
662 }
663 
664 int
b3_617_dmamem_alloc(vsc,len,am,datasizes,swap,segs,nsegs,rsegs,flags)665 b3_617_dmamem_alloc(vsc, len, am, datasizes, swap,
666 		    segs, nsegs, rsegs, flags)
667 	void *vsc;
668 	vme_size_t len;
669 	vme_am_t am;
670 	vme_datasize_t datasizes;
671 	vme_swap_t swap;
672 	bus_dma_segment_t *segs;
673 	int nsegs;
674 	int *rsegs;
675 	int flags;
676 {
677 	return (EINVAL);
678 }
679 
680 void
b3_617_dmamem_free(void * vsc,bus_dma_segment_t * segs,int nsegs)681 b3_617_dmamem_free(void *vsc, bus_dma_segment_t *segs, int nsegs)
682 {
683 }
684 
685 #undef sc
686