xref: /netbsd-src/sys/arch/acorn32/podulebus/ptsc.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /*	$NetBSD: ptsc.c,v 1.21 2021/08/07 16:18:40 thorpej Exp $	*/
2aad01611Sagc 
3aad01611Sagc /*
4aad01611Sagc  * Copyright (c) 1982, 1990 The Regents of the University of California.
5aad01611Sagc  * All rights reserved.
6aad01611Sagc  *
7aad01611Sagc  * Redistribution and use in source and binary forms, with or without
8aad01611Sagc  * modification, are permitted provided that the following conditions
9aad01611Sagc  * are met:
10aad01611Sagc  * 1. Redistributions of source code must retain the above copyright
11aad01611Sagc  *    notice, this list of conditions and the following disclaimer.
12aad01611Sagc  * 2. Redistributions in binary form must reproduce the above copyright
13aad01611Sagc  *    notice, this list of conditions and the following disclaimer in the
14aad01611Sagc  *    documentation and/or other materials provided with the distribution.
15aad01611Sagc  * 3. Neither the name of the University nor the names of its contributors
16aad01611Sagc  *    may be used to endorse or promote products derived from this software
17aad01611Sagc  *    without specific prior written permission.
18aad01611Sagc  *
19aad01611Sagc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20aad01611Sagc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21aad01611Sagc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22aad01611Sagc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23aad01611Sagc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24aad01611Sagc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25aad01611Sagc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26aad01611Sagc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27aad01611Sagc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28aad01611Sagc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29aad01611Sagc  * SUCH DAMAGE.
30aad01611Sagc  *
31aad01611Sagc  *	@(#)ptsc.c
32aad01611Sagc  */
337d4a1addSreinoud 
347d4a1addSreinoud /*
357d4a1addSreinoud  * Copyright (c) 1995 Scott Stevens
367d4a1addSreinoud  * Copyright (c) 1995 Daniel Widenfalk
377d4a1addSreinoud  * Copyright (c) 1994 Christian E. Hopps
387d4a1addSreinoud  *
397d4a1addSreinoud  * Redistribution and use in source and binary forms, with or without
407d4a1addSreinoud  * modification, are permitted provided that the following conditions
417d4a1addSreinoud  * are met:
427d4a1addSreinoud  * 1. Redistributions of source code must retain the above copyright
437d4a1addSreinoud  *    notice, this list of conditions and the following disclaimer.
447d4a1addSreinoud  * 2. Redistributions in binary form must reproduce the above copyright
457d4a1addSreinoud  *    notice, this list of conditions and the following disclaimer in the
467d4a1addSreinoud  *    documentation and/or other materials provided with the distribution.
477d4a1addSreinoud  * 3. All advertising materials mentioning features or use of this software
487d4a1addSreinoud  *    must display the following acknowledgement:
497d4a1addSreinoud  *	This product includes software developed by the University of
507d4a1addSreinoud  *	California, Berkeley and its contributors.
517d4a1addSreinoud  * 4. Neither the name of the University nor the names of its contributors
527d4a1addSreinoud  *    may be used to endorse or promote products derived from this software
537d4a1addSreinoud  *    without specific prior written permission.
547d4a1addSreinoud  *
557d4a1addSreinoud  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
567d4a1addSreinoud  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
577d4a1addSreinoud  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
587d4a1addSreinoud  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
597d4a1addSreinoud  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
607d4a1addSreinoud  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
617d4a1addSreinoud  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
627d4a1addSreinoud  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
637d4a1addSreinoud  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
647d4a1addSreinoud  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
657d4a1addSreinoud  * SUCH DAMAGE.
667d4a1addSreinoud  *
677d4a1addSreinoud  *	@(#)ptsc.c
687d4a1addSreinoud  */
697d4a1addSreinoud 
707d4a1addSreinoud /*
717d4a1addSreinoud  * Power-tec SCSI-2 driver uses SFAS216 generic driver
727d4a1addSreinoud  *
737d4a1addSreinoud  * Thanks to Alsystems for loaning a development card and providing
747d4a1addSreinoud  * programming information.
757d4a1addSreinoud  */
767d4a1addSreinoud 
771b7326b5Slukem #include <sys/cdefs.h>
78*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: ptsc.c,v 1.21 2021/08/07 16:18:40 thorpej Exp $");
791b7326b5Slukem 
807d4a1addSreinoud #include <sys/param.h>
817d4a1addSreinoud #include <sys/systm.h>
827d4a1addSreinoud #include <sys/kernel.h>
837d4a1addSreinoud #include <sys/device.h>
8489a25a09Sthorpej 
8589a25a09Sthorpej #include <uvm/uvm_extern.h>
8689a25a09Sthorpej 
877d4a1addSreinoud #include <dev/scsipi/scsi_all.h>
887d4a1addSreinoud #include <dev/scsipi/scsipi_all.h>
897d4a1addSreinoud #include <dev/scsipi/scsiconf.h>
907d4a1addSreinoud #include <machine/io.h>
91ce1401feSthorpej #include <machine/intr.h>
927d4a1addSreinoud #include <machine/bootconfig.h>
937d4a1addSreinoud #include <acorn32/podulebus/podulebus.h>
947d4a1addSreinoud #include <acorn32/podulebus/sfasreg.h>
957d4a1addSreinoud #include <acorn32/podulebus/sfasvar.h>
967d4a1addSreinoud #include <acorn32/podulebus/ptscreg.h>
977d4a1addSreinoud #include <acorn32/podulebus/ptscvar.h>
987d4a1addSreinoud #include <dev/podulebus/podules.h>
997d4a1addSreinoud #include <dev/podulebus/powerromreg.h>
1007d4a1addSreinoud 
101a8c167faSmatt int  ptscmatch(device_t, cfdata_t, void *);
102a8c167faSmatt void ptscattach(device_t, device_t, void *);
1037d4a1addSreinoud 
104cbab9cadSchs CFATTACH_DECL_NEW(ptsc, sizeof(struct ptsc_softc),
1055a9ddc14Sthorpej     ptscmatch, ptscattach, NULL, NULL);
1067d4a1addSreinoud 
107ecdf1b40Schs int ptsc_intr(void *);
108ecdf1b40Schs int ptsc_setup_dma(void *, void *, int, int);
109ecdf1b40Schs int ptsc_build_dma_chain(void *, void *, void *, int);
110ecdf1b40Schs int ptsc_need_bump(void *, void *, int);
111ecdf1b40Schs void ptsc_led(void *, int);
112ecdf1b40Schs 
113ecdf1b40Schs void ptsc_set_dma_adr(struct sfas_softc *, void *);
114ecdf1b40Schs void ptsc_set_dma_tc(struct sfas_softc *, unsigned int);
115ecdf1b40Schs void ptsc_set_dma_mode(struct sfas_softc *, int);
1167d4a1addSreinoud 
1177d4a1addSreinoud /*
1187d4a1addSreinoud  * if we are a Power-tec SCSI-2 card
1197d4a1addSreinoud  */
1207d4a1addSreinoud int
ptscmatch(device_t parent,cfdata_t cf,void * aux)121a8c167faSmatt ptscmatch(device_t parent, cfdata_t cf, void *aux)
1227d4a1addSreinoud {
123a8c167faSmatt 	struct podule_attach_args *pa = aux;
1247d4a1addSreinoud 
1257d4a1addSreinoud 	/* Look for the card */
1267d4a1addSreinoud 
1277d4a1addSreinoud 	/*
1287d4a1addSreinoud 	 * All Power-tec cards effectively have PowerROMS.  Note,
1297d4a1addSreinoud 	 * though, that here, if we fail to initialise the loader, we
1307d4a1addSreinoud 	 * assume this _is_ the right kind of card.
1317d4a1addSreinoud 	 */
1327d4a1addSreinoud         if (pa->pa_product == PODULE_ALSYSTEMS_SCSI &&
1337d4a1addSreinoud             (podulebus_initloader(pa) != 0 ||
1347d4a1addSreinoud 	     podloader_callloader(pa, 0, 0) == PRID_POWERTEC))
1357d4a1addSreinoud                 return 1;
1367d4a1addSreinoud 
1377d4a1addSreinoud 	return 0;
1387d4a1addSreinoud }
1397d4a1addSreinoud 
1407d4a1addSreinoud void
ptscattach(device_t parent,device_t self,void * aux)141a8c167faSmatt ptscattach(device_t parent, device_t self, void *aux)
1427d4a1addSreinoud {
143a8c167faSmatt 	struct ptsc_softc *sc = device_private(self);
144a8c167faSmatt 	struct podule_attach_args  *pa = aux;
1457d4a1addSreinoud 	ptsc_regmap_p	   rp = &sc->sc_regmap;
1467d4a1addSreinoud 	vu_char		  *fas;
1477d4a1addSreinoud 
1487d4a1addSreinoud 	if (pa->pa_podule_number == -1)
1497d4a1addSreinoud 		panic("Podule has disappeared !");
1507d4a1addSreinoud 
1517d4a1addSreinoud 	sc->sc_specific.sc_podule_number = pa->pa_podule_number;
1527d4a1addSreinoud 	sc->sc_specific.sc_podule = pa->pa_podule;
1537d4a1addSreinoud 	sc->sc_specific.sc_iobase =
1547d4a1addSreinoud 	  (vu_char *)sc->sc_specific.sc_podule->fast_base;
1557d4a1addSreinoud 
1567d4a1addSreinoud 	rp->chipreset = &sc->sc_specific.sc_iobase[PTSC_CONTROL_CHIPRESET];
1577d4a1addSreinoud 	rp->inten = &sc->sc_specific.sc_iobase[PTSC_CONTROL_INTEN];
1587d4a1addSreinoud 	rp->status = &sc->sc_specific.sc_iobase[PTSC_STATUS];
1597d4a1addSreinoud 	rp->term = &sc->sc_specific.sc_iobase[PTSC_CONTROL_TERM];
1607d4a1addSreinoud 	rp->led = &sc->sc_specific.sc_iobase[PTSC_CONTROL_LED];
1617d4a1addSreinoud 	fas = &sc->sc_specific.sc_iobase[PTSC_FASOFFSET_BASE];
1627d4a1addSreinoud 
1637d4a1addSreinoud 	rp->FAS216.sfas_tc_low	= &fas[PTSC_FASOFFSET_TCL];
1647d4a1addSreinoud 	rp->FAS216.sfas_tc_mid	= &fas[PTSC_FASOFFSET_TCM];
1657d4a1addSreinoud 	rp->FAS216.sfas_fifo	= &fas[PTSC_FASOFFSET_FIFO];
1667d4a1addSreinoud 	rp->FAS216.sfas_command	= &fas[PTSC_FASOFFSET_COMMAND];
1677d4a1addSreinoud 	rp->FAS216.sfas_dest_id	= &fas[PTSC_FASOFFSET_DESTID];
1687d4a1addSreinoud 	rp->FAS216.sfas_timeout	= &fas[PTSC_FASOFFSET_TIMEOUT];
1697d4a1addSreinoud 	rp->FAS216.sfas_syncper	= &fas[PTSC_FASOFFSET_PERIOD];
1707d4a1addSreinoud 	rp->FAS216.sfas_syncoff	= &fas[PTSC_FASOFFSET_OFFSET];
1717d4a1addSreinoud 	rp->FAS216.sfas_config1	= &fas[PTSC_FASOFFSET_CONFIG1];
1727d4a1addSreinoud 	rp->FAS216.sfas_clkconv	= &fas[PTSC_FASOFFSET_CLOCKCONV];
1737d4a1addSreinoud 	rp->FAS216.sfas_test	= &fas[PTSC_FASOFFSET_TEST];
1747d4a1addSreinoud 	rp->FAS216.sfas_config2	= &fas[PTSC_FASOFFSET_CONFIG2];
1757d4a1addSreinoud 	rp->FAS216.sfas_config3	= &fas[PTSC_FASOFFSET_CONFIG3];
1767d4a1addSreinoud 	rp->FAS216.sfas_tc_high	= &fas[PTSC_FASOFFSET_TCH];
1777d4a1addSreinoud 	rp->FAS216.sfas_fifo_bot = &fas[PTSC_FASOFFSET_FIFOBOTTOM];
1787d4a1addSreinoud 
179cbab9cadSchs 	sc->sc_softc.sc_dev	= self;
1807d4a1addSreinoud 	sc->sc_softc.sc_fas	= (sfas_regmap_p)rp;
1817d4a1addSreinoud 	sc->sc_softc.sc_spec	= &sc->sc_specific;
1827d4a1addSreinoud 
1837d4a1addSreinoud 	sc->sc_softc.sc_led	= ptsc_led;
1847d4a1addSreinoud 
1857d4a1addSreinoud 	sc->sc_softc.sc_setup_dma	= ptsc_setup_dma;
1867d4a1addSreinoud 	sc->sc_softc.sc_build_dma_chain = ptsc_build_dma_chain;
1877d4a1addSreinoud 	sc->sc_softc.sc_need_bump	= ptsc_need_bump;
1887d4a1addSreinoud 
1897d4a1addSreinoud 	sc->sc_softc.sc_clock_freq   = 40;   /* Power-Tec runs at 8MHz */
1907d4a1addSreinoud 	sc->sc_softc.sc_timeout      = 250;  /* Set default timeout to 250ms */
1917d4a1addSreinoud 	sc->sc_softc.sc_config_flags = SFAS_NO_DMA /*| SFAS_NF_DEBUG*/;
1927d4a1addSreinoud 	sc->sc_softc.sc_host_id      = 7;    /* Should check the jumpers */
1937d4a1addSreinoud 
19489a25a09Sthorpej 	sc->sc_softc.sc_bump_sz = PAGE_SIZE;
1957d4a1addSreinoud 	sc->sc_softc.sc_bump_pa = 0x0;
1967d4a1addSreinoud 
1977d4a1addSreinoud 	sfasinitialize((struct sfas_softc *)sc);
1987d4a1addSreinoud 
199cbab9cadSchs 	sc->sc_softc.sc_adapter.adapt_dev = sc->sc_softc.sc_dev;
2007d4a1addSreinoud 	sc->sc_softc.sc_adapter.adapt_nchannels = 1;
2017d4a1addSreinoud 	sc->sc_softc.sc_adapter.adapt_openings = 7;
2027d4a1addSreinoud 	sc->sc_softc.sc_adapter.adapt_max_periph = 1;
2037d4a1addSreinoud 	sc->sc_softc.sc_adapter.adapt_ioctl = NULL;
2047d4a1addSreinoud 	sc->sc_softc.sc_adapter.adapt_minphys = sfas_minphys;
205ed8346a5Sbjh21 	sc->sc_softc.sc_adapter.adapt_request = sfas_scsi_request;
2067d4a1addSreinoud 
2077d4a1addSreinoud 	sc->sc_softc.sc_channel.chan_adapter = &sc->sc_softc.sc_adapter;
2087d4a1addSreinoud 	sc->sc_softc.sc_channel.chan_bustype = &scsi_bustype;
2097d4a1addSreinoud 	sc->sc_softc.sc_channel.chan_channel = 0;
2107d4a1addSreinoud 	sc->sc_softc.sc_channel.chan_ntargets = 8;
2117d4a1addSreinoud 	sc->sc_softc.sc_channel.chan_nluns = 8;
2127d4a1addSreinoud 	sc->sc_softc.sc_channel.chan_id = sc->sc_softc.sc_host_id;
2137d4a1addSreinoud 
2147d4a1addSreinoud 	/* Provide an override for the host id */
2157d4a1addSreinoud 	(void)get_bootconf_option(boot_args, "ptsc.hostid",
2167d4a1addSreinoud 	    BOOTOPT_TYPE_INT, &sc->sc_softc.sc_channel.chan_id);
2177d4a1addSreinoud 
2187d4a1addSreinoud 	printf(": host=%d", sc->sc_softc.sc_channel.chan_id);
2197d4a1addSreinoud 
2207d4a1addSreinoud 	/* initialise the card */
2217d4a1addSreinoud /*	*rp->term = 0;*/
2227d4a1addSreinoud 	*rp->inten = (PTSC_POLL?0:1);
2237d4a1addSreinoud 	*rp->led = 0;
2247d4a1addSreinoud 
2257d4a1addSreinoud #if PTSC_POLL == 0
2267d4a1addSreinoud 	evcnt_attach_dynamic(&sc->sc_softc.sc_intrcnt, EVCNT_TYPE_INTR, NULL,
227a8c167faSmatt 	    device_xname(self), "intr");
2287d4a1addSreinoud 	sc->sc_softc.sc_ih = podulebus_irq_establish(pa->pa_ih, IPL_BIO,
2297d4a1addSreinoud 	    ptsc_intr, &sc->sc_softc, &sc->sc_softc.sc_intrcnt);
2307d4a1addSreinoud 	if (sc->sc_softc.sc_ih == NULL)
231a8c167faSmatt 	    panic("%s: Cannot install IRQ handler", device_xname(self));
2327d4a1addSreinoud #else
2337d4a1addSreinoud 	printf(" polling");
234ed8346a5Sbjh21 	sc->sc_softc.sc_adapter.adapt_flags = SCSIPI_ADAPT_POLL_ONLY;
2357d4a1addSreinoud #endif
2367d4a1addSreinoud 
2377d4a1addSreinoud 	printf("\n");
2387d4a1addSreinoud 
2397d4a1addSreinoud 	/* attach all scsi units on us */
240*c7fb772bSthorpej 	config_found(self, &sc->sc_softc.sc_channel, scsiprint, CFARGS_NONE);
2417d4a1addSreinoud }
2427d4a1addSreinoud 
2437d4a1addSreinoud 
2447d4a1addSreinoud int
ptsc_intr(void * arg)245454af1c0Sdsl ptsc_intr(void *arg)
2467d4a1addSreinoud {
2477d4a1addSreinoud 	struct sfas_softc *dev = arg;
2487d4a1addSreinoud 	ptsc_regmap_p	      rp;
2497d4a1addSreinoud 	int		      quickints;
2507d4a1addSreinoud 
2517d4a1addSreinoud 	rp = (ptsc_regmap_p)dev->sc_fas;
2527d4a1addSreinoud 
2537d4a1addSreinoud 	if (*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING) {
2547d4a1addSreinoud 		quickints = 16;
2557d4a1addSreinoud 		do {
2567d4a1addSreinoud 			dev->sc_status = *rp->FAS216.sfas_status;
2577d4a1addSreinoud 			dev->sc_interrupt = *rp->FAS216.sfas_interrupt;
2587d4a1addSreinoud 
2597d4a1addSreinoud 			if (dev->sc_interrupt & SFAS_INT_RESELECTED) {
2607d4a1addSreinoud 				dev->sc_resel[0] = *rp->FAS216.sfas_fifo;
2617d4a1addSreinoud 				dev->sc_resel[1] = *rp->FAS216.sfas_fifo;
2627d4a1addSreinoud 			}
2637d4a1addSreinoud 
2647d4a1addSreinoud 			sfasintr(dev);
2657d4a1addSreinoud 
2667d4a1addSreinoud 		} while((*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING)
2677d4a1addSreinoud 			&& --quickints);
2687d4a1addSreinoud 	}
2697d4a1addSreinoud 
2707d4a1addSreinoud 	return(0);	/* Pass interrupt on down the chain */
2717d4a1addSreinoud }
2727d4a1addSreinoud 
2731ffa7b76Swiz /* Load transfer address into DMA register */
2747d4a1addSreinoud void
ptsc_set_dma_adr(struct sfas_softc * sc,void * ptr)275454af1c0Sdsl ptsc_set_dma_adr(struct sfas_softc *sc, void *ptr)
2767d4a1addSreinoud {
2777d4a1addSreinoud #if 0
2787d4a1addSreinoud 	ptsc_regmap_p	rp;
2797d4a1addSreinoud 	unsigned int   *p;
2807d4a1addSreinoud 	unsigned int	d;
2817d4a1addSreinoud #endif
2827d4a1addSreinoud #if 0
2837d4a1addSreinoud 	printf("ptsc_set_dma_adr(sc = 0x%08x, ptr = 0x%08x)\n", (u_int)sc, (u_int)ptr);
2847d4a1addSreinoud #endif
2857d4a1addSreinoud 	return;
2867d4a1addSreinoud #if 0
2877d4a1addSreinoud 	rp = (ptsc_regmap_p)sc->sc_fas;
2887d4a1addSreinoud 
2897d4a1addSreinoud 	d = (unsigned int)ptr;
2907d4a1addSreinoud 	p = (unsigned int *)((d & 0xFFFFFF) + (int)rp->dmabase);
2917d4a1addSreinoud 
2927d4a1addSreinoud 	*rp->clear=0;
2937d4a1addSreinoud 	*p = d;
2947d4a1addSreinoud #endif
2957d4a1addSreinoud }
2967d4a1addSreinoud 
2977d4a1addSreinoud /* Set DMA transfer counter */
2987d4a1addSreinoud void
ptsc_set_dma_tc(struct sfas_softc * sc,unsigned int len)299454af1c0Sdsl ptsc_set_dma_tc(struct sfas_softc *sc, unsigned int len)
3007d4a1addSreinoud {
3017d4a1addSreinoud 	printf("ptsc_set_dma_tc(sc, len = 0x%08x)", len);
3027d4a1addSreinoud 
3037d4a1addSreinoud 	*sc->sc_fas->sfas_tc_low  = len; len >>= 8;
3047d4a1addSreinoud 	*sc->sc_fas->sfas_tc_mid  = len; len >>= 8;
3057d4a1addSreinoud 	*sc->sc_fas->sfas_tc_high = len;
3067d4a1addSreinoud }
3077d4a1addSreinoud 
3087d4a1addSreinoud /* Set DMA mode */
3097d4a1addSreinoud void
ptsc_set_dma_mode(struct sfas_softc * sc,int mode)310454af1c0Sdsl ptsc_set_dma_mode(struct sfas_softc *sc, int mode)
3117d4a1addSreinoud {
3127d4a1addSreinoud #if 0
3137d4a1addSreinoud 	struct csc_specific *spec;
3147d4a1addSreinoud 
3157d4a1addSreinoud 	spec = sc->sc_spec;
3167d4a1addSreinoud 
3177d4a1addSreinoud 	spec->portbits = (spec->portbits & ~FLSC_PB_DMA_BITS) | mode;
3187d4a1addSreinoud 	*((flsc_regmap_p)sc->sc_fas)->hardbits = spec->portbits;
3197d4a1addSreinoud #endif
3207d4a1addSreinoud }
3217d4a1addSreinoud 
3227d4a1addSreinoud /* Initialize DMA for transfer */
3237d4a1addSreinoud int
ptsc_setup_dma(void * v,void * ptr,int len,int mode)324454af1c0Sdsl ptsc_setup_dma(void *v, void *ptr, int len, int mode)
3257d4a1addSreinoud {
326ecdf1b40Schs 	return(0);
327ecdf1b40Schs 
328ecdf1b40Schs #if 0
329ecdf1b40Schs 	struct sfas_softc *sc = v;
3307d4a1addSreinoud 	int	retval;
3317d4a1addSreinoud 
3327d4a1addSreinoud 	retval = 0;
3337d4a1addSreinoud 
3347d4a1addSreinoud 	printf("ptsc_setup_dma(sc, ptr = 0x%08x, len = 0x%08x, mode = 0x%08x)\n", (u_int)ptr, len, mode);
3357d4a1addSreinoud 
3367d4a1addSreinoud 	switch(mode) {
3377d4a1addSreinoud 	case SFAS_DMA_READ:
3387d4a1addSreinoud 	case SFAS_DMA_WRITE:
3397d4a1addSreinoud 		flsc_set_dma_adr(sc, ptr);
3407d4a1addSreinoud 		if (mode == SFAS_DMA_READ)
3417d4a1addSreinoud 		  flsc_set_dma_mode(sc,FLSC_PB_ENABLE_DMA | FLSC_PB_DMA_READ);
3427d4a1addSreinoud 		else
3437d4a1addSreinoud 		  flsc_set_dma_mode(sc,FLSC_PB_ENABLE_DMA | FLSC_PB_DMA_WRITE);
3447d4a1addSreinoud 
3457d4a1addSreinoud 		flsc_set_dma_tc(sc, len);
3467d4a1addSreinoud 		break;
3477d4a1addSreinoud 
3487d4a1addSreinoud 	case SFAS_DMA_CLEAR:
3497d4a1addSreinoud 	default:
3507d4a1addSreinoud 		flsc_set_dma_mode(sc, FLSC_PB_DISABLE_DMA);
3517d4a1addSreinoud 		flsc_set_dma_adr(sc, 0);
3527d4a1addSreinoud 
3537d4a1addSreinoud 		retval = (*sc->sc_fas->sfas_tc_high << 16) |
3547d4a1addSreinoud 			 (*sc->sc_fas->sfas_tc_mid  <<  8) |
3557d4a1addSreinoud 			  *sc->sc_fas->sfas_tc_low;
3567d4a1addSreinoud 
3577d4a1addSreinoud 		flsc_set_dma_tc(sc, 0);
3587d4a1addSreinoud 		break;
3597d4a1addSreinoud 	}
3607d4a1addSreinoud 
3617d4a1addSreinoud 	return(retval);
3627d4a1addSreinoud #endif
3637d4a1addSreinoud }
3647d4a1addSreinoud 
3657d4a1addSreinoud /* Check if address and len is ok for DMA transfer */
3667d4a1addSreinoud int
ptsc_need_bump(void * v,void * ptr,int len)367454af1c0Sdsl ptsc_need_bump(void *v, void *ptr, int len)
3687d4a1addSreinoud {
3697d4a1addSreinoud 	int	p;
3707d4a1addSreinoud 
3717d4a1addSreinoud 	p = (int)ptr & 0x03;
3727d4a1addSreinoud 
3737d4a1addSreinoud 	if (p) {
3747d4a1addSreinoud 		p = 4-p;
3757d4a1addSreinoud 
3767d4a1addSreinoud 		if (len < 256)
3777d4a1addSreinoud 			p = len;
3787d4a1addSreinoud 	}
3797d4a1addSreinoud 
3807d4a1addSreinoud 	return(p);
3817d4a1addSreinoud }
3827d4a1addSreinoud 
3837d4a1addSreinoud /* Interrupt driven routines */
3847d4a1addSreinoud int
ptsc_build_dma_chain(void * v1,void * v2,void * p,int l)385ecdf1b40Schs ptsc_build_dma_chain(void *v1, void *v2, void *p, int l)
3867d4a1addSreinoud {
3877d4a1addSreinoud #if 0
388d3d059aaSmatt 	vaddr_t  pa, lastpa;
3897d4a1addSreinoud 	char	    *ptr;
3907d4a1addSreinoud 	int	     len, prelen, postlen, max_t, n;
3917d4a1addSreinoud #endif
3927d4a1addSreinoud #if 0
3937d4a1addSreinoud 	printf("ptsc_build_dma_chain()\n");
3947d4a1addSreinoud #endif
3957d4a1addSreinoud 	return(0);
3967d4a1addSreinoud 
3977d4a1addSreinoud #if 0
3987d4a1addSreinoud 	if (l == 0)
3997d4a1addSreinoud 		return(0);
4007d4a1addSreinoud 
4017d4a1addSreinoud #define set_link(n, p, l, f)\
4027d4a1addSreinoud do { chain[n].ptr = (p); chain[n].len = (l); chain[n++].flg = (f); } while(0)
4037d4a1addSreinoud 
4047d4a1addSreinoud 	n = 0;
4057d4a1addSreinoud 
4067d4a1addSreinoud 	if (l < 512)
407d3d059aaSmatt 		set_link(n, (vaddr_t)p, l, SFAS_CHAIN_BUMP);
4087d4a1addSreinoud 	else if (p >= (void *)0xFF000000) {
4097d4a1addSreinoud 		while(l != 0) {
4107d4a1addSreinoud 			len = ((l > sc->sc_bump_sz) ? sc->sc_bump_sz : l);
4117d4a1addSreinoud 
412d3d059aaSmatt 			set_link(n, (vaddr_t)p, len, SFAS_CHAIN_BUMP);
4137d4a1addSreinoud 
4147d4a1addSreinoud 			p += len;
4157d4a1addSreinoud 			l -= len;
4167d4a1addSreinoud 		}
4177d4a1addSreinoud 	} else {
4187d4a1addSreinoud 		ptr = p;
4197d4a1addSreinoud 		len = l;
4207d4a1addSreinoud 
4217d4a1addSreinoud 		pa = kvtop(ptr);
4227d4a1addSreinoud 		prelen = ((int)ptr & 0x03);
4237d4a1addSreinoud 
4247d4a1addSreinoud 		if (prelen) {
4257d4a1addSreinoud 			prelen = 4-prelen;
426d3d059aaSmatt 			set_link(n, (vaddr_t)ptr, prelen, SFAS_CHAIN_BUMP);
4277d4a1addSreinoud 			ptr += prelen;
4287d4a1addSreinoud 			len -= prelen;
4297d4a1addSreinoud 		}
4307d4a1addSreinoud 
4317d4a1addSreinoud 		lastpa = 0;
4327d4a1addSreinoud 		while(len > 3) {
4337d4a1addSreinoud 			pa = kvtop(ptr);
43489a25a09Sthorpej 			max_t = PAGE_SIZE - (pa & PGOFSET);
4357d4a1addSreinoud 			if (max_t > len)
4367d4a1addSreinoud 			  max_t = len;
4377d4a1addSreinoud 
4387d4a1addSreinoud 			max_t &= ~3;
4397d4a1addSreinoud 
4407d4a1addSreinoud 			if (lastpa == pa)
4417d4a1addSreinoud 				sc->sc_chain[n-1].len += max_t;
4427d4a1addSreinoud 			else
4437d4a1addSreinoud 				set_link(n, pa, max_t, SFAS_CHAIN_DMA);
4447d4a1addSreinoud 
4457d4a1addSreinoud 			lastpa = pa+max_t;
4467d4a1addSreinoud 
4477d4a1addSreinoud 			ptr += max_t;
4487d4a1addSreinoud 			len -= max_t;
4497d4a1addSreinoud 		}
4507d4a1addSreinoud 
4517d4a1addSreinoud 		if (len)
452d3d059aaSmatt 			set_link(n, (vaddr_t)ptr, len, SFAS_CHAIN_BUMP);
4537d4a1addSreinoud 	}
4547d4a1addSreinoud 
4557d4a1addSreinoud 	return(n);
4567d4a1addSreinoud #endif
4577d4a1addSreinoud }
4587d4a1addSreinoud 
4597d4a1addSreinoud /* Turn on/off led */
4607d4a1addSreinoud void
ptsc_led(void * v,int mode)461ecdf1b40Schs ptsc_led(void *v, int mode)
4627d4a1addSreinoud {
463ecdf1b40Schs 	struct sfas_softc	*sc = v;
4647d4a1addSreinoud 	ptsc_regmap_p		rp;
4657d4a1addSreinoud 
4667d4a1addSreinoud 	rp = (ptsc_regmap_p)sc->sc_fas;
4677d4a1addSreinoud 
4687d4a1addSreinoud 	if (mode) {
4697d4a1addSreinoud 		sc->sc_led_status++;
4707d4a1addSreinoud 	} else {
4717d4a1addSreinoud 		if (sc->sc_led_status)
4727d4a1addSreinoud 			sc->sc_led_status--;
4737d4a1addSreinoud 	}
4747d4a1addSreinoud 	*rp->led = (sc->sc_led_status?1:0);
4757d4a1addSreinoud }
476