Home | History | Annotate | Line # | Download | only in jazz
asc.c revision 1.1.2.2
      1  1.1.2.2  bouyer /*	$NetBSD: asc.c,v 1.1.2.2 2001/01/05 17:33:57 bouyer Exp $	*/
      2  1.1.2.2  bouyer /*	$OpenBSD: asc.c,v 1.9 1998/03/16 09:38:39 pefo Exp $	*/
      3  1.1.2.2  bouyer /*	NetBSD: asc.c,v 1.10 1994/12/05 19:11:12 dean Exp 	*/
      4  1.1.2.2  bouyer 
      5  1.1.2.2  bouyer /*-
      6  1.1.2.2  bouyer  * Copyright (c) 1992, 1993
      7  1.1.2.2  bouyer  *	The Regents of the University of California.  All rights reserved.
      8  1.1.2.2  bouyer  *
      9  1.1.2.2  bouyer  * This code is derived from software contributed to Berkeley by
     10  1.1.2.2  bouyer  * Ralph Campbell and Rick Macklem.
     11  1.1.2.2  bouyer  *
     12  1.1.2.2  bouyer  * Redistribution and use in source and binary forms, with or without
     13  1.1.2.2  bouyer  * modification, are permitted provided that the following conditions
     14  1.1.2.2  bouyer  * are met:
     15  1.1.2.2  bouyer  * 1. Redistributions of source code must retain the above copyright
     16  1.1.2.2  bouyer  *    notice, this list of conditions and the following disclaimer.
     17  1.1.2.2  bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     18  1.1.2.2  bouyer  *    notice, this list of conditions and the following disclaimer in the
     19  1.1.2.2  bouyer  *    documentation and/or other materials provided with the distribution.
     20  1.1.2.2  bouyer  * 3. All advertising materials mentioning features or use of this software
     21  1.1.2.2  bouyer  *    must display the following acknowledgement:
     22  1.1.2.2  bouyer  *	This product includes software developed by the University of
     23  1.1.2.2  bouyer  *	California, Berkeley and its contributors.
     24  1.1.2.2  bouyer  * 4. Neither the name of the University nor the names of its contributors
     25  1.1.2.2  bouyer  *    may be used to endorse or promote products derived from this software
     26  1.1.2.2  bouyer  *    without specific prior written permission.
     27  1.1.2.2  bouyer  *
     28  1.1.2.2  bouyer  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     29  1.1.2.2  bouyer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     30  1.1.2.2  bouyer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     31  1.1.2.2  bouyer  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     32  1.1.2.2  bouyer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     33  1.1.2.2  bouyer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     34  1.1.2.2  bouyer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     35  1.1.2.2  bouyer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     36  1.1.2.2  bouyer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     37  1.1.2.2  bouyer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     38  1.1.2.2  bouyer  * SUCH DAMAGE.
     39  1.1.2.2  bouyer  *
     40  1.1.2.2  bouyer  *	@(#)asc.c	8.3 (Berkeley) 7/3/94
     41  1.1.2.2  bouyer  */
     42  1.1.2.2  bouyer 
     43  1.1.2.2  bouyer /*
     44  1.1.2.2  bouyer  * Mach Operating System
     45  1.1.2.2  bouyer  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
     46  1.1.2.2  bouyer  * All Rights Reserved.
     47  1.1.2.2  bouyer  *
     48  1.1.2.2  bouyer  * Permission to use, copy, modify and distribute this software and its
     49  1.1.2.2  bouyer  * documentation is hereby granted, provided that both the copyright
     50  1.1.2.2  bouyer  * notice and this permission notice appear in all copies of the
     51  1.1.2.2  bouyer  * software, derivative works or modified versions, and any portions
     52  1.1.2.2  bouyer  * thereof, and that both notices appear in supporting documentation.
     53  1.1.2.2  bouyer  *
     54  1.1.2.2  bouyer  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     55  1.1.2.2  bouyer  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
     56  1.1.2.2  bouyer  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     57  1.1.2.2  bouyer  *
     58  1.1.2.2  bouyer  * Carnegie Mellon requests users of this software to return to
     59  1.1.2.2  bouyer  *
     60  1.1.2.2  bouyer  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     61  1.1.2.2  bouyer  *  School of Computer Science
     62  1.1.2.2  bouyer  *  Carnegie Mellon University
     63  1.1.2.2  bouyer  *  Pittsburgh PA 15213-3890
     64  1.1.2.2  bouyer  *
     65  1.1.2.2  bouyer  * any improvements or extensions that they make and grant Carnegie the
     66  1.1.2.2  bouyer  * rights to redistribute these changes.
     67  1.1.2.2  bouyer  */
     68  1.1.2.2  bouyer 
     69  1.1.2.2  bouyer /*
     70  1.1.2.2  bouyer  * HISTORY
     71  1.1.2.2  bouyer  * Log:	scsi_53C94_hdw.c,v
     72  1.1.2.2  bouyer  * Revision 2.5  91/02/05  17:45:07  mrt
     73  1.1.2.2  bouyer  * 	Added author notices
     74  1.1.2.2  bouyer  * 	[91/02/04  11:18:43  mrt]
     75  1.1.2.2  bouyer  *
     76  1.1.2.2  bouyer  * 	Changed to use new Mach copyright
     77  1.1.2.2  bouyer  * 	[91/02/02  12:17:20  mrt]
     78  1.1.2.2  bouyer  *
     79  1.1.2.2  bouyer  * Revision 2.4  91/01/08  15:48:24  rpd
     80  1.1.2.2  bouyer  * 	Added continuation argument to thread_block.
     81  1.1.2.2  bouyer  * 	[90/12/27            rpd]
     82  1.1.2.2  bouyer  *
     83  1.1.2.2  bouyer  * Revision 2.3  90/12/05  23:34:48  af
     84  1.1.2.2  bouyer  * 	Recovered from pmax merge.. and from the destruction of a disk.
     85  1.1.2.2  bouyer  * 	[90/12/03  23:40:40  af]
     86  1.1.2.2  bouyer  *
     87  1.1.2.2  bouyer  * Revision 2.1.1.1  90/11/01  03:39:09  af
     88  1.1.2.2  bouyer  * 	Created, from the DEC specs:
     89  1.1.2.2  bouyer  * 	"PMAZ-AA TURBOchannel SCSI Module Functional Specification"
     90  1.1.2.2  bouyer  * 	Workstation Systems Engineering, Palo Alto, CA. Aug 27, 1990.
     91  1.1.2.2  bouyer  * 	And from the NCR data sheets
     92  1.1.2.2  bouyer  * 	"NCR 53C94, 53C95, 53C96 Advances SCSI Controller"
     93  1.1.2.2  bouyer  * 	[90/09/03            af]
     94  1.1.2.2  bouyer  */
     95  1.1.2.2  bouyer 
     96  1.1.2.2  bouyer /*
     97  1.1.2.2  bouyer  *	File: scsi_53C94_hdw.h
     98  1.1.2.2  bouyer  * 	Author: Alessandro Forin, Carnegie Mellon University
     99  1.1.2.2  bouyer  *	Date:	9/90
    100  1.1.2.2  bouyer  *
    101  1.1.2.2  bouyer  *	Bottom layer of the SCSI driver: chip-dependent functions
    102  1.1.2.2  bouyer  *
    103  1.1.2.2  bouyer  *	This file contains the code that is specific to the NCR 53C94
    104  1.1.2.2  bouyer  *	SCSI chip (Host Bus Adapter in SCSI parlance): probing, start
    105  1.1.2.2  bouyer  *	operation, and interrupt routine.
    106  1.1.2.2  bouyer  */
    107  1.1.2.2  bouyer 
    108  1.1.2.2  bouyer /*
    109  1.1.2.2  bouyer  * This layer works based on small simple 'scripts' that are installed
    110  1.1.2.2  bouyer  * at the start of the command and drive the chip to completion.
    111  1.1.2.2  bouyer  * The idea comes from the specs of the NCR 53C700 'script' processor.
    112  1.1.2.2  bouyer  *
    113  1.1.2.2  bouyer  * There are various reasons for this, mainly
    114  1.1.2.2  bouyer  * - Performance: identify the common (successful) path, and follow it;
    115  1.1.2.2  bouyer  *   at interrupt time no code is needed to find the current status
    116  1.1.2.2  bouyer  * - Code size: it should be easy to compact common operations
    117  1.1.2.2  bouyer  * - Adaptability: the code skeleton should adapt to different chips without
    118  1.1.2.2  bouyer  *   terrible complications.
    119  1.1.2.2  bouyer  * - Error handling: and it is easy to modify the actions performed
    120  1.1.2.2  bouyer  *   by the scripts to cope with strange but well identified sequences
    121  1.1.2.2  bouyer  *
    122  1.1.2.2  bouyer  */
    123  1.1.2.2  bouyer 
    124  1.1.2.2  bouyer #include <sys/param.h>
    125  1.1.2.2  bouyer #include <sys/systm.h>
    126  1.1.2.2  bouyer #include <sys/dkstat.h>
    127  1.1.2.2  bouyer #include <sys/buf.h>
    128  1.1.2.2  bouyer #include <sys/proc.h>
    129  1.1.2.2  bouyer #include <sys/conf.h>
    130  1.1.2.2  bouyer #include <sys/errno.h>
    131  1.1.2.2  bouyer #include <sys/device.h>
    132  1.1.2.2  bouyer #include <uvm/uvm_extern.h>
    133  1.1.2.2  bouyer 
    134  1.1.2.2  bouyer #include <dev/scsipi/scsi_all.h>
    135  1.1.2.2  bouyer #include <dev/scsipi/scsipi_all.h>
    136  1.1.2.2  bouyer #include <dev/scsipi/scsiconf.h>
    137  1.1.2.2  bouyer 
    138  1.1.2.2  bouyer #include <mips/locore.h> /* for mips3_HitFlushDCache() */
    139  1.1.2.2  bouyer #include <machine/cpu.h>
    140  1.1.2.2  bouyer #include <machine/autoconf.h>
    141  1.1.2.2  bouyer #include <machine/bus.h>
    142  1.1.2.2  bouyer 
    143  1.1.2.2  bouyer #include <arc/jazz/jazziovar.h>
    144  1.1.2.2  bouyer #include <arc/jazz/jazzdmatlbreg.h>
    145  1.1.2.2  bouyer #include <arc/jazz/dma.h>
    146  1.1.2.2  bouyer #include <arc/jazz/scsi.h>
    147  1.1.2.2  bouyer #include <arc/jazz/ascreg.h>
    148  1.1.2.2  bouyer 
    149  1.1.2.2  bouyer #include <arc/jazz/pica.h>
    150  1.1.2.2  bouyer #include <arc/arc/arctype.h>
    151  1.1.2.2  bouyer 
    152  1.1.2.2  bouyer 
    153  1.1.2.2  bouyer #define	readback(a)	{ register int foo; foo = (a); }
    154  1.1.2.2  bouyer 
    155  1.1.2.2  bouyer /*
    156  1.1.2.2  bouyer  * In 4ns ticks.
    157  1.1.2.2  bouyer  */
    158  1.1.2.2  bouyer int	asc_to_scsi_period[] = {
    159  1.1.2.2  bouyer 	32,
    160  1.1.2.2  bouyer 	33,
    161  1.1.2.2  bouyer 	34,
    162  1.1.2.2  bouyer 	35,
    163  1.1.2.2  bouyer 	5,
    164  1.1.2.2  bouyer 	5,
    165  1.1.2.2  bouyer 	6,
    166  1.1.2.2  bouyer 	7,
    167  1.1.2.2  bouyer 	8,
    168  1.1.2.2  bouyer 	9,
    169  1.1.2.2  bouyer 	10,
    170  1.1.2.2  bouyer 	11,
    171  1.1.2.2  bouyer 	12,
    172  1.1.2.2  bouyer 	13,
    173  1.1.2.2  bouyer 	14,
    174  1.1.2.2  bouyer 	15,
    175  1.1.2.2  bouyer 	16,
    176  1.1.2.2  bouyer 	17,
    177  1.1.2.2  bouyer 	18,
    178  1.1.2.2  bouyer 	19,
    179  1.1.2.2  bouyer 	20,
    180  1.1.2.2  bouyer 	21,
    181  1.1.2.2  bouyer 	22,
    182  1.1.2.2  bouyer 	23,
    183  1.1.2.2  bouyer 	24,
    184  1.1.2.2  bouyer 	25,
    185  1.1.2.2  bouyer 	26,
    186  1.1.2.2  bouyer 	27,
    187  1.1.2.2  bouyer 	28,
    188  1.1.2.2  bouyer 	29,
    189  1.1.2.2  bouyer 	30,
    190  1.1.2.2  bouyer 	31,
    191  1.1.2.2  bouyer };
    192  1.1.2.2  bouyer 
    193  1.1.2.2  bouyer /*
    194  1.1.2.2  bouyer  * Internal forward declarations.
    195  1.1.2.2  bouyer  */
    196  1.1.2.2  bouyer struct asc_softc;
    197  1.1.2.2  bouyer static void asc_reset __P((struct asc_softc *, asc_regmap_t *));
    198  1.1.2.2  bouyer static void asc_startcmd __P((struct asc_softc *, int));
    199  1.1.2.2  bouyer 
    200  1.1.2.2  bouyer #ifdef DEBUG
    201  1.1.2.2  bouyer int	asc_debug = 1;
    202  1.1.2.2  bouyer int	asc_debug_cmd;
    203  1.1.2.2  bouyer int	asc_debug_bn;
    204  1.1.2.2  bouyer int	asc_debug_sz;
    205  1.1.2.2  bouyer #define NLOG 16
    206  1.1.2.2  bouyer struct asc_log {
    207  1.1.2.2  bouyer 	u_int	status;
    208  1.1.2.2  bouyer 	u_char	state;
    209  1.1.2.2  bouyer 	u_char	msg;
    210  1.1.2.2  bouyer 	int	target;
    211  1.1.2.2  bouyer 	int	resid;
    212  1.1.2.2  bouyer } asc_log[NLOG], *asc_logp = asc_log;
    213  1.1.2.2  bouyer #define PACK(unit, status, ss, ir) \
    214  1.1.2.2  bouyer 	((unit << 24) | (status << 16) | (ss << 8) | ir)
    215  1.1.2.2  bouyer #endif
    216  1.1.2.2  bouyer 
    217  1.1.2.2  bouyer /*
    218  1.1.2.2  bouyer  * Scripts are entries in a state machine table.
    219  1.1.2.2  bouyer  * A script has four parts: a pre-condition, an action, a command to the chip,
    220  1.1.2.2  bouyer  * and an index into asc_scripts for the next state. The first triggers error
    221  1.1.2.2  bouyer  * handling if not satisfied and in our case it is formed by the
    222  1.1.2.2  bouyer  * values of the interrupt register and status register, this
    223  1.1.2.2  bouyer  * basically captures the phase of the bus and the TC and BS
    224  1.1.2.2  bouyer  * bits.  The action part is just a function pointer, and the
    225  1.1.2.2  bouyer  * command is what the 53C94 should be told to do at the end
    226  1.1.2.2  bouyer  * of the action processing.  This command is only issued and the
    227  1.1.2.2  bouyer  * script proceeds if the action routine returns TRUE.
    228  1.1.2.2  bouyer  * See asc_intr() for how and where this is all done.
    229  1.1.2.2  bouyer  */
    230  1.1.2.2  bouyer typedef struct script {
    231  1.1.2.2  bouyer 	int		condition;	/* expected state at interrupt time */
    232  1.1.2.2  bouyer 	int		(*action)(struct asc_softc *, int, int, int);
    233  1.1.2.2  bouyer 					/* extra operations */
    234  1.1.2.2  bouyer 	int		command;	/* command to the chip */
    235  1.1.2.2  bouyer 	struct script	*next;		/* index into asc_scripts for next state */
    236  1.1.2.2  bouyer } script_t;
    237  1.1.2.2  bouyer 
    238  1.1.2.2  bouyer /* Matching on the condition value */
    239  1.1.2.2  bouyer #define	SCRIPT_MATCH(ir, csr)		((ir) | (((csr) & 0x67) << 8))
    240  1.1.2.2  bouyer 
    241  1.1.2.2  bouyer 
    242  1.1.2.2  bouyer /* forward decls of script actions */
    243  1.1.2.2  bouyer 	/* when nothing needed */
    244  1.1.2.2  bouyer static int script_nop __P((struct asc_softc *, int, int, int));
    245  1.1.2.2  bouyer 	/* all come to an end */
    246  1.1.2.2  bouyer static int asc_end __P((struct asc_softc *, int, int, int));
    247  1.1.2.2  bouyer 	/* get status from target */
    248  1.1.2.2  bouyer static int asc_get_status __P((struct asc_softc *, int, int, int));
    249  1.1.2.2  bouyer 	/* start reading data from target */
    250  1.1.2.2  bouyer static int asc_dma_in __P((struct asc_softc *, int, int, int));
    251  1.1.2.2  bouyer 	/* cleanup after all data is read */
    252  1.1.2.2  bouyer static int asc_last_dma_in __P((struct asc_softc *, int, int, int));
    253  1.1.2.2  bouyer 	/* resume data in after a message */
    254  1.1.2.2  bouyer static int asc_resume_in __P((struct asc_softc *, int, int, int));
    255  1.1.2.2  bouyer 	/* resume DMA after a disconnect */
    256  1.1.2.2  bouyer static int asc_resume_dma_in __P((struct asc_softc *, int, int, int));
    257  1.1.2.2  bouyer 	/* send data to target via dma */
    258  1.1.2.2  bouyer static int asc_dma_out __P((struct asc_softc *, int, int, int));
    259  1.1.2.2  bouyer 	/* cleanup after all data is written */
    260  1.1.2.2  bouyer static int asc_last_dma_out __P((struct asc_softc *, int, int, int));
    261  1.1.2.2  bouyer 	/* resume data out after a message */
    262  1.1.2.2  bouyer static int asc_resume_out __P((struct asc_softc *, int, int, int));
    263  1.1.2.2  bouyer 	/* resume DMA after a disconnect */
    264  1.1.2.2  bouyer static int asc_resume_dma_out __P((struct asc_softc *, int, int, int));
    265  1.1.2.2  bouyer 	/* negotiate sync xfer */
    266  1.1.2.2  bouyer static int asc_sendsync __P((struct asc_softc *, int, int, int));
    267  1.1.2.2  bouyer 	/* negotiate sync xfer */
    268  1.1.2.2  bouyer static int asc_replysync __P((struct asc_softc *, int, int, int));
    269  1.1.2.2  bouyer 	/* process a message byte */
    270  1.1.2.2  bouyer static int asc_msg_in __P((struct asc_softc *, int, int, int));
    271  1.1.2.2  bouyer 	/* process an expected disconnect */
    272  1.1.2.2  bouyer static int asc_disconnect __P((struct asc_softc *, int, int, int));
    273  1.1.2.2  bouyer 
    274  1.1.2.2  bouyer /* Define the index into asc_scripts for various state transitions */
    275  1.1.2.2  bouyer #define	SCRIPT_DATA_IN		0
    276  1.1.2.2  bouyer #define	SCRIPT_CONTINUE_IN	2
    277  1.1.2.2  bouyer #define	SCRIPT_DATA_OUT		3
    278  1.1.2.2  bouyer #define	SCRIPT_CONTINUE_OUT	5
    279  1.1.2.2  bouyer #define	SCRIPT_SIMPLE		6
    280  1.1.2.2  bouyer #define	SCRIPT_GET_STATUS	7
    281  1.1.2.2  bouyer #define	SCRIPT_DONE		8
    282  1.1.2.2  bouyer #define	SCRIPT_MSG_IN		9
    283  1.1.2.2  bouyer #define	SCRIPT_REPLY_SYNC	11
    284  1.1.2.2  bouyer #define	SCRIPT_TRY_SYNC		12
    285  1.1.2.2  bouyer #define	SCRIPT_DISCONNECT	15
    286  1.1.2.2  bouyer #define	SCRIPT_RESEL		16
    287  1.1.2.2  bouyer #define	SCRIPT_RESUME_IN	17
    288  1.1.2.2  bouyer #define	SCRIPT_RESUME_DMA_IN	18
    289  1.1.2.2  bouyer #define	SCRIPT_RESUME_OUT	19
    290  1.1.2.2  bouyer #define	SCRIPT_RESUME_DMA_OUT	20
    291  1.1.2.2  bouyer #define	SCRIPT_RESUME_NO_DATA	21
    292  1.1.2.2  bouyer 
    293  1.1.2.2  bouyer /*
    294  1.1.2.2  bouyer  * Scripts
    295  1.1.2.2  bouyer  */
    296  1.1.2.2  bouyer script_t asc_scripts[] = {
    297  1.1.2.2  bouyer 	/* start data in */
    298  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, ASC_PHASE_DATAI),	/*  0 */
    299  1.1.2.2  bouyer 		asc_dma_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
    300  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_DATA_IN + 1]},
    301  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_STATUS),			/*  1 */
    302  1.1.2.2  bouyer 		asc_last_dma_in, ASC_CMD_I_COMPLETE,
    303  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_GET_STATUS]},
    304  1.1.2.2  bouyer 
    305  1.1.2.2  bouyer 	/* continue data in after a chunk is finished */
    306  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAI),			/*  2 */
    307  1.1.2.2  bouyer 		asc_dma_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
    308  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_DATA_IN + 1]},
    309  1.1.2.2  bouyer 
    310  1.1.2.2  bouyer 	/* start data out */
    311  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, ASC_PHASE_DATAO),	/*  3 */
    312  1.1.2.2  bouyer 		asc_dma_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
    313  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_DATA_OUT + 1]},
    314  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_STATUS),			/*  4 */
    315  1.1.2.2  bouyer 		asc_last_dma_out, ASC_CMD_I_COMPLETE,
    316  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_GET_STATUS]},
    317  1.1.2.2  bouyer 
    318  1.1.2.2  bouyer 	/* continue data out after a chunk is finished */
    319  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAO),			/*  5 */
    320  1.1.2.2  bouyer 		asc_dma_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
    321  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_DATA_OUT + 1]},
    322  1.1.2.2  bouyer 
    323  1.1.2.2  bouyer 	/* simple command with no data transfer */
    324  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, ASC_PHASE_STATUS),	/*  6 */
    325  1.1.2.2  bouyer 		script_nop, ASC_CMD_I_COMPLETE,
    326  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_GET_STATUS]},
    327  1.1.2.2  bouyer 
    328  1.1.2.2  bouyer 	/* get status and finish command */
    329  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_FC, ASC_PHASE_MSG_IN),			/*  7 */
    330  1.1.2.2  bouyer 		asc_get_status, ASC_CMD_MSG_ACPT,
    331  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_DONE]},
    332  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_DISC, 0),					/*  8 */
    333  1.1.2.2  bouyer 		asc_end, ASC_CMD_NOP,
    334  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_DONE]},
    335  1.1.2.2  bouyer 
    336  1.1.2.2  bouyer 	/* message in */
    337  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_FC, ASC_PHASE_MSG_IN),			/*  9 */
    338  1.1.2.2  bouyer 		asc_msg_in, ASC_CMD_MSG_ACPT,
    339  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_MSG_IN + 1]},
    340  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_MSG_IN),			/* 10 */
    341  1.1.2.2  bouyer 		script_nop, ASC_CMD_XFER_INFO,
    342  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_MSG_IN]},
    343  1.1.2.2  bouyer 
    344  1.1.2.2  bouyer 	/* send synchonous negotiation reply */
    345  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_MSG_OUT),			/* 11 */
    346  1.1.2.2  bouyer 		asc_replysync, ASC_CMD_XFER_INFO,
    347  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_REPLY_SYNC]},
    348  1.1.2.2  bouyer 
    349  1.1.2.2  bouyer 	/* try to negotiate synchonous transfer parameters */
    350  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, ASC_PHASE_MSG_OUT),	/* 12 */
    351  1.1.2.2  bouyer 		asc_sendsync, ASC_CMD_XFER_INFO,
    352  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_TRY_SYNC + 1]},
    353  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_MSG_IN),			/* 13 */
    354  1.1.2.2  bouyer 		script_nop, ASC_CMD_XFER_INFO,
    355  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_MSG_IN]},
    356  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_COMMAND),			/* 14 */
    357  1.1.2.2  bouyer 		script_nop, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
    358  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_RESUME_NO_DATA]},
    359  1.1.2.2  bouyer 
    360  1.1.2.2  bouyer 	/* handle a disconnect */
    361  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_DISC, ASC_PHASE_DATAO),			/* 15 */
    362  1.1.2.2  bouyer 		asc_disconnect, ASC_CMD_ENABLE_SEL,
    363  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_RESEL]},
    364  1.1.2.2  bouyer 
    365  1.1.2.2  bouyer 	/* reselect sequence: this is just a placeholder so match fails */
    366  1.1.2.2  bouyer 	{SCRIPT_MATCH(0, ASC_PHASE_MSG_IN),				/* 16 */
    367  1.1.2.2  bouyer 		script_nop, ASC_CMD_MSG_ACPT,
    368  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_RESEL]},
    369  1.1.2.2  bouyer 
    370  1.1.2.2  bouyer 	/* resume data in after a message */
    371  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAI),			/* 17 */
    372  1.1.2.2  bouyer 		asc_resume_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
    373  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_DATA_IN + 1]},
    374  1.1.2.2  bouyer 
    375  1.1.2.2  bouyer 	/* resume partial DMA data in after a message */
    376  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAI),			/* 18 */
    377  1.1.2.2  bouyer 		asc_resume_dma_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
    378  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_DATA_IN + 1]},
    379  1.1.2.2  bouyer 
    380  1.1.2.2  bouyer 	/* resume data out after a message */
    381  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAO),			/* 19 */
    382  1.1.2.2  bouyer 		asc_resume_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
    383  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_DATA_OUT + 1]},
    384  1.1.2.2  bouyer 
    385  1.1.2.2  bouyer 	/* resume partial DMA data out after a message */
    386  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_DATAO),			/* 20 */
    387  1.1.2.2  bouyer 		asc_resume_dma_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
    388  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_DATA_OUT + 1]},
    389  1.1.2.2  bouyer 
    390  1.1.2.2  bouyer 	/* resume after a message when there is no more data */
    391  1.1.2.2  bouyer 	{SCRIPT_MATCH(ASC_INT_BS, ASC_PHASE_STATUS),			/* 21 */
    392  1.1.2.2  bouyer 		script_nop, ASC_CMD_I_COMPLETE,
    393  1.1.2.2  bouyer 		&asc_scripts[SCRIPT_GET_STATUS]},
    394  1.1.2.2  bouyer };
    395  1.1.2.2  bouyer 
    396  1.1.2.2  bouyer /*
    397  1.1.2.2  bouyer  * State kept for each active SCSI device.
    398  1.1.2.2  bouyer  */
    399  1.1.2.2  bouyer typedef struct scsi_state {
    400  1.1.2.2  bouyer 	script_t *script;	/* saved script while processing error */
    401  1.1.2.2  bouyer 	struct scsi_generic cmd;/* storage for scsi command */
    402  1.1.2.2  bouyer 	int	statusByte;	/* status byte returned during STATUS_PHASE */
    403  1.1.2.2  bouyer 	u_int	dmaBufSize;	/* DMA buffer size */
    404  1.1.2.2  bouyer 	int	dmalen;		/* amount to transfer in this chunk */
    405  1.1.2.2  bouyer 	int	dmaresid;	/* amount not transfered if chunk suspended */
    406  1.1.2.2  bouyer 	int	cmdlen;		/* length of command in cmd */
    407  1.1.2.2  bouyer 	int	buflen;		/* total remaining amount of data to transfer */
    408  1.1.2.2  bouyer 	vaddr_t	buf;		/* current pointer within scsicmd->buf */
    409  1.1.2.2  bouyer 	int	flags;		/* see below */
    410  1.1.2.2  bouyer 	int	msglen;		/* number of message bytes to read */
    411  1.1.2.2  bouyer 	int	msgcnt;		/* number of message bytes received */
    412  1.1.2.2  bouyer 	u_char	sync_period;	/* DMA synchronous period */
    413  1.1.2.2  bouyer 	u_char	sync_offset;	/* DMA synchronous xfer offset or 0 if async */
    414  1.1.2.2  bouyer 	u_char	msg_out;	/* next MSG_OUT byte to send */
    415  1.1.2.2  bouyer 	u_char	msg_in[16];	/* buffer for multibyte messages */
    416  1.1.2.2  bouyer } State;
    417  1.1.2.2  bouyer 
    418  1.1.2.2  bouyer /* state flags */
    419  1.1.2.2  bouyer #define DISCONN		0x001	/* true if currently disconnected from bus */
    420  1.1.2.2  bouyer #define DMA_IN_PROGRESS	0x002	/* true if data DMA started */
    421  1.1.2.2  bouyer #define DMA_IN		0x004	/* true if reading from SCSI device */
    422  1.1.2.2  bouyer #define DMA_OUT		0x010	/* true if writing to SCSI device */
    423  1.1.2.2  bouyer #define DID_SYNC	0x020	/* true if synchronous offset was negotiated */
    424  1.1.2.2  bouyer #define TRY_SYNC	0x040	/* true if try neg. synchronous offset */
    425  1.1.2.2  bouyer #define PARITY_ERR	0x080	/* true if parity error seen */
    426  1.1.2.2  bouyer #define	CHECK_SENSE	0x100	/* true if doing sense command */
    427  1.1.2.2  bouyer 
    428  1.1.2.2  bouyer /*
    429  1.1.2.2  bouyer  * State kept for each active SCSI host interface (53C94).
    430  1.1.2.2  bouyer  */
    431  1.1.2.2  bouyer struct asc_softc {
    432  1.1.2.2  bouyer 	struct device	sc_dev;		/* use as a device */
    433  1.1.2.2  bouyer 	asc_regmap_t	*regs;		/* chip address */
    434  1.1.2.2  bouyer 	dma_softc_t	__dma;		/* stupid macro..... */
    435  1.1.2.2  bouyer 	dma_softc_t	*dma;		/* dma control structure */
    436  1.1.2.2  bouyer 	int		sc_id;		/* SCSI ID of this interface */
    437  1.1.2.2  bouyer 	int		myidmask;	/* ~(1 << myid) */
    438  1.1.2.2  bouyer 	int		state;		/* current SCSI connection state */
    439  1.1.2.2  bouyer 	int		target;		/* target SCSI ID if busy */
    440  1.1.2.2  bouyer 	script_t	*script;	/* next expected interrupt & action */
    441  1.1.2.2  bouyer 	struct scsipi_xfer *cmdq[ASC_NCMD];/* Pointer to queued commands */
    442  1.1.2.2  bouyer 	struct scsipi_xfer *cmd[ASC_NCMD];/* Pointer to current active command */
    443  1.1.2.2  bouyer 	State		st[ASC_NCMD];	/* state info for each active command */
    444  1.1.2.2  bouyer 	int		min_period;	/* Min transfer period clk/byte */
    445  1.1.2.2  bouyer 	int		max_period;	/* Max transfer period clk/byte */
    446  1.1.2.2  bouyer 	int		ccf;		/* CCF, whatever that really is? */
    447  1.1.2.2  bouyer 	int		timeout_250;	/* 250ms timeout */
    448  1.1.2.2  bouyer 	int		tb_ticks;	/* 4ns. ticks/tb channel ticks */
    449  1.1.2.2  bouyer 	int		is24bit;	/* if 53CF94/96-2, 24bit address */
    450  1.1.2.2  bouyer 	struct scsipi_link sc_link;	/* scsipi link struct */
    451  1.1.2.2  bouyer 	struct scsipi_adapter sc_adapter;
    452  1.1.2.2  bouyer };
    453  1.1.2.2  bouyer 
    454  1.1.2.2  bouyer #define	ASC_STATE_IDLE		0	/* idle state */
    455  1.1.2.2  bouyer #define	ASC_STATE_BUSY		1	/* selecting or currently connected */
    456  1.1.2.2  bouyer #define ASC_STATE_TARGET	2	/* currently selected as target */
    457  1.1.2.2  bouyer #define ASC_STATE_RESEL		3	/* currently waiting for reselect */
    458  1.1.2.2  bouyer 
    459  1.1.2.2  bouyer typedef struct asc_softc *asc_softc_t;
    460  1.1.2.2  bouyer 
    461  1.1.2.2  bouyer /*
    462  1.1.2.2  bouyer  * Autoconfiguration data for config.
    463  1.1.2.2  bouyer  */
    464  1.1.2.2  bouyer int	ascmatch __P((struct device *, struct cfdata *, void *));
    465  1.1.2.2  bouyer void	ascattach __P((struct device *, struct device *, void *));
    466  1.1.2.2  bouyer 
    467  1.1.2.2  bouyer int	asc_doprobe __P((void *, int, int, struct device *));
    468  1.1.2.2  bouyer 
    469  1.1.2.2  bouyer struct cfattach asc_ca = {
    470  1.1.2.2  bouyer 	sizeof(struct asc_softc), ascmatch, ascattach
    471  1.1.2.2  bouyer };
    472  1.1.2.2  bouyer 
    473  1.1.2.2  bouyer /*
    474  1.1.2.2  bouyer  *  Glue to the machine dependent scsi
    475  1.1.2.2  bouyer  */
    476  1.1.2.2  bouyer int asc_scsi_cmd __P((struct scsipi_xfer *));
    477  1.1.2.2  bouyer void asc_minphys __P((struct buf *));
    478  1.1.2.2  bouyer 
    479  1.1.2.2  bouyer struct scsipi_device asc_dev = {
    480  1.1.2.2  bouyer /*XXX*/	NULL,		/* Use default error handler */
    481  1.1.2.2  bouyer /*XXX*/	NULL,		/* have a queue, served by this */
    482  1.1.2.2  bouyer /*XXX*/	NULL,		/* have no async handler */
    483  1.1.2.2  bouyer /*XXX*/	NULL,		/* Use default 'done' routine */
    484  1.1.2.2  bouyer };
    485  1.1.2.2  bouyer 
    486  1.1.2.2  bouyer static int asc_intr __P((void *));
    487  1.1.2.2  bouyer static int asc_poll __P((struct asc_softc *, int));
    488  1.1.2.2  bouyer #ifdef DEBUG
    489  1.1.2.2  bouyer static void asc_DumpLog __P((char *));
    490  1.1.2.2  bouyer #endif
    491  1.1.2.2  bouyer 
    492  1.1.2.2  bouyer /*
    493  1.1.2.2  bouyer  * Match driver based on name
    494  1.1.2.2  bouyer  */
    495  1.1.2.2  bouyer int
    496  1.1.2.2  bouyer ascmatch(parent, match, aux)
    497  1.1.2.2  bouyer 	struct device *parent;
    498  1.1.2.2  bouyer 	struct cfdata *match;
    499  1.1.2.2  bouyer 	void *aux;
    500  1.1.2.2  bouyer {
    501  1.1.2.2  bouyer 	struct jazzio_attach_args *ja = aux;
    502  1.1.2.2  bouyer 
    503  1.1.2.2  bouyer 	if(strcmp(ja->ja_name, "asc") != 0)
    504  1.1.2.2  bouyer 		return (0);
    505  1.1.2.2  bouyer 	return (1);
    506  1.1.2.2  bouyer }
    507  1.1.2.2  bouyer 
    508  1.1.2.2  bouyer void
    509  1.1.2.2  bouyer ascattach(parent, self, aux)
    510  1.1.2.2  bouyer 	struct device *parent;
    511  1.1.2.2  bouyer 	struct device *self;
    512  1.1.2.2  bouyer 	void *aux;
    513  1.1.2.2  bouyer {
    514  1.1.2.2  bouyer 	struct jazzio_attach_args *ja = aux;
    515  1.1.2.2  bouyer 	asc_softc_t asc = (void *)self;
    516  1.1.2.2  bouyer 	asc_regmap_t *regs;
    517  1.1.2.2  bouyer 	int id, s, i;
    518  1.1.2.2  bouyer 	int bufsiz;
    519  1.1.2.2  bouyer 
    520  1.1.2.2  bouyer 	/*
    521  1.1.2.2  bouyer 	 * Initialize hw descriptor, cache some pointers
    522  1.1.2.2  bouyer 	 */
    523  1.1.2.2  bouyer 	asc->regs = (asc_regmap_t *)ja->ja_addr;	/* XXX */
    524  1.1.2.2  bouyer 
    525  1.1.2.2  bouyer 	/*
    526  1.1.2.2  bouyer 	 * Set up machine dependencies.
    527  1.1.2.2  bouyer 	 * 1) how to do dma
    528  1.1.2.2  bouyer 	 * 2) timing based on chip clock frequency
    529  1.1.2.2  bouyer 	 */
    530  1.1.2.2  bouyer 	switch (cputype) {
    531  1.1.2.2  bouyer 	case ACER_PICA_61:
    532  1.1.2.2  bouyer 	case MAGNUM:
    533  1.1.2.2  bouyer 		bufsiz = 63 * 1024; /*XXX check if code handles 0 as 64k */
    534  1.1.2.2  bouyer 		asc->dma = &asc->__dma;
    535  1.1.2.2  bouyer 		asc_dma_init(asc->dma);
    536  1.1.2.2  bouyer 		break;
    537  1.1.2.2  bouyer 	default:
    538  1.1.2.2  bouyer 		bufsiz = 64 * 1024;
    539  1.1.2.2  bouyer 	};
    540  1.1.2.2  bouyer 	/*
    541  1.1.2.2  bouyer 	 * Now for timing. The pica has a 25Mhz, NEC M403 has a 40MHz.
    542  1.1.2.2  bouyer 	 */
    543  1.1.2.2  bouyer 	switch (cputype) {
    544  1.1.2.2  bouyer 	case MAGNUM: /* XXX - NEC M403 */
    545  1.1.2.2  bouyer 		asc->min_period = ASC_MIN_PERIOD40;
    546  1.1.2.2  bouyer 		asc->max_period = ASC_MAX_PERIOD40;
    547  1.1.2.2  bouyer 		asc->ccf = ASC_CCF(40);
    548  1.1.2.2  bouyer 		asc->timeout_250 = ASC_TIMEOUT_250(40,
    549  1.1.2.2  bouyer 		    asc->ccf != 0 ? asc->ccf : 8);
    550  1.1.2.2  bouyer 		asc->tb_ticks = 6; /* 6.25 */
    551  1.1.2.2  bouyer 		break;
    552  1.1.2.2  bouyer 	case ACER_PICA_61:
    553  1.1.2.2  bouyer 		asc->min_period = ASC_MIN_PERIOD25;
    554  1.1.2.2  bouyer 		asc->max_period = ASC_MAX_PERIOD25;
    555  1.1.2.2  bouyer 		asc->ccf = ASC_CCF(25);
    556  1.1.2.2  bouyer 		asc->timeout_250 = ASC_TIMEOUT_250(25, asc->ccf);
    557  1.1.2.2  bouyer 		asc->tb_ticks = 10;
    558  1.1.2.2  bouyer 		break;
    559  1.1.2.2  bouyer 	default:
    560  1.1.2.2  bouyer 		asc->min_period = ASC_MIN_PERIOD12;
    561  1.1.2.2  bouyer 		asc->max_period = ASC_MAX_PERIOD12;
    562  1.1.2.2  bouyer 		asc->ccf = ASC_CCF(13);
    563  1.1.2.2  bouyer 		asc->timeout_250 = ASC_TIMEOUT_250(13, asc->ccf);
    564  1.1.2.2  bouyer 		asc->tb_ticks = 20;
    565  1.1.2.2  bouyer 		break;
    566  1.1.2.2  bouyer 	};
    567  1.1.2.2  bouyer 
    568  1.1.2.2  bouyer 	asc->state = ASC_STATE_IDLE;
    569  1.1.2.2  bouyer 	asc->target = -1;
    570  1.1.2.2  bouyer 
    571  1.1.2.2  bouyer 	regs = asc->regs;
    572  1.1.2.2  bouyer 
    573  1.1.2.2  bouyer 	/*
    574  1.1.2.2  bouyer 	 * Reset chip, fully.  Note that interrupts are already enabled.
    575  1.1.2.2  bouyer 	 */
    576  1.1.2.2  bouyer 	s = splbio();
    577  1.1.2.2  bouyer 
    578  1.1.2.2  bouyer 	/* preserve our ID for now */
    579  1.1.2.2  bouyer 	asc->sc_id = regs->asc_cnfg1 & ASC_CNFG1_MY_BUS_ID;
    580  1.1.2.2  bouyer 	asc->myidmask = ~(1 << asc->sc_id);
    581  1.1.2.2  bouyer 
    582  1.1.2.2  bouyer 	/* identify 53CF9x-2 or not */
    583  1.1.2.2  bouyer 	regs->asc_cmd = ASC_CMD_RESET;
    584  1.1.2.2  bouyer 	wbflush(); DELAY(25);
    585  1.1.2.2  bouyer 	regs->asc_cmd = ASC_CMD_DMA | ASC_CMD_NOP;
    586  1.1.2.2  bouyer 	wbflush(); DELAY(25);
    587  1.1.2.2  bouyer 	regs->asc_cnfg2 = ASC_CNFG2_FE;
    588  1.1.2.2  bouyer 	wbflush(); DELAY(25);
    589  1.1.2.2  bouyer 	regs->asc_cmd = ASC_CMD_DMA | ASC_CMD_NOP;
    590  1.1.2.2  bouyer 	wbflush(); DELAY(25);
    591  1.1.2.2  bouyer 	asc->is24bit = regs->asc_id == ASC_ID_53CF94;
    592  1.1.2.2  bouyer 
    593  1.1.2.2  bouyer 	asc_reset(asc, regs);
    594  1.1.2.2  bouyer 
    595  1.1.2.2  bouyer 	/*
    596  1.1.2.2  bouyer 	 * Our SCSI id on the bus.
    597  1.1.2.2  bouyer 	 * The user can set this via the prom on 3maxen/picaen.
    598  1.1.2.2  bouyer 	 * If this changes it is easy to fix: make a default that
    599  1.1.2.2  bouyer 	 * can be changed as boot arg.
    600  1.1.2.2  bouyer 	 */
    601  1.1.2.2  bouyer #ifdef	unneeded
    602  1.1.2.2  bouyer 	regs->asc_cnfg1 = (regs->asc_cnfg1 & ~ASC_CNFG1_MY_BUS_ID) |
    603  1.1.2.2  bouyer 			      (scsi_initiator_id[unit] & 0x7);
    604  1.1.2.2  bouyer 	asc->sc_id = regs->asc_cnfg1 & ASC_CNFG1_MY_BUS_ID;
    605  1.1.2.2  bouyer #endif
    606  1.1.2.2  bouyer 	id = asc->sc_id;
    607  1.1.2.2  bouyer 	splx(s);
    608  1.1.2.2  bouyer 
    609  1.1.2.2  bouyer 	/*
    610  1.1.2.2  bouyer 	 * Give each target its DMA buffer region.
    611  1.1.2.2  bouyer 	 * The buffer address is the same for all targets,
    612  1.1.2.2  bouyer 	 * the allocated dma viritual scatter/gather space.
    613  1.1.2.2  bouyer 	 */
    614  1.1.2.2  bouyer 	for (i = 0; i < ASC_NCMD; i++) {
    615  1.1.2.2  bouyer 		asc->st[i].dmaBufSize = bufsiz;
    616  1.1.2.2  bouyer 	}
    617  1.1.2.2  bouyer 
    618  1.1.2.2  bouyer 	/*
    619  1.1.2.2  bouyer 	 * Set up interrupt handler.
    620  1.1.2.2  bouyer          */
    621  1.1.2.2  bouyer 	jazzio_intr_establish(ja->ja_intr, asc_intr, (void *)asc);
    622  1.1.2.2  bouyer 
    623  1.1.2.2  bouyer 	printf(": %s, target %d\n", asc->is24bit ? "NCR53CF9X-2" : "NCR53C94",
    624  1.1.2.2  bouyer 	    id);
    625  1.1.2.2  bouyer 
    626  1.1.2.2  bouyer 	/*
    627  1.1.2.2  bouyer 	 * Fill in the adapter.
    628  1.1.2.2  bouyer 	 */
    629  1.1.2.2  bouyer 	asc->sc_adapter.scsipi_cmd = asc_scsi_cmd;
    630  1.1.2.2  bouyer 	asc->sc_adapter.scsipi_minphys = asc_minphys;
    631  1.1.2.2  bouyer 
    632  1.1.2.2  bouyer 	/*
    633  1.1.2.2  bouyer 	 * Fill in the prototype scsipi link.
    634  1.1.2.2  bouyer 	 */
    635  1.1.2.2  bouyer 	asc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
    636  1.1.2.2  bouyer 	asc->sc_link.adapter_softc = asc;
    637  1.1.2.2  bouyer 	asc->sc_link.scsipi_scsi.adapter_target = asc->sc_id;
    638  1.1.2.2  bouyer 	asc->sc_link.adapter = &asc->sc_adapter;
    639  1.1.2.2  bouyer 	asc->sc_link.device = &asc_dev;
    640  1.1.2.2  bouyer 	asc->sc_link.openings = 2;
    641  1.1.2.2  bouyer 	asc->sc_link.scsipi_scsi.max_target = 7;
    642  1.1.2.2  bouyer 	asc->sc_link.scsipi_scsi.max_lun = 7;
    643  1.1.2.2  bouyer 	asc->sc_link.type = BUS_SCSI;
    644  1.1.2.2  bouyer 
    645  1.1.2.2  bouyer 	/*
    646  1.1.2.2  bouyer 	 * Now try to attach all the sub devices.
    647  1.1.2.2  bouyer 	 */
    648  1.1.2.2  bouyer 	config_found(self, &asc->sc_link, scsiprint);
    649  1.1.2.2  bouyer }
    650  1.1.2.2  bouyer 
    651  1.1.2.2  bouyer /*
    652  1.1.2.2  bouyer  *  Driver breaks down request transfer size.
    653  1.1.2.2  bouyer  */
    654  1.1.2.2  bouyer void
    655  1.1.2.2  bouyer asc_minphys(bp)
    656  1.1.2.2  bouyer 	struct buf *bp;
    657  1.1.2.2  bouyer {
    658  1.1.2.2  bouyer 	minphys(bp);
    659  1.1.2.2  bouyer }
    660  1.1.2.2  bouyer 
    661  1.1.2.2  bouyer /*
    662  1.1.2.2  bouyer  * Start activity on a SCSI device.
    663  1.1.2.2  bouyer  * We maintain information on each device separately since devices can
    664  1.1.2.2  bouyer  * connect/disconnect during an operation.
    665  1.1.2.2  bouyer  */
    666  1.1.2.2  bouyer int
    667  1.1.2.2  bouyer asc_scsi_cmd(xs)
    668  1.1.2.2  bouyer 	struct scsipi_xfer *xs;
    669  1.1.2.2  bouyer {
    670  1.1.2.2  bouyer 	struct scsipi_link *sc_link = xs->sc_link;
    671  1.1.2.2  bouyer 	struct asc_softc *asc = sc_link->adapter_softc;
    672  1.1.2.2  bouyer 
    673  1.1.2.2  bouyer 	int dontqueue = xs->xs_control & XS_CTL_POLL;
    674  1.1.2.2  bouyer 	int s;
    675  1.1.2.2  bouyer 
    676  1.1.2.2  bouyer 	/*
    677  1.1.2.2  bouyer 	 *  Flush caches for any data buffer
    678  1.1.2.2  bouyer 	 */
    679  1.1.2.2  bouyer 	if(xs->datalen != 0) {
    680  1.1.2.2  bouyer 		mips3_HitFlushDCache((vaddr_t)xs->data, xs->datalen);
    681  1.1.2.2  bouyer 	}
    682  1.1.2.2  bouyer 	/*
    683  1.1.2.2  bouyer 	 *  The hack on the next few lines are to avoid buffers
    684  1.1.2.2  bouyer 	 *  mapped to UADDR. Realloc to the kva uarea address.
    685  1.1.2.2  bouyer 	 */
    686  1.1.2.2  bouyer 	if((u_int)(xs->data) >= UADDR) {
    687  1.1.2.2  bouyer 		xs->data = ((u_int)(xs->data) & ~UADDR) + (u_char *)(curproc->p_addr);
    688  1.1.2.2  bouyer 	}
    689  1.1.2.2  bouyer 
    690  1.1.2.2  bouyer 	/*
    691  1.1.2.2  bouyer 	 * Check if another command is already in progress.
    692  1.1.2.2  bouyer 	 * We may have to change this if we allow SCSI devices with
    693  1.1.2.2  bouyer 	 * separate LUNs.
    694  1.1.2.2  bouyer 	 */
    695  1.1.2.2  bouyer 	s = splbio();
    696  1.1.2.2  bouyer 	if (asc->cmd[sc_link->scsipi_scsi.target]) {
    697  1.1.2.2  bouyer 		if (asc->cmdq[sc_link->scsipi_scsi.target]) {
    698  1.1.2.2  bouyer 			splx(s);
    699  1.1.2.2  bouyer 			printf("asc_scsi_cmd: called when target busy");
    700  1.1.2.2  bouyer 			xs->error = XS_DRIVER_STUFFUP;
    701  1.1.2.2  bouyer 			return TRY_AGAIN_LATER;
    702  1.1.2.2  bouyer 		}
    703  1.1.2.2  bouyer 		asc->cmdq[sc_link->scsipi_scsi.target] = xs;
    704  1.1.2.2  bouyer 		splx(s);
    705  1.1.2.2  bouyer 		return SUCCESSFULLY_QUEUED;
    706  1.1.2.2  bouyer 	}
    707  1.1.2.2  bouyer 	asc->cmd[sc_link->scsipi_scsi.target] = xs;
    708  1.1.2.2  bouyer 
    709  1.1.2.2  bouyer 	/*
    710  1.1.2.2  bouyer 	 *  Going to launch.
    711  1.1.2.2  bouyer 	 *  Make a local copy of the command and some pointers.
    712  1.1.2.2  bouyer 	 */
    713  1.1.2.2  bouyer 	asc_startcmd(asc, sc_link->scsipi_scsi.target);
    714  1.1.2.2  bouyer 
    715  1.1.2.2  bouyer 	/*
    716  1.1.2.2  bouyer 	 *  If in startup, interrupts not usable yet.
    717  1.1.2.2  bouyer 	 */
    718  1.1.2.2  bouyer 	if(dontqueue) {
    719  1.1.2.2  bouyer 		return(asc_poll(asc,sc_link->scsipi_scsi.target));
    720  1.1.2.2  bouyer 	}
    721  1.1.2.2  bouyer 	splx(s);
    722  1.1.2.2  bouyer 	return SUCCESSFULLY_QUEUED;
    723  1.1.2.2  bouyer }
    724  1.1.2.2  bouyer 
    725  1.1.2.2  bouyer int
    726  1.1.2.2  bouyer asc_poll(asc, target)
    727  1.1.2.2  bouyer 	struct asc_softc *asc;
    728  1.1.2.2  bouyer 	int target;
    729  1.1.2.2  bouyer {
    730  1.1.2.2  bouyer 	struct scsipi_xfer *scsicmd = asc->cmd[target];
    731  1.1.2.2  bouyer 	int count = scsicmd->timeout * 10;
    732  1.1.2.2  bouyer 
    733  1.1.2.2  bouyer 	while(count) {
    734  1.1.2.2  bouyer 		if(asc->regs->asc_status &ASC_CSR_INT) {
    735  1.1.2.2  bouyer 			asc_intr(asc);
    736  1.1.2.2  bouyer 		}
    737  1.1.2.2  bouyer 		if(scsicmd->xs_status & XS_STS_DONE)
    738  1.1.2.2  bouyer 			break;
    739  1.1.2.2  bouyer 		DELAY(5);
    740  1.1.2.2  bouyer 		count--;
    741  1.1.2.2  bouyer 	}
    742  1.1.2.2  bouyer 	if(count == 0) {
    743  1.1.2.2  bouyer 		scsicmd->error = XS_TIMEOUT;
    744  1.1.2.2  bouyer 		asc_end(asc, 0, 0, 0);
    745  1.1.2.2  bouyer 	}
    746  1.1.2.2  bouyer 	return COMPLETE;
    747  1.1.2.2  bouyer }
    748  1.1.2.2  bouyer 
    749  1.1.2.2  bouyer static void
    750  1.1.2.2  bouyer asc_reset(asc, regs)
    751  1.1.2.2  bouyer 	asc_softc_t asc;
    752  1.1.2.2  bouyer 	asc_regmap_t *regs;
    753  1.1.2.2  bouyer {
    754  1.1.2.2  bouyer 
    755  1.1.2.2  bouyer 	/*
    756  1.1.2.2  bouyer 	 * Reset chip and wait till done
    757  1.1.2.2  bouyer 	 */
    758  1.1.2.2  bouyer 	regs->asc_cmd = ASC_CMD_RESET;
    759  1.1.2.2  bouyer 	wbflush(); DELAY(25);
    760  1.1.2.2  bouyer 
    761  1.1.2.2  bouyer 	/* spec says this is needed after reset */
    762  1.1.2.2  bouyer 	regs->asc_cmd = ASC_CMD_NOP;
    763  1.1.2.2  bouyer 	wbflush(); DELAY(25);
    764  1.1.2.2  bouyer 
    765  1.1.2.2  bouyer 	/*
    766  1.1.2.2  bouyer 	 * Set up various chip parameters
    767  1.1.2.2  bouyer 	 */
    768  1.1.2.2  bouyer 	regs->asc_ccf = asc->ccf;
    769  1.1.2.2  bouyer 	wbflush(); DELAY(25);
    770  1.1.2.2  bouyer 	regs->asc_sel_timo = asc->timeout_250;
    771  1.1.2.2  bouyer 	/* restore our ID */
    772  1.1.2.2  bouyer 	regs->asc_cnfg1 = asc->sc_id | ASC_CNFG1_P_CHECK;
    773  1.1.2.2  bouyer 	/* include ASC_CNFG2_SCSI2 if you want to allow SCSI II commands */
    774  1.1.2.2  bouyer 	regs->asc_cnfg2 = /* ASC_CNFG2_RFB | ASC_CNFG2_SCSI2 | */ ASC_CNFG2_EPL;
    775  1.1.2.2  bouyer 	switch (cputype) {
    776  1.1.2.2  bouyer 	case MAGNUM: /* XXX - NEC M403 */
    777  1.1.2.2  bouyer 		/* only if EPL is FE (Feature Enable bit for 53CF94) */
    778  1.1.2.2  bouyer 		regs->asc_cnfg3 = ASC_CNFG3_FCLK; /* clock 40MHz */
    779  1.1.2.2  bouyer 		break;
    780  1.1.2.2  bouyer 	default:
    781  1.1.2.2  bouyer 		regs->asc_cnfg3 = 0;
    782  1.1.2.2  bouyer 		break;
    783  1.1.2.2  bouyer 	}
    784  1.1.2.2  bouyer 	/* zero anything else */
    785  1.1.2.2  bouyer 	ASC_TC_PUT(regs, 0, asc->is24bit);
    786  1.1.2.2  bouyer 	regs->asc_syn_p = asc->min_period;
    787  1.1.2.2  bouyer 	regs->asc_syn_o = 0;	/* async for now */
    788  1.1.2.2  bouyer 	wbflush();
    789  1.1.2.2  bouyer }
    790  1.1.2.2  bouyer 
    791  1.1.2.2  bouyer /*
    792  1.1.2.2  bouyer  * Start a SCSI command on a target.
    793  1.1.2.2  bouyer  */
    794  1.1.2.2  bouyer static void
    795  1.1.2.2  bouyer asc_startcmd(asc, target)
    796  1.1.2.2  bouyer 	asc_softc_t asc;
    797  1.1.2.2  bouyer 	int target;
    798  1.1.2.2  bouyer {
    799  1.1.2.2  bouyer 	asc_regmap_t *regs;
    800  1.1.2.2  bouyer 	State *state;
    801  1.1.2.2  bouyer 	struct scsipi_xfer *scsicmd;
    802  1.1.2.2  bouyer 	int i, len;
    803  1.1.2.2  bouyer 
    804  1.1.2.2  bouyer 	/*
    805  1.1.2.2  bouyer 	 * See if another target is currently selected on this SCSI bus.
    806  1.1.2.2  bouyer 	 */
    807  1.1.2.2  bouyer 	if (asc->target >= 0)
    808  1.1.2.2  bouyer 		return;
    809  1.1.2.2  bouyer 
    810  1.1.2.2  bouyer 	regs = asc->regs;
    811  1.1.2.2  bouyer 
    812  1.1.2.2  bouyer 	/*
    813  1.1.2.2  bouyer 	 * If a reselection is in progress, it is Ok to ignore it since
    814  1.1.2.2  bouyer 	 * the ASC will automatically cancel the command and flush
    815  1.1.2.2  bouyer 	 * the FIFO if the ASC is reselected before the command starts.
    816  1.1.2.2  bouyer 	 * If we try to use ASC_CMD_DISABLE_SEL, we can hang the system if
    817  1.1.2.2  bouyer 	 * a reselect occurs before starting the command.
    818  1.1.2.2  bouyer 	 */
    819  1.1.2.2  bouyer 
    820  1.1.2.2  bouyer 	asc->state = ASC_STATE_BUSY;
    821  1.1.2.2  bouyer 	asc->target = target;
    822  1.1.2.2  bouyer 
    823  1.1.2.2  bouyer 	/* cache some pointers */
    824  1.1.2.2  bouyer 	scsicmd = asc->cmd[target];
    825  1.1.2.2  bouyer 	state = &asc->st[target];
    826  1.1.2.2  bouyer 
    827  1.1.2.2  bouyer 	/*
    828  1.1.2.2  bouyer 	 * Init the chip and target state.
    829  1.1.2.2  bouyer 	 */
    830  1.1.2.2  bouyer 	state->flags = state->flags & (DID_SYNC | CHECK_SENSE);
    831  1.1.2.2  bouyer 	state->script = (script_t *)0;
    832  1.1.2.2  bouyer 	state->msg_out = SCSI_NO_OP;
    833  1.1.2.2  bouyer 
    834  1.1.2.2  bouyer 	/*
    835  1.1.2.2  bouyer 	 * Set up for DMA of command output. Also need to flush cache.
    836  1.1.2.2  bouyer 	 */
    837  1.1.2.2  bouyer 	if(!(state->flags & CHECK_SENSE)) {
    838  1.1.2.2  bouyer 		bcopy(scsicmd->cmd, &state->cmd, scsicmd->cmdlen);
    839  1.1.2.2  bouyer 		state->cmdlen = scsicmd->cmdlen;
    840  1.1.2.2  bouyer 		state->buf = (vaddr_t)scsicmd->data;
    841  1.1.2.2  bouyer 		state->buflen = scsicmd->datalen;
    842  1.1.2.2  bouyer 	}
    843  1.1.2.2  bouyer 	len = state->cmdlen;
    844  1.1.2.2  bouyer 	state->dmalen = len;
    845  1.1.2.2  bouyer 
    846  1.1.2.2  bouyer #ifdef DEBUG
    847  1.1.2.2  bouyer 	if (asc_debug > 1) {
    848  1.1.2.2  bouyer 		printf("asc_startcmd: %s target %d cmd %x len %d\n",
    849  1.1.2.2  bouyer 			asc->sc_dev.dv_xname, target,
    850  1.1.2.2  bouyer 			state->cmd.opcode, state->buflen);
    851  1.1.2.2  bouyer 	}
    852  1.1.2.2  bouyer #endif
    853  1.1.2.2  bouyer 
    854  1.1.2.2  bouyer 	/* check for simple SCSI command with no data transfer */
    855  1.1.2.2  bouyer 	if(state->flags & CHECK_SENSE) {
    856  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_DATA_IN];
    857  1.1.2.2  bouyer 		state->flags |= DMA_IN;
    858  1.1.2.2  bouyer 	}
    859  1.1.2.2  bouyer 	else if (scsicmd->xs_control & XS_CTL_DATA_OUT) {
    860  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_DATA_OUT];
    861  1.1.2.2  bouyer 		state->flags |= DMA_OUT;
    862  1.1.2.2  bouyer 	}
    863  1.1.2.2  bouyer 	else if (scsicmd->xs_control & XS_CTL_DATA_IN) {
    864  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_DATA_IN];
    865  1.1.2.2  bouyer 		state->flags |= DMA_IN;
    866  1.1.2.2  bouyer 	}
    867  1.1.2.2  bouyer 	else if (state->buflen == 0) {
    868  1.1.2.2  bouyer 		/* check for sync negotiation */
    869  1.1.2.2  bouyer 		if ((scsicmd->xs_status & /* SCSICMD_USE_SYNC */ 0) &&
    870  1.1.2.2  bouyer 		    !(state->flags & DID_SYNC)) {
    871  1.1.2.2  bouyer 			asc->script = &asc_scripts[SCRIPT_TRY_SYNC];
    872  1.1.2.2  bouyer 			state->flags |= TRY_SYNC;
    873  1.1.2.2  bouyer 		} else
    874  1.1.2.2  bouyer 			asc->script = &asc_scripts[SCRIPT_SIMPLE];
    875  1.1.2.2  bouyer 		state->buf = (vaddr_t)0;
    876  1.1.2.2  bouyer 	}
    877  1.1.2.2  bouyer 
    878  1.1.2.2  bouyer #ifdef DEBUG
    879  1.1.2.2  bouyer 	asc_debug_cmd = state->cmd.opcode;
    880  1.1.2.2  bouyer 	if (state->cmd.opcode == SCSI_READ_EXT) {
    881  1.1.2.2  bouyer 		asc_debug_bn = (state->cmd.bytes[1] << 24) |
    882  1.1.2.2  bouyer 			(state->cmd.bytes[2] << 16) |
    883  1.1.2.2  bouyer 			(state->cmd.bytes[3] << 8) |
    884  1.1.2.2  bouyer 			 state->cmd.bytes[4];
    885  1.1.2.2  bouyer 		asc_debug_sz = (state->cmd.bytes[6] << 8) | state->cmd.bytes[7];
    886  1.1.2.2  bouyer 	}
    887  1.1.2.2  bouyer 	asc_logp->status = PACK(asc->sc_dev.dv_unit, 0, 0, asc_debug_cmd);
    888  1.1.2.2  bouyer 	asc_logp->target = asc->target;
    889  1.1.2.2  bouyer 	asc_logp->state = asc->script - asc_scripts;
    890  1.1.2.2  bouyer 	asc_logp->msg = SCSI_DIS_REC_IDENTIFY;
    891  1.1.2.2  bouyer 	asc_logp->resid = scsicmd->datalen;
    892  1.1.2.2  bouyer 	if (++asc_logp >= &asc_log[NLOG])
    893  1.1.2.2  bouyer 		asc_logp = asc_log;
    894  1.1.2.2  bouyer #endif
    895  1.1.2.2  bouyer 
    896  1.1.2.2  bouyer 	/* preload the FIFO with the message and command to be sent */
    897  1.1.2.2  bouyer 	regs->asc_fifo = SCSI_DIS_REC_IDENTIFY |
    898  1.1.2.2  bouyer 	    (scsicmd->sc_link->scsipi_scsi.lun & 0x07);
    899  1.1.2.2  bouyer 
    900  1.1.2.2  bouyer 	for( i = 0; i < len; i++ ) {
    901  1.1.2.2  bouyer 		regs->asc_fifo = ((caddr_t)&state->cmd)[i];
    902  1.1.2.2  bouyer 	}
    903  1.1.2.2  bouyer 	ASC_TC_PUT(regs, 0, asc->is24bit);
    904  1.1.2.2  bouyer 	readback(regs->asc_cmd);
    905  1.1.2.2  bouyer 	regs->asc_cmd = ASC_CMD_DMA;
    906  1.1.2.2  bouyer 	readback(regs->asc_cmd);
    907  1.1.2.2  bouyer 
    908  1.1.2.2  bouyer 	regs->asc_dbus_id = target;
    909  1.1.2.2  bouyer 	readback(regs->asc_dbus_id);
    910  1.1.2.2  bouyer 	regs->asc_syn_p = state->sync_period;
    911  1.1.2.2  bouyer 	readback(regs->asc_syn_p);
    912  1.1.2.2  bouyer 	regs->asc_syn_o = state->sync_offset;
    913  1.1.2.2  bouyer 	readback(regs->asc_syn_o);
    914  1.1.2.2  bouyer 
    915  1.1.2.2  bouyer /*XXX PEFO */
    916  1.1.2.2  bouyer /* we are not using sync transfer now, need to check this if we will */
    917  1.1.2.2  bouyer 
    918  1.1.2.2  bouyer 	if (state->flags & TRY_SYNC)
    919  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_SEL_ATN_STOP;
    920  1.1.2.2  bouyer 	else
    921  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_SEL_ATN;
    922  1.1.2.2  bouyer 	readback(regs->asc_cmd);
    923  1.1.2.2  bouyer }
    924  1.1.2.2  bouyer 
    925  1.1.2.2  bouyer /*
    926  1.1.2.2  bouyer  * Interrupt routine
    927  1.1.2.2  bouyer  *	Take interrupts from the chip
    928  1.1.2.2  bouyer  *
    929  1.1.2.2  bouyer  * Implementation:
    930  1.1.2.2  bouyer  *	Move along the current command's script if
    931  1.1.2.2  bouyer  *	all is well, invoke error handler if not.
    932  1.1.2.2  bouyer  */
    933  1.1.2.2  bouyer int
    934  1.1.2.2  bouyer asc_intr(sc)
    935  1.1.2.2  bouyer 	void *sc;
    936  1.1.2.2  bouyer {
    937  1.1.2.2  bouyer 	asc_softc_t asc = sc;
    938  1.1.2.2  bouyer 	asc_regmap_t *regs = asc->regs;
    939  1.1.2.2  bouyer 	State *state;
    940  1.1.2.2  bouyer 	script_t *scpt;
    941  1.1.2.2  bouyer 	int ss, ir, status;
    942  1.1.2.2  bouyer 
    943  1.1.2.2  bouyer 	/* collect ephemeral information */
    944  1.1.2.2  bouyer 	status = regs->asc_status;
    945  1.1.2.2  bouyer 	ss = regs->asc_ss;
    946  1.1.2.2  bouyer 
    947  1.1.2.2  bouyer 	if ((status & ASC_CSR_INT) == 0) /* Make shure it's a real interrupt */
    948  1.1.2.2  bouyer 		 return(0);
    949  1.1.2.2  bouyer 
    950  1.1.2.2  bouyer 	ir = regs->asc_intr;	/* this resets the previous two */
    951  1.1.2.2  bouyer 	scpt = asc->script;
    952  1.1.2.2  bouyer 
    953  1.1.2.2  bouyer #ifdef DEBUG
    954  1.1.2.2  bouyer 	asc_logp->status = PACK(asc->sc_dev.dv_unit, status, ss, ir);
    955  1.1.2.2  bouyer 	asc_logp->target = (asc->state == ASC_STATE_BUSY) ? asc->target : -1;
    956  1.1.2.2  bouyer 	asc_logp->state = scpt - asc_scripts;
    957  1.1.2.2  bouyer 	asc_logp->msg = -1;
    958  1.1.2.2  bouyer 	asc_logp->resid = 0;
    959  1.1.2.2  bouyer 	if (++asc_logp >= &asc_log[NLOG])
    960  1.1.2.2  bouyer 		asc_logp = asc_log;
    961  1.1.2.2  bouyer 	if (asc_debug > 2)
    962  1.1.2.2  bouyer 		printf("asc_intr: status %x ss %x ir %x cond %d:%x\n",
    963  1.1.2.2  bouyer 			status, ss, ir, scpt - asc_scripts, scpt->condition);
    964  1.1.2.2  bouyer #endif
    965  1.1.2.2  bouyer 
    966  1.1.2.2  bouyer 	/* check the expected state */
    967  1.1.2.2  bouyer 	if (SCRIPT_MATCH(ir, status) == scpt->condition) {
    968  1.1.2.2  bouyer 		/*
    969  1.1.2.2  bouyer 		 * Perform the appropriate operation, then proceed.
    970  1.1.2.2  bouyer 		 */
    971  1.1.2.2  bouyer 		if ((*scpt->action)(asc, status, ss, ir)) {
    972  1.1.2.2  bouyer 			regs->asc_cmd = scpt->command;
    973  1.1.2.2  bouyer 			readback(regs->asc_cmd);
    974  1.1.2.2  bouyer 			asc->script = scpt->next;
    975  1.1.2.2  bouyer 		}
    976  1.1.2.2  bouyer 		goto done;
    977  1.1.2.2  bouyer 	}
    978  1.1.2.2  bouyer 
    979  1.1.2.2  bouyer 	/*
    980  1.1.2.2  bouyer 	 * Check for parity error.
    981  1.1.2.2  bouyer 	 * Hardware will automatically set ATN
    982  1.1.2.2  bouyer 	 * to request the device for a MSG_OUT phase.
    983  1.1.2.2  bouyer 	 */
    984  1.1.2.2  bouyer 	if (status & ASC_CSR_PE) {
    985  1.1.2.2  bouyer 		printf("%s: SCSI device %d: incomming parity error seen\n",
    986  1.1.2.2  bouyer 			asc->sc_dev.dv_xname, asc->target);
    987  1.1.2.2  bouyer 		asc->st[asc->target].flags |= PARITY_ERR;
    988  1.1.2.2  bouyer 	}
    989  1.1.2.2  bouyer 
    990  1.1.2.2  bouyer 	/*
    991  1.1.2.2  bouyer 	 * Check for gross error.
    992  1.1.2.2  bouyer 	 * Probably a bug in a device driver.
    993  1.1.2.2  bouyer 	 */
    994  1.1.2.2  bouyer 	if (status & ASC_CSR_GE) {
    995  1.1.2.2  bouyer 		printf("%s: SCSI device %d: gross error\n",
    996  1.1.2.2  bouyer 			asc->sc_dev.dv_xname, asc->target);
    997  1.1.2.2  bouyer 		goto abort;
    998  1.1.2.2  bouyer 	}
    999  1.1.2.2  bouyer 
   1000  1.1.2.2  bouyer 	/* check for message in or out */
   1001  1.1.2.2  bouyer 	if ((ir & ~ASC_INT_FC) == ASC_INT_BS) {
   1002  1.1.2.2  bouyer 		register int len, fifo;
   1003  1.1.2.2  bouyer 
   1004  1.1.2.2  bouyer 		state = &asc->st[asc->target];
   1005  1.1.2.2  bouyer 		switch (ASC_PHASE(status)) {
   1006  1.1.2.2  bouyer 		case ASC_PHASE_DATAI:
   1007  1.1.2.2  bouyer 		case ASC_PHASE_DATAO:
   1008  1.1.2.2  bouyer 			ASC_TC_GET(regs, len);
   1009  1.1.2.2  bouyer 			fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
   1010  1.1.2.2  bouyer 			printf("asc_intr: data overrun: buflen %d dmalen %d tc %d fifo %d\n",
   1011  1.1.2.2  bouyer 				state->buflen, state->dmalen, len, fifo);
   1012  1.1.2.2  bouyer 			goto abort;
   1013  1.1.2.2  bouyer 
   1014  1.1.2.2  bouyer 		case ASC_PHASE_MSG_IN:
   1015  1.1.2.2  bouyer 			break;
   1016  1.1.2.2  bouyer 
   1017  1.1.2.2  bouyer 		case ASC_PHASE_MSG_OUT:
   1018  1.1.2.2  bouyer 			/*
   1019  1.1.2.2  bouyer 			 * Check for parity error.
   1020  1.1.2.2  bouyer 			 * Hardware will automatically set ATN
   1021  1.1.2.2  bouyer 			 * to request the device for a MSG_OUT phase.
   1022  1.1.2.2  bouyer 			 */
   1023  1.1.2.2  bouyer 			if (state->flags & PARITY_ERR) {
   1024  1.1.2.2  bouyer 				state->flags &= ~PARITY_ERR;
   1025  1.1.2.2  bouyer 				state->msg_out = SCSI_MESSAGE_PARITY_ERROR;
   1026  1.1.2.2  bouyer 				/* reset message in counter */
   1027  1.1.2.2  bouyer 				state->msglen = 0;
   1028  1.1.2.2  bouyer 			} else
   1029  1.1.2.2  bouyer 				state->msg_out = SCSI_NO_OP;
   1030  1.1.2.2  bouyer 			regs->asc_fifo = state->msg_out;
   1031  1.1.2.2  bouyer 			regs->asc_cmd = ASC_CMD_XFER_INFO;
   1032  1.1.2.2  bouyer 			readback(regs->asc_cmd);
   1033  1.1.2.2  bouyer 			goto done;
   1034  1.1.2.2  bouyer 
   1035  1.1.2.2  bouyer 		case ASC_PHASE_STATUS:
   1036  1.1.2.2  bouyer 			/* probably an error in the SCSI command */
   1037  1.1.2.2  bouyer 			asc->script = &asc_scripts[SCRIPT_GET_STATUS];
   1038  1.1.2.2  bouyer 			regs->asc_cmd = ASC_CMD_I_COMPLETE;
   1039  1.1.2.2  bouyer 			readback(regs->asc_cmd);
   1040  1.1.2.2  bouyer 			goto done;
   1041  1.1.2.2  bouyer 
   1042  1.1.2.2  bouyer 		default:
   1043  1.1.2.2  bouyer 			goto abort;
   1044  1.1.2.2  bouyer 		}
   1045  1.1.2.2  bouyer 
   1046  1.1.2.2  bouyer 		if (state->script)
   1047  1.1.2.2  bouyer 			goto abort;
   1048  1.1.2.2  bouyer 
   1049  1.1.2.2  bouyer 		/*
   1050  1.1.2.2  bouyer 		 * OK, message coming in clean up whatever is going on.
   1051  1.1.2.2  bouyer 		 * Get number of bytes left to transfered from byte counter
   1052  1.1.2.2  bouyer 		 * counter decrements when data is trf on the SCSI bus
   1053  1.1.2.2  bouyer 		 */
   1054  1.1.2.2  bouyer 		ASC_TC_GET(regs, len);
   1055  1.1.2.2  bouyer 		fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
   1056  1.1.2.2  bouyer 		/* flush any data in the FIFO */
   1057  1.1.2.2  bouyer 		if (fifo && !(state->flags & DMA_IN_PROGRESS)) {
   1058  1.1.2.2  bouyer printf("asc_intr: fifo flush %d len %d fifo %x\n", fifo, len, regs->asc_fifo);
   1059  1.1.2.2  bouyer 			regs->asc_cmd = ASC_CMD_FLUSH;
   1060  1.1.2.2  bouyer 			readback(regs->asc_cmd);
   1061  1.1.2.2  bouyer 			DELAY(2);
   1062  1.1.2.2  bouyer 		}
   1063  1.1.2.2  bouyer 		else if (fifo && state->flags & DMA_IN_PROGRESS) {
   1064  1.1.2.2  bouyer 			if (state->flags & DMA_OUT) {
   1065  1.1.2.2  bouyer 				len += fifo; /* Bytes dma'ed but not sent */
   1066  1.1.2.2  bouyer 			}
   1067  1.1.2.2  bouyer 			else if (state->flags & DMA_IN) {
   1068  1.1.2.2  bouyer 				printf("asc_intr: IN: dmalen %d len %d fifo %d\n",
   1069  1.1.2.2  bouyer 					state->dmalen, len, fifo); /* XXX */
   1070  1.1.2.2  bouyer 			}
   1071  1.1.2.2  bouyer 			regs->asc_cmd = ASC_CMD_FLUSH;
   1072  1.1.2.2  bouyer 			readback(regs->asc_cmd);
   1073  1.1.2.2  bouyer 			DELAY(2);
   1074  1.1.2.2  bouyer 		}
   1075  1.1.2.2  bouyer 		if (len && (state->flags & DMA_IN_PROGRESS)) {
   1076  1.1.2.2  bouyer 			/* save number of bytes still to be sent or received */
   1077  1.1.2.2  bouyer 			state->dmaresid = len;
   1078  1.1.2.2  bouyer 			state->flags &= ~DMA_IN_PROGRESS;
   1079  1.1.2.2  bouyer 			ASC_TC_PUT(regs, 0, asc->is24bit);
   1080  1.1.2.2  bouyer #ifdef DEBUG
   1081  1.1.2.2  bouyer 			if (asc_logp == asc_log)
   1082  1.1.2.2  bouyer 				asc_log[NLOG - 1].resid = len;
   1083  1.1.2.2  bouyer 			else
   1084  1.1.2.2  bouyer 				asc_logp[-1].resid = len;
   1085  1.1.2.2  bouyer #endif
   1086  1.1.2.2  bouyer 			/* setup state to resume to */
   1087  1.1.2.2  bouyer 			if (state->flags & DMA_IN) {
   1088  1.1.2.2  bouyer 				/*
   1089  1.1.2.2  bouyer 				 * Since the ASC_CNFG3_SRB bit of the
   1090  1.1.2.2  bouyer 				 * cnfg3 register bit is not set,
   1091  1.1.2.2  bouyer 				 * we just transferred an extra byte.
   1092  1.1.2.2  bouyer 				 * Since we can't resume on an odd byte
   1093  1.1.2.2  bouyer 				 * boundary, we copy the valid data out
   1094  1.1.2.2  bouyer 				 * and resume DMA at the start address.
   1095  1.1.2.2  bouyer 				 */
   1096  1.1.2.2  bouyer 				if (len & 1) {
   1097  1.1.2.2  bouyer 					printf("asc_intr: msg in len %d (fifo %d)\n",
   1098  1.1.2.2  bouyer 						len, fifo); /* XXX */
   1099  1.1.2.2  bouyer 					len = state->dmalen - len;
   1100  1.1.2.2  bouyer 					goto do_in;
   1101  1.1.2.2  bouyer 				}
   1102  1.1.2.2  bouyer 				state->script =
   1103  1.1.2.2  bouyer 					&asc_scripts[SCRIPT_RESUME_DMA_IN];
   1104  1.1.2.2  bouyer 			} else if (state->flags & DMA_OUT)
   1105  1.1.2.2  bouyer 				state->script =
   1106  1.1.2.2  bouyer 					&asc_scripts[SCRIPT_RESUME_DMA_OUT];
   1107  1.1.2.2  bouyer 			else
   1108  1.1.2.2  bouyer 				state->script = asc->script;
   1109  1.1.2.2  bouyer 		} else if (state->flags & DMA_IN) {
   1110  1.1.2.2  bouyer 			if (len) {
   1111  1.1.2.2  bouyer #ifdef DEBUG
   1112  1.1.2.2  bouyer 				printf("asc_intr: 1: bn %d len %d (fifo %d)\n",
   1113  1.1.2.2  bouyer 					asc_debug_bn, len, fifo); /* XXX */
   1114  1.1.2.2  bouyer #endif
   1115  1.1.2.2  bouyer 				goto abort;
   1116  1.1.2.2  bouyer 			}
   1117  1.1.2.2  bouyer 			/* setup state to resume to */
   1118  1.1.2.2  bouyer 			if (state->flags & DMA_IN_PROGRESS) {
   1119  1.1.2.2  bouyer 				len = state->dmalen;
   1120  1.1.2.2  bouyer 				state->flags &= ~DMA_IN_PROGRESS;
   1121  1.1.2.2  bouyer 			do_in:
   1122  1.1.2.2  bouyer 				DMA_END(asc->dma);
   1123  1.1.2.2  bouyer 				state->buf += len;
   1124  1.1.2.2  bouyer 				state->buflen -= len;
   1125  1.1.2.2  bouyer 			}
   1126  1.1.2.2  bouyer 			if (state->buflen)
   1127  1.1.2.2  bouyer 				state->script =
   1128  1.1.2.2  bouyer 				    &asc_scripts[SCRIPT_RESUME_IN];
   1129  1.1.2.2  bouyer 			else
   1130  1.1.2.2  bouyer 				state->script =
   1131  1.1.2.2  bouyer 				    &asc_scripts[SCRIPT_RESUME_NO_DATA];
   1132  1.1.2.2  bouyer 		} else if (state->flags & DMA_OUT) {
   1133  1.1.2.2  bouyer 			if (len) {
   1134  1.1.2.2  bouyer 				printf("asc_intr: 2: len %d (fifo %d)\n", len,
   1135  1.1.2.2  bouyer 					fifo); /* XXX */
   1136  1.1.2.2  bouyer /* XXX THEO */
   1137  1.1.2.2  bouyer #if 1
   1138  1.1.2.2  bouyer 				regs->asc_cmd = ASC_CMD_FLUSH;
   1139  1.1.2.2  bouyer 				readback(regs->asc_cmd);
   1140  1.1.2.2  bouyer 				DELAY(2);
   1141  1.1.2.2  bouyer 				len = 0;
   1142  1.1.2.2  bouyer #else
   1143  1.1.2.2  bouyer 				goto abort;
   1144  1.1.2.2  bouyer #endif
   1145  1.1.2.2  bouyer 			}
   1146  1.1.2.2  bouyer 			/*
   1147  1.1.2.2  bouyer 			 * If this is the last chunk, the next expected
   1148  1.1.2.2  bouyer 			 * state is to get status.
   1149  1.1.2.2  bouyer 			 */
   1150  1.1.2.2  bouyer 			if (state->flags & DMA_IN_PROGRESS) {
   1151  1.1.2.2  bouyer 				state->flags &= ~DMA_IN_PROGRESS;
   1152  1.1.2.2  bouyer 				DMA_END(asc->dma);
   1153  1.1.2.2  bouyer 				len = state->dmalen;
   1154  1.1.2.2  bouyer 				state->buf += len;
   1155  1.1.2.2  bouyer 				state->buflen -= len;
   1156  1.1.2.2  bouyer 			}
   1157  1.1.2.2  bouyer 			if (state->buflen)
   1158  1.1.2.2  bouyer 				state->script =
   1159  1.1.2.2  bouyer 				    &asc_scripts[SCRIPT_RESUME_OUT];
   1160  1.1.2.2  bouyer 			else
   1161  1.1.2.2  bouyer 				state->script =
   1162  1.1.2.2  bouyer 				    &asc_scripts[SCRIPT_RESUME_NO_DATA];
   1163  1.1.2.2  bouyer 		} else if (asc->script == &asc_scripts[SCRIPT_SIMPLE])
   1164  1.1.2.2  bouyer 			state->script = &asc_scripts[SCRIPT_RESUME_NO_DATA];
   1165  1.1.2.2  bouyer 		else
   1166  1.1.2.2  bouyer 			state->script = asc->script;
   1167  1.1.2.2  bouyer 
   1168  1.1.2.2  bouyer 		/* setup to receive a message */
   1169  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_MSG_IN];
   1170  1.1.2.2  bouyer 		state->msglen = 0;
   1171  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_XFER_INFO;
   1172  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1173  1.1.2.2  bouyer 		goto done;
   1174  1.1.2.2  bouyer 	}
   1175  1.1.2.2  bouyer 
   1176  1.1.2.2  bouyer 	/* check for SCSI bus reset */
   1177  1.1.2.2  bouyer 	if (ir & ASC_INT_RESET) {
   1178  1.1.2.2  bouyer 		register int i;
   1179  1.1.2.2  bouyer 
   1180  1.1.2.2  bouyer 		printf("%s: SCSI bus reset!!\n", asc->sc_dev.dv_xname);
   1181  1.1.2.2  bouyer 		/* need to flush any pending commands */
   1182  1.1.2.2  bouyer 		for (i = 0; i < ASC_NCMD; i++) {
   1183  1.1.2.2  bouyer 			if (!asc->cmd[i])
   1184  1.1.2.2  bouyer 				continue;
   1185  1.1.2.2  bouyer 			asc->cmd[i]->error = XS_DRIVER_STUFFUP;
   1186  1.1.2.2  bouyer 			asc_end(asc, 0, 0, 0);
   1187  1.1.2.2  bouyer 		}
   1188  1.1.2.2  bouyer 		/* rearbitrate synchronous offset */
   1189  1.1.2.2  bouyer 		for (i = 0; i < ASC_NCMD; i++) {
   1190  1.1.2.2  bouyer 			asc->st[i].sync_offset = 0;
   1191  1.1.2.2  bouyer 			asc->st[i].flags = 0;
   1192  1.1.2.2  bouyer 		}
   1193  1.1.2.2  bouyer 		asc->target = -1;
   1194  1.1.2.2  bouyer 		return(1);
   1195  1.1.2.2  bouyer 	}
   1196  1.1.2.2  bouyer 
   1197  1.1.2.2  bouyer 	/* check for command errors */
   1198  1.1.2.2  bouyer 	if (ir & ASC_INT_ILL)
   1199  1.1.2.2  bouyer 		goto abort;
   1200  1.1.2.2  bouyer 
   1201  1.1.2.2  bouyer 	/* check for disconnect */
   1202  1.1.2.2  bouyer 	if (ir & ASC_INT_DISC) {
   1203  1.1.2.2  bouyer 		state = &asc->st[asc->target];
   1204  1.1.2.2  bouyer 		switch (asc->script - asc_scripts) {
   1205  1.1.2.2  bouyer 		case SCRIPT_DONE:
   1206  1.1.2.2  bouyer 		case SCRIPT_DISCONNECT:
   1207  1.1.2.2  bouyer 			/*
   1208  1.1.2.2  bouyer 			 * Disconnects can happen normally when the
   1209  1.1.2.2  bouyer 			 * command is complete with the phase being
   1210  1.1.2.2  bouyer 			 * either ASC_PHASE_DATAO or ASC_PHASE_MSG_IN.
   1211  1.1.2.2  bouyer 			 * The SCRIPT_MATCH() only checks for one phase
   1212  1.1.2.2  bouyer 			 * so we can wind up here.
   1213  1.1.2.2  bouyer 			 * Perform the appropriate operation, then proceed.
   1214  1.1.2.2  bouyer 			 */
   1215  1.1.2.2  bouyer 			if ((*scpt->action)(asc, status, ss, ir)) {
   1216  1.1.2.2  bouyer 				regs->asc_cmd = scpt->command;
   1217  1.1.2.2  bouyer 				readback(regs->asc_cmd);
   1218  1.1.2.2  bouyer 				asc->script = scpt->next;
   1219  1.1.2.2  bouyer 			}
   1220  1.1.2.2  bouyer 			goto done;
   1221  1.1.2.2  bouyer 
   1222  1.1.2.2  bouyer 		case SCRIPT_TRY_SYNC:
   1223  1.1.2.2  bouyer 		case SCRIPT_SIMPLE:
   1224  1.1.2.2  bouyer 		case SCRIPT_DATA_IN:
   1225  1.1.2.2  bouyer 		case SCRIPT_DATA_OUT: /* one of the starting scripts */
   1226  1.1.2.2  bouyer 			if (ASC_SS(ss) == 0) {
   1227  1.1.2.2  bouyer 				/* device did not respond */
   1228  1.1.2.2  bouyer 				if (regs->asc_flags & ASC_FLAGS_FIFO_CNT) {
   1229  1.1.2.2  bouyer 					regs->asc_cmd = ASC_CMD_FLUSH;
   1230  1.1.2.2  bouyer 					readback(regs->asc_cmd);
   1231  1.1.2.2  bouyer 				}
   1232  1.1.2.2  bouyer 				asc->cmd[asc->target]->error = XS_DRIVER_STUFFUP;
   1233  1.1.2.2  bouyer 				asc_end(asc, status, ss, ir);
   1234  1.1.2.2  bouyer 				return(1);
   1235  1.1.2.2  bouyer 			}
   1236  1.1.2.2  bouyer 			/* FALLTHROUGH */
   1237  1.1.2.2  bouyer 
   1238  1.1.2.2  bouyer 		default:
   1239  1.1.2.2  bouyer 			printf("%s: SCSI device %d: unexpected disconnect\n",
   1240  1.1.2.2  bouyer 				asc->sc_dev.dv_xname, asc->target);
   1241  1.1.2.2  bouyer #ifdef DEBUG
   1242  1.1.2.2  bouyer 			asc_DumpLog("asc_disc");
   1243  1.1.2.2  bouyer #endif
   1244  1.1.2.2  bouyer 			/*
   1245  1.1.2.2  bouyer 			 * On rare occasions my RZ24 does a disconnect during
   1246  1.1.2.2  bouyer 			 * data in phase and the following seems to keep it
   1247  1.1.2.2  bouyer 			 * happy.
   1248  1.1.2.2  bouyer 			 * XXX Should a scsi disk ever do this??
   1249  1.1.2.2  bouyer 			 */
   1250  1.1.2.2  bouyer 			asc->script = &asc_scripts[SCRIPT_RESEL];
   1251  1.1.2.2  bouyer 			asc->state = ASC_STATE_RESEL;
   1252  1.1.2.2  bouyer 			state->flags |= DISCONN;
   1253  1.1.2.2  bouyer 			regs->asc_cmd = ASC_CMD_ENABLE_SEL;
   1254  1.1.2.2  bouyer 			readback(regs->asc_cmd);
   1255  1.1.2.2  bouyer 			return(1);
   1256  1.1.2.2  bouyer 		}
   1257  1.1.2.2  bouyer 	}
   1258  1.1.2.2  bouyer 
   1259  1.1.2.2  bouyer 	/* check for reselect */
   1260  1.1.2.2  bouyer 	if (ir & ASC_INT_RESEL) {
   1261  1.1.2.2  bouyer 		unsigned fifo, id, msg;
   1262  1.1.2.2  bouyer 
   1263  1.1.2.2  bouyer 		fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
   1264  1.1.2.2  bouyer 		if (fifo < 2)
   1265  1.1.2.2  bouyer 			goto abort;
   1266  1.1.2.2  bouyer 		/* read unencoded SCSI ID and convert to binary */
   1267  1.1.2.2  bouyer 		msg = regs->asc_fifo & asc->myidmask;
   1268  1.1.2.2  bouyer 		for (id = 0; (msg & 1) == 0; id++)
   1269  1.1.2.2  bouyer 			msg >>= 1;
   1270  1.1.2.2  bouyer 		/* read identify message */
   1271  1.1.2.2  bouyer 		msg = regs->asc_fifo;
   1272  1.1.2.2  bouyer #ifdef DEBUG
   1273  1.1.2.2  bouyer 		if (asc_logp == asc_log)
   1274  1.1.2.2  bouyer 			asc_log[NLOG - 1].msg = msg;
   1275  1.1.2.2  bouyer 		else
   1276  1.1.2.2  bouyer 			asc_logp[-1].msg = msg;
   1277  1.1.2.2  bouyer #endif
   1278  1.1.2.2  bouyer 		asc->state = ASC_STATE_BUSY;
   1279  1.1.2.2  bouyer 		asc->target = id;
   1280  1.1.2.2  bouyer 		state = &asc->st[id];
   1281  1.1.2.2  bouyer 		asc->script = state->script;
   1282  1.1.2.2  bouyer 		state->script = (script_t *)0;
   1283  1.1.2.2  bouyer 		if (!(state->flags & DISCONN))
   1284  1.1.2.2  bouyer 			goto abort;
   1285  1.1.2.2  bouyer 		state->flags &= ~DISCONN;
   1286  1.1.2.2  bouyer 		regs->asc_syn_p = state->sync_period;
   1287  1.1.2.2  bouyer 		regs->asc_syn_o = state->sync_offset;
   1288  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_MSG_ACPT;
   1289  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1290  1.1.2.2  bouyer 		goto done;
   1291  1.1.2.2  bouyer 	}
   1292  1.1.2.2  bouyer 
   1293  1.1.2.2  bouyer 	/* check if we are being selected as a target */
   1294  1.1.2.2  bouyer 	if (ir & (ASC_INT_SEL | ASC_INT_SEL_ATN))
   1295  1.1.2.2  bouyer 		goto abort;
   1296  1.1.2.2  bouyer 
   1297  1.1.2.2  bouyer 	/*
   1298  1.1.2.2  bouyer 	 * 'ir' must be just ASC_INT_FC.
   1299  1.1.2.2  bouyer 	 * This is normal if canceling an ASC_ENABLE_SEL.
   1300  1.1.2.2  bouyer 	 */
   1301  1.1.2.2  bouyer 
   1302  1.1.2.2  bouyer done:
   1303  1.1.2.2  bouyer 	wbflush();
   1304  1.1.2.2  bouyer 	/*
   1305  1.1.2.2  bouyer 	 * If the next interrupt comes in immediatly the interrupt
   1306  1.1.2.2  bouyer 	 * dispatcher (which we are returning to) will catch it
   1307  1.1.2.2  bouyer 	 * before returning to the interrupted code.
   1308  1.1.2.2  bouyer 	 */
   1309  1.1.2.2  bouyer 	return(1);
   1310  1.1.2.2  bouyer 
   1311  1.1.2.2  bouyer abort:
   1312  1.1.2.2  bouyer #ifdef DEBUG
   1313  1.1.2.2  bouyer 	asc_DumpLog("asc_intr");
   1314  1.1.2.2  bouyer #endif
   1315  1.1.2.2  bouyer 	panic("asc_intr");
   1316  1.1.2.2  bouyer 	return(1);
   1317  1.1.2.2  bouyer }
   1318  1.1.2.2  bouyer 
   1319  1.1.2.2  bouyer /*
   1320  1.1.2.2  bouyer  * All the many little things that the interrupt
   1321  1.1.2.2  bouyer  * routine might switch to.
   1322  1.1.2.2  bouyer  */
   1323  1.1.2.2  bouyer 
   1324  1.1.2.2  bouyer /* ARGSUSED */
   1325  1.1.2.2  bouyer static int
   1326  1.1.2.2  bouyer script_nop(asc, status, ss, ir)
   1327  1.1.2.2  bouyer 	asc_softc_t asc;
   1328  1.1.2.2  bouyer 	int status, ss, ir;
   1329  1.1.2.2  bouyer {
   1330  1.1.2.2  bouyer 	return (1);
   1331  1.1.2.2  bouyer }
   1332  1.1.2.2  bouyer 
   1333  1.1.2.2  bouyer /* ARGSUSED */
   1334  1.1.2.2  bouyer static int
   1335  1.1.2.2  bouyer asc_get_status(asc, status, ss, ir)
   1336  1.1.2.2  bouyer 	register asc_softc_t asc;
   1337  1.1.2.2  bouyer 	register int status, ss, ir;
   1338  1.1.2.2  bouyer {
   1339  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1340  1.1.2.2  bouyer 	register int data;
   1341  1.1.2.2  bouyer 
   1342  1.1.2.2  bouyer 	/*
   1343  1.1.2.2  bouyer 	 * Get the last two bytes in the FIFO.
   1344  1.1.2.2  bouyer 	 */
   1345  1.1.2.2  bouyer 	if ((data = regs->asc_flags & ASC_FLAGS_FIFO_CNT) != 2) {
   1346  1.1.2.2  bouyer 		printf("asc_get_status: cmdreg %x, fifo cnt %d\n",
   1347  1.1.2.2  bouyer 		       regs->asc_cmd, data); /* XXX */
   1348  1.1.2.2  bouyer #ifdef DEBUG
   1349  1.1.2.2  bouyer 		asc_DumpLog("get_status"); /* XXX */
   1350  1.1.2.2  bouyer #endif
   1351  1.1.2.2  bouyer 		if (data < 2) {
   1352  1.1.2.2  bouyer 			asc->regs->asc_cmd = ASC_CMD_MSG_ACPT;
   1353  1.1.2.2  bouyer 			readback(asc->regs->asc_cmd);
   1354  1.1.2.2  bouyer 			return (0);
   1355  1.1.2.2  bouyer 		}
   1356  1.1.2.2  bouyer 		do {
   1357  1.1.2.2  bouyer 			data = regs->asc_fifo;
   1358  1.1.2.2  bouyer 		} while ((regs->asc_flags & ASC_FLAGS_FIFO_CNT) > 2);
   1359  1.1.2.2  bouyer 	}
   1360  1.1.2.2  bouyer 
   1361  1.1.2.2  bouyer 	/* save the status byte */
   1362  1.1.2.2  bouyer 	asc->st[asc->target].statusByte = data = regs->asc_fifo;
   1363  1.1.2.2  bouyer #ifdef DEBUG
   1364  1.1.2.2  bouyer 	if (asc_logp == asc_log)
   1365  1.1.2.2  bouyer 		asc_log[NLOG - 1].msg = data;
   1366  1.1.2.2  bouyer 	else
   1367  1.1.2.2  bouyer 		asc_logp[-1].msg = data;
   1368  1.1.2.2  bouyer #endif
   1369  1.1.2.2  bouyer 
   1370  1.1.2.2  bouyer 	/* get the (presumed) command_complete message */
   1371  1.1.2.2  bouyer 	if ((data = regs->asc_fifo) == SCSI_COMMAND_COMPLETE)
   1372  1.1.2.2  bouyer 		return (1);
   1373  1.1.2.2  bouyer 
   1374  1.1.2.2  bouyer #ifdef DEBUG
   1375  1.1.2.2  bouyer 	printf("asc_get_status: status %x cmd %x\n",
   1376  1.1.2.2  bouyer 		asc->st[asc->target].statusByte, data);
   1377  1.1.2.2  bouyer 	asc_DumpLog("asc_get_status");
   1378  1.1.2.2  bouyer #endif
   1379  1.1.2.2  bouyer 	return (0);
   1380  1.1.2.2  bouyer }
   1381  1.1.2.2  bouyer 
   1382  1.1.2.2  bouyer /* ARGSUSED */
   1383  1.1.2.2  bouyer static int
   1384  1.1.2.2  bouyer asc_end(asc, status, ss, ir)
   1385  1.1.2.2  bouyer 	asc_softc_t asc;
   1386  1.1.2.2  bouyer 	int status, ss, ir;
   1387  1.1.2.2  bouyer {
   1388  1.1.2.2  bouyer 	struct scsipi_xfer *scsicmd;
   1389  1.1.2.2  bouyer 	struct scsipi_link *sc_link;
   1390  1.1.2.2  bouyer 	State *state;
   1391  1.1.2.2  bouyer 	int i, target;
   1392  1.1.2.2  bouyer 
   1393  1.1.2.2  bouyer 	asc->state = ASC_STATE_IDLE;
   1394  1.1.2.2  bouyer 	target = asc->target;
   1395  1.1.2.2  bouyer 	asc->target = -1;
   1396  1.1.2.2  bouyer 	scsicmd = asc->cmd[target];
   1397  1.1.2.2  bouyer 	sc_link = scsicmd->sc_link;
   1398  1.1.2.2  bouyer 	asc->cmd[target] = (struct scsipi_xfer *)0;
   1399  1.1.2.2  bouyer 	state = &asc->st[target];
   1400  1.1.2.2  bouyer 
   1401  1.1.2.2  bouyer #ifdef DEBUG
   1402  1.1.2.2  bouyer 	if (asc_debug > 1) {
   1403  1.1.2.2  bouyer 		printf("asc_end: %s target %d cmd %x err %d resid %d\n",
   1404  1.1.2.2  bouyer 			asc->sc_dev.dv_xname, target,
   1405  1.1.2.2  bouyer 			state->cmd.opcode, scsicmd->error, state->buflen);
   1406  1.1.2.2  bouyer 	}
   1407  1.1.2.2  bouyer #endif
   1408  1.1.2.2  bouyer #ifdef DIAGNOSTIC
   1409  1.1.2.2  bouyer 	if (target < 0 || !scsicmd)
   1410  1.1.2.2  bouyer 		panic("asc_end");
   1411  1.1.2.2  bouyer #endif
   1412  1.1.2.2  bouyer 
   1413  1.1.2.2  bouyer 	/* look for disconnected devices */
   1414  1.1.2.2  bouyer 	for (i = 0; i < ASC_NCMD; i++) {
   1415  1.1.2.2  bouyer 		if (!asc->cmd[i] || !(asc->st[i].flags & DISCONN))
   1416  1.1.2.2  bouyer 			continue;
   1417  1.1.2.2  bouyer 		asc->regs->asc_cmd = ASC_CMD_ENABLE_SEL;
   1418  1.1.2.2  bouyer 		readback(asc->regs->asc_cmd);
   1419  1.1.2.2  bouyer 		asc->state = ASC_STATE_RESEL;
   1420  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_RESEL];
   1421  1.1.2.2  bouyer 		break;
   1422  1.1.2.2  bouyer 	}
   1423  1.1.2.2  bouyer 
   1424  1.1.2.2  bouyer 	if(scsicmd->error == XS_NOERROR && !(state->flags & CHECK_SENSE)) {
   1425  1.1.2.2  bouyer 		if((state->statusByte & ST_MASK) == SCSI_CHECK) {
   1426  1.1.2.2  bouyer 			struct scsipi_sense *ss = (void *)&state->cmd;
   1427  1.1.2.2  bouyer 			/* Save return values */
   1428  1.1.2.2  bouyer 			scsicmd->resid = state->buflen;
   1429  1.1.2.2  bouyer 			scsicmd->status = state->statusByte;
   1430  1.1.2.2  bouyer 			/* Set up sense request command */
   1431  1.1.2.2  bouyer 			bzero(ss, sizeof(*ss));
   1432  1.1.2.2  bouyer 			ss->opcode = REQUEST_SENSE;
   1433  1.1.2.2  bouyer 			ss->byte2 = sc_link->scsipi_scsi.lun << 5;
   1434  1.1.2.2  bouyer 			ss->length = sizeof(struct scsipi_sense_data);
   1435  1.1.2.2  bouyer 			state->cmdlen = sizeof(*ss);
   1436  1.1.2.2  bouyer 			state->buf = (vaddr_t)&scsicmd->sense.scsi_sense;
   1437  1.1.2.2  bouyer 			state->buflen = sizeof(struct scsipi_sense_data);
   1438  1.1.2.2  bouyer 			state->flags |= CHECK_SENSE;
   1439  1.1.2.2  bouyer 			mips3_HitFlushDCache(state->buf, state->buflen);
   1440  1.1.2.2  bouyer 			asc->cmd[target] = scsicmd;
   1441  1.1.2.2  bouyer 			asc_startcmd(asc, target);
   1442  1.1.2.2  bouyer 			return(0);
   1443  1.1.2.2  bouyer 		}
   1444  1.1.2.2  bouyer 	}
   1445  1.1.2.2  bouyer 
   1446  1.1.2.2  bouyer 	if(scsicmd->error == XS_NOERROR && (state->flags & CHECK_SENSE)) {
   1447  1.1.2.2  bouyer 		scsicmd->error = XS_SENSE;
   1448  1.1.2.2  bouyer 	}
   1449  1.1.2.2  bouyer 	else {
   1450  1.1.2.2  bouyer 		scsicmd->resid = state->buflen;
   1451  1.1.2.2  bouyer 	}
   1452  1.1.2.2  bouyer 	state->flags &= ~CHECK_SENSE;
   1453  1.1.2.2  bouyer 
   1454  1.1.2.2  bouyer 	/*
   1455  1.1.2.2  bouyer 	 * Look for another device that is ready.
   1456  1.1.2.2  bouyer 	 * May want to keep last one started and increment for fairness
   1457  1.1.2.2  bouyer 	 * rather than always starting at zero.
   1458  1.1.2.2  bouyer 	 */
   1459  1.1.2.2  bouyer 	for (i = 0; i < ASC_NCMD; i++) {
   1460  1.1.2.2  bouyer 		if (asc->cmd[i] == 0 && asc->cmdq[i] != 0) {
   1461  1.1.2.2  bouyer 			asc->cmd[i] = asc->cmdq[i];
   1462  1.1.2.2  bouyer 			asc->cmdq[i] = 0;
   1463  1.1.2.2  bouyer 		}
   1464  1.1.2.2  bouyer 	}
   1465  1.1.2.2  bouyer 	for (i = 0; i < ASC_NCMD; i++) {
   1466  1.1.2.2  bouyer 		/* don't restart a disconnected command */
   1467  1.1.2.2  bouyer 		if (!asc->cmd[i] || (asc->st[i].flags & DISCONN))
   1468  1.1.2.2  bouyer 			continue;
   1469  1.1.2.2  bouyer 		asc_startcmd(asc, i);
   1470  1.1.2.2  bouyer 		break;
   1471  1.1.2.2  bouyer 	}
   1472  1.1.2.2  bouyer 
   1473  1.1.2.2  bouyer 	/* signal device driver that the command is done */
   1474  1.1.2.2  bouyer 	scsicmd->xs_status |= XS_STS_DONE;
   1475  1.1.2.2  bouyer 	scsipi_done(scsicmd);
   1476  1.1.2.2  bouyer 
   1477  1.1.2.2  bouyer 	return (0);
   1478  1.1.2.2  bouyer }
   1479  1.1.2.2  bouyer 
   1480  1.1.2.2  bouyer /* ARGSUSED */
   1481  1.1.2.2  bouyer static int
   1482  1.1.2.2  bouyer asc_dma_in(asc, status, ss, ir)
   1483  1.1.2.2  bouyer 	register asc_softc_t asc;
   1484  1.1.2.2  bouyer 	register int status, ss, ir;
   1485  1.1.2.2  bouyer {
   1486  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1487  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1488  1.1.2.2  bouyer 	register int len;
   1489  1.1.2.2  bouyer 
   1490  1.1.2.2  bouyer 	/* check for previous chunk in buffer */
   1491  1.1.2.2  bouyer 	if (state->flags & DMA_IN_PROGRESS) {
   1492  1.1.2.2  bouyer 		/*
   1493  1.1.2.2  bouyer 		 * Only count bytes that have been copied to memory.
   1494  1.1.2.2  bouyer 		 * There may be some bytes in the FIFO if synchonous transfers
   1495  1.1.2.2  bouyer 		 * are in progress.
   1496  1.1.2.2  bouyer 		 */
   1497  1.1.2.2  bouyer 		DMA_END(asc->dma);
   1498  1.1.2.2  bouyer 		ASC_TC_GET(regs, len);
   1499  1.1.2.2  bouyer 		len = state->dmalen - len;
   1500  1.1.2.2  bouyer 		state->buf += len;
   1501  1.1.2.2  bouyer 		state->buflen -= len;
   1502  1.1.2.2  bouyer 	}
   1503  1.1.2.2  bouyer 
   1504  1.1.2.2  bouyer 	/* setup to start reading the next chunk */
   1505  1.1.2.2  bouyer 	len = state->buflen;
   1506  1.1.2.2  bouyer #ifdef DEBUG
   1507  1.1.2.2  bouyer 	if (asc_logp == asc_log)
   1508  1.1.2.2  bouyer 		asc_log[NLOG - 1].resid = len;
   1509  1.1.2.2  bouyer 	else
   1510  1.1.2.2  bouyer 		asc_logp[-1].resid = len;
   1511  1.1.2.2  bouyer #endif
   1512  1.1.2.2  bouyer 	if (len > state->dmaBufSize)
   1513  1.1.2.2  bouyer 		len = state->dmaBufSize;
   1514  1.1.2.2  bouyer 	state->dmalen = len;
   1515  1.1.2.2  bouyer 	DMA_START(asc->dma, (caddr_t)state->buf, len, DMA_FROM_DEV);
   1516  1.1.2.2  bouyer 	ASC_TC_PUT(regs, len, asc->is24bit);
   1517  1.1.2.2  bouyer #ifdef DEBUG
   1518  1.1.2.2  bouyer 	if (asc_debug > 2)
   1519  1.1.2.2  bouyer 		printf("asc_dma_in: buflen %d, len %d\n", state->buflen, len);
   1520  1.1.2.2  bouyer #endif
   1521  1.1.2.2  bouyer 
   1522  1.1.2.2  bouyer 	/* check for next chunk */
   1523  1.1.2.2  bouyer 	state->flags |= DMA_IN_PROGRESS;
   1524  1.1.2.2  bouyer 	if (len != state->buflen) {
   1525  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
   1526  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1527  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
   1528  1.1.2.2  bouyer 		return (0);
   1529  1.1.2.2  bouyer 	}
   1530  1.1.2.2  bouyer 	return (1);
   1531  1.1.2.2  bouyer }
   1532  1.1.2.2  bouyer 
   1533  1.1.2.2  bouyer /* ARGSUSED */
   1534  1.1.2.2  bouyer static int
   1535  1.1.2.2  bouyer asc_last_dma_in(asc, status, ss, ir)
   1536  1.1.2.2  bouyer 	register asc_softc_t asc;
   1537  1.1.2.2  bouyer 	register int status, ss, ir;
   1538  1.1.2.2  bouyer {
   1539  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1540  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1541  1.1.2.2  bouyer 	register int len, fifo;
   1542  1.1.2.2  bouyer 
   1543  1.1.2.2  bouyer 	DMA_END(asc->dma);
   1544  1.1.2.2  bouyer 	ASC_TC_GET(regs, len);
   1545  1.1.2.2  bouyer 	fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
   1546  1.1.2.2  bouyer #ifdef DEBUG
   1547  1.1.2.2  bouyer 	if (asc_debug > 2)
   1548  1.1.2.2  bouyer 		printf("asc_last_dma_in: buflen %d dmalen %d tc %d fifo %d\n",
   1549  1.1.2.2  bouyer 			state->buflen, state->dmalen, len, fifo);
   1550  1.1.2.2  bouyer #endif
   1551  1.1.2.2  bouyer 	if (fifo) {
   1552  1.1.2.2  bouyer 		/* device must be trying to send more than we expect */
   1553  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_FLUSH;
   1554  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1555  1.1.2.2  bouyer 	}
   1556  1.1.2.2  bouyer 	state->flags &= ~DMA_IN_PROGRESS;
   1557  1.1.2.2  bouyer 	len = state->dmalen - len;
   1558  1.1.2.2  bouyer 	state->buflen -= len;
   1559  1.1.2.2  bouyer 
   1560  1.1.2.2  bouyer 	return (1);
   1561  1.1.2.2  bouyer }
   1562  1.1.2.2  bouyer 
   1563  1.1.2.2  bouyer /* ARGSUSED */
   1564  1.1.2.2  bouyer static int
   1565  1.1.2.2  bouyer asc_resume_in(asc, status, ss, ir)
   1566  1.1.2.2  bouyer 	register asc_softc_t asc;
   1567  1.1.2.2  bouyer 	register int status, ss, ir;
   1568  1.1.2.2  bouyer {
   1569  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1570  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1571  1.1.2.2  bouyer 	register int len;
   1572  1.1.2.2  bouyer 
   1573  1.1.2.2  bouyer 	/* setup to start reading the next chunk */
   1574  1.1.2.2  bouyer 	len = state->buflen;
   1575  1.1.2.2  bouyer #ifdef DEBUG
   1576  1.1.2.2  bouyer 	if (asc_logp == asc_log)
   1577  1.1.2.2  bouyer 		asc_log[NLOG - 1].resid = len;
   1578  1.1.2.2  bouyer 	else
   1579  1.1.2.2  bouyer 		asc_logp[-1].resid = len;
   1580  1.1.2.2  bouyer #endif
   1581  1.1.2.2  bouyer 	if (len > state->dmaBufSize)
   1582  1.1.2.2  bouyer 		len = state->dmaBufSize;
   1583  1.1.2.2  bouyer 	state->dmalen = len;
   1584  1.1.2.2  bouyer #ifdef DEBUG
   1585  1.1.2.2  bouyer 	if (asc_logp == asc_log)
   1586  1.1.2.2  bouyer 		asc_log[NLOG - 1].resid = len;
   1587  1.1.2.2  bouyer 	else
   1588  1.1.2.2  bouyer 		asc_logp[-1].resid = len;
   1589  1.1.2.2  bouyer #endif
   1590  1.1.2.2  bouyer 	DMA_START(asc->dma, (caddr_t)state->buf, len, DMA_FROM_DEV);
   1591  1.1.2.2  bouyer 	ASC_TC_PUT(regs, len, asc->is24bit);
   1592  1.1.2.2  bouyer #ifdef DEBUG
   1593  1.1.2.2  bouyer 	if (asc_debug > 2)
   1594  1.1.2.2  bouyer 		printf("asc_resume_in: buflen %d, len %d\n", state->buflen,
   1595  1.1.2.2  bouyer 			len);
   1596  1.1.2.2  bouyer #endif
   1597  1.1.2.2  bouyer 
   1598  1.1.2.2  bouyer 	/* check for next chunk */
   1599  1.1.2.2  bouyer 	state->flags |= DMA_IN_PROGRESS;
   1600  1.1.2.2  bouyer 	if (len != state->buflen) {
   1601  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
   1602  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1603  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
   1604  1.1.2.2  bouyer 		return (0);
   1605  1.1.2.2  bouyer 	}
   1606  1.1.2.2  bouyer 	return (1);
   1607  1.1.2.2  bouyer }
   1608  1.1.2.2  bouyer 
   1609  1.1.2.2  bouyer /* ARGSUSED */
   1610  1.1.2.2  bouyer static int
   1611  1.1.2.2  bouyer asc_resume_dma_in(asc, status, ss, ir)
   1612  1.1.2.2  bouyer 	register asc_softc_t asc;
   1613  1.1.2.2  bouyer 	register int status, ss, ir;
   1614  1.1.2.2  bouyer {
   1615  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1616  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1617  1.1.2.2  bouyer 	register int len, off;
   1618  1.1.2.2  bouyer 
   1619  1.1.2.2  bouyer 	/* setup to finish reading the current chunk */
   1620  1.1.2.2  bouyer 	len = state->dmaresid;
   1621  1.1.2.2  bouyer 	off = state->dmalen - len;
   1622  1.1.2.2  bouyer 	if ((off & 1) && state->sync_offset) {
   1623  1.1.2.2  bouyer 		printf("asc_resume_dma_in: odd xfer dmalen %d len %d off %d\n",
   1624  1.1.2.2  bouyer 			state->dmalen, len, off); /* XXX */
   1625  1.1.2.2  bouyer 		regs->asc_res_fifo = ((u_char *)state->buf)[off];
   1626  1.1.2.2  bouyer /*XXX Need to flush cache ? */
   1627  1.1.2.2  bouyer 	}
   1628  1.1.2.2  bouyer 	DMA_START(asc->dma, (caddr_t)state->buf + off, len, DMA_FROM_DEV);
   1629  1.1.2.2  bouyer 	ASC_TC_PUT(regs, len, asc->is24bit);
   1630  1.1.2.2  bouyer #ifdef DEBUG
   1631  1.1.2.2  bouyer 	if (asc_debug > 2)
   1632  1.1.2.2  bouyer 		printf("asc_resume_dma_in: buflen %d dmalen %d len %d off %d\n",
   1633  1.1.2.2  bouyer 			state->dmalen, state->buflen, len, off);
   1634  1.1.2.2  bouyer #endif
   1635  1.1.2.2  bouyer 
   1636  1.1.2.2  bouyer 	/* check for next chunk */
   1637  1.1.2.2  bouyer 	state->flags |= DMA_IN_PROGRESS;
   1638  1.1.2.2  bouyer 	if (state->dmalen != state->buflen) {
   1639  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
   1640  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1641  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
   1642  1.1.2.2  bouyer 		return (0);
   1643  1.1.2.2  bouyer 	}
   1644  1.1.2.2  bouyer 	return (1);
   1645  1.1.2.2  bouyer }
   1646  1.1.2.2  bouyer 
   1647  1.1.2.2  bouyer /* ARGSUSED */
   1648  1.1.2.2  bouyer static int
   1649  1.1.2.2  bouyer asc_dma_out(asc, status, ss, ir)
   1650  1.1.2.2  bouyer 	register asc_softc_t asc;
   1651  1.1.2.2  bouyer 	register int status, ss, ir;
   1652  1.1.2.2  bouyer {
   1653  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1654  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1655  1.1.2.2  bouyer 	register int len, fifo;
   1656  1.1.2.2  bouyer 
   1657  1.1.2.2  bouyer 	if (state->flags & DMA_IN_PROGRESS) {
   1658  1.1.2.2  bouyer 		/* check to be sure previous chunk was finished */
   1659  1.1.2.2  bouyer 		ASC_TC_GET(regs, len);
   1660  1.1.2.2  bouyer 		fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
   1661  1.1.2.2  bouyer 		if (len || fifo)
   1662  1.1.2.2  bouyer 			printf("asc_dma_out: buflen %d dmalen %d tc %d fifo %d\n",
   1663  1.1.2.2  bouyer 				state->buflen, state->dmalen, len, fifo); /* XXX */
   1664  1.1.2.2  bouyer 		len += fifo;
   1665  1.1.2.2  bouyer 		len = state->dmalen - len;
   1666  1.1.2.2  bouyer 		state->buf += len;
   1667  1.1.2.2  bouyer 		state->buflen -= len;
   1668  1.1.2.2  bouyer 	}
   1669  1.1.2.2  bouyer 
   1670  1.1.2.2  bouyer 	/* setup for this chunk */
   1671  1.1.2.2  bouyer 	len = state->buflen;
   1672  1.1.2.2  bouyer #ifdef DEBUG
   1673  1.1.2.2  bouyer 	if (asc_logp == asc_log)
   1674  1.1.2.2  bouyer 		asc_log[NLOG - 1].resid = len;
   1675  1.1.2.2  bouyer 	else
   1676  1.1.2.2  bouyer 		asc_logp[-1].resid = len;
   1677  1.1.2.2  bouyer #endif
   1678  1.1.2.2  bouyer 	if (len > state->dmaBufSize)
   1679  1.1.2.2  bouyer 		len = state->dmaBufSize;
   1680  1.1.2.2  bouyer 	state->dmalen = len;
   1681  1.1.2.2  bouyer 	DMA_START(asc->dma, (caddr_t)state->buf, len, DMA_TO_DEV);
   1682  1.1.2.2  bouyer 	ASC_TC_PUT(regs, len, asc->is24bit);
   1683  1.1.2.2  bouyer #ifdef DEBUG
   1684  1.1.2.2  bouyer 	if (asc_debug > 2)
   1685  1.1.2.2  bouyer 		printf("asc_dma_out: buflen %d, len %d\n", state->buflen, len);
   1686  1.1.2.2  bouyer #endif
   1687  1.1.2.2  bouyer 
   1688  1.1.2.2  bouyer 	/* check for next chunk */
   1689  1.1.2.2  bouyer 	state->flags |= DMA_IN_PROGRESS;
   1690  1.1.2.2  bouyer 	if (len != state->buflen) {
   1691  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
   1692  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1693  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
   1694  1.1.2.2  bouyer 		return (0);
   1695  1.1.2.2  bouyer 	}
   1696  1.1.2.2  bouyer 	return (1);
   1697  1.1.2.2  bouyer }
   1698  1.1.2.2  bouyer 
   1699  1.1.2.2  bouyer /* ARGSUSED */
   1700  1.1.2.2  bouyer static int
   1701  1.1.2.2  bouyer asc_last_dma_out(asc, status, ss, ir)
   1702  1.1.2.2  bouyer 	register asc_softc_t asc;
   1703  1.1.2.2  bouyer 	register int status, ss, ir;
   1704  1.1.2.2  bouyer {
   1705  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1706  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1707  1.1.2.2  bouyer 	register int len, fifo;
   1708  1.1.2.2  bouyer 
   1709  1.1.2.2  bouyer 	ASC_TC_GET(regs, len);
   1710  1.1.2.2  bouyer 	fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
   1711  1.1.2.2  bouyer #ifdef DEBUG
   1712  1.1.2.2  bouyer 	if (asc_debug > 2)
   1713  1.1.2.2  bouyer 		printf("asc_last_dma_out: buflen %d dmalen %d tc %d fifo %d\n",
   1714  1.1.2.2  bouyer 			state->buflen, state->dmalen, len, fifo);
   1715  1.1.2.2  bouyer #endif
   1716  1.1.2.2  bouyer 	if (fifo) {
   1717  1.1.2.2  bouyer 		len += fifo;
   1718  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_FLUSH;
   1719  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1720  1.1.2.2  bouyer 	}
   1721  1.1.2.2  bouyer 	state->flags &= ~DMA_IN_PROGRESS;
   1722  1.1.2.2  bouyer 	len = state->dmalen - len;
   1723  1.1.2.2  bouyer 	state->buflen -= len;
   1724  1.1.2.2  bouyer 	return (1);
   1725  1.1.2.2  bouyer }
   1726  1.1.2.2  bouyer 
   1727  1.1.2.2  bouyer /* ARGSUSED */
   1728  1.1.2.2  bouyer static int
   1729  1.1.2.2  bouyer asc_resume_out(asc, status, ss, ir)
   1730  1.1.2.2  bouyer 	register asc_softc_t asc;
   1731  1.1.2.2  bouyer 	register int status, ss, ir;
   1732  1.1.2.2  bouyer {
   1733  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1734  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1735  1.1.2.2  bouyer 	register int len;
   1736  1.1.2.2  bouyer 
   1737  1.1.2.2  bouyer 	/* setup for this chunk */
   1738  1.1.2.2  bouyer 	len = state->buflen;
   1739  1.1.2.2  bouyer #ifdef DEBUG
   1740  1.1.2.2  bouyer 	if (asc_logp == asc_log)
   1741  1.1.2.2  bouyer 		asc_log[NLOG - 1].resid = len;
   1742  1.1.2.2  bouyer 	else
   1743  1.1.2.2  bouyer 		asc_logp[-1].resid = len;
   1744  1.1.2.2  bouyer #endif
   1745  1.1.2.2  bouyer 	if (len > state->dmaBufSize)
   1746  1.1.2.2  bouyer 		len = state->dmaBufSize;
   1747  1.1.2.2  bouyer 	state->dmalen = len;
   1748  1.1.2.2  bouyer #ifdef DEBUG
   1749  1.1.2.2  bouyer  	if (asc_logp == asc_log)
   1750  1.1.2.2  bouyer 		asc_log[NLOG - 1].resid = len;
   1751  1.1.2.2  bouyer 	else
   1752  1.1.2.2  bouyer 		asc_logp[-1].resid = len;
   1753  1.1.2.2  bouyer #endif
   1754  1.1.2.2  bouyer 	DMA_START(asc->dma, (caddr_t)state->buf, len, DMA_TO_DEV);
   1755  1.1.2.2  bouyer 	ASC_TC_PUT(regs, len, asc->is24bit);
   1756  1.1.2.2  bouyer #ifdef DEBUG
   1757  1.1.2.2  bouyer 	if (asc_debug > 2)
   1758  1.1.2.2  bouyer 		printf("asc_resume_out: buflen %d, len %d\n", state->buflen,
   1759  1.1.2.2  bouyer 			len);
   1760  1.1.2.2  bouyer #endif
   1761  1.1.2.2  bouyer 
   1762  1.1.2.2  bouyer 	/* check for next chunk */
   1763  1.1.2.2  bouyer 	state->flags |= DMA_IN_PROGRESS;
   1764  1.1.2.2  bouyer 	if (len != state->buflen) {
   1765  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
   1766  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1767  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
   1768  1.1.2.2  bouyer 		return (0);
   1769  1.1.2.2  bouyer 	}
   1770  1.1.2.2  bouyer 	return (1);
   1771  1.1.2.2  bouyer }
   1772  1.1.2.2  bouyer 
   1773  1.1.2.2  bouyer /* ARGSUSED */
   1774  1.1.2.2  bouyer static int
   1775  1.1.2.2  bouyer asc_resume_dma_out(asc, status, ss, ir)
   1776  1.1.2.2  bouyer 	register asc_softc_t asc;
   1777  1.1.2.2  bouyer 	register int status, ss, ir;
   1778  1.1.2.2  bouyer {
   1779  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1780  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1781  1.1.2.2  bouyer 	register int len, off;
   1782  1.1.2.2  bouyer 
   1783  1.1.2.2  bouyer 	/* setup to finish writing this chunk */
   1784  1.1.2.2  bouyer 	len = state->dmaresid;
   1785  1.1.2.2  bouyer 	off = state->dmalen - len;
   1786  1.1.2.2  bouyer 	if (off & 1) {
   1787  1.1.2.2  bouyer 		printf("asc_resume_dma_out: odd xfer dmalen %d len %d off %d\n",
   1788  1.1.2.2  bouyer 			state->dmalen, len, off); /* XXX */
   1789  1.1.2.2  bouyer 		regs->asc_fifo = ((u_char *)state->buf)[off];
   1790  1.1.2.2  bouyer /*XXX Need to flush Cache ? */
   1791  1.1.2.2  bouyer 		off++;
   1792  1.1.2.2  bouyer 		len--;
   1793  1.1.2.2  bouyer 	}
   1794  1.1.2.2  bouyer 	DMA_START(asc->dma, (caddr_t)state->buf + off, len, DMA_TO_DEV);
   1795  1.1.2.2  bouyer 	ASC_TC_PUT(regs, len, asc->is24bit);
   1796  1.1.2.2  bouyer #ifdef DEBUG
   1797  1.1.2.2  bouyer 	if (asc_debug > 2)
   1798  1.1.2.2  bouyer 		printf("asc_resume_dma_out: buflen %d dmalen %d len %d off %d\n",
   1799  1.1.2.2  bouyer 			state->dmalen, state->buflen, len, off);
   1800  1.1.2.2  bouyer #endif
   1801  1.1.2.2  bouyer 
   1802  1.1.2.2  bouyer 	/* check for next chunk */
   1803  1.1.2.2  bouyer 	state->flags |= DMA_IN_PROGRESS;
   1804  1.1.2.2  bouyer 	if (state->dmalen != state->buflen) {
   1805  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
   1806  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1807  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
   1808  1.1.2.2  bouyer 		return (0);
   1809  1.1.2.2  bouyer 	}
   1810  1.1.2.2  bouyer 	return (1);
   1811  1.1.2.2  bouyer }
   1812  1.1.2.2  bouyer 
   1813  1.1.2.2  bouyer /* ARGSUSED */
   1814  1.1.2.2  bouyer static int
   1815  1.1.2.2  bouyer asc_sendsync(asc, status, ss, ir)
   1816  1.1.2.2  bouyer 	register asc_softc_t asc;
   1817  1.1.2.2  bouyer 	register int status, ss, ir;
   1818  1.1.2.2  bouyer {
   1819  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1820  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1821  1.1.2.2  bouyer 
   1822  1.1.2.2  bouyer 	/* send the extended synchronous negotiation message */
   1823  1.1.2.2  bouyer 	regs->asc_fifo = SCSI_EXTENDED_MSG;
   1824  1.1.2.2  bouyer 	wbflush();
   1825  1.1.2.2  bouyer 	regs->asc_fifo = 3;
   1826  1.1.2.2  bouyer 	wbflush();
   1827  1.1.2.2  bouyer 	regs->asc_fifo = SCSI_SYNCHRONOUS_XFER;
   1828  1.1.2.2  bouyer 	wbflush();
   1829  1.1.2.2  bouyer 	regs->asc_fifo = SCSI_MIN_PERIOD;
   1830  1.1.2.2  bouyer 	wbflush();
   1831  1.1.2.2  bouyer 	regs->asc_fifo = ASC_MAX_OFFSET;
   1832  1.1.2.2  bouyer 	/* state to resume after we see the sync reply message */
   1833  1.1.2.2  bouyer 	state->script = asc->script + 2;
   1834  1.1.2.2  bouyer 	state->msglen = 0;
   1835  1.1.2.2  bouyer 	return (1);
   1836  1.1.2.2  bouyer }
   1837  1.1.2.2  bouyer 
   1838  1.1.2.2  bouyer /* ARGSUSED */
   1839  1.1.2.2  bouyer static int
   1840  1.1.2.2  bouyer asc_replysync(asc, status, ss, ir)
   1841  1.1.2.2  bouyer 	register asc_softc_t asc;
   1842  1.1.2.2  bouyer 	register int status, ss, ir;
   1843  1.1.2.2  bouyer {
   1844  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1845  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1846  1.1.2.2  bouyer 
   1847  1.1.2.2  bouyer #ifdef DEBUG
   1848  1.1.2.2  bouyer 	if (asc_debug > 2)
   1849  1.1.2.2  bouyer 		printf("asc_replysync: %x %x\n",
   1850  1.1.2.2  bouyer 			asc_to_scsi_period[state->sync_period] * asc->tb_ticks,
   1851  1.1.2.2  bouyer 			state->sync_offset);
   1852  1.1.2.2  bouyer #endif
   1853  1.1.2.2  bouyer 	/* send synchronous transfer in response to a request */
   1854  1.1.2.2  bouyer 	regs->asc_fifo = SCSI_EXTENDED_MSG;
   1855  1.1.2.2  bouyer 	wbflush();
   1856  1.1.2.2  bouyer 	regs->asc_fifo = 3;
   1857  1.1.2.2  bouyer 	wbflush();
   1858  1.1.2.2  bouyer 	regs->asc_fifo = SCSI_SYNCHRONOUS_XFER;
   1859  1.1.2.2  bouyer 	wbflush();
   1860  1.1.2.2  bouyer 	regs->asc_fifo = asc_to_scsi_period[state->sync_period] * asc->tb_ticks;
   1861  1.1.2.2  bouyer 	wbflush();
   1862  1.1.2.2  bouyer 	regs->asc_fifo = state->sync_offset;
   1863  1.1.2.2  bouyer 	regs->asc_cmd = ASC_CMD_XFER_INFO;
   1864  1.1.2.2  bouyer 	readback(regs->asc_cmd);
   1865  1.1.2.2  bouyer 
   1866  1.1.2.2  bouyer 	/* return to the appropriate script */
   1867  1.1.2.2  bouyer 	if (!state->script) {
   1868  1.1.2.2  bouyer #ifdef DEBUG
   1869  1.1.2.2  bouyer 		asc_DumpLog("asc_replsync");
   1870  1.1.2.2  bouyer #endif
   1871  1.1.2.2  bouyer 		panic("asc_replysync");
   1872  1.1.2.2  bouyer 	}
   1873  1.1.2.2  bouyer 	asc->script = state->script;
   1874  1.1.2.2  bouyer 	state->script = (script_t *)0;
   1875  1.1.2.2  bouyer 	return (0);
   1876  1.1.2.2  bouyer }
   1877  1.1.2.2  bouyer 
   1878  1.1.2.2  bouyer /* ARGSUSED */
   1879  1.1.2.2  bouyer static int
   1880  1.1.2.2  bouyer asc_msg_in(asc, status, ss, ir)
   1881  1.1.2.2  bouyer 	register asc_softc_t asc;
   1882  1.1.2.2  bouyer 	register int status, ss, ir;
   1883  1.1.2.2  bouyer {
   1884  1.1.2.2  bouyer 	register asc_regmap_t *regs = asc->regs;
   1885  1.1.2.2  bouyer 	register State *state = &asc->st[asc->target];
   1886  1.1.2.2  bouyer 	register int msg;
   1887  1.1.2.2  bouyer 	int i;
   1888  1.1.2.2  bouyer 
   1889  1.1.2.2  bouyer 	/* read one message byte */
   1890  1.1.2.2  bouyer 	msg = regs->asc_fifo;
   1891  1.1.2.2  bouyer #ifdef DEBUG
   1892  1.1.2.2  bouyer 	if (asc_logp == asc_log)
   1893  1.1.2.2  bouyer 		asc_log[NLOG - 1].msg = msg;
   1894  1.1.2.2  bouyer 	else
   1895  1.1.2.2  bouyer 		asc_logp[-1].msg = msg;
   1896  1.1.2.2  bouyer #endif
   1897  1.1.2.2  bouyer 
   1898  1.1.2.2  bouyer 	/* check for multi-byte message */
   1899  1.1.2.2  bouyer 	if (state->msglen != 0) {
   1900  1.1.2.2  bouyer 		/* first byte is the message length */
   1901  1.1.2.2  bouyer 		if (state->msglen < 0) {
   1902  1.1.2.2  bouyer 			state->msglen = msg;
   1903  1.1.2.2  bouyer 			return (1);
   1904  1.1.2.2  bouyer 		}
   1905  1.1.2.2  bouyer 		if (state->msgcnt >= state->msglen)
   1906  1.1.2.2  bouyer 			goto abort;
   1907  1.1.2.2  bouyer 		state->msg_in[state->msgcnt++] = msg;
   1908  1.1.2.2  bouyer 
   1909  1.1.2.2  bouyer 		/* did we just read the last byte of the message? */
   1910  1.1.2.2  bouyer 		if (state->msgcnt != state->msglen)
   1911  1.1.2.2  bouyer 			return (1);
   1912  1.1.2.2  bouyer 
   1913  1.1.2.2  bouyer 		/* process an extended message */
   1914  1.1.2.2  bouyer #ifdef DEBUG
   1915  1.1.2.2  bouyer 		if (asc_debug > 2)
   1916  1.1.2.2  bouyer 			printf("asc_msg_in: msg %x %x %x\n",
   1917  1.1.2.2  bouyer 				state->msg_in[0],
   1918  1.1.2.2  bouyer 				state->msg_in[1],
   1919  1.1.2.2  bouyer 				state->msg_in[2]);
   1920  1.1.2.2  bouyer #endif
   1921  1.1.2.2  bouyer 		switch (state->msg_in[0]) {
   1922  1.1.2.2  bouyer 		case SCSI_SYNCHRONOUS_XFER:
   1923  1.1.2.2  bouyer 			state->flags |= DID_SYNC;
   1924  1.1.2.2  bouyer 			state->sync_offset = state->msg_in[2];
   1925  1.1.2.2  bouyer 
   1926  1.1.2.2  bouyer 			/* convert SCSI period to ASC period */
   1927  1.1.2.2  bouyer 			i = state->msg_in[1] / asc->tb_ticks;
   1928  1.1.2.2  bouyer 			if (i < asc->min_period)
   1929  1.1.2.2  bouyer 				i = asc->min_period;
   1930  1.1.2.2  bouyer 			else if (i >= asc->max_period) {
   1931  1.1.2.2  bouyer 				/* can't do sync transfer, period too long */
   1932  1.1.2.2  bouyer 				printf("%s: SCSI device %d: sync xfer period too long (%d)\n",
   1933  1.1.2.2  bouyer 					asc->sc_dev.dv_xname, asc->target, i);
   1934  1.1.2.2  bouyer 				i = asc->max_period;
   1935  1.1.2.2  bouyer 				state->sync_offset = 0;
   1936  1.1.2.2  bouyer 			}
   1937  1.1.2.2  bouyer 			if ((i * asc->tb_ticks) != state->msg_in[1])
   1938  1.1.2.2  bouyer 				i++;
   1939  1.1.2.2  bouyer 			state->sync_period = i & 0x1F;
   1940  1.1.2.2  bouyer 
   1941  1.1.2.2  bouyer 			/*
   1942  1.1.2.2  bouyer 			 * If this is a request, check minimums and
   1943  1.1.2.2  bouyer 			 * send back an acknowledge.
   1944  1.1.2.2  bouyer 			 */
   1945  1.1.2.2  bouyer 			if (!(state->flags & TRY_SYNC)) {
   1946  1.1.2.2  bouyer 				regs->asc_cmd = ASC_CMD_SET_ATN;
   1947  1.1.2.2  bouyer 				readback(regs->asc_cmd);
   1948  1.1.2.2  bouyer 
   1949  1.1.2.2  bouyer 				if (state->sync_period < asc->min_period)
   1950  1.1.2.2  bouyer 					state->sync_period =
   1951  1.1.2.2  bouyer 						asc->min_period;
   1952  1.1.2.2  bouyer 				if (state->sync_offset > ASC_MAX_OFFSET)
   1953  1.1.2.2  bouyer 					state->sync_offset =
   1954  1.1.2.2  bouyer 						ASC_MAX_OFFSET;
   1955  1.1.2.2  bouyer 				asc->script = &asc_scripts[SCRIPT_REPLY_SYNC];
   1956  1.1.2.2  bouyer 				regs->asc_syn_p = state->sync_period;
   1957  1.1.2.2  bouyer 				readback(regs->asc_syn_p);
   1958  1.1.2.2  bouyer 				regs->asc_syn_o = state->sync_offset;
   1959  1.1.2.2  bouyer 				readback(regs->asc_syn_o);
   1960  1.1.2.2  bouyer 				regs->asc_cmd = ASC_CMD_MSG_ACPT;
   1961  1.1.2.2  bouyer 				readback(regs->asc_cmd);
   1962  1.1.2.2  bouyer 				return (0);
   1963  1.1.2.2  bouyer 			}
   1964  1.1.2.2  bouyer 
   1965  1.1.2.2  bouyer 			regs->asc_syn_p = state->sync_period;
   1966  1.1.2.2  bouyer 			readback(regs->asc_syn_p);
   1967  1.1.2.2  bouyer 			regs->asc_syn_o = state->sync_offset;
   1968  1.1.2.2  bouyer 			readback(regs->asc_syn_o);
   1969  1.1.2.2  bouyer 			goto done;
   1970  1.1.2.2  bouyer 
   1971  1.1.2.2  bouyer 		default:
   1972  1.1.2.2  bouyer 			printf("%s: SCSI device %d: rejecting extended message 0x%x\n",
   1973  1.1.2.2  bouyer 				 asc->sc_dev.dv_xname, asc->target,
   1974  1.1.2.2  bouyer 				state->msg_in[0]);
   1975  1.1.2.2  bouyer 			goto reject;
   1976  1.1.2.2  bouyer 		}
   1977  1.1.2.2  bouyer 	}
   1978  1.1.2.2  bouyer 
   1979  1.1.2.2  bouyer 	/* process first byte of a message */
   1980  1.1.2.2  bouyer #ifdef DEBUG
   1981  1.1.2.2  bouyer 	if (asc_debug > 2)
   1982  1.1.2.2  bouyer 		printf("asc_msg_in: msg %x\n", msg);
   1983  1.1.2.2  bouyer #endif
   1984  1.1.2.2  bouyer 	switch (msg) {
   1985  1.1.2.2  bouyer #if 0
   1986  1.1.2.2  bouyer 	case SCSI_MESSAGE_REJECT:
   1987  1.1.2.2  bouyer 		printf(" did not like SYNCH xfer "); /* XXX */
   1988  1.1.2.2  bouyer 		state->flags |= DID_SYNC;
   1989  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_MSG_ACPT;
   1990  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   1991  1.1.2.2  bouyer 		status = asc_wait(regs, ASC_CSR_INT);
   1992  1.1.2.2  bouyer 		ir = regs->asc_intr;
   1993  1.1.2.2  bouyer 		/* some just break out here, some dont */
   1994  1.1.2.2  bouyer 		if (ASC_PHASE(status) == ASC_PHASE_MSG_OUT) {
   1995  1.1.2.2  bouyer 			regs->asc_fifo = SCSI_ABORT;
   1996  1.1.2.2  bouyer 			regs->asc_cmd = ASC_CMD_XFER_INFO;
   1997  1.1.2.2  bouyer 			readback(regs->asc_cmd);
   1998  1.1.2.2  bouyer 			status = asc_wait(regs, ASC_CSR_INT);
   1999  1.1.2.2  bouyer 			ir = regs->asc_intr;
   2000  1.1.2.2  bouyer 		}
   2001  1.1.2.2  bouyer 		if (ir & ASC_INT_DISC) {
   2002  1.1.2.2  bouyer 			asc_end(asc, status, 0, ir);
   2003  1.1.2.2  bouyer 			return (0);
   2004  1.1.2.2  bouyer 		}
   2005  1.1.2.2  bouyer 		goto status;
   2006  1.1.2.2  bouyer #endif /* 0 */
   2007  1.1.2.2  bouyer 
   2008  1.1.2.2  bouyer 	case SCSI_EXTENDED_MSG: /* read an extended message */
   2009  1.1.2.2  bouyer 		/* setup to read message length next */
   2010  1.1.2.2  bouyer 		state->msglen = -1;
   2011  1.1.2.2  bouyer 		state->msgcnt = 0;
   2012  1.1.2.2  bouyer 		return (1);
   2013  1.1.2.2  bouyer 
   2014  1.1.2.2  bouyer 	case SCSI_NO_OP:
   2015  1.1.2.2  bouyer 		break;
   2016  1.1.2.2  bouyer 
   2017  1.1.2.2  bouyer 	case SCSI_SAVE_DATA_POINTER:
   2018  1.1.2.2  bouyer 		/* expect another message */
   2019  1.1.2.2  bouyer 		return (1);
   2020  1.1.2.2  bouyer 
   2021  1.1.2.2  bouyer 	case SCSI_RESTORE_POINTERS:
   2022  1.1.2.2  bouyer 		/*
   2023  1.1.2.2  bouyer 		 * Need to do the following if resuming synchonous data in
   2024  1.1.2.2  bouyer 		 * on an odd byte boundary.
   2025  1.1.2.2  bouyer 		regs->asc_cnfg2 |= ASC_CNFG2_RFB;
   2026  1.1.2.2  bouyer 		 */
   2027  1.1.2.2  bouyer 		break;
   2028  1.1.2.2  bouyer 
   2029  1.1.2.2  bouyer 	case SCSI_DISCONNECT:
   2030  1.1.2.2  bouyer 		if (state->flags & DISCONN)
   2031  1.1.2.2  bouyer 			goto abort;
   2032  1.1.2.2  bouyer 		state->flags |= DISCONN;
   2033  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_MSG_ACPT;
   2034  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   2035  1.1.2.2  bouyer 		asc->script = &asc_scripts[SCRIPT_DISCONNECT];
   2036  1.1.2.2  bouyer 		return (0);
   2037  1.1.2.2  bouyer 
   2038  1.1.2.2  bouyer 	default:
   2039  1.1.2.2  bouyer 		printf("%s: SCSI device %d: rejecting message 0x%x\n",
   2040  1.1.2.2  bouyer 			asc->sc_dev.dv_xname, asc->target, msg);
   2041  1.1.2.2  bouyer 	reject:
   2042  1.1.2.2  bouyer 		/* request a message out before acknowledging this message */
   2043  1.1.2.2  bouyer 		state->msg_out = SCSI_MESSAGE_REJECT;
   2044  1.1.2.2  bouyer 		regs->asc_cmd = ASC_CMD_SET_ATN;
   2045  1.1.2.2  bouyer 		readback(regs->asc_cmd);
   2046  1.1.2.2  bouyer 	}
   2047  1.1.2.2  bouyer 
   2048  1.1.2.2  bouyer done:
   2049  1.1.2.2  bouyer 	/* return to original script */
   2050  1.1.2.2  bouyer 	regs->asc_cmd = ASC_CMD_MSG_ACPT;
   2051  1.1.2.2  bouyer 	readback(regs->asc_cmd);
   2052  1.1.2.2  bouyer 	if (!state->script) {
   2053  1.1.2.2  bouyer 	abort:
   2054  1.1.2.2  bouyer #ifdef DEBUG
   2055  1.1.2.2  bouyer 		asc_DumpLog("asc_msg_in");
   2056  1.1.2.2  bouyer #endif
   2057  1.1.2.2  bouyer 		panic("asc_msg_in");
   2058  1.1.2.2  bouyer 	}
   2059  1.1.2.2  bouyer 	asc->script = state->script;
   2060  1.1.2.2  bouyer 	state->script = (script_t *)0;
   2061  1.1.2.2  bouyer 	return (0);
   2062  1.1.2.2  bouyer }
   2063  1.1.2.2  bouyer 
   2064  1.1.2.2  bouyer /* ARGSUSED */
   2065  1.1.2.2  bouyer static int
   2066  1.1.2.2  bouyer asc_disconnect(asc, status, ss, ir)
   2067  1.1.2.2  bouyer 	asc_softc_t asc;
   2068  1.1.2.2  bouyer 	int status, ss, ir;
   2069  1.1.2.2  bouyer {
   2070  1.1.2.2  bouyer 	State *state = &asc->st[asc->target];
   2071  1.1.2.2  bouyer 
   2072  1.1.2.2  bouyer #ifdef DIAGNOSTIC
   2073  1.1.2.2  bouyer 	if (!(state->flags & DISCONN)) {
   2074  1.1.2.2  bouyer 		printf("asc_disconnect: device %d: DISCONN not set!\n",
   2075  1.1.2.2  bouyer 			asc->target);
   2076  1.1.2.2  bouyer 	}
   2077  1.1.2.2  bouyer #endif /* DIAGNOSTIC */
   2078  1.1.2.2  bouyer 	asc->target = -1;
   2079  1.1.2.2  bouyer 	asc->state = ASC_STATE_RESEL;
   2080  1.1.2.2  bouyer 	return (1);
   2081  1.1.2.2  bouyer }
   2082  1.1.2.2  bouyer 
   2083  1.1.2.2  bouyer #ifdef DEBUG
   2084  1.1.2.2  bouyer /*
   2085  1.1.2.2  bouyer  * Dump the log buffer.
   2086  1.1.2.2  bouyer  */
   2087  1.1.2.2  bouyer static void
   2088  1.1.2.2  bouyer asc_DumpLog(str)
   2089  1.1.2.2  bouyer 	char *str;
   2090  1.1.2.2  bouyer {
   2091  1.1.2.2  bouyer 	register struct asc_log *lp;
   2092  1.1.2.2  bouyer 	register u_int status;
   2093  1.1.2.2  bouyer 
   2094  1.1.2.2  bouyer 	printf("asc: %s: cmd %x bn %d cnt %d\n", str, asc_debug_cmd,
   2095  1.1.2.2  bouyer 		asc_debug_bn, asc_debug_sz);
   2096  1.1.2.2  bouyer 	lp = asc_logp;
   2097  1.1.2.2  bouyer 	do {
   2098  1.1.2.2  bouyer 		status = lp->status;
   2099  1.1.2.2  bouyer 		printf("asc%d tgt %d status %x ss %x ir %x cond %d:%x msg %x resid %d\n",
   2100  1.1.2.2  bouyer 			status >> 24,
   2101  1.1.2.2  bouyer 			lp->target,
   2102  1.1.2.2  bouyer 			(status >> 16) & 0xFF,
   2103  1.1.2.2  bouyer 			(status >> 8) & 0xFF,
   2104  1.1.2.2  bouyer 			status & 0XFF,
   2105  1.1.2.2  bouyer 			lp->state,
   2106  1.1.2.2  bouyer 			asc_scripts[lp->state].condition,
   2107  1.1.2.2  bouyer 			lp->msg, lp->resid);
   2108  1.1.2.2  bouyer 		if (++lp >= &asc_log[NLOG])
   2109  1.1.2.2  bouyer 			lp = asc_log;
   2110  1.1.2.2  bouyer 	} while (lp != asc_logp);
   2111  1.1.2.2  bouyer }
   2112  1.1.2.2  bouyer #endif	/* DEBUG */
   2113