Home | History | Annotate | Line # | Download | only in dev
sci.c revision 1.1
      1  1.1  chopps  /*
      2  1.1  chopps  * Copyright (c) 1990 The Regents of the University of California.
      3  1.1  chopps  * All rights reserved.
      4  1.1  chopps  *
      5  1.1  chopps  * This code is derived from software contributed to Berkeley by
      6  1.1  chopps  * Van Jacobson of Lawrence Berkeley Laboratory.
      7  1.1  chopps  *
      8  1.1  chopps  * Redistribution and use in source and binary forms, with or without
      9  1.1  chopps  * modification, are permitted provided that the following conditions
     10  1.1  chopps  * are met:
     11  1.1  chopps  * 1. Redistributions of source code must retain the above copyright
     12  1.1  chopps  *    notice, this list of conditions and the following disclaimer.
     13  1.1  chopps  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  chopps  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  chopps  *    documentation and/or other materials provided with the distribution.
     16  1.1  chopps  * 3. All advertising materials mentioning features or use of this software
     17  1.1  chopps  *    must display the following acknowledgement:
     18  1.1  chopps  *	This product includes software developed by the University of
     19  1.1  chopps  *	California, Berkeley and its contributors.
     20  1.1  chopps  * 4. Neither the name of the University nor the names of its contributors
     21  1.1  chopps  *    may be used to endorse or promote products derived from this software
     22  1.1  chopps  *    without specific prior written permission.
     23  1.1  chopps  *
     24  1.1  chopps  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25  1.1  chopps  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  1.1  chopps  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  1.1  chopps  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28  1.1  chopps  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  1.1  chopps  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  1.1  chopps  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  1.1  chopps  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  1.1  chopps  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  1.1  chopps  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  1.1  chopps  * SUCH DAMAGE.
     35  1.1  chopps  *
     36  1.1  chopps  *	@(#)sci.c	7.5 (Berkeley) 5/4/91
     37  1.1  chopps  *	$Id: sci.c,v 1.1 1994/02/28 06:06:23 chopps Exp $
     38  1.1  chopps  *
     39  1.1  chopps  */
     40  1.1  chopps 
     41  1.1  chopps /*
     42  1.1  chopps  * AMIGA NCR 5380 scsi adaptor driver
     43  1.1  chopps  */
     44  1.1  chopps 
     45  1.1  chopps #include "mlhscsi.h"
     46  1.1  chopps #include "csa12gscsi.h"
     47  1.1  chopps #include "suprascsi.h"
     48  1.1  chopps #include "ivsscsi.h"
     49  1.1  chopps #if (NMLHSCSI + NCSA12GSCSI + NSUPRASCSI + NIVSSCSI) > 0
     50  1.1  chopps #define NSCI	NMLHSCSI
     51  1.1  chopps #if NSCI < NCSA12GSCSI
     52  1.1  chopps #undef NSCI
     53  1.1  chopps #define NSCI	NCSA12GSCSI
     54  1.1  chopps #endif
     55  1.1  chopps #if NSCI < NSUPRASCSI
     56  1.1  chopps #undef NSCI
     57  1.1  chopps #define NSCI	NSUPRASCI
     58  1.1  chopps #endif
     59  1.1  chopps #if NSCI < NIVSSCSI
     60  1.1  chopps #undef NSCI
     61  1.1  chopps #define NSCI	NIVSSCI
     62  1.1  chopps #endif
     63  1.1  chopps 
     64  1.1  chopps #ifndef lint
     65  1.1  chopps static char rcsid[] = "$Header: /tank/opengrok/rsync2/NetBSD/src/sys/arch/amiga/dev/sci.c,v 1.1 1994/02/28 06:06:23 chopps Exp $";
     66  1.1  chopps #endif
     67  1.1  chopps 
     68  1.1  chopps /* need to know if any tapes have been configured */
     69  1.1  chopps #include "st.h"
     70  1.1  chopps 
     71  1.1  chopps #include <sys/param.h>
     72  1.1  chopps #include <sys/systm.h>
     73  1.1  chopps #include <sys/buf.h>
     74  1.1  chopps #include <vm/vm.h>
     75  1.1  chopps #include <vm/vm_kern.h>
     76  1.1  chopps #include <vm/vm_page.h>
     77  1.1  chopps #include <vm/vm_statistics.h>
     78  1.1  chopps #include <machine/pmap.h>
     79  1.1  chopps 
     80  1.1  chopps #include <amiga/dev/device.h>
     81  1.1  chopps 
     82  1.1  chopps #include <amiga/dev/scsidefs.h>
     83  1.1  chopps #include <amiga/dev/scivar.h>
     84  1.1  chopps #include <amiga/dev/scireg.h>
     85  1.1  chopps 
     86  1.1  chopps #include <amiga/amiga/custom.h>
     87  1.1  chopps 
     88  1.1  chopps #include <machine/cpu.h>
     89  1.1  chopps 
     90  1.1  chopps extern u_int kvtop();
     91  1.1  chopps 
     92  1.1  chopps static int sci_wait __P((char until, int timeo, int line));
     93  1.1  chopps static void scsiabort __P((register struct sci_softc *dev, char *where));
     94  1.1  chopps static void scsierror __P((register struct sci_softc *dev, u_char csr));
     95  1.1  chopps static int issue_select __P((register struct sci_softc *dev, u_char target,
     96  1.1  chopps     u_char our_addr));
     97  1.1  chopps static int ixfer_out __P((register struct sci_softc *dev, int len,
     98  1.1  chopps     register u_char *buf, int phase));
     99  1.1  chopps static void ixfer_in __P((register struct sci_softc *dev, int len,
    100  1.1  chopps     register u_char *buf, int phase));
    101  1.1  chopps static int scsiicmd __P((struct sci_softc *dev, int target, u_char *cbuf,
    102  1.1  chopps     int clen, u_char *buf, int len, u_char xferphase));
    103  1.1  chopps 
    104  1.1  chopps 
    105  1.1  chopps /*
    106  1.1  chopps  * SCSI delays
    107  1.1  chopps  * In u-seconds, primarily for state changes on the SPC.
    108  1.1  chopps  */
    109  1.1  chopps #define	SCSI_CMD_WAIT	50000	/* wait per step of 'immediate' cmds */
    110  1.1  chopps #define	SCSI_DATA_WAIT	50000	/* wait per data in/out step */
    111  1.1  chopps #define	SCSI_INIT_WAIT	50000	/* wait per step (both) during init */
    112  1.1  chopps 
    113  1.1  chopps extern void _insque();
    114  1.1  chopps extern void _remque();
    115  1.1  chopps 
    116  1.1  chopps void scistart __P((int unit));
    117  1.1  chopps int scigo __P((int ctlr, int slave, int unit, struct buf *bp,
    118  1.1  chopps     struct scsi_fmt_cdb *cdb, int pad));
    119  1.1  chopps int sciintr __P((void));
    120  1.1  chopps void scidone __P((int unit));
    121  1.1  chopps int sciustart __P((int unit));
    122  1.1  chopps int scireq __P((register struct devqueue *dq));
    123  1.1  chopps void scifree __P((register struct devqueue *dq));
    124  1.1  chopps void scireset __P((int unit));
    125  1.1  chopps void sci_delay __P((int delay));
    126  1.1  chopps int sci_test_unit_rdy __P((int ctlr, int slave, int unit));
    127  1.1  chopps int sci_start_stop_unit __P((int ctlr, int slave, int unit, int start));
    128  1.1  chopps int sci_request_sense __P((int ctlr, int slave, int unit, u_char *buf,
    129  1.1  chopps     unsigned int len));
    130  1.1  chopps int sci_immed_command __P((int ctlr, int slave, int unit,
    131  1.1  chopps     struct scsi_fmt_cdb *cdb, u_char *buf, unsigned int len, int rd));
    132  1.1  chopps int sci_immed_command_nd __P((int ctlr, int slave, int unit,
    133  1.1  chopps      struct scsi_fmt_cdb *cdb));
    134  1.1  chopps int sci_tt_read __P((int ctlr, int slave, int unit, u_char *buf,
    135  1.1  chopps     u_int len, daddr_t blk, int bshift));
    136  1.1  chopps int sci_tt_write __P((int ctlr, int slave, int unit, u_char *buf,
    137  1.1  chopps     u_int len, daddr_t blk, int bshift));
    138  1.1  chopps #if NST > 0
    139  1.1  chopps int sci_tt_oddio __P((int ctlr, int slave, int unit, u_char *buf, u_int len, int b_flags, int freedma));
    140  1.1  chopps #endif
    141  1.1  chopps 
    142  1.1  chopps 
    143  1.1  chopps #if NMLHSCSI > 0
    144  1.1  chopps int mlhscsiinit ();
    145  1.1  chopps 
    146  1.1  chopps struct driver mlhscsidriver = {
    147  1.1  chopps 	(int (*)(void *)) mlhscsiinit, "Mlhscsi", (int (*)(int)) scistart,
    148  1.1  chopps 	(int (*)(int,...)) scigo, (int (*)(int,int)) sciintr,
    149  1.1  chopps 	(int (*)())scidone, sciustart, scireq, scifree, scireset,
    150  1.1  chopps 	sci_delay, sci_test_unit_rdy, sci_start_stop_unit,
    151  1.1  chopps 	sci_request_sense, sci_immed_command, sci_immed_command_nd,
    152  1.1  chopps 	sci_tt_read, sci_tt_write,
    153  1.1  chopps #if NST > 0
    154  1.1  chopps 	sci_tt_oddio
    155  1.1  chopps #else
    156  1.1  chopps 	NULL
    157  1.1  chopps #endif
    158  1.1  chopps };
    159  1.1  chopps #endif
    160  1.1  chopps 
    161  1.1  chopps #if NCSA12GSCSI > 0
    162  1.1  chopps int csa12gscsiinit ();
    163  1.1  chopps 
    164  1.1  chopps struct driver csa12gscsidriver = {
    165  1.1  chopps 	(int (*)(void *)) csa12gscsiinit, "Csa12gscsi", (int (*)(int)) scistart,
    166  1.1  chopps 	(int (*)(int,...)) scigo, (int (*)(int,int)) sciintr,
    167  1.1  chopps 	(int (*)())scidone, sciustart, scireq, scifree, scireset,
    168  1.1  chopps 	sci_delay, sci_test_unit_rdy, sci_start_stop_unit,
    169  1.1  chopps 	sci_request_sense, sci_immed_command, sci_immed_command_nd,
    170  1.1  chopps 	sci_tt_read, sci_tt_write,
    171  1.1  chopps #if NST > 0
    172  1.1  chopps 	sci_tt_oddio
    173  1.1  chopps #else
    174  1.1  chopps 	NULL
    175  1.1  chopps #endif
    176  1.1  chopps };
    177  1.1  chopps #endif
    178  1.1  chopps 
    179  1.1  chopps #if NSUPRASCSI > 0
    180  1.1  chopps int suprascsiinit ();
    181  1.1  chopps 
    182  1.1  chopps struct driver suprascsidriver = {
    183  1.1  chopps 	(int (*)(void *)) suprascsiinit, "Suprascsi", (int (*)(int)) scistart,
    184  1.1  chopps 	(int (*)(int,...)) scigo, (int (*)(int,int)) sciintr,
    185  1.1  chopps 	(int (*)())scidone, sciustart, scireq, scifree, scireset,
    186  1.1  chopps 	sci_delay, sci_test_unit_rdy, sci_start_stop_unit,
    187  1.1  chopps 	sci_request_sense, sci_immed_command, sci_immed_command_nd,
    188  1.1  chopps 	sci_tt_read, sci_tt_write,
    189  1.1  chopps #if NST > 0
    190  1.1  chopps 	sci_tt_oddio
    191  1.1  chopps #else
    192  1.1  chopps 	NULL
    193  1.1  chopps #endif
    194  1.1  chopps };
    195  1.1  chopps #endif
    196  1.1  chopps 
    197  1.1  chopps #if NIVSSCSI > 0
    198  1.1  chopps int ivsscsiinit ();
    199  1.1  chopps 
    200  1.1  chopps struct driver ivsscsidriver = {
    201  1.1  chopps 	(int (*)(void *)) ivsscsiinit, "IVSscsi", (int (*)(int)) scistart,
    202  1.1  chopps 	(int (*)(int,...)) scigo, (int (*)(int,int)) sciintr,
    203  1.1  chopps 	(int (*)())scidone, sciustart, scireq, scifree, scireset,
    204  1.1  chopps 	sci_delay, sci_test_unit_rdy, sci_start_stop_unit,
    205  1.1  chopps 	sci_request_sense, sci_immed_command, sci_immed_command_nd,
    206  1.1  chopps 	sci_tt_read, sci_tt_write,
    207  1.1  chopps #if NST > 0
    208  1.1  chopps 	sci_tt_oddio
    209  1.1  chopps #else
    210  1.1  chopps 	NULL
    211  1.1  chopps #endif
    212  1.1  chopps };
    213  1.1  chopps #endif
    214  1.1  chopps 
    215  1.1  chopps struct	sci_softc sci_softc[NSCI];
    216  1.1  chopps 
    217  1.1  chopps int sci_cmd_wait = SCSI_CMD_WAIT;
    218  1.1  chopps int sci_data_wait = SCSI_DATA_WAIT;
    219  1.1  chopps int sci_init_wait = SCSI_INIT_WAIT;
    220  1.1  chopps 
    221  1.1  chopps int sci_no_dma = 0;
    222  1.1  chopps 
    223  1.1  chopps #ifdef DEBUG
    224  1.1  chopps int	sci_debug = 0;
    225  1.1  chopps #define WAITHIST
    226  1.1  chopps #define QUASEL
    227  1.1  chopps 
    228  1.1  chopps static long	dmahits[NSCI];
    229  1.1  chopps static long	dmamisses[NSCI];
    230  1.1  chopps #endif
    231  1.1  chopps 
    232  1.1  chopps #ifdef QUASEL
    233  1.1  chopps #define QPRINTF(a) if (sci_debug > 1) printf a
    234  1.1  chopps #else
    235  1.1  chopps #define QPRINTF
    236  1.1  chopps #endif
    237  1.1  chopps 
    238  1.1  chopps #ifdef WAITHIST
    239  1.1  chopps #define MAXWAIT	1022
    240  1.1  chopps u_int	ixstart_wait[MAXWAIT+2];
    241  1.1  chopps u_int	ixin_wait[MAXWAIT+2];
    242  1.1  chopps u_int	ixout_wait[MAXWAIT+2];
    243  1.1  chopps u_int	mxin_wait[MAXWAIT+2];
    244  1.1  chopps u_int	mxin2_wait[MAXWAIT+2];
    245  1.1  chopps u_int	cxin_wait[MAXWAIT+2];
    246  1.1  chopps u_int	fxfr_wait[MAXWAIT+2];
    247  1.1  chopps u_int	sgo_wait[MAXWAIT+2];
    248  1.1  chopps #define HIST(h,w) (++h[((w)>MAXWAIT? MAXWAIT : ((w) < 0 ? -1 : (w))) + 1]);
    249  1.1  chopps #else
    250  1.1  chopps #define HIST(h,w)
    251  1.1  chopps #endif
    252  1.1  chopps 
    253  1.1  chopps #define	b_cylin		b_resid
    254  1.1  chopps 
    255  1.1  chopps static sci_wait (until, timeo, line)
    256  1.1  chopps 	char until;
    257  1.1  chopps 	int timeo;
    258  1.1  chopps 	int line;
    259  1.1  chopps {
    260  1.1  chopps 	register unsigned char val;
    261  1.1  chopps 
    262  1.1  chopps 	if (! timeo)
    263  1.1  chopps 		timeo = 1000000;	/* some large value.. */
    264  1.1  chopps 
    265  1.1  chopps 	return val;
    266  1.1  chopps }
    267  1.1  chopps 
    268  1.1  chopps static void
    269  1.1  chopps scsiabort(dev, where)
    270  1.1  chopps 	register struct sci_softc *dev;
    271  1.1  chopps 	char *where;
    272  1.1  chopps {
    273  1.1  chopps 
    274  1.1  chopps 	printf ("sci%d: abort %s: csr = 0x%02x, bus = 0x%02x\n",
    275  1.1  chopps 	  dev->sc_ac->amiga_unit,
    276  1.1  chopps 	  where, *dev->sci_csr, *dev->sci_bus_csr);
    277  1.1  chopps 
    278  1.1  chopps 	if (dev->sc_flags & SCI_SELECTED) {
    279  1.1  chopps 
    280  1.1  chopps 		/* XXX */
    281  1.1  chopps 		scireset (dev->sc_ac->amiga_unit);
    282  1.1  chopps 		/* lets just hope it worked.. */
    283  1.1  chopps 		dev->sc_flags &= ~SCI_SELECTED;
    284  1.1  chopps 	}
    285  1.1  chopps }
    286  1.1  chopps 
    287  1.1  chopps /*
    288  1.1  chopps  * XXX Set/reset long delays.
    289  1.1  chopps  *
    290  1.1  chopps  * if delay == 0, reset default delays
    291  1.1  chopps  * if delay < 0,  set both delays to default long initialization values
    292  1.1  chopps  * if delay > 0,  set both delays to this value
    293  1.1  chopps  *
    294  1.1  chopps  * Used when a devices is expected to respond slowly (e.g. during
    295  1.1  chopps  * initialization).
    296  1.1  chopps  */
    297  1.1  chopps void
    298  1.1  chopps sci_delay(delay)
    299  1.1  chopps 	int delay;
    300  1.1  chopps {
    301  1.1  chopps 	static int saved_cmd_wait, saved_data_wait;
    302  1.1  chopps 
    303  1.1  chopps 	if (delay) {
    304  1.1  chopps 		saved_cmd_wait = sci_cmd_wait;
    305  1.1  chopps 		saved_data_wait = sci_data_wait;
    306  1.1  chopps 		if (delay > 0)
    307  1.1  chopps 			sci_cmd_wait = sci_data_wait = delay;
    308  1.1  chopps 		else
    309  1.1  chopps 			sci_cmd_wait = sci_data_wait = sci_init_wait;
    310  1.1  chopps 	} else {
    311  1.1  chopps 		sci_cmd_wait = saved_cmd_wait;
    312  1.1  chopps 		sci_data_wait = saved_data_wait;
    313  1.1  chopps 	}
    314  1.1  chopps }
    315  1.1  chopps 
    316  1.1  chopps static int initialized[NSCI];
    317  1.1  chopps 
    318  1.1  chopps #if NMLHSCSI > 0
    319  1.1  chopps int
    320  1.1  chopps mlhscsiinit(ac)
    321  1.1  chopps 	register struct amiga_ctlr *ac;
    322  1.1  chopps {
    323  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ac->amiga_unit];
    324  1.1  chopps 
    325  1.1  chopps 	if (! ac->amiga_addr)
    326  1.1  chopps 		return 0;
    327  1.1  chopps 
    328  1.1  chopps 	if (initialized[ac->amiga_unit])
    329  1.1  chopps 		return 0;
    330  1.1  chopps 
    331  1.1  chopps 	if (ac->amiga_unit > NSCI)
    332  1.1  chopps 		return 0;
    333  1.1  chopps 
    334  1.1  chopps 	initialized[ac->amiga_unit] = 1;
    335  1.1  chopps 
    336  1.1  chopps 	/* advance ac->amiga_addr to point to the real sci-registers */
    337  1.1  chopps 	ac->amiga_addr = (caddr_t) ((int)ac->amiga_addr);
    338  1.1  chopps 	dev->sci_data = (caddr_t) ac->amiga_addr + 1;
    339  1.1  chopps 	dev->sci_odata = (caddr_t) ac->amiga_addr + 1;
    340  1.1  chopps 	dev->sci_icmd = (caddr_t) ac->amiga_addr + 3;
    341  1.1  chopps 	dev->sci_mode = (caddr_t) ac->amiga_addr + 5;
    342  1.1  chopps 	dev->sci_tcmd = (caddr_t) ac->amiga_addr + 7;
    343  1.1  chopps 	dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 9;
    344  1.1  chopps 	dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 9;
    345  1.1  chopps 	dev->sci_csr = (caddr_t) ac->amiga_addr + 11;
    346  1.1  chopps 	dev->sci_dma_send = (caddr_t) ac->amiga_addr + 11;
    347  1.1  chopps 	dev->sci_idata = (caddr_t) ac->amiga_addr + 13;
    348  1.1  chopps 	dev->sci_trecv = (caddr_t) ac->amiga_addr + 13;
    349  1.1  chopps 	dev->sci_iack = (caddr_t) ac->amiga_addr + 15;
    350  1.1  chopps 	dev->sci_irecv = (caddr_t) ac->amiga_addr + 15;
    351  1.1  chopps 	mlhdmainit (dev);
    352  1.1  chopps 
    353  1.1  chopps 	/* hardwired IPL */
    354  1.1  chopps 	ac->amiga_ipl = 0;		/* doesn't use interrupts */
    355  1.1  chopps 	dev->sc_ac = ac;
    356  1.1  chopps 	dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq;
    357  1.1  chopps 	scireset (ac->amiga_unit);
    358  1.1  chopps 
    359  1.1  chopps 	return(1);
    360  1.1  chopps }
    361  1.1  chopps #endif
    362  1.1  chopps 
    363  1.1  chopps #if NCSA12GSCSI > 0
    364  1.1  chopps int
    365  1.1  chopps csa12gscsiinit(ac)
    366  1.1  chopps 	register struct amiga_ctlr *ac;
    367  1.1  chopps {
    368  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ac->amiga_unit];
    369  1.1  chopps 
    370  1.1  chopps 	if (! ac->amiga_addr)
    371  1.1  chopps 		return 0;
    372  1.1  chopps 
    373  1.1  chopps 	if (initialized[ac->amiga_unit])
    374  1.1  chopps 		return 0;
    375  1.1  chopps 
    376  1.1  chopps 	if (ac->amiga_unit > NSCI)
    377  1.1  chopps 		return 0;
    378  1.1  chopps 
    379  1.1  chopps 	initialized[ac->amiga_unit] = 1;
    380  1.1  chopps 
    381  1.1  chopps 	/* advance ac->amiga_addr to point to the real sci-registers */
    382  1.1  chopps 	ac->amiga_addr = (caddr_t) ((int)ac->amiga_addr + 0x2000);
    383  1.1  chopps 	dev->sci_data = (caddr_t) ac->amiga_addr;
    384  1.1  chopps 	dev->sci_odata = (caddr_t) ac->amiga_addr;
    385  1.1  chopps 	dev->sci_icmd = (caddr_t) ac->amiga_addr + 0x10;
    386  1.1  chopps 	dev->sci_mode = (caddr_t) ac->amiga_addr + 0x20;
    387  1.1  chopps 	dev->sci_tcmd = (caddr_t) ac->amiga_addr + 0x30;
    388  1.1  chopps 	dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 0x40;
    389  1.1  chopps 	dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 0x40;
    390  1.1  chopps 	dev->sci_csr = (caddr_t) ac->amiga_addr + 0x50;
    391  1.1  chopps 	dev->sci_dma_send = (caddr_t) ac->amiga_addr + 0x50;
    392  1.1  chopps 	dev->sci_idata = (caddr_t) ac->amiga_addr + 0x60;
    393  1.1  chopps 	dev->sci_trecv = (caddr_t) ac->amiga_addr + 0x60;
    394  1.1  chopps 	dev->sci_iack = (caddr_t) ac->amiga_addr + 0x70;
    395  1.1  chopps 	dev->sci_irecv = (caddr_t) ac->amiga_addr + 0x70;
    396  1.1  chopps 	csa12gdmainit (dev);
    397  1.1  chopps 
    398  1.1  chopps 	/* hardwired IPL */
    399  1.1  chopps 	ac->amiga_ipl = 2;
    400  1.1  chopps 	dev->sc_ac = ac;
    401  1.1  chopps 	dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq;
    402  1.1  chopps 	scireset (ac->amiga_unit);
    403  1.1  chopps 
    404  1.1  chopps 	/* make sure IPL2 interrupts are delivered to the cpu when the sci
    405  1.1  chopps 	   generates some. Note that this does not yet enable sci-interrupts,
    406  1.1  chopps 	   this is handled in dma.c, which selectively enables interrupts only
    407  1.1  chopps 	   while DMA requests are pending.
    408  1.1  chopps 
    409  1.1  chopps 	   Note that enabling PORTS interrupts also enables keyboard interrupts
    410  1.1  chopps 	   as soon as the corresponding int-enable bit in CIA-A is set. */
    411  1.1  chopps 
    412  1.1  chopps 	custom.intreq = INTF_PORTS;
    413  1.1  chopps 	custom.intena = INTF_SETCLR | INTF_PORTS;
    414  1.1  chopps 	return(1);
    415  1.1  chopps }
    416  1.1  chopps #endif
    417  1.1  chopps 
    418  1.1  chopps #if NSUPRASCSI > 0
    419  1.1  chopps int
    420  1.1  chopps suprascsiinit(ac)
    421  1.1  chopps 	register struct amiga_ctlr *ac;
    422  1.1  chopps {
    423  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ac->amiga_unit];
    424  1.1  chopps 
    425  1.1  chopps 	if (! ac->amiga_addr)
    426  1.1  chopps 		return 0;
    427  1.1  chopps 
    428  1.1  chopps 	if (initialized[ac->amiga_unit])
    429  1.1  chopps 		return 0;
    430  1.1  chopps 
    431  1.1  chopps 	if (ac->amiga_unit > NSCI)
    432  1.1  chopps 		return 0;
    433  1.1  chopps 
    434  1.1  chopps 	initialized[ac->amiga_unit] = 1;
    435  1.1  chopps 
    436  1.1  chopps 	/* advance ac->amiga_addr to point to the real sci-registers */
    437  1.1  chopps 	/* XXX Supra Word Sync version 2 only for now !!! */
    438  1.1  chopps 	dev->sci_data = (caddr_t) ac->amiga_addr;
    439  1.1  chopps 	dev->sci_odata = (caddr_t) ac->amiga_addr;
    440  1.1  chopps 	dev->sci_icmd = (caddr_t) ac->amiga_addr + 2;
    441  1.1  chopps 	dev->sci_mode = (caddr_t) ac->amiga_addr + 4;
    442  1.1  chopps 	dev->sci_tcmd = (caddr_t) ac->amiga_addr + 6;
    443  1.1  chopps 	dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 8;
    444  1.1  chopps 	dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 8;
    445  1.1  chopps 	dev->sci_csr = (caddr_t) ac->amiga_addr + 10;
    446  1.1  chopps 	dev->sci_dma_send = (caddr_t) ac->amiga_addr + 10;
    447  1.1  chopps 	dev->sci_idata = (caddr_t) ac->amiga_addr + 12;
    448  1.1  chopps 	dev->sci_trecv = (caddr_t) ac->amiga_addr + 12;
    449  1.1  chopps 	dev->sci_iack = (caddr_t) ac->amiga_addr + 14;
    450  1.1  chopps 	dev->sci_irecv = (caddr_t) ac->amiga_addr + 14;
    451  1.1  chopps 	supradmainit (dev);
    452  1.1  chopps 
    453  1.1  chopps 	/* hardwired IPL */
    454  1.1  chopps 	ac->amiga_ipl = 2;
    455  1.1  chopps 	dev->sc_ac = ac;
    456  1.1  chopps 	dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq;
    457  1.1  chopps 	scireset (ac->amiga_unit);
    458  1.1  chopps 
    459  1.1  chopps 	/* make sure IPL2 interrupts are delivered to the cpu when the sci
    460  1.1  chopps 	   generates some. Note that this does not yet enable sci-interrupts,
    461  1.1  chopps 	   this is handled in dma.c, which selectively enables interrupts only
    462  1.1  chopps 	   while DMA requests are pending.
    463  1.1  chopps 
    464  1.1  chopps 	   Note that enabling PORTS interrupts also enables keyboard interrupts
    465  1.1  chopps 	   as soon as the corresponding int-enable bit in CIA-A is set. */
    466  1.1  chopps 
    467  1.1  chopps 	custom.intreq = INTF_PORTS;
    468  1.1  chopps 	custom.intena = INTF_SETCLR | INTF_PORTS;
    469  1.1  chopps 	return(1);
    470  1.1  chopps }
    471  1.1  chopps #endif
    472  1.1  chopps 
    473  1.1  chopps #if NIVSSCSI > 0
    474  1.1  chopps int
    475  1.1  chopps ivsscsiinit(ac)
    476  1.1  chopps 	register struct amiga_ctlr *ac;
    477  1.1  chopps {
    478  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ac->amiga_unit];
    479  1.1  chopps 
    480  1.1  chopps 	if (! ac->amiga_addr)
    481  1.1  chopps 		return 0;
    482  1.1  chopps 
    483  1.1  chopps 	if (initialized[ac->amiga_unit])
    484  1.1  chopps 		return 0;
    485  1.1  chopps 
    486  1.1  chopps 	if (ac->amiga_unit > NSCI)
    487  1.1  chopps 		return 0;
    488  1.1  chopps 
    489  1.1  chopps 	initialized[ac->amiga_unit] = 1;
    490  1.1  chopps 
    491  1.1  chopps 	/* advance ac->amiga_addr to point to the real sci-registers */
    492  1.1  chopps 	ac->amiga_addr = (caddr_t) ((int)ac->amiga_addr + 0x40);
    493  1.1  chopps 	dev->sci_data = (caddr_t) ac->amiga_addr;
    494  1.1  chopps 	dev->sci_odata = (caddr_t) ac->amiga_addr;
    495  1.1  chopps 	dev->sci_icmd = (caddr_t) ac->amiga_addr + 2;
    496  1.1  chopps 	dev->sci_mode = (caddr_t) ac->amiga_addr + 4;
    497  1.1  chopps 	dev->sci_tcmd = (caddr_t) ac->amiga_addr + 6;
    498  1.1  chopps 	dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 8;
    499  1.1  chopps 	dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 8;
    500  1.1  chopps 	dev->sci_csr = (caddr_t) ac->amiga_addr + 10;
    501  1.1  chopps 	dev->sci_dma_send = (caddr_t) ac->amiga_addr + 10;
    502  1.1  chopps 	dev->sci_idata = (caddr_t) ac->amiga_addr + 12;
    503  1.1  chopps 	dev->sci_trecv = (caddr_t) ac->amiga_addr + 12;
    504  1.1  chopps 	dev->sci_iack = (caddr_t) ac->amiga_addr + 14;
    505  1.1  chopps 	dev->sci_irecv = (caddr_t) ac->amiga_addr + 14;
    506  1.1  chopps 	ivsdmainit (dev);
    507  1.1  chopps 
    508  1.1  chopps 	/* hardwired IPL */
    509  1.1  chopps 	ac->amiga_ipl = 2;
    510  1.1  chopps 	dev->sc_ac = ac;
    511  1.1  chopps 	dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq;
    512  1.1  chopps 	scireset (ac->amiga_unit);
    513  1.1  chopps 
    514  1.1  chopps 	/* make sure IPL2 interrupts are delivered to the cpu when the sci
    515  1.1  chopps 	   generates some. Note that this does not yet enable sci-interrupts,
    516  1.1  chopps 	   this is handled in dma.c, which selectively enables interrupts only
    517  1.1  chopps 	   while DMA requests are pending.
    518  1.1  chopps 
    519  1.1  chopps 	   Note that enabling PORTS interrupts also enables keyboard interrupts
    520  1.1  chopps 	   as soon as the corresponding int-enable bit in CIA-A is set. */
    521  1.1  chopps 
    522  1.1  chopps 	custom.intreq = INTF_PORTS;
    523  1.1  chopps 	custom.intena = INTF_SETCLR | INTF_PORTS;
    524  1.1  chopps 	return(1);
    525  1.1  chopps }
    526  1.1  chopps #endif
    527  1.1  chopps 
    528  1.1  chopps void
    529  1.1  chopps scireset(unit)
    530  1.1  chopps 	register int unit;
    531  1.1  chopps {
    532  1.1  chopps 	register struct sci_softc *dev = &sci_softc[unit];
    533  1.1  chopps 	u_int i, s;
    534  1.1  chopps 	u_char my_id, csr;
    535  1.1  chopps 
    536  1.1  chopps 	if (dev->sc_flags & SCI_ALIVE)
    537  1.1  chopps 		scsiabort(dev, "reset");
    538  1.1  chopps 
    539  1.1  chopps 	printf("sci%d: ", unit);
    540  1.1  chopps 
    541  1.1  chopps 	s = splbio();
    542  1.1  chopps 	/* preserve our ID for now */
    543  1.1  chopps 	my_id = 7;
    544  1.1  chopps 
    545  1.1  chopps 	/*
    546  1.1  chopps 	 * Disable interrupts (in dmainit) then reset the chip
    547  1.1  chopps 	 */
    548  1.1  chopps 	*dev->sci_icmd = SCI_ICMD_TEST;
    549  1.1  chopps 	*dev->sci_icmd = SCI_ICMD_TEST | SCI_ICMD_RST;
    550  1.1  chopps 	DELAY (25);
    551  1.1  chopps 	*dev->sci_icmd = 0;
    552  1.1  chopps 
    553  1.1  chopps 	/*
    554  1.1  chopps 	 * Set up various chip parameters
    555  1.1  chopps 	 */
    556  1.1  chopps 	*dev->sci_icmd = 0;
    557  1.1  chopps 	*dev->sci_tcmd = 0;
    558  1.1  chopps 	*dev->sci_sel_enb = 0;
    559  1.1  chopps 
    560  1.1  chopps 	/* anything else was zeroed by reset */
    561  1.1  chopps 
    562  1.1  chopps 	splx (s);
    563  1.1  chopps 
    564  1.1  chopps 	printf("sci id %d\n", my_id);
    565  1.1  chopps 	dev->sc_flags |= SCI_ALIVE;
    566  1.1  chopps 	dev->sc_flags &= ~SCI_SELECTED;
    567  1.1  chopps }
    568  1.1  chopps 
    569  1.1  chopps static void
    570  1.1  chopps scsierror(dev, csr)
    571  1.1  chopps 	register struct sci_softc *dev;
    572  1.1  chopps 	u_char csr;
    573  1.1  chopps {
    574  1.1  chopps 	int unit = dev->sc_ac->amiga_unit;
    575  1.1  chopps 	char *sep = "";
    576  1.1  chopps 
    577  1.1  chopps 	printf("sci%d: ", unit);
    578  1.1  chopps 	printf("\n");
    579  1.1  chopps }
    580  1.1  chopps 
    581  1.1  chopps static int
    582  1.1  chopps issue_select(dev, target, our_addr)
    583  1.1  chopps 	register struct sci_softc *dev;
    584  1.1  chopps 	u_char target, our_addr;
    585  1.1  chopps {
    586  1.1  chopps 	register int timeo = 2500;
    587  1.1  chopps 
    588  1.1  chopps 	QPRINTF (("issue_select %d\n", target));
    589  1.1  chopps 
    590  1.1  chopps 	/* if we're already selected, return */
    591  1.1  chopps 	if (dev->sc_flags & SCI_SELECTED)	/* XXXX */
    592  1.1  chopps 		return 1;
    593  1.1  chopps 
    594  1.1  chopps 	if ((*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
    595  1.1  chopps 	    (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
    596  1.1  chopps 	    (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)))
    597  1.1  chopps 		return 1;
    598  1.1  chopps 
    599  1.1  chopps 	*dev->sci_tcmd = 0;
    600  1.1  chopps 	*dev->sci_odata = 0x80 + (1 << target);
    601  1.1  chopps 	*dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_SEL;
    602  1.1  chopps 	while ((*dev->sci_bus_csr & SCI_BUS_BSY) == 0) {
    603  1.1  chopps 		if (--timeo > 0) {
    604  1.1  chopps 			DELAY(100);
    605  1.1  chopps 		} else {
    606  1.1  chopps 			break;
    607  1.1  chopps 		}
    608  1.1  chopps 	}
    609  1.1  chopps 	if (timeo) {
    610  1.1  chopps 		*dev->sci_icmd = 0;
    611  1.1  chopps 		dev->sc_flags |= SCI_SELECTED;
    612  1.1  chopps 		return (0);
    613  1.1  chopps 	}
    614  1.1  chopps 	*dev->sci_icmd = 0;
    615  1.1  chopps 	return (1);
    616  1.1  chopps }
    617  1.1  chopps 
    618  1.1  chopps static int
    619  1.1  chopps ixfer_out(dev, len, buf, phase)
    620  1.1  chopps 	register struct sci_softc *dev;
    621  1.1  chopps 	int len;
    622  1.1  chopps 	register u_char *buf;
    623  1.1  chopps 	int phase;
    624  1.1  chopps {
    625  1.1  chopps 	register int wait = sci_data_wait;
    626  1.1  chopps 	u_char csr;
    627  1.1  chopps 
    628  1.1  chopps 	QPRINTF(("ixfer_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
    629  1.1  chopps 	  len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
    630  1.1  chopps 	  buf[6], buf[7], buf[8], buf[9]));
    631  1.1  chopps 
    632  1.1  chopps 	*dev->sci_tcmd = phase;
    633  1.1  chopps 	*dev->sci_icmd = SCI_ICMD_DATA;
    634  1.1  chopps 	for (;len > 0; len--) {
    635  1.1  chopps 		csr = *dev->sci_bus_csr;
    636  1.1  chopps 		while (!(csr & SCI_BUS_REQ)) {
    637  1.1  chopps 			if ((csr & SCI_BUS_BSY) == 0 || --wait < 0) {
    638  1.1  chopps #ifdef DEBUG
    639  1.1  chopps 				if (sci_debug)
    640  1.1  chopps 					printf("ixfer_out fail: l%d i%x w%d\n",
    641  1.1  chopps 					  len, csr, wait);
    642  1.1  chopps #endif
    643  1.1  chopps 				HIST(ixout_wait, wait)
    644  1.1  chopps 				return (len);
    645  1.1  chopps 			}
    646  1.1  chopps 			DELAY(1);
    647  1.1  chopps 			csr = *dev->sci_bus_csr;
    648  1.1  chopps 		}
    649  1.1  chopps 
    650  1.1  chopps 		if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH))
    651  1.1  chopps 			break;
    652  1.1  chopps 		*dev->sci_odata = *buf;
    653  1.1  chopps 		*dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_ACK;
    654  1.1  chopps 		buf++;
    655  1.1  chopps 		while (*dev->sci_bus_csr & SCI_BUS_REQ);
    656  1.1  chopps 		*dev->sci_icmd = SCI_ICMD_DATA;
    657  1.1  chopps 	}
    658  1.1  chopps 
    659  1.1  chopps 	QPRINTF(("ixfer_out done\n"));
    660  1.1  chopps 	/* this leaves with one csr to be read */
    661  1.1  chopps 	HIST(ixout_wait, wait)
    662  1.1  chopps 	return (0);
    663  1.1  chopps }
    664  1.1  chopps 
    665  1.1  chopps static void
    666  1.1  chopps ixfer_in(dev, len, buf, phase)
    667  1.1  chopps 	struct sci_softc *dev;
    668  1.1  chopps 	int len;
    669  1.1  chopps 	register u_char *buf;
    670  1.1  chopps 	int phase;
    671  1.1  chopps {
    672  1.1  chopps 	int wait = sci_data_wait;
    673  1.1  chopps 	u_char *obp = buf;
    674  1.1  chopps 	u_char csr;
    675  1.1  chopps 	volatile register u_char *sci_bus_csr = dev->sci_bus_csr;
    676  1.1  chopps 	volatile register u_char *sci_data = dev->sci_data;
    677  1.1  chopps 	volatile register u_char *sci_icmd = dev->sci_icmd;
    678  1.1  chopps 
    679  1.1  chopps 	csr = *sci_bus_csr;
    680  1.1  chopps 
    681  1.1  chopps 	QPRINTF(("ixfer_in %d, csr=%02x\n", len, csr));
    682  1.1  chopps 
    683  1.1  chopps 	*dev->sci_tcmd = phase;
    684  1.1  chopps 	*sci_icmd = 0;
    685  1.1  chopps 	for (;len > 0; len--) {
    686  1.1  chopps 		csr = *sci_bus_csr;
    687  1.1  chopps 		while (!(csr & SCI_BUS_REQ)) {
    688  1.1  chopps 			if (!(csr & SCI_BUS_BSY) || --wait < 0) {
    689  1.1  chopps #ifdef DEBUG
    690  1.1  chopps 				if (sci_debug)
    691  1.1  chopps 					printf("ixfer_in fail: l%d i%x w%d\n",
    692  1.1  chopps 					len, csr, wait);
    693  1.1  chopps #endif
    694  1.1  chopps 				HIST(ixin_wait, wait)
    695  1.1  chopps 				return;
    696  1.1  chopps 			}
    697  1.1  chopps 
    698  1.1  chopps 			DELAY(1);
    699  1.1  chopps 			csr = *sci_bus_csr;
    700  1.1  chopps 		}
    701  1.1  chopps 
    702  1.1  chopps 		if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH))
    703  1.1  chopps 			break;
    704  1.1  chopps 		*buf = *sci_data;
    705  1.1  chopps 		*sci_icmd = SCI_ICMD_ACK;
    706  1.1  chopps 		buf++;
    707  1.1  chopps 		while (*sci_bus_csr & SCI_BUS_REQ);
    708  1.1  chopps 		*sci_icmd = 0;
    709  1.1  chopps 	}
    710  1.1  chopps 
    711  1.1  chopps 	QPRINTF(("ixfer_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
    712  1.1  chopps 	  len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
    713  1.1  chopps 	  obp[6], obp[7], obp[8], obp[9]));
    714  1.1  chopps 
    715  1.1  chopps 	/* this leaves with one csr to be read */
    716  1.1  chopps 	HIST(ixin_wait, wait)
    717  1.1  chopps }
    718  1.1  chopps 
    719  1.1  chopps /*
    720  1.1  chopps  * SCSI 'immediate' command:  issue a command to some SCSI device
    721  1.1  chopps  * and get back an 'immediate' response (i.e., do programmed xfer
    722  1.1  chopps  * to get the response data).  'cbuf' is a buffer containing a scsi
    723  1.1  chopps  * command of length clen bytes.  'buf' is a buffer of length 'len'
    724  1.1  chopps  * bytes for data.  The transfer direction is determined by the device
    725  1.1  chopps  * (i.e., by the scsi bus data xfer phase).  If 'len' is zero, the
    726  1.1  chopps  * command must supply no data.  'xferphase' is the bus phase the
    727  1.1  chopps  * caller expects to happen after the command is issued.  It should
    728  1.1  chopps  * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE.
    729  1.1  chopps  */
    730  1.1  chopps static int
    731  1.1  chopps scsiicmd(dev, target, cbuf, clen, buf, len, xferphase)
    732  1.1  chopps 	struct sci_softc *dev;
    733  1.1  chopps 	int target;
    734  1.1  chopps 	u_char *cbuf;
    735  1.1  chopps 	int clen;
    736  1.1  chopps 	u_char *buf;
    737  1.1  chopps 	int len;
    738  1.1  chopps 	u_char xferphase;
    739  1.1  chopps {
    740  1.1  chopps 	u_char phase, csr, asr;
    741  1.1  chopps 	register int wait;
    742  1.1  chopps 
    743  1.1  chopps 	/* select the SCSI bus (it's an error if bus isn't free) */
    744  1.1  chopps 	if (issue_select (dev, target, dev->sc_scsi_addr))
    745  1.1  chopps 		return -1;
    746  1.1  chopps 	/*
    747  1.1  chopps 	 * Wait for a phase change (or error) then let the device
    748  1.1  chopps 	 * sequence us through the various SCSI phases.
    749  1.1  chopps 	 */
    750  1.1  chopps 	dev->sc_stat[0] = 0xff;
    751  1.1  chopps 	dev->sc_msg[0] = 0xff;
    752  1.1  chopps 	phase = CMD_PHASE;
    753  1.1  chopps 	while (1) {
    754  1.1  chopps 		wait = sci_cmd_wait;
    755  1.1  chopps 
    756  1.1  chopps 		while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == SCI_BUS_BSY);
    757  1.1  chopps 
    758  1.1  chopps 		QPRINTF((">CSR:%02x<", *dev->sci_bus_csr));
    759  1.1  chopps 		if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) {
    760  1.1  chopps 			return -1;
    761  1.1  chopps 		}
    762  1.1  chopps 		phase = SCI_PHASE(*dev->sci_bus_csr);
    763  1.1  chopps 
    764  1.1  chopps 		switch (phase) {
    765  1.1  chopps 		case CMD_PHASE:
    766  1.1  chopps 			if (ixfer_out (dev, clen, cbuf, phase))
    767  1.1  chopps 				goto abort;
    768  1.1  chopps 			phase = xferphase;
    769  1.1  chopps 			break;
    770  1.1  chopps 
    771  1.1  chopps 		case DATA_IN_PHASE:
    772  1.1  chopps 			if (len <= 0)
    773  1.1  chopps 				goto abort;
    774  1.1  chopps 			wait = sci_data_wait;
    775  1.1  chopps 			ixfer_in (dev, len, buf, phase);
    776  1.1  chopps 			phase = STATUS_PHASE;
    777  1.1  chopps 			break;
    778  1.1  chopps 
    779  1.1  chopps 		case DATA_OUT_PHASE:
    780  1.1  chopps 			if (len <= 0)
    781  1.1  chopps 				goto abort;
    782  1.1  chopps 			wait = sci_data_wait;
    783  1.1  chopps 			if (ixfer_out (dev, len, buf, phase))
    784  1.1  chopps 				goto abort;
    785  1.1  chopps 			phase = STATUS_PHASE;
    786  1.1  chopps 			break;
    787  1.1  chopps 
    788  1.1  chopps 		case MESG_IN_PHASE:
    789  1.1  chopps 			dev->sc_msg[0] = 0xff;
    790  1.1  chopps 			ixfer_in (dev, 1, dev->sc_msg,phase);
    791  1.1  chopps 			dev->sc_flags &= ~SCI_SELECTED;
    792  1.1  chopps 			while (*dev->sci_bus_csr & SCI_BUS_BSY);
    793  1.1  chopps 			goto out;
    794  1.1  chopps 			break;
    795  1.1  chopps 
    796  1.1  chopps 		case MESG_OUT_PHASE:
    797  1.1  chopps 			phase = STATUS_PHASE;
    798  1.1  chopps 			break;
    799  1.1  chopps 
    800  1.1  chopps 		case STATUS_PHASE:
    801  1.1  chopps 			ixfer_in (dev, 1, dev->sc_stat, phase);
    802  1.1  chopps 			phase = MESG_IN_PHASE;
    803  1.1  chopps 			break;
    804  1.1  chopps 
    805  1.1  chopps 		case BUS_FREE_PHASE:
    806  1.1  chopps 			goto out;
    807  1.1  chopps 
    808  1.1  chopps 		default:
    809  1.1  chopps 		printf("sci: unexpected phase %d in icmd from %d\n",
    810  1.1  chopps 		  phase, target);
    811  1.1  chopps 		goto abort;
    812  1.1  chopps 		}
    813  1.1  chopps #if 0
    814  1.1  chopps 		if (wait <= 0)
    815  1.1  chopps 			goto abort;
    816  1.1  chopps #endif
    817  1.1  chopps 	}
    818  1.1  chopps 
    819  1.1  chopps abort:
    820  1.1  chopps 	scsiabort(dev, "icmd");
    821  1.1  chopps out:
    822  1.1  chopps 	QPRINTF(("=STS:%02x=", dev->sc_stat[0]));
    823  1.1  chopps 	return (dev->sc_stat[0]);
    824  1.1  chopps }
    825  1.1  chopps 
    826  1.1  chopps int
    827  1.1  chopps sci_test_unit_rdy(ctlr, slave, unit)
    828  1.1  chopps 	int ctlr, slave, unit;
    829  1.1  chopps {
    830  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ctlr];
    831  1.1  chopps 	static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY };
    832  1.1  chopps 
    833  1.1  chopps 	cdb.lun = unit;
    834  1.1  chopps 	return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), (u_char *)0, 0,
    835  1.1  chopps 			 STATUS_PHASE));
    836  1.1  chopps }
    837  1.1  chopps 
    838  1.1  chopps int
    839  1.1  chopps sci_start_stop_unit (ctlr, slave, unit, start)
    840  1.1  chopps 	int ctlr, slave, unit;
    841  1.1  chopps {
    842  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ctlr];
    843  1.1  chopps 	static struct scsi_cdb6 cdb = { CMD_LOADUNLOAD };
    844  1.1  chopps 
    845  1.1  chopps 	cdb.lun = unit;
    846  1.1  chopps 	/* we don't set the immediate bit, so we wait for the
    847  1.1  chopps 	   command to succeed.
    848  1.1  chopps 	   We also don't touch the LoEj bit, which is primarily meant
    849  1.1  chopps 	   for floppies. */
    850  1.1  chopps 	cdb.len = start & 0x01;
    851  1.1  chopps 	return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), (u_char *)0, 0,
    852  1.1  chopps 			 STATUS_PHASE));
    853  1.1  chopps }
    854  1.1  chopps 
    855  1.1  chopps 
    856  1.1  chopps int
    857  1.1  chopps sci_request_sense(ctlr, slave, unit, buf, len)
    858  1.1  chopps 	int ctlr, slave, unit;
    859  1.1  chopps 	u_char *buf;
    860  1.1  chopps 	unsigned len;
    861  1.1  chopps {
    862  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ctlr];
    863  1.1  chopps 	static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE };
    864  1.1  chopps 
    865  1.1  chopps 	cdb.lun = unit;
    866  1.1  chopps 	cdb.len = len;
    867  1.1  chopps 	return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), buf, len, DATA_IN_PHASE));
    868  1.1  chopps }
    869  1.1  chopps 
    870  1.1  chopps int
    871  1.1  chopps sci_immed_command_nd(ctlr, slave, unit, cdb)
    872  1.1  chopps 	int ctlr, slave, unit;
    873  1.1  chopps 	struct scsi_fmt_cdb *cdb;
    874  1.1  chopps {
    875  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ctlr];
    876  1.1  chopps 
    877  1.1  chopps 	cdb->cdb[1] |= (unit << 5);
    878  1.1  chopps 	return(scsiicmd(dev, slave, (u_char *) cdb->cdb, cdb->len,
    879  1.1  chopps 	    0, 0, STATUS_PHASE));
    880  1.1  chopps }
    881  1.1  chopps 
    882  1.1  chopps int
    883  1.1  chopps sci_immed_command(ctlr, slave, unit, cdb, buf, len, rd)
    884  1.1  chopps 	int ctlr, slave, unit;
    885  1.1  chopps 	struct scsi_fmt_cdb *cdb;
    886  1.1  chopps 	u_char *buf;
    887  1.1  chopps 	unsigned len;
    888  1.1  chopps {
    889  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ctlr];
    890  1.1  chopps 
    891  1.1  chopps 	cdb->cdb[1] |= (unit << 5);
    892  1.1  chopps 	return (scsiicmd(dev, slave, (u_char *) cdb->cdb, cdb->len, buf, len,
    893  1.1  chopps 			 rd != 0? DATA_IN_PHASE : DATA_OUT_PHASE));
    894  1.1  chopps }
    895  1.1  chopps 
    896  1.1  chopps /*
    897  1.1  chopps  * The following routines are test-and-transfer i/o versions of read/write
    898  1.1  chopps  * for things like reading disk labels and writing core dumps.  The
    899  1.1  chopps  * routine scigo should be used for normal data transfers, NOT these
    900  1.1  chopps  * routines.
    901  1.1  chopps  */
    902  1.1  chopps int
    903  1.1  chopps sci_tt_read(ctlr, slave, unit, buf, len, blk, bshift)
    904  1.1  chopps 	int ctlr, slave, unit;
    905  1.1  chopps 	u_char *buf;
    906  1.1  chopps 	u_int len;
    907  1.1  chopps 	daddr_t blk;
    908  1.1  chopps 	int bshift;
    909  1.1  chopps {
    910  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ctlr];
    911  1.1  chopps 	struct scsi_cdb10 cdb;
    912  1.1  chopps 	int stat;
    913  1.1  chopps 	int old_wait = sci_data_wait;
    914  1.1  chopps 
    915  1.1  chopps 	sci_data_wait = 300000;
    916  1.1  chopps 	bzero(&cdb, sizeof(cdb));
    917  1.1  chopps 	cdb.cmd = CMD_READ_EXT;
    918  1.1  chopps 	cdb.lun = unit;
    919  1.1  chopps 	blk >>= bshift;
    920  1.1  chopps 	cdb.lbah = blk >> 24;
    921  1.1  chopps 	cdb.lbahm = blk >> 16;
    922  1.1  chopps 	cdb.lbalm = blk >> 8;
    923  1.1  chopps 	cdb.lbal = blk;
    924  1.1  chopps 	cdb.lenh = len >> (8 + DEV_BSHIFT + bshift);
    925  1.1  chopps 	cdb.lenl = len >> (DEV_BSHIFT + bshift);
    926  1.1  chopps 	stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE);
    927  1.1  chopps 	sci_data_wait = old_wait;
    928  1.1  chopps 	return (stat);
    929  1.1  chopps }
    930  1.1  chopps 
    931  1.1  chopps int
    932  1.1  chopps sci_tt_write(ctlr, slave, unit, buf, len, blk, bshift)
    933  1.1  chopps 	int ctlr, slave, unit;
    934  1.1  chopps 	u_char *buf;
    935  1.1  chopps 	u_int len;
    936  1.1  chopps 	daddr_t blk;
    937  1.1  chopps 	int bshift;
    938  1.1  chopps {
    939  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ctlr];
    940  1.1  chopps 	struct scsi_cdb10 cdb;
    941  1.1  chopps 	int stat;
    942  1.1  chopps 	int old_wait = sci_data_wait;
    943  1.1  chopps 
    944  1.1  chopps 	sci_data_wait = 300000;
    945  1.1  chopps 
    946  1.1  chopps 	bzero(&cdb, sizeof(cdb));
    947  1.1  chopps 	cdb.cmd = CMD_WRITE_EXT;
    948  1.1  chopps 	cdb.lun = unit;
    949  1.1  chopps 	blk >>= bshift;
    950  1.1  chopps 	cdb.lbah = blk >> 24;
    951  1.1  chopps 	cdb.lbahm = blk >> 16;
    952  1.1  chopps 	cdb.lbalm = blk >> 8;
    953  1.1  chopps 	cdb.lbal = blk;
    954  1.1  chopps 	cdb.lenh = len >> (8 + DEV_BSHIFT + bshift);
    955  1.1  chopps 	cdb.lenl = len >> (DEV_BSHIFT + bshift);
    956  1.1  chopps 	stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, DATA_OUT_PHASE);
    957  1.1  chopps 	sci_data_wait = old_wait;
    958  1.1  chopps 	return (stat);
    959  1.1  chopps }
    960  1.1  chopps 
    961  1.1  chopps int
    962  1.1  chopps scireq(dq)
    963  1.1  chopps 	register struct devqueue *dq;
    964  1.1  chopps {
    965  1.1  chopps 	register struct devqueue *hq;
    966  1.1  chopps 
    967  1.1  chopps 	hq = &sci_softc[dq->dq_ctlr].sc_sq;
    968  1.1  chopps 	insque(dq, hq->dq_back);
    969  1.1  chopps 	if (dq->dq_back == hq)
    970  1.1  chopps 		return(1);
    971  1.1  chopps 	return(0);
    972  1.1  chopps }
    973  1.1  chopps 
    974  1.1  chopps int
    975  1.1  chopps sciustart (int unit)
    976  1.1  chopps {
    977  1.1  chopps 	register struct sci_softc *dev = &sci_softc[unit];
    978  1.1  chopps 
    979  1.1  chopps 	/* If we got here, this controller is not busy
    980  1.1  chopps 	   so we are ready to accept a command
    981  1.1  chopps 	 */
    982  1.1  chopps 	return(1);
    983  1.1  chopps }
    984  1.1  chopps 
    985  1.1  chopps void
    986  1.1  chopps scistart (int unit)
    987  1.1  chopps {
    988  1.1  chopps 	register struct devqueue *dq;
    989  1.1  chopps 
    990  1.1  chopps 	dq = sci_softc[unit].sc_sq.dq_forw;
    991  1.1  chopps 	(dq->dq_driver->d_go)(dq->dq_unit);
    992  1.1  chopps }
    993  1.1  chopps 
    994  1.1  chopps int
    995  1.1  chopps scigo(ctlr, slave, unit, bp, cdb, pad)
    996  1.1  chopps 	int ctlr, slave, unit;
    997  1.1  chopps 	struct buf *bp;
    998  1.1  chopps 	struct scsi_fmt_cdb *cdb;
    999  1.1  chopps 	int pad;
   1000  1.1  chopps {
   1001  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ctlr];
   1002  1.1  chopps 	u_char phase, csr, asr, cmd;
   1003  1.1  chopps 	char *addr;
   1004  1.1  chopps 	int count;
   1005  1.1  chopps 	register struct devqueue *dq;
   1006  1.1  chopps 
   1007  1.1  chopps 	cdb->cdb[1] |= unit << 5;
   1008  1.1  chopps 
   1009  1.1  chopps 	addr = bp->b_un.b_addr;
   1010  1.1  chopps 	count = bp->b_bcount;
   1011  1.1  chopps 
   1012  1.1  chopps 	if (sci_no_dma)	{
   1013  1.1  chopps 
   1014  1.1  chopps 		scsiicmd (dev, slave, (u_char *) cdb->cdb, cdb->len,
   1015  1.1  chopps 		  addr, count,
   1016  1.1  chopps 		  bp->b_flags & B_READ ? DATA_IN_PHASE : DATA_OUT_PHASE);
   1017  1.1  chopps 
   1018  1.1  chopps 		dq = dev->sc_sq.dq_forw;
   1019  1.1  chopps 		dev->sc_flags &=~ (SCI_IO);
   1020  1.1  chopps 		(dq->dq_driver->d_intr)(dq->dq_unit, dev->sc_stat[0]);
   1021  1.1  chopps 		return dev->sc_stat[0];
   1022  1.1  chopps 	}
   1023  1.1  chopps 
   1024  1.1  chopps 	/* select the SCSI bus (it's an error if bus isn't free) */
   1025  1.1  chopps 	if (issue_select (dev, slave, dev->sc_scsi_addr))
   1026  1.1  chopps 		return -1;
   1027  1.1  chopps 	/*
   1028  1.1  chopps 	 * Wait for a phase change (or error) then let the device
   1029  1.1  chopps 	 * sequence us through the various SCSI phases.
   1030  1.1  chopps 	 */
   1031  1.1  chopps 	dev->sc_stat[0] = 0xff;
   1032  1.1  chopps 	dev->sc_msg[0] = 0xff;
   1033  1.1  chopps 	phase = CMD_PHASE;
   1034  1.1  chopps 	while (1) {
   1035  1.1  chopps 		while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) ==
   1036  1.1  chopps 		  SCI_BUS_BSY);
   1037  1.1  chopps 
   1038  1.1  chopps 		QPRINTF((">CSR:%02x<", *dev->sci_bus_csr));
   1039  1.1  chopps 		if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) {
   1040  1.1  chopps 			goto abort;
   1041  1.1  chopps 		}
   1042  1.1  chopps 		phase = SCI_PHASE(*dev->sci_bus_csr);
   1043  1.1  chopps 
   1044  1.1  chopps 		switch (phase) {
   1045  1.1  chopps 		case CMD_PHASE:
   1046  1.1  chopps 			if (ixfer_out (dev, cdb->len, cdb->cdb, phase))
   1047  1.1  chopps 				goto abort;
   1048  1.1  chopps 			phase = bp->b_flags & B_READ ? DATA_IN_PHASE : DATA_OUT_PHASE;
   1049  1.1  chopps 			break;
   1050  1.1  chopps 
   1051  1.1  chopps 		case DATA_IN_PHASE:
   1052  1.1  chopps 			if (count <= 0)
   1053  1.1  chopps 				goto abort;
   1054  1.1  chopps 			/* XXX use psuedo DMA if available */
   1055  1.1  chopps 			if (count >= 128 && dev->dma_xfer_in)
   1056  1.1  chopps 				(*dev->dma_xfer_in)(dev, count, addr, phase);
   1057  1.1  chopps 			else
   1058  1.1  chopps 				ixfer_in (dev, count, addr, phase);
   1059  1.1  chopps 			phase = STATUS_PHASE;
   1060  1.1  chopps 			break;
   1061  1.1  chopps 
   1062  1.1  chopps 		case DATA_OUT_PHASE:
   1063  1.1  chopps 			if (count <= 0)
   1064  1.1  chopps 				goto abort;
   1065  1.1  chopps 			/* XXX use psuedo DMA if available */
   1066  1.1  chopps 			if (count >= 128 && dev->dma_xfer_out)
   1067  1.1  chopps 				(*dev->dma_xfer_out)(dev, count, addr, phase);
   1068  1.1  chopps 			else
   1069  1.1  chopps 				if (ixfer_out (dev, count, addr, phase))
   1070  1.1  chopps 					goto abort;
   1071  1.1  chopps 			phase = STATUS_PHASE;
   1072  1.1  chopps 			break;
   1073  1.1  chopps 
   1074  1.1  chopps 		case MESG_IN_PHASE:
   1075  1.1  chopps 			dev->sc_msg[0] = 0xff;
   1076  1.1  chopps 			ixfer_in (dev, 1, dev->sc_msg,phase);
   1077  1.1  chopps 			dev->sc_flags &= ~SCI_SELECTED;
   1078  1.1  chopps 			while (*dev->sci_bus_csr & SCI_BUS_BSY);
   1079  1.1  chopps 			goto out;
   1080  1.1  chopps 			break;
   1081  1.1  chopps 
   1082  1.1  chopps 		case MESG_OUT_PHASE:
   1083  1.1  chopps 			phase = STATUS_PHASE;
   1084  1.1  chopps 			break;
   1085  1.1  chopps 
   1086  1.1  chopps 		case STATUS_PHASE:
   1087  1.1  chopps 			ixfer_in (dev, 1, dev->sc_stat, phase);
   1088  1.1  chopps 			phase = MESG_IN_PHASE;
   1089  1.1  chopps 			break;
   1090  1.1  chopps 
   1091  1.1  chopps 		case BUS_FREE_PHASE:
   1092  1.1  chopps 			goto out;
   1093  1.1  chopps 
   1094  1.1  chopps 		default:
   1095  1.1  chopps 		printf("sci: unexpected phase %d in icmd from %d\n",
   1096  1.1  chopps 		  phase, slave);
   1097  1.1  chopps 		goto abort;
   1098  1.1  chopps 		}
   1099  1.1  chopps 	}
   1100  1.1  chopps 
   1101  1.1  chopps abort:
   1102  1.1  chopps 	scsiabort(dev, "go");
   1103  1.1  chopps out:
   1104  1.1  chopps 	QPRINTF(("=STS:%02x=", dev->sc_stat[0]));
   1105  1.1  chopps 	dq = dev->sc_sq.dq_forw;
   1106  1.1  chopps 	dev->sc_flags &=~ (SCI_IO);
   1107  1.1  chopps 	(dq->dq_driver->d_intr)(dq->dq_unit, dev->sc_stat[0]);
   1108  1.1  chopps 	return dev->sc_stat[0];
   1109  1.1  chopps }
   1110  1.1  chopps 
   1111  1.1  chopps void
   1112  1.1  chopps scidone (int unit)
   1113  1.1  chopps {
   1114  1.1  chopps 
   1115  1.1  chopps #ifdef DEBUG
   1116  1.1  chopps 	if (sci_debug)
   1117  1.1  chopps 		printf("sci%d: done called!\n", unit);
   1118  1.1  chopps #endif
   1119  1.1  chopps }
   1120  1.1  chopps 
   1121  1.1  chopps int
   1122  1.1  chopps sciintr ()
   1123  1.1  chopps {
   1124  1.1  chopps 	register struct sci_softc *dev = sci_softc;
   1125  1.1  chopps 	int unit;
   1126  1.1  chopps 	int dummy;
   1127  1.1  chopps 	int found = 0;
   1128  1.1  chopps 
   1129  1.1  chopps 	for (unit = 0; unit < NSCI; ++unit, ++dev) {
   1130  1.1  chopps 		if (dev->sc_ac->amiga_ipl == 0)
   1131  1.1  chopps 			continue;
   1132  1.1  chopps 		/* XXX check if expecting interrupt? */
   1133  1.1  chopps 		if (dev->dma_intr)
   1134  1.1  chopps 			found += (*dev->dma_intr)(dev);
   1135  1.1  chopps 		else if ((*dev->sci_csr & SCI_CSR_INT)) {
   1136  1.1  chopps 			*dev->sci_mode = 0;
   1137  1.1  chopps 			dummy = *dev->sci_iack;
   1138  1.1  chopps 			++found;
   1139  1.1  chopps 		}
   1140  1.1  chopps 	}
   1141  1.1  chopps 	return found;
   1142  1.1  chopps }
   1143  1.1  chopps 
   1144  1.1  chopps void
   1145  1.1  chopps scifree(dq)
   1146  1.1  chopps 	register struct devqueue *dq;
   1147  1.1  chopps {
   1148  1.1  chopps 	register struct devqueue *hq;
   1149  1.1  chopps 
   1150  1.1  chopps 	hq = &sci_softc[dq->dq_ctlr].sc_sq;
   1151  1.1  chopps 	remque(dq);
   1152  1.1  chopps 	if ((dq = hq->dq_forw) != hq)
   1153  1.1  chopps 		(dq->dq_driver->d_start)(dq->dq_unit);
   1154  1.1  chopps }
   1155  1.1  chopps 
   1156  1.1  chopps /*
   1157  1.1  chopps  * (XXX) The following routine is needed for the SCSI tape driver
   1158  1.1  chopps  * to read odd-size records.
   1159  1.1  chopps  */
   1160  1.1  chopps 
   1161  1.1  chopps #if NST > 0
   1162  1.1  chopps int
   1163  1.1  chopps sci_tt_oddio(ctlr, slave, unit, buf, len, b_flags, freedma)
   1164  1.1  chopps 	int ctlr, slave, unit, b_flags;
   1165  1.1  chopps 	u_char *buf;
   1166  1.1  chopps 	u_int len;
   1167  1.1  chopps {
   1168  1.1  chopps 	register struct sci_softc *dev = &sci_softc[ctlr];
   1169  1.1  chopps 	struct scsi_cdb6 cdb;
   1170  1.1  chopps 	u_char iphase;
   1171  1.1  chopps 	int stat;
   1172  1.1  chopps 
   1173  1.1  chopps 	/*
   1174  1.1  chopps 	 * First free any DMA channel that was allocated.
   1175  1.1  chopps 	 * We can't use DMA to do this transfer.
   1176  1.1  chopps 	 */
   1177  1.1  chopps 	/*
   1178  1.1  chopps 	 * Initialize command block
   1179  1.1  chopps 	 */
   1180  1.1  chopps 	bzero(&cdb, sizeof(cdb));
   1181  1.1  chopps 	cdb.lun  = unit;
   1182  1.1  chopps 	cdb.lbam = (len >> 16) & 0xff;
   1183  1.1  chopps 	cdb.lbal = (len >> 8) & 0xff;
   1184  1.1  chopps 	cdb.len = len & 0xff;
   1185  1.1  chopps 	if (buf == 0) {
   1186  1.1  chopps 		cdb.cmd = CMD_SPACE;
   1187  1.1  chopps 		cdb.lun |= 0x00;
   1188  1.1  chopps 		len = 0;
   1189  1.1  chopps 		iphase = MESG_IN_PHASE;
   1190  1.1  chopps 	} else if (b_flags & B_READ) {
   1191  1.1  chopps 		cdb.cmd = CMD_READ;
   1192  1.1  chopps 		iphase = DATA_IN_PHASE;
   1193  1.1  chopps 	} else {
   1194  1.1  chopps 		cdb.cmd = CMD_WRITE;
   1195  1.1  chopps 		iphase = DATA_OUT_PHASE;
   1196  1.1  chopps 	}
   1197  1.1  chopps 	/*
   1198  1.1  chopps 	 * Perform command (with very long delays)
   1199  1.1  chopps 	 */
   1200  1.1  chopps 	sci_delay(30000000);
   1201  1.1  chopps 	stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, iphase);
   1202  1.1  chopps 	sci_delay(0);
   1203  1.1  chopps 	return (stat);
   1204  1.1  chopps }
   1205  1.1  chopps #endif
   1206  1.1  chopps #endif
   1207