Home | History | Annotate | Line # | Download | only in ebus
icap_ebus.c revision 1.1.8.2
      1  1.1.8.2  jruoho /*	$NetBSD: icap_ebus.c,v 1.1.8.2 2011/06/06 09:05:16 jruoho Exp $	*/
      2  1.1.8.2  jruoho 
      3  1.1.8.2  jruoho /*-
      4  1.1.8.2  jruoho  * Copyright (c) 2010 The NetBSD Foundation, Inc.
      5  1.1.8.2  jruoho  * All rights reserved.
      6  1.1.8.2  jruoho  *
      7  1.1.8.2  jruoho  * This code was written by Alessandro Forin and Neil Pittman
      8  1.1.8.2  jruoho  * at Microsoft Research and contributed to The NetBSD Foundation
      9  1.1.8.2  jruoho  * by Microsoft Corporation.
     10  1.1.8.2  jruoho  *
     11  1.1.8.2  jruoho  * Redistribution and use in source and binary forms, with or without
     12  1.1.8.2  jruoho  * modification, are permitted provided that the following conditions
     13  1.1.8.2  jruoho  * are met:
     14  1.1.8.2  jruoho  * 1. Redistributions of source code must retain the above copyright
     15  1.1.8.2  jruoho  *    notice, this list of conditions and the following disclaimer.
     16  1.1.8.2  jruoho  * 2. Redistributions in binary form must reproduce the above copyright
     17  1.1.8.2  jruoho  *    notice, this list of conditions and the following disclaimer in the
     18  1.1.8.2  jruoho  *    documentation and/or other materials provided with the distribution.
     19  1.1.8.2  jruoho  *
     20  1.1.8.2  jruoho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  1.1.8.2  jruoho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  1.1.8.2  jruoho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  1.1.8.2  jruoho  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  1.1.8.2  jruoho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  1.1.8.2  jruoho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  1.1.8.2  jruoho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  1.1.8.2  jruoho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  1.1.8.2  jruoho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  1.1.8.2  jruoho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  1.1.8.2  jruoho  * POSSIBILITY OF SUCH DAMAGE.
     31  1.1.8.2  jruoho  */
     32  1.1.8.2  jruoho 
     33  1.1.8.2  jruoho #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
     34  1.1.8.2  jruoho __KERNEL_RCSID(0, "$NetBSD: icap_ebus.c,v 1.1.8.2 2011/06/06 09:05:16 jruoho Exp $");
     35  1.1.8.2  jruoho 
     36  1.1.8.2  jruoho #include <sys/param.h>
     37  1.1.8.2  jruoho #include <sys/systm.h>
     38  1.1.8.2  jruoho #include <sys/buf.h>
     39  1.1.8.2  jruoho #include <sys/bufq.h>
     40  1.1.8.2  jruoho #include <sys/proc.h>
     41  1.1.8.2  jruoho #include <sys/errno.h>
     42  1.1.8.2  jruoho #include <sys/ioctl.h>
     43  1.1.8.2  jruoho #include <sys/device.h>
     44  1.1.8.2  jruoho #include <sys/conf.h>
     45  1.1.8.2  jruoho #include <uvm/uvm_param.h>
     46  1.1.8.2  jruoho 
     47  1.1.8.2  jruoho #include <emips/ebus/ebusvar.h>
     48  1.1.8.2  jruoho #include <emips/emips/machdep.h>
     49  1.1.8.2  jruoho #include <machine/emipsreg.h>
     50  1.1.8.2  jruoho 
     51  1.1.8.2  jruoho #define DEBUG_INTR   0x01
     52  1.1.8.2  jruoho #define DEBUG_XFERS  0x02
     53  1.1.8.2  jruoho #define DEBUG_STATUS 0x04
     54  1.1.8.2  jruoho #define DEBUG_FUNCS  0x08
     55  1.1.8.2  jruoho #define DEBUG_PROBE  0x10
     56  1.1.8.2  jruoho #define DEBUG_WRITES 0x20
     57  1.1.8.2  jruoho #define DEBUG_READS  0x40
     58  1.1.8.2  jruoho #define DEBUG_ERRORS 0x80
     59  1.1.8.2  jruoho #ifdef DEBUG
     60  1.1.8.2  jruoho int icap_debug = DEBUG_ERRORS;
     61  1.1.8.2  jruoho #define ICAP_DEBUG(x) (icap_debug & (x))
     62  1.1.8.2  jruoho #define DBGME(_lev_,_x_) if ((_lev_) & icap_debug) _x_
     63  1.1.8.2  jruoho #else
     64  1.1.8.2  jruoho #define ICAP_DEBUG(x) (0)
     65  1.1.8.2  jruoho #define DBGME(_lev_,_x_)
     66  1.1.8.2  jruoho #endif
     67  1.1.8.2  jruoho #define DEBUG_PRINT(_args_,_lev_) DBGME(_lev_,printf _args_)
     68  1.1.8.2  jruoho 
     69  1.1.8.2  jruoho /*
     70  1.1.8.2  jruoho  * Device softc
     71  1.1.8.2  jruoho  */
     72  1.1.8.2  jruoho struct icap_softc {
     73  1.1.8.2  jruoho 	device_t sc_dev;
     74  1.1.8.2  jruoho 	struct _Icap *sc_dp;
     75  1.1.8.2  jruoho 	struct bufq_state *sc_buflist;
     76  1.1.8.2  jruoho 	struct buf *sc_bp;
     77  1.1.8.2  jruoho 	char *sc_data;
     78  1.1.8.2  jruoho 	int sc_count;
     79  1.1.8.2  jruoho };
     80  1.1.8.2  jruoho 
     81  1.1.8.2  jruoho /* Required funcs
     82  1.1.8.2  jruoho  */
     83  1.1.8.2  jruoho static int	icap_ebus_match (struct device *, struct cfdata *, void *);
     84  1.1.8.2  jruoho static void	icap_ebus_attach (struct device *, struct device *, void *);
     85  1.1.8.2  jruoho 
     86  1.1.8.2  jruoho static dev_type_open(icapopen);
     87  1.1.8.2  jruoho static dev_type_close(icapclose);
     88  1.1.8.2  jruoho static dev_type_read(icapread);
     89  1.1.8.2  jruoho static dev_type_write(icapwrite);
     90  1.1.8.2  jruoho static dev_type_ioctl(icapioctl);
     91  1.1.8.2  jruoho static dev_type_strategy(icapstrategy);
     92  1.1.8.2  jruoho 
     93  1.1.8.2  jruoho /* Other functions
     94  1.1.8.2  jruoho  */
     95  1.1.8.2  jruoho extern paddr_t kvtophys(vaddr_t);
     96  1.1.8.2  jruoho static void icapstart(struct icap_softc *sc);
     97  1.1.8.2  jruoho static int  icap_ebus_intr(void *cookie, void *f);
     98  1.1.8.2  jruoho static void icap_reset(struct icap_softc *sc);
     99  1.1.8.2  jruoho 
    100  1.1.8.2  jruoho /* Config stuff
    101  1.1.8.2  jruoho  */
    102  1.1.8.2  jruoho extern struct cfdriver icap_cd;
    103  1.1.8.2  jruoho 
    104  1.1.8.2  jruoho CFATTACH_DECL_NEW(icap_ebus, sizeof (struct icap_softc),
    105  1.1.8.2  jruoho     icap_ebus_match, icap_ebus_attach, NULL, NULL);
    106  1.1.8.2  jruoho 
    107  1.1.8.2  jruoho static int
    108  1.1.8.2  jruoho icap_ebus_match(struct device *parent, struct cfdata *match, void *aux)
    109  1.1.8.2  jruoho {
    110  1.1.8.2  jruoho 	struct ebus_attach_args *ia = aux;
    111  1.1.8.2  jruoho     struct _Icap *f = (struct _Icap *)ia->ia_vaddr;
    112  1.1.8.2  jruoho 
    113  1.1.8.2  jruoho 	DEBUG_PRINT(("icap_match %x\n", (f) ? f->Tag : 0), DEBUG_PROBE);
    114  1.1.8.2  jruoho 	if (strcmp("icap", ia->ia_name) != 0)
    115  1.1.8.2  jruoho 		return (0);
    116  1.1.8.2  jruoho     if ((f == NULL) ||
    117  1.1.8.2  jruoho         (! (f->Tag == PMTTAG_ICAP)))
    118  1.1.8.2  jruoho 		return (0);
    119  1.1.8.2  jruoho 
    120  1.1.8.2  jruoho 	return (1);
    121  1.1.8.2  jruoho }
    122  1.1.8.2  jruoho 
    123  1.1.8.2  jruoho static void
    124  1.1.8.2  jruoho icap_ebus_attach(struct device *parent, struct device *self, void *aux)
    125  1.1.8.2  jruoho {
    126  1.1.8.2  jruoho 	struct icap_softc *sc = device_private(self);
    127  1.1.8.2  jruoho 	struct ebus_attach_args *ia =aux;
    128  1.1.8.2  jruoho 
    129  1.1.8.2  jruoho 	DEBUG_PRINT(("icap_attach %p\n", sc), DEBUG_PROBE);
    130  1.1.8.2  jruoho 
    131  1.1.8.2  jruoho 	sc->sc_dev = self;
    132  1.1.8.2  jruoho 	sc->sc_dp = (struct _Icap*)ia->ia_vaddr;
    133  1.1.8.2  jruoho 	bufq_alloc(&sc->sc_buflist, "fcfs", 0);
    134  1.1.8.2  jruoho 	sc->sc_bp = NULL;
    135  1.1.8.2  jruoho 	sc->sc_data = NULL;
    136  1.1.8.2  jruoho 	sc->sc_count = 0;
    137  1.1.8.2  jruoho 
    138  1.1.8.2  jruoho #if DEBUG
    139  1.1.8.2  jruoho     printf(" virt=%p", (void*)sc->sc_dp);
    140  1.1.8.2  jruoho #endif
    141  1.1.8.2  jruoho 	printf(": %s\n", "Internal Configuration Access Port");
    142  1.1.8.2  jruoho 
    143  1.1.8.2  jruoho 	ebus_intr_establish(parent, (void*)ia->ia_cookie, IPL_BIO,
    144  1.1.8.2  jruoho 	    icap_ebus_intr, sc);
    145  1.1.8.2  jruoho 
    146  1.1.8.2  jruoho 	icap_reset(sc);
    147  1.1.8.2  jruoho }
    148  1.1.8.2  jruoho 
    149  1.1.8.2  jruoho /* The character device handlers
    150  1.1.8.2  jruoho  */
    151  1.1.8.2  jruoho const struct cdevsw icap_cdevsw = {
    152  1.1.8.2  jruoho 	icapopen,
    153  1.1.8.2  jruoho 	icapclose,
    154  1.1.8.2  jruoho 	icapread,
    155  1.1.8.2  jruoho 	icapwrite,
    156  1.1.8.2  jruoho 	icapioctl,
    157  1.1.8.2  jruoho 	nostop,
    158  1.1.8.2  jruoho 	notty,
    159  1.1.8.2  jruoho 	nopoll,
    160  1.1.8.2  jruoho 	nommap,
    161  1.1.8.2  jruoho 	nokqfilter,
    162  1.1.8.2  jruoho };
    163  1.1.8.2  jruoho 
    164  1.1.8.2  jruoho /*
    165  1.1.8.2  jruoho  * Handle an open request on the device.
    166  1.1.8.2  jruoho  */
    167  1.1.8.2  jruoho static int
    168  1.1.8.2  jruoho icapopen(dev_t device, int flags, int fmt, struct lwp *process)
    169  1.1.8.2  jruoho {
    170  1.1.8.2  jruoho 	struct icap_softc *sc;
    171  1.1.8.2  jruoho 
    172  1.1.8.2  jruoho 	DEBUG_PRINT(("icapopen\n"), DEBUG_FUNCS);
    173  1.1.8.2  jruoho 	sc = device_lookup_private(&icap_cd, minor(device));
    174  1.1.8.2  jruoho 	if (sc == NULL)
    175  1.1.8.2  jruoho 		return (ENXIO);
    176  1.1.8.2  jruoho 
    177  1.1.8.2  jruoho 	return 0;
    178  1.1.8.2  jruoho }
    179  1.1.8.2  jruoho 
    180  1.1.8.2  jruoho /*
    181  1.1.8.2  jruoho  * Handle the close request for the device.
    182  1.1.8.2  jruoho  */
    183  1.1.8.2  jruoho static int
    184  1.1.8.2  jruoho icapclose(dev_t device, int flags, int fmt, struct lwp *process)
    185  1.1.8.2  jruoho {
    186  1.1.8.2  jruoho 	DEBUG_PRINT(("icapclose\n"), DEBUG_FUNCS);
    187  1.1.8.2  jruoho 	return 0; /* this always succeeds */
    188  1.1.8.2  jruoho }
    189  1.1.8.2  jruoho 
    190  1.1.8.2  jruoho /*
    191  1.1.8.2  jruoho  * Handle the read request for the device.
    192  1.1.8.2  jruoho  */
    193  1.1.8.2  jruoho static int
    194  1.1.8.2  jruoho icapread(dev_t dev, struct uio *uio, int flags)
    195  1.1.8.2  jruoho {
    196  1.1.8.2  jruoho 	DEBUG_PRINT(("icapread\n"), DEBUG_READS);
    197  1.1.8.2  jruoho 	return (physio(icapstrategy, NULL, dev, B_READ, minphys, uio));
    198  1.1.8.2  jruoho }
    199  1.1.8.2  jruoho 
    200  1.1.8.2  jruoho /*
    201  1.1.8.2  jruoho  * Handle the write request for the device.
    202  1.1.8.2  jruoho  */
    203  1.1.8.2  jruoho static int
    204  1.1.8.2  jruoho icapwrite(dev_t dev, struct uio *uio, int flags)
    205  1.1.8.2  jruoho {
    206  1.1.8.2  jruoho 	DEBUG_PRINT(("icapwrite\n"), DEBUG_WRITES);
    207  1.1.8.2  jruoho 	return (physio(icapstrategy, NULL, dev, B_WRITE, minphys, uio));
    208  1.1.8.2  jruoho }
    209  1.1.8.2  jruoho 
    210  1.1.8.2  jruoho /*
    211  1.1.8.2  jruoho  * Handle the ioctl request for the device.
    212  1.1.8.2  jruoho  */
    213  1.1.8.2  jruoho static int
    214  1.1.8.2  jruoho icapioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
    215  1.1.8.2  jruoho {
    216  1.1.8.2  jruoho 
    217  1.1.8.2  jruoho 	return ENOTTY;
    218  1.1.8.2  jruoho }
    219  1.1.8.2  jruoho 
    220  1.1.8.2  jruoho /*
    221  1.1.8.2  jruoho  * Strategy function for the device.
    222  1.1.8.2  jruoho  */
    223  1.1.8.2  jruoho static void
    224  1.1.8.2  jruoho icapstrategy(struct buf *bp)
    225  1.1.8.2  jruoho {
    226  1.1.8.2  jruoho 	struct icap_softc *sc;
    227  1.1.8.2  jruoho 	int s;
    228  1.1.8.2  jruoho 
    229  1.1.8.2  jruoho 	DEBUG_PRINT(("icapstrategy\n"), DEBUG_FUNCS);
    230  1.1.8.2  jruoho 
    231  1.1.8.2  jruoho 	/* We did nothing lest we did */
    232  1.1.8.2  jruoho 	bp->b_resid = bp->b_bcount;
    233  1.1.8.2  jruoho 
    234  1.1.8.2  jruoho 	/* Do we know you.  */
    235  1.1.8.2  jruoho 	sc = device_lookup_private(&icap_cd, minor(bp->b_dev));
    236  1.1.8.2  jruoho 	if (sc == NULL) {
    237  1.1.8.2  jruoho 		DEBUG_PRINT(("icapstrategy: nodev %x\n",bp->b_dev),
    238  1.1.8.2  jruoho 		    DEBUG_ERRORS);
    239  1.1.8.2  jruoho 		bp->b_error = ENXIO;
    240  1.1.8.2  jruoho 		biodone(bp);
    241  1.1.8.2  jruoho 		return;
    242  1.1.8.2  jruoho 	    }
    243  1.1.8.2  jruoho 
    244  1.1.8.2  jruoho 	/* Add to Q. If Q was empty get it started */
    245  1.1.8.2  jruoho 	s = splbio();
    246  1.1.8.2  jruoho 	bufq_put(sc->sc_buflist, bp);
    247  1.1.8.2  jruoho 	if (bufq_peek(sc->sc_buflist) == bp) {
    248  1.1.8.2  jruoho 		icapstart(sc);
    249  1.1.8.2  jruoho 	}
    250  1.1.8.2  jruoho 	splx(s);
    251  1.1.8.2  jruoho }
    252  1.1.8.2  jruoho 
    253  1.1.8.2  jruoho /*
    254  1.1.8.2  jruoho  * Get the next I/O request started
    255  1.1.8.2  jruoho  */
    256  1.1.8.2  jruoho static void
    257  1.1.8.2  jruoho icapstart(struct icap_softc *sc)
    258  1.1.8.2  jruoho {
    259  1.1.8.2  jruoho 	paddr_t phys, phys2;
    260  1.1.8.2  jruoho 	vaddr_t virt;
    261  1.1.8.2  jruoho 	size_t count;
    262  1.1.8.2  jruoho 	uint32_t fl;
    263  1.1.8.2  jruoho 	struct buf *bp = sc->sc_bp;
    264  1.1.8.2  jruoho 
    265  1.1.8.2  jruoho 	DEBUG_PRINT(("icapstart %p %p\n",sc,bp), DEBUG_FUNCS);
    266  1.1.8.2  jruoho 
    267  1.1.8.2  jruoho     /* Were we idle?
    268  1.1.8.2  jruoho      */
    269  1.1.8.2  jruoho  recheck:
    270  1.1.8.2  jruoho     if (bp == NULL) {
    271  1.1.8.2  jruoho 
    272  1.1.8.2  jruoho         /* Yes, get the next request if any
    273  1.1.8.2  jruoho          */
    274  1.1.8.2  jruoho         bp = bufq_get(sc->sc_buflist);
    275  1.1.8.2  jruoho         DEBUG_PRINT(("icapnext: %p\n",bp), DEBUG_XFERS);
    276  1.1.8.2  jruoho         if (bp == NULL)
    277  1.1.8.2  jruoho             return;
    278  1.1.8.2  jruoho     }
    279  1.1.8.2  jruoho 
    280  1.1.8.2  jruoho     /* Done with this request?
    281  1.1.8.2  jruoho      */
    282  1.1.8.2  jruoho     if ((bp->b_resid == 0) || bp->b_error) {
    283  1.1.8.2  jruoho 
    284  1.1.8.2  jruoho         /* Yes, complete and move to next, if any
    285  1.1.8.2  jruoho          */
    286  1.1.8.2  jruoho         sc->sc_bp = NULL;
    287  1.1.8.2  jruoho         biodone(bp);
    288  1.1.8.2  jruoho         DEBUG_PRINT(("icapdone %p\n",bp), DEBUG_XFERS);
    289  1.1.8.2  jruoho         bp = NULL;
    290  1.1.8.2  jruoho         goto recheck;
    291  1.1.8.2  jruoho     }
    292  1.1.8.2  jruoho 
    293  1.1.8.2  jruoho     /* If new request init the xfer info
    294  1.1.8.2  jruoho      */
    295  1.1.8.2  jruoho     if (sc->sc_bp == NULL) {
    296  1.1.8.2  jruoho         sc->sc_bp = bp;
    297  1.1.8.2  jruoho         sc->sc_data = bp->b_data;
    298  1.1.8.2  jruoho         sc->sc_count = bp->b_resid;
    299  1.1.8.2  jruoho     }
    300  1.1.8.2  jruoho 
    301  1.1.8.2  jruoho     /* Loop filling as many buffers as will fit in the FIFO
    302  1.1.8.2  jruoho      */
    303  1.1.8.2  jruoho     fl = (bp->b_flags & B_READ) ? ICAPS_F_RECV : ICAPS_F_XMIT;
    304  1.1.8.2  jruoho     for (;;) {
    305  1.1.8.2  jruoho 
    306  1.1.8.2  jruoho         /* Make sure there's still room in the FIFO, no errors.
    307  1.1.8.2  jruoho          */
    308  1.1.8.2  jruoho         if (sc->sc_dp->Control & (ICAPC_IF_FULL|ICAPC_ERROR))
    309  1.1.8.2  jruoho             break;
    310  1.1.8.2  jruoho 
    311  1.1.8.2  jruoho         /* How much data do we xfer and where
    312  1.1.8.2  jruoho          */
    313  1.1.8.2  jruoho         virt = (vaddr_t)sc->sc_data;
    314  1.1.8.2  jruoho         phys = kvtophys(virt);
    315  1.1.8.2  jruoho         count = round_page(virt) - virt;
    316  1.1.8.2  jruoho         if (count == 0) count = PAGE_SIZE;/* could(will) be aligned */
    317  1.1.8.2  jruoho 
    318  1.1.8.2  jruoho         /* How much of it is contiguous
    319  1.1.8.2  jruoho          */
    320  1.1.8.2  jruoho         while (count < sc->sc_count) {
    321  1.1.8.2  jruoho             phys2 = kvtophys(virt + count);
    322  1.1.8.2  jruoho             if (phys2 != (phys + count)) {
    323  1.1.8.2  jruoho 
    324  1.1.8.2  jruoho                 /* No longer contig, ship it
    325  1.1.8.2  jruoho                  */
    326  1.1.8.2  jruoho                 break;
    327  1.1.8.2  jruoho             }
    328  1.1.8.2  jruoho             count += PAGE_SIZE;
    329  1.1.8.2  jruoho         }
    330  1.1.8.2  jruoho 
    331  1.1.8.2  jruoho         /* Trim if we went too far
    332  1.1.8.2  jruoho          */
    333  1.1.8.2  jruoho         if (count > sc->sc_count)
    334  1.1.8.2  jruoho             count = sc->sc_count;
    335  1.1.8.2  jruoho 
    336  1.1.8.2  jruoho         /* Ship it
    337  1.1.8.2  jruoho          */
    338  1.1.8.2  jruoho         DEBUG_PRINT(("icapship %lx %d\n",phys,count), DEBUG_XFERS);
    339  1.1.8.2  jruoho         sc->sc_dp->SizeAndFlags = fl | count;
    340  1.1.8.2  jruoho         sc->sc_dp->BufferAddressHi32 = 0; /* BUGBUG 64bit */
    341  1.1.8.2  jruoho         sc->sc_dp->BufferAddressLo32 = phys; /* this pushes the fifo */
    342  1.1.8.2  jruoho 
    343  1.1.8.2  jruoho         /* Adjust pointers and continue
    344  1.1.8.2  jruoho          */
    345  1.1.8.2  jruoho         sc->sc_data  += count;
    346  1.1.8.2  jruoho         sc->sc_count -= count;
    347  1.1.8.2  jruoho 
    348  1.1.8.2  jruoho         if (sc->sc_count <= 0)
    349  1.1.8.2  jruoho             break;
    350  1.1.8.2  jruoho     }
    351  1.1.8.2  jruoho }
    352  1.1.8.2  jruoho 
    353  1.1.8.2  jruoho /*
    354  1.1.8.2  jruoho  * Interrupt handler
    355  1.1.8.2  jruoho  */
    356  1.1.8.2  jruoho static int
    357  1.1.8.2  jruoho icap_ebus_intr(void *cookie, void *f)
    358  1.1.8.2  jruoho {
    359  1.1.8.2  jruoho 	struct icap_softc *sc = cookie;
    360  1.1.8.2  jruoho     struct buf *bp = sc->sc_bp;
    361  1.1.8.2  jruoho 	u_int32_t isr, saf = 0, hi, lo;
    362  1.1.8.2  jruoho 
    363  1.1.8.2  jruoho 	isr = sc->sc_dp->Control;
    364  1.1.8.2  jruoho 
    365  1.1.8.2  jruoho 	DEBUG_PRINT(("i %x\n",isr), DEBUG_INTR);
    366  1.1.8.2  jruoho 
    367  1.1.8.2  jruoho     /* Make sure there is an interrupt and that we should take it
    368  1.1.8.2  jruoho      */
    369  1.1.8.2  jruoho 	if ((isr & (ICAPC_INTEN|ICAPC_DONE)) != (ICAPC_INTEN|ICAPC_DONE))
    370  1.1.8.2  jruoho 		return (0);
    371  1.1.8.2  jruoho 
    372  1.1.8.2  jruoho     /* Pull out all completed buffers
    373  1.1.8.2  jruoho      */
    374  1.1.8.2  jruoho     while ((isr & ICAPC_OF_EMPTY) == 0) {
    375  1.1.8.2  jruoho 
    376  1.1.8.2  jruoho         if (isr & ICAPC_ERROR) {
    377  1.1.8.2  jruoho             printf("%s: internal error (%x)\n", device_xname(sc->sc_dev),isr);
    378  1.1.8.2  jruoho             icap_reset(sc);
    379  1.1.8.2  jruoho             if (bp) {
    380  1.1.8.2  jruoho                 bp->b_error = EIO;
    381  1.1.8.2  jruoho                 icapstart(sc);
    382  1.1.8.2  jruoho             }
    383  1.1.8.2  jruoho             return (1);
    384  1.1.8.2  jruoho         }
    385  1.1.8.2  jruoho 
    386  1.1.8.2  jruoho         /* Beware, order matters */
    387  1.1.8.2  jruoho         saf = sc->sc_dp->SizeAndFlags;
    388  1.1.8.2  jruoho         hi  = sc->sc_dp->BufferAddressHi32; /* BUGBUG 64bit */
    389  1.1.8.2  jruoho         lo  = sc->sc_dp->BufferAddressLo32; /* this pops the fifo */
    390  1.1.8.2  jruoho 
    391  1.1.8.2  jruoho         /* Say its done that much (and sanity)
    392  1.1.8.2  jruoho          */
    393  1.1.8.2  jruoho         if (bp) {
    394  1.1.8.2  jruoho             size_t count = saf & ICAPS_S_MASK;
    395  1.1.8.2  jruoho             /* more sanity */
    396  1.1.8.2  jruoho             if (count > bp->b_resid)
    397  1.1.8.2  jruoho                 count = bp->b_resid;
    398  1.1.8.2  jruoho             bp->b_resid -= count;
    399  1.1.8.2  jruoho         }
    400  1.1.8.2  jruoho 
    401  1.1.8.2  jruoho         /* More? */
    402  1.1.8.2  jruoho         isr = sc->sc_dp->Control;
    403  1.1.8.2  jruoho     }
    404  1.1.8.2  jruoho 
    405  1.1.8.2  jruoho     /* Did we pop at least one */
    406  1.1.8.2  jruoho     if (saf)
    407  1.1.8.2  jruoho         icapstart(sc);
    408  1.1.8.2  jruoho 
    409  1.1.8.2  jruoho 	return (1);
    410  1.1.8.2  jruoho }
    411  1.1.8.2  jruoho 
    412  1.1.8.2  jruoho /*
    413  1.1.8.2  jruoho  * HW (re)Initialization
    414  1.1.8.2  jruoho  */
    415  1.1.8.2  jruoho static void
    416  1.1.8.2  jruoho icap_reset(struct icap_softc *sc)
    417  1.1.8.2  jruoho {
    418  1.1.8.2  jruoho 	DEBUG_PRINT(("icap_reset %x\n",sc->sc_dp->Control), DEBUG_STATUS);
    419  1.1.8.2  jruoho     sc->sc_dp->Control = ICAPC_RESET;
    420  1.1.8.2  jruoho     DELAY(2);
    421  1.1.8.2  jruoho     sc->sc_dp->Control = ICAPC_INTEN;
    422  1.1.8.2  jruoho }
    423