Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / acorn32 / podulebus / ptsc.c
blob3a06f03decc8f9b7ad74ef51ec92b6b4cbc79f31
1 /* $NetBSD: ptsc.c,v 1.15 2009/03/14 15:35:59 dsl Exp $ */
3 /*
4 * Copyright (c) 1982, 1990 The Regents of the University of California.
5 * All rights reserved.
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. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
31 * @(#)ptsc.c
35 * Copyright (c) 1995 Scott Stevens
36 * Copyright (c) 1995 Daniel Widenfalk
37 * Copyright (c) 1994 Christian E. Hopps
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
41 * are met:
42 * 1. Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer.
44 * 2. Redistributions in binary form must reproduce the above copyright
45 * notice, this list of conditions and the following disclaimer in the
46 * documentation and/or other materials provided with the distribution.
47 * 3. All advertising materials mentioning features or use of this software
48 * must display the following acknowledgement:
49 * This product includes software developed by the University of
50 * California, Berkeley and its contributors.
51 * 4. Neither the name of the University nor the names of its contributors
52 * may be used to endorse or promote products derived from this software
53 * without specific prior written permission.
55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * SUCH DAMAGE.
67 * @(#)ptsc.c
71 * Power-tec SCSI-2 driver uses SFAS216 generic driver
73 * Thanks to Alsystems for loaning a development card and providing
74 * programming information.
77 #include <sys/cdefs.h>
78 __KERNEL_RCSID(0, "$NetBSD: ptsc.c,v 1.15 2009/03/14 15:35:59 dsl Exp $");
80 #include <sys/param.h>
81 #include <sys/systm.h>
82 #include <sys/kernel.h>
83 #include <sys/device.h>
85 #include <uvm/uvm_extern.h>
87 #include <dev/scsipi/scsi_all.h>
88 #include <dev/scsipi/scsipi_all.h>
89 #include <dev/scsipi/scsiconf.h>
90 #include <machine/io.h>
91 #include <machine/intr.h>
92 #include <machine/bootconfig.h>
93 #include <acorn32/podulebus/podulebus.h>
94 #include <acorn32/podulebus/sfasreg.h>
95 #include <acorn32/podulebus/sfasvar.h>
96 #include <acorn32/podulebus/ptscreg.h>
97 #include <acorn32/podulebus/ptscvar.h>
98 #include <dev/podulebus/podules.h>
99 #include <dev/podulebus/powerromreg.h>
101 int ptscmatch(struct device *, struct cfdata *, void *);
102 void ptscattach(struct device *, struct device *, void *);
104 CFATTACH_DECL(ptsc, sizeof(struct ptsc_softc),
105 ptscmatch, ptscattach, NULL, NULL);
107 int ptsc_intr(void *);
108 int ptsc_setup_dma(void *, void *, int, int);
109 int ptsc_build_dma_chain(void *, void *, void *, int);
110 int ptsc_need_bump(void *, void *, int);
111 void ptsc_led(void *, int);
113 void ptsc_set_dma_adr(struct sfas_softc *, void *);
114 void ptsc_set_dma_tc(struct sfas_softc *, unsigned int);
115 void ptsc_set_dma_mode(struct sfas_softc *, int);
118 * if we are a Power-tec SCSI-2 card
121 ptscmatch(struct device *pdp, struct cfdata *cf, void *auxp)
123 struct podule_attach_args *pa = (struct podule_attach_args *)auxp;
125 /* Look for the card */
128 * All Power-tec cards effectively have PowerROMS. Note,
129 * though, that here, if we fail to initialise the loader, we
130 * assume this _is_ the right kind of card.
132 if (pa->pa_product == PODULE_ALSYSTEMS_SCSI &&
133 (podulebus_initloader(pa) != 0 ||
134 podloader_callloader(pa, 0, 0) == PRID_POWERTEC))
135 return 1;
137 return 0;
140 void
141 ptscattach(struct device *pdp, struct device *dp, void *auxp)
143 struct ptsc_softc *sc = (struct ptsc_softc *)dp;
144 struct podule_attach_args *pa;
145 ptsc_regmap_p rp = &sc->sc_regmap;
146 vu_char *fas;
148 pa = (struct podule_attach_args *)auxp;
150 if (pa->pa_podule_number == -1)
151 panic("Podule has disappeared !");
153 sc->sc_specific.sc_podule_number = pa->pa_podule_number;
154 sc->sc_specific.sc_podule = pa->pa_podule;
155 sc->sc_specific.sc_iobase =
156 (vu_char *)sc->sc_specific.sc_podule->fast_base;
158 rp->chipreset = &sc->sc_specific.sc_iobase[PTSC_CONTROL_CHIPRESET];
159 rp->inten = &sc->sc_specific.sc_iobase[PTSC_CONTROL_INTEN];
160 rp->status = &sc->sc_specific.sc_iobase[PTSC_STATUS];
161 rp->term = &sc->sc_specific.sc_iobase[PTSC_CONTROL_TERM];
162 rp->led = &sc->sc_specific.sc_iobase[PTSC_CONTROL_LED];
163 fas = &sc->sc_specific.sc_iobase[PTSC_FASOFFSET_BASE];
165 rp->FAS216.sfas_tc_low = &fas[PTSC_FASOFFSET_TCL];
166 rp->FAS216.sfas_tc_mid = &fas[PTSC_FASOFFSET_TCM];
167 rp->FAS216.sfas_fifo = &fas[PTSC_FASOFFSET_FIFO];
168 rp->FAS216.sfas_command = &fas[PTSC_FASOFFSET_COMMAND];
169 rp->FAS216.sfas_dest_id = &fas[PTSC_FASOFFSET_DESTID];
170 rp->FAS216.sfas_timeout = &fas[PTSC_FASOFFSET_TIMEOUT];
171 rp->FAS216.sfas_syncper = &fas[PTSC_FASOFFSET_PERIOD];
172 rp->FAS216.sfas_syncoff = &fas[PTSC_FASOFFSET_OFFSET];
173 rp->FAS216.sfas_config1 = &fas[PTSC_FASOFFSET_CONFIG1];
174 rp->FAS216.sfas_clkconv = &fas[PTSC_FASOFFSET_CLOCKCONV];
175 rp->FAS216.sfas_test = &fas[PTSC_FASOFFSET_TEST];
176 rp->FAS216.sfas_config2 = &fas[PTSC_FASOFFSET_CONFIG2];
177 rp->FAS216.sfas_config3 = &fas[PTSC_FASOFFSET_CONFIG3];
178 rp->FAS216.sfas_tc_high = &fas[PTSC_FASOFFSET_TCH];
179 rp->FAS216.sfas_fifo_bot = &fas[PTSC_FASOFFSET_FIFOBOTTOM];
181 sc->sc_softc.sc_fas = (sfas_regmap_p)rp;
182 sc->sc_softc.sc_spec = &sc->sc_specific;
184 sc->sc_softc.sc_led = ptsc_led;
186 sc->sc_softc.sc_setup_dma = ptsc_setup_dma;
187 sc->sc_softc.sc_build_dma_chain = ptsc_build_dma_chain;
188 sc->sc_softc.sc_need_bump = ptsc_need_bump;
190 sc->sc_softc.sc_clock_freq = 40; /* Power-Tec runs at 8MHz */
191 sc->sc_softc.sc_timeout = 250; /* Set default timeout to 250ms */
192 sc->sc_softc.sc_config_flags = SFAS_NO_DMA /*| SFAS_NF_DEBUG*/;
193 sc->sc_softc.sc_host_id = 7; /* Should check the jumpers */
195 sc->sc_softc.sc_bump_sz = PAGE_SIZE;
196 sc->sc_softc.sc_bump_pa = 0x0;
198 sfasinitialize((struct sfas_softc *)sc);
200 sc->sc_softc.sc_adapter.adapt_dev = &sc->sc_softc.sc_dev;
201 sc->sc_softc.sc_adapter.adapt_nchannels = 1;
202 sc->sc_softc.sc_adapter.adapt_openings = 7;
203 sc->sc_softc.sc_adapter.adapt_max_periph = 1;
204 sc->sc_softc.sc_adapter.adapt_ioctl = NULL;
205 sc->sc_softc.sc_adapter.adapt_minphys = sfas_minphys;
206 sc->sc_softc.sc_adapter.adapt_request = sfas_scsi_request;
208 sc->sc_softc.sc_channel.chan_adapter = &sc->sc_softc.sc_adapter;
209 sc->sc_softc.sc_channel.chan_bustype = &scsi_bustype;
210 sc->sc_softc.sc_channel.chan_channel = 0;
211 sc->sc_softc.sc_channel.chan_ntargets = 8;
212 sc->sc_softc.sc_channel.chan_nluns = 8;
213 sc->sc_softc.sc_channel.chan_id = sc->sc_softc.sc_host_id;
215 /* Provide an override for the host id */
216 (void)get_bootconf_option(boot_args, "ptsc.hostid",
217 BOOTOPT_TYPE_INT, &sc->sc_softc.sc_channel.chan_id);
219 printf(": host=%d", sc->sc_softc.sc_channel.chan_id);
221 /* initialise the card */
222 /* *rp->term = 0;*/
223 *rp->inten = (PTSC_POLL?0:1);
224 *rp->led = 0;
226 #if PTSC_POLL == 0
227 evcnt_attach_dynamic(&sc->sc_softc.sc_intrcnt, EVCNT_TYPE_INTR, NULL,
228 device_xname(dp), "intr");
229 sc->sc_softc.sc_ih = podulebus_irq_establish(pa->pa_ih, IPL_BIO,
230 ptsc_intr, &sc->sc_softc, &sc->sc_softc.sc_intrcnt);
231 if (sc->sc_softc.sc_ih == NULL)
232 panic("%s: Cannot install IRQ handler", dp->dv_xname);
233 #else
234 printf(" polling");
235 sc->sc_softc.sc_adapter.adapt_flags = SCSIPI_ADAPT_POLL_ONLY;
236 #endif
238 printf("\n");
240 /* attach all scsi units on us */
241 config_found(dp, &sc->sc_softc.sc_channel, scsiprint);
246 ptsc_intr(void *arg)
248 struct sfas_softc *dev = arg;
249 ptsc_regmap_p rp;
250 int quickints;
252 rp = (ptsc_regmap_p)dev->sc_fas;
254 if (*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING) {
255 quickints = 16;
256 do {
257 dev->sc_status = *rp->FAS216.sfas_status;
258 dev->sc_interrupt = *rp->FAS216.sfas_interrupt;
260 if (dev->sc_interrupt & SFAS_INT_RESELECTED) {
261 dev->sc_resel[0] = *rp->FAS216.sfas_fifo;
262 dev->sc_resel[1] = *rp->FAS216.sfas_fifo;
265 sfasintr(dev);
267 } while((*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING)
268 && --quickints);
271 return(0); /* Pass interrupt on down the chain */
274 /* Load transfer address into DMA register */
275 void
276 ptsc_set_dma_adr(struct sfas_softc *sc, void *ptr)
278 #if 0
279 ptsc_regmap_p rp;
280 unsigned int *p;
281 unsigned int d;
282 #endif
283 #if 0
284 printf("ptsc_set_dma_adr(sc = 0x%08x, ptr = 0x%08x)\n", (u_int)sc, (u_int)ptr);
285 #endif
286 return;
287 #if 0
288 rp = (ptsc_regmap_p)sc->sc_fas;
290 d = (unsigned int)ptr;
291 p = (unsigned int *)((d & 0xFFFFFF) + (int)rp->dmabase);
293 *rp->clear=0;
294 *p = d;
295 #endif
298 /* Set DMA transfer counter */
299 void
300 ptsc_set_dma_tc(struct sfas_softc *sc, unsigned int len)
302 printf("ptsc_set_dma_tc(sc, len = 0x%08x)", len);
304 *sc->sc_fas->sfas_tc_low = len; len >>= 8;
305 *sc->sc_fas->sfas_tc_mid = len; len >>= 8;
306 *sc->sc_fas->sfas_tc_high = len;
309 /* Set DMA mode */
310 void
311 ptsc_set_dma_mode(struct sfas_softc *sc, int mode)
313 #if 0
314 struct csc_specific *spec;
316 spec = sc->sc_spec;
318 spec->portbits = (spec->portbits & ~FLSC_PB_DMA_BITS) | mode;
319 *((flsc_regmap_p)sc->sc_fas)->hardbits = spec->portbits;
320 #endif
323 /* Initialize DMA for transfer */
325 ptsc_setup_dma(void *v, void *ptr, int len, int mode)
327 return(0);
329 #if 0
330 struct sfas_softc *sc = v;
331 int retval;
333 retval = 0;
335 printf("ptsc_setup_dma(sc, ptr = 0x%08x, len = 0x%08x, mode = 0x%08x)\n", (u_int)ptr, len, mode);
337 switch(mode) {
338 case SFAS_DMA_READ:
339 case SFAS_DMA_WRITE:
340 flsc_set_dma_adr(sc, ptr);
341 if (mode == SFAS_DMA_READ)
342 flsc_set_dma_mode(sc,FLSC_PB_ENABLE_DMA | FLSC_PB_DMA_READ);
343 else
344 flsc_set_dma_mode(sc,FLSC_PB_ENABLE_DMA | FLSC_PB_DMA_WRITE);
346 flsc_set_dma_tc(sc, len);
347 break;
349 case SFAS_DMA_CLEAR:
350 default:
351 flsc_set_dma_mode(sc, FLSC_PB_DISABLE_DMA);
352 flsc_set_dma_adr(sc, 0);
354 retval = (*sc->sc_fas->sfas_tc_high << 16) |
355 (*sc->sc_fas->sfas_tc_mid << 8) |
356 *sc->sc_fas->sfas_tc_low;
358 flsc_set_dma_tc(sc, 0);
359 break;
362 return(retval);
363 #endif
366 /* Check if address and len is ok for DMA transfer */
368 ptsc_need_bump(void *v, void *ptr, int len)
370 int p;
372 p = (int)ptr & 0x03;
374 if (p) {
375 p = 4-p;
377 if (len < 256)
378 p = len;
381 return(p);
384 /* Interrupt driven routines */
386 ptsc_build_dma_chain(void *v1, void *v2, void *p, int l)
388 #if 0
389 vm_offset_t pa, lastpa;
390 char *ptr;
391 int len, prelen, postlen, max_t, n;
392 #endif
393 #if 0
394 printf("ptsc_build_dma_chain()\n");
395 #endif
396 return(0);
398 #if 0
399 if (l == 0)
400 return(0);
402 #define set_link(n, p, l, f)\
403 do { chain[n].ptr = (p); chain[n].len = (l); chain[n++].flg = (f); } while(0)
405 n = 0;
407 if (l < 512)
408 set_link(n, (vm_offset_t)p, l, SFAS_CHAIN_BUMP);
409 else if (p >= (void *)0xFF000000) {
410 while(l != 0) {
411 len = ((l > sc->sc_bump_sz) ? sc->sc_bump_sz : l);
413 set_link(n, (vm_offset_t)p, len, SFAS_CHAIN_BUMP);
415 p += len;
416 l -= len;
418 } else {
419 ptr = p;
420 len = l;
422 pa = kvtop(ptr);
423 prelen = ((int)ptr & 0x03);
425 if (prelen) {
426 prelen = 4-prelen;
427 set_link(n, (vm_offset_t)ptr, prelen, SFAS_CHAIN_BUMP);
428 ptr += prelen;
429 len -= prelen;
432 lastpa = 0;
433 while(len > 3) {
434 pa = kvtop(ptr);
435 max_t = PAGE_SIZE - (pa & PGOFSET);
436 if (max_t > len)
437 max_t = len;
439 max_t &= ~3;
441 if (lastpa == pa)
442 sc->sc_chain[n-1].len += max_t;
443 else
444 set_link(n, pa, max_t, SFAS_CHAIN_DMA);
446 lastpa = pa+max_t;
448 ptr += max_t;
449 len -= max_t;
452 if (len)
453 set_link(n, (vm_offset_t)ptr, len, SFAS_CHAIN_BUMP);
456 return(n);
457 #endif
460 /* Turn on/off led */
461 void
462 ptsc_led(void *v, int mode)
464 struct sfas_softc *sc = v;
465 ptsc_regmap_p rp;
467 rp = (ptsc_regmap_p)sc->sc_fas;
469 if (mode) {
470 sc->sc_led_status++;
471 } else {
472 if (sc->sc_led_status)
473 sc->sc_led_status--;
475 *rp->led = (sc->sc_led_status?1:0);