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