File:  [DragonFly] / src / sys / dev / disk / ncr / ncr.c
Revision 1.5: download - view: text, annotated - select for diffs
Sat Nov 15 21:05:41 2003 UTC (10 years, 11 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
Misc cleanups to take care of GCC3.x warnings.  Missing 'U' and 'LL'
postfixes on large unsigned or 64 bit constants, non-storage structural
declarations embedded in structures, deprecated use of __FUNCTION__,
missing 'break' statements in the last switch case, goto label ops where
the label occurs just before an end-brace (many of which appear to be
fixable with 'break' or 'continue' instead and existed simply due to
programmer-paranoia), garbage data in #endif lines that was not commented
out.  GCC3 also caught some argument count issues in kernel printfs.

Many of these (obvious) fixes are similar to or copied from 5.x.

Also fix a few other minor issues such as certain drivers declaring a
proc pointer instead of a thread pointer.

Move -ffreestanding from CWARNFLAGS to CFLAGS.  It doesn't belong in
CWARNFLAGS.

    1: /**************************************************************************
    2: **
    3: ** $FreeBSD: src/sys/pci/ncr.c,v 1.155.2.3 2001/03/05 13:09:10 obrien Exp $
    4: ** $DragonFly: src/sys/dev/disk/ncr/ncr.c,v 1.5 2003/11/15 21:05:41 dillon Exp $
    5: **
    6: **  Device driver for the   NCR 53C8XX   PCI-SCSI-Controller Family.
    7: **
    8: **-------------------------------------------------------------------------
    9: **
   10: **  Written for 386bsd and FreeBSD by
   11: **	Wolfgang Stanglmeier	<wolf@cologne.de>
   12: **	Stefan Esser		<se@mi.Uni-Koeln.de>
   13: **
   14: **-------------------------------------------------------------------------
   15: **
   16: ** Copyright (c) 1994 Wolfgang Stanglmeier.  All rights reserved.
   17: **
   18: ** Redistribution and use in source and binary forms, with or without
   19: ** modification, are permitted provided that the following conditions
   20: ** are met:
   21: ** 1. Redistributions of source code must retain the above copyright
   22: **    notice, this list of conditions and the following disclaimer.
   23: ** 2. Redistributions in binary form must reproduce the above copyright
   24: **    notice, this list of conditions and the following disclaimer in the
   25: **    documentation and/or other materials provided with the distribution.
   26: ** 3. The name of the author may not be used to endorse or promote products
   27: **    derived from this software without specific prior written permission.
   28: **
   29: ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   30: ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   31: ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   32: ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   33: ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   34: ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   35: ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   36: ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   37: ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   38: ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   39: **
   40: ***************************************************************************
   41: */
   42: 
   43: #define NCR_DATE "pl30 98/1/1"
   44: 
   45: #define NCR_VERSION	(2)
   46: #define	MAX_UNITS	(16)
   47: 
   48: #define NCR_GETCC_WITHMSG
   49: 
   50: #if defined (__FreeBSD__) && defined(_KERNEL)
   51: #include "opt_ncr.h"
   52: #endif
   53: 
   54: /*==========================================================
   55: **
   56: **	Configuration and Debugging
   57: **
   58: **	May be overwritten in <arch/conf/xxxx>
   59: **
   60: **==========================================================
   61: */
   62: 
   63: /*
   64: **    SCSI address of this device.
   65: **    The boot routines should have set it.
   66: **    If not, use this.
   67: */
   68: 
   69: #ifndef SCSI_NCR_MYADDR
   70: #define SCSI_NCR_MYADDR      (7)
   71: #endif /* SCSI_NCR_MYADDR */
   72: 
   73: /*
   74: **    The default synchronous period factor
   75: **    (0=asynchronous)
   76: **    If maximum synchronous frequency is defined, use it instead.
   77: */
   78: 
   79: #ifndef	SCSI_NCR_MAX_SYNC
   80: 
   81: #ifndef SCSI_NCR_DFLT_SYNC
   82: #define SCSI_NCR_DFLT_SYNC   (12)
   83: #endif /* SCSI_NCR_DFLT_SYNC */
   84: 
   85: #else
   86: 
   87: #if	SCSI_NCR_MAX_SYNC == 0
   88: #define	SCSI_NCR_DFLT_SYNC 0
   89: #else
   90: #define	SCSI_NCR_DFLT_SYNC (250000 / SCSI_NCR_MAX_SYNC)
   91: #endif
   92: 
   93: #endif
   94: 
   95: /*
   96: **    The minimal asynchronous pre-scaler period (ns)
   97: **    Shall be 40.
   98: */
   99: 
  100: #ifndef SCSI_NCR_MIN_ASYNC
  101: #define SCSI_NCR_MIN_ASYNC   (40)
  102: #endif /* SCSI_NCR_MIN_ASYNC */
  103: 
  104: /*
  105: **    The maximal bus with (in log2 byte)
  106: **    (0=8 bit, 1=16 bit)
  107: */
  108: 
  109: #ifndef SCSI_NCR_MAX_WIDE
  110: #define SCSI_NCR_MAX_WIDE   (1)
  111: #endif /* SCSI_NCR_MAX_WIDE */
  112: 
  113: /*==========================================================
  114: **
  115: **      Configuration and Debugging
  116: **
  117: **==========================================================
  118: */
  119: 
  120: /*
  121: **    Number of targets supported by the driver.
  122: **    n permits target numbers 0..n-1.
  123: **    Default is 7, meaning targets #0..#6.
  124: **    #7 .. is myself.
  125: */
  126: 
  127: #define MAX_TARGET  (16)
  128: 
  129: /*
  130: **    Number of logic units supported by the driver.
  131: **    n enables logic unit numbers 0..n-1.
  132: **    The common SCSI devices require only
  133: **    one lun, so take 1 as the default.
  134: */
  135: 
  136: #ifndef	MAX_LUN
  137: #define MAX_LUN     (8)
  138: #endif	/* MAX_LUN */
  139: 
  140: /*
  141: **    The maximum number of jobs scheduled for starting.
  142: **    There should be one slot per target, and one slot
  143: **    for each tag of each target in use.
  144: */
  145: 
  146: #define MAX_START   (256)
  147: 
  148: /*
  149: **    The maximum number of segments a transfer is split into.
  150: */
  151: 
  152: #define MAX_SCATTER (33)
  153: 
  154: /*
  155: **    The maximum transfer length (should be >= 64k).
  156: **    MUST NOT be greater than (MAX_SCATTER-1) * PAGE_SIZE.
  157: */
  158: 
  159: #define MAX_SIZE  ((MAX_SCATTER-1) * (long) PAGE_SIZE)
  160: 
  161: /*
  162: **	other
  163: */
  164: 
  165: #define NCR_SNOOP_TIMEOUT (1000000)
  166: 
  167: /*==========================================================
  168: **
  169: **      Include files
  170: **
  171: **==========================================================
  172: */
  173: 
  174: #include <sys/param.h>
  175: #include <sys/time.h>
  176: 
  177: #ifdef _KERNEL
  178: #include <sys/systm.h>
  179: #include <sys/malloc.h>
  180: #include <sys/buf.h>
  181: #include <sys/kernel.h>
  182: #include <sys/sysctl.h>
  183: #include <sys/bus.h>
  184: #include <machine/clock.h>
  185: #include <machine/md_var.h>
  186: #include <machine/bus.h>
  187: #include <machine/resource.h>
  188: #include <sys/rman.h>
  189: #include <vm/vm.h>
  190: #include <vm/pmap.h>
  191: #include <vm/vm_extern.h>
  192: #endif
  193: 
  194: #include <bus/pci/pcivar.h>
  195: #include <bus/pci/pcireg.h>
  196: #include "ncrreg.h"
  197: 
  198: #include <bus/cam/cam.h>
  199: #include <bus/cam/cam_ccb.h>
  200: #include <bus/cam/cam_sim.h>
  201: #include <bus/cam/cam_xpt_sim.h>
  202: #include <bus/cam/cam_debug.h>
  203: 
  204: #include <bus/cam/scsi/scsi_all.h>
  205: #include <bus/cam/scsi/scsi_message.h>
  206: 
  207: /*==========================================================
  208: **
  209: **	Debugging tags
  210: **
  211: **==========================================================
  212: */
  213: 
  214: #define DEBUG_ALLOC    (0x0001)
  215: #define DEBUG_PHASE    (0x0002)
  216: #define DEBUG_POLL     (0x0004)
  217: #define DEBUG_QUEUE    (0x0008)
  218: #define DEBUG_RESULT   (0x0010)
  219: #define DEBUG_SCATTER  (0x0020)
  220: #define DEBUG_SCRIPT   (0x0040)
  221: #define DEBUG_TINY     (0x0080)
  222: #define DEBUG_TIMING   (0x0100)
  223: #define DEBUG_NEGO     (0x0200)
  224: #define DEBUG_TAGS     (0x0400)
  225: #define DEBUG_FREEZE   (0x0800)
  226: #define DEBUG_RESTART  (0x1000)
  227: 
  228: /*
  229: **    Enable/Disable debug messages.
  230: **    Can be changed at runtime too.
  231: */
  232: #ifdef SCSI_NCR_DEBUG
  233: 	#define DEBUG_FLAGS ncr_debug
  234: #else /* SCSI_NCR_DEBUG */
  235: 	#define SCSI_NCR_DEBUG	0
  236: 	#define DEBUG_FLAGS	0
  237: #endif /* SCSI_NCR_DEBUG */
  238: 
  239: 
  240: 
  241: /*==========================================================
  242: **
  243: **	assert ()
  244: **
  245: **==========================================================
  246: **
  247: **	modified copy from 386bsd:/usr/include/sys/assert.h
  248: **
  249: **----------------------------------------------------------
  250: */
  251: 
  252: #ifdef DIAGNOSTIC
  253: #define	assert(expression) {					\
  254: 	if (!(expression)) {					\
  255: 		(void)printf("assertion \"%s\" failed: "	\
  256: 			     "file \"%s\", line %d\n",		\
  257: 			     #expression, __FILE__, __LINE__);	\
  258: 	     Debugger("");					\
  259: 	}							\
  260: }
  261: #else
  262: #define	assert(expression) {					\
  263: 	if (!(expression)) {					\
  264: 		(void)printf("assertion \"%s\" failed: "	\
  265: 			     "file \"%s\", line %d\n",		\
  266: 			     #expression, __FILE__, __LINE__);	\
  267: 	}							\
  268: }
  269: #endif
  270: 
  271: /*==========================================================
  272: **
  273: **	Access to the controller chip.
  274: **
  275: **==========================================================
  276: */
  277: 
  278: #ifdef __alpha__
  279: /* XXX */
  280: #undef vtophys
  281: #define	vtophys(va)	alpha_XXX_dmamap((vm_offset_t)va)
  282: #endif
  283: 
  284: #define	INB(r) bus_space_read_1(np->bst, np->bsh, offsetof(struct ncr_reg, r))
  285: #define	INW(r) bus_space_read_2(np->bst, np->bsh, offsetof(struct ncr_reg, r))
  286: #define	INL(r) bus_space_read_4(np->bst, np->bsh, offsetof(struct ncr_reg, r))
  287: 
  288: #define	OUTB(r, val) bus_space_write_1(np->bst, np->bsh, \
  289: 				       offsetof(struct ncr_reg, r), val)
  290: #define	OUTW(r, val) bus_space_write_2(np->bst, np->bsh, \
  291: 				       offsetof(struct ncr_reg, r), val)
  292: #define	OUTL(r, val) bus_space_write_4(np->bst, np->bsh, \
  293: 				       offsetof(struct ncr_reg, r), val)
  294: #define	OUTL_OFF(o, val) bus_space_write_4(np->bst, np->bsh, o, val)
  295: 
  296: #define	INB_OFF(o) bus_space_read_1(np->bst, np->bsh, o)
  297: #define	INW_OFF(o) bus_space_read_2(np->bst, np->bsh, o)
  298: #define	INL_OFF(o) bus_space_read_4(np->bst, np->bsh, o)
  299: 
  300: #define	READSCRIPT_OFF(base, off)					\
  301:     (base ? *((volatile u_int32_t *)((volatile char *)base + (off))) :	\
  302:     bus_space_read_4(np->bst2, np->bsh2, off))
  303: 
  304: #define	WRITESCRIPT_OFF(base, off, val)					\
  305:     do {								\
  306:     	if (base)							\
  307:     		*((volatile u_int32_t *)				\
  308: 			((volatile char *)base + (off))) = (val);	\
  309:     	else								\
  310: 		bus_space_write_4(np->bst2, np->bsh2, off, val);	\
  311:     } while (0)
  312: 
  313: #define	READSCRIPT(r) \
  314:     READSCRIPT_OFF(np->script, offsetof(struct script, r))
  315: 
  316: #define	WRITESCRIPT(r, val) \
  317:     WRITESCRIPT_OFF(np->script, offsetof(struct script, r), val)
  318: 
  319: /*
  320: **	Set bit field ON, OFF 
  321: */
  322: 
  323: #define OUTONB(r, m)	OUTB(r, INB(r) | (m))
  324: #define OUTOFFB(r, m)	OUTB(r, INB(r) & ~(m))
  325: #define OUTONW(r, m)	OUTW(r, INW(r) | (m))
  326: #define OUTOFFW(r, m)	OUTW(r, INW(r) & ~(m))
  327: #define OUTONL(r, m)	OUTL(r, INL(r) | (m))
  328: #define OUTOFFL(r, m)	OUTL(r, INL(r) & ~(m))
  329: 
  330: /*==========================================================
  331: **
  332: **	Command control block states.
  333: **
  334: **==========================================================
  335: */
  336: 
  337: #define HS_IDLE		(0)
  338: #define HS_BUSY		(1)
  339: #define HS_NEGOTIATE	(2)	/* sync/wide data transfer*/
  340: #define HS_DISCONNECT	(3)	/* Disconnected by target */
  341: 
  342: #define HS_COMPLETE	(4)
  343: #define HS_SEL_TIMEOUT	(5)	/* Selection timeout      */
  344: #define HS_RESET	(6)	/* SCSI reset	     */
  345: #define HS_ABORTED	(7)	/* Transfer aborted       */
  346: #define HS_TIMEOUT	(8)	/* Software timeout       */
  347: #define HS_FAIL		(9)	/* SCSI or PCI bus errors */
  348: #define HS_UNEXPECTED	(10)	/* Unexpected disconnect  */
  349: #define HS_STALL	(11)	/* QUEUE FULL or BUSY	  */
  350: 
  351: #define HS_DONEMASK	(0xfc)
  352: 
  353: /*==========================================================
  354: **
  355: **	Software Interrupt Codes
  356: **
  357: **==========================================================
  358: */
  359: 
  360: #define	SIR_SENSE_RESTART	(1)
  361: #define	SIR_SENSE_FAILED	(2)
  362: #define	SIR_STALL_RESTART	(3)
  363: #define	SIR_STALL_QUEUE		(4)
  364: #define	SIR_NEGO_SYNC		(5)
  365: #define	SIR_NEGO_WIDE		(6)
  366: #define	SIR_NEGO_FAILED		(7)
  367: #define	SIR_NEGO_PROTO		(8)
  368: #define	SIR_REJECT_RECEIVED	(9)
  369: #define	SIR_REJECT_SENT		(10)
  370: #define	SIR_IGN_RESIDUE		(11)
  371: #define	SIR_MISSING_SAVE	(12)
  372: #define	SIR_MAX			(12)
  373: 
  374: /*==========================================================
  375: **
  376: **	Extended error codes.
  377: **	xerr_status field of struct nccb.
  378: **
  379: **==========================================================
  380: */
  381: 
  382: #define	XE_OK		(0)
  383: #define	XE_EXTRA_DATA	(1)	/* unexpected data phase */
  384: #define	XE_BAD_PHASE	(2)	/* illegal phase (4/5)   */
  385: 
  386: /*==========================================================
  387: **
  388: **	Negotiation status.
  389: **	nego_status field	of struct nccb.
  390: **
  391: **==========================================================
  392: */
  393: 
  394: #define NS_SYNC		(1)
  395: #define NS_WIDE		(2)
  396: 
  397: /*==========================================================
  398: **
  399: **	XXX These are no longer used.  Remove once the
  400: **	    script is updated.
  401: **	"Special features" of targets.
  402: **	quirks field of struct tcb.
  403: **	actualquirks field of struct nccb.
  404: **
  405: **==========================================================
  406: */
  407: 
  408: #define	QUIRK_AUTOSAVE	(0x01)
  409: #define	QUIRK_NOMSG	(0x02)
  410: #define	QUIRK_NOSYNC	(0x10)
  411: #define	QUIRK_NOWIDE16	(0x20)
  412: #define	QUIRK_NOTAGS	(0x40)
  413: #define	QUIRK_UPDATE	(0x80)
  414: 
  415: /*==========================================================
  416: **
  417: **	Misc.
  418: **
  419: **==========================================================
  420: */
  421: 
  422: #define CCB_MAGIC	(0xf2691ad2)
  423: #define	MAX_TAGS	(32)		/* hard limit */
  424: 
  425: /*==========================================================
  426: **
  427: **	OS dependencies.
  428: **
  429: **==========================================================
  430: */
  431: 
  432: #define PRINT_ADDR(ccb) xpt_print_path((ccb)->ccb_h.path)
  433: 
  434: /*==========================================================
  435: **
  436: **	Declaration of structs.
  437: **
  438: **==========================================================
  439: */
  440: 
  441: struct tcb;
  442: struct lcb;
  443: struct nccb;
  444: struct ncb;
  445: struct script;
  446: 
  447: typedef struct ncb * ncb_p;
  448: typedef struct tcb * tcb_p;
  449: typedef struct lcb * lcb_p;
  450: typedef struct nccb * nccb_p;
  451: 
  452: struct link {
  453: 	ncrcmd	l_cmd;
  454: 	ncrcmd	l_paddr;
  455: };
  456: 
  457: struct	usrcmd {
  458: 	u_long	target;
  459: 	u_long	lun;
  460: 	u_long	data;
  461: 	u_long	cmd;
  462: };
  463: 
  464: #define UC_SETSYNC      10
  465: #define UC_SETTAGS	11
  466: #define UC_SETDEBUG	12
  467: #define UC_SETORDER	13
  468: #define UC_SETWIDE	14
  469: #define UC_SETFLAG	15
  470: 
  471: #define	UF_TRACE	(0x01)
  472: 
  473: /*---------------------------------------
  474: **
  475: **	Timestamps for profiling
  476: **
  477: **---------------------------------------
  478: */
  479: 
  480: /* Type of the kernel variable `ticks'.  XXX should be declared with the var. */
  481: typedef int ticks_t;
  482: 
  483: struct tstamp {
  484: 	ticks_t	start;
  485: 	ticks_t	end;
  486: 	ticks_t	select;
  487: 	ticks_t	command;
  488: 	ticks_t	data;
  489: 	ticks_t	status;
  490: 	ticks_t	disconnect;
  491: };
  492: 
  493: /*
  494: **	profiling data (per device)
  495: */
  496: 
  497: struct profile {
  498: 	u_long	num_trans;
  499: 	u_long	num_bytes;
  500: 	u_long	num_disc;
  501: 	u_long	num_break;
  502: 	u_long	num_int;
  503: 	u_long	num_fly;
  504: 	u_long	ms_setup;
  505: 	u_long	ms_data;
  506: 	u_long	ms_disc;
  507: 	u_long	ms_post;
  508: };
  509: 
  510: /*==========================================================
  511: **
  512: **	Declaration of structs:		target control block
  513: **
  514: **==========================================================
  515: */
  516: 
  517: #define NCR_TRANS_CUR		0x01	/* Modify current neogtiation status */
  518: #define NCR_TRANS_ACTIVE	0x03	/* Assume this is the active target */
  519: #define NCR_TRANS_GOAL		0x04	/* Modify negotiation goal */
  520: #define NCR_TRANS_USER		0x08	/* Modify user negotiation settings */
  521: 
  522: struct ncr_transinfo {
  523: 	u_int8_t width;
  524: 	u_int8_t period;
  525: 	u_int8_t offset;
  526: };
  527: 
  528: struct ncr_target_tinfo {
  529: 	/* Hardware version of our sync settings */
  530: 	u_int8_t disc_tag;
  531: #define		NCR_CUR_DISCENB	0x01
  532: #define		NCR_CUR_TAGENB	0x02
  533: #define		NCR_USR_DISCENB	0x04
  534: #define		NCR_USR_TAGENB	0x08
  535: 	u_int8_t sval;
  536:         struct	 ncr_transinfo current;
  537:         struct	 ncr_transinfo goal;
  538:         struct	 ncr_transinfo user;
  539: 	/* Hardware version of our wide settings */
  540: 	u_int8_t wval;
  541: };
  542: 
  543: struct tcb {
  544: 	/*
  545: 	**	during reselection the ncr jumps to this point
  546: 	**	with SFBR set to the encoded target number
  547: 	**	with bit 7 set.
  548: 	**	if it's not this target, jump to the next.
  549: 	**
  550: 	**	JUMP  IF (SFBR != #target#)
  551: 	**	@(next tcb)
  552: 	*/
  553: 
  554: 	struct link   jump_tcb;
  555: 
  556: 	/*
  557: 	**	load the actual values for the sxfer and the scntl3
  558: 	**	register (sync/wide mode).
  559: 	**
  560: 	**	SCR_COPY (1);
  561: 	**	@(sval field of this tcb)
  562: 	**	@(sxfer register)
  563: 	**	SCR_COPY (1);
  564: 	**	@(wval field of this tcb)
  565: 	**	@(scntl3 register)
  566: 	*/
  567: 
  568: 	ncrcmd	getscr[6];
  569: 
  570: 	/*
  571: 	**	if next message is "identify"
  572: 	**	then load the message to SFBR,
  573: 	**	else load 0 to SFBR.
  574: 	**
  575: 	**	CALL
  576: 	**	<RESEL_LUN>
  577: 	*/
  578: 
  579: 	struct link   call_lun;
  580: 
  581: 	/*
  582: 	**	now look for the right lun.
  583: 	**
  584: 	**	JUMP
  585: 	**	@(first nccb of this lun)
  586: 	*/
  587: 
  588: 	struct link   jump_lcb;
  589: 
  590: 	/*
  591: 	**	pointer to interrupted getcc nccb
  592: 	*/
  593: 
  594: 	nccb_p   hold_cp;
  595: 
  596: 	/*
  597: 	**	pointer to nccb used for negotiating.
  598: 	**	Avoid to start a nego for all queued commands 
  599: 	**	when tagged command queuing is enabled.
  600: 	*/
  601: 
  602: 	nccb_p   nego_cp;
  603: 
  604: 	/*
  605: 	**	statistical data
  606: 	*/
  607: 
  608: 	u_long	transfers;
  609: 	u_long	bytes;
  610: 
  611: 	/*
  612: 	**	user settable limits for sync transfer
  613: 	**	and tagged commands.
  614: 	*/
  615: 
  616: 	struct	 ncr_target_tinfo tinfo;
  617: 
  618: 	/*
  619: 	**	the lcb's of this tcb
  620: 	*/
  621: 
  622: 	lcb_p   lp[MAX_LUN];
  623: };
  624: 
  625: /*==========================================================
  626: **
  627: **	Declaration of structs:		lun control block
  628: **
  629: **==========================================================
  630: */
  631: 
  632: struct lcb {
  633: 	/*
  634: 	**	during reselection the ncr jumps to this point
  635: 	**	with SFBR set to the "Identify" message.
  636: 	**	if it's not this lun, jump to the next.
  637: 	**
  638: 	**	JUMP  IF (SFBR != #lun#)
  639: 	**	@(next lcb of this target)
  640: 	*/
  641: 
  642: 	struct link	jump_lcb;
  643: 
  644: 	/*
  645: 	**	if next message is "simple tag",
  646: 	**	then load the tag to SFBR,
  647: 	**	else load 0 to SFBR.
  648: 	**
  649: 	**	CALL
  650: 	**	<RESEL_TAG>
  651: 	*/
  652: 
  653: 	struct link	call_tag;
  654: 
  655: 	/*
  656: 	**	now look for the right nccb.
  657: 	**
  658: 	**	JUMP
  659: 	**	@(first nccb of this lun)
  660: 	*/
  661: 
  662: 	struct link	jump_nccb;
  663: 
  664: 	/*
  665: 	**	start of the nccb chain
  666: 	*/
  667: 
  668: 	nccb_p	next_nccb;
  669: 
  670: 	/*
  671: 	**	Control of tagged queueing
  672: 	*/
  673: 
  674: 	u_char		reqnccbs;
  675: 	u_char		reqlink;
  676: 	u_char		actlink;
  677: 	u_char		usetags;
  678: 	u_char		lasttag;
  679: };
  680: 
  681: /*==========================================================
  682: **
  683: **      Declaration of structs:     COMMAND control block
  684: **
  685: **==========================================================
  686: **
  687: **	This substructure is copied from the nccb to a
  688: **	global address after selection (or reselection)
  689: **	and copied back before disconnect.
  690: **
  691: **	These fields are accessible to the script processor.
  692: **
  693: **----------------------------------------------------------
  694: */
  695: 
  696: struct head {
  697: 	/*
  698: 	**	Execution of a nccb starts at this point.
  699: 	**	It's a jump to the "SELECT" label
  700: 	**	of the script.
  701: 	**
  702: 	**	After successful selection the script
  703: 	**	processor overwrites it with a jump to
  704: 	**	the IDLE label of the script.
  705: 	*/
  706: 
  707: 	struct link	launch;
  708: 
  709: 	/*
  710: 	**	Saved data pointer.
  711: 	**	Points to the position in the script
  712: 	**	responsible for the actual transfer
  713: 	**	of data.
  714: 	**	It's written after reception of a
  715: 	**	"SAVE_DATA_POINTER" message.
  716: 	**	The goalpointer points after
  717: 	**	the last transfer command.
  718: 	*/
  719: 
  720: 	u_int32_t	savep;
  721: 	u_int32_t	lastp;
  722: 	u_int32_t	goalp;
  723: 
  724: 	/*
  725: 	**	The virtual address of the nccb
  726: 	**	containing this header.
  727: 	*/
  728: 
  729: 	nccb_p	cp;
  730: 
  731: 	/*
  732: 	**	space for some timestamps to gather
  733: 	**	profiling data about devices and this driver.
  734: 	*/
  735: 
  736: 	struct tstamp	stamp;
  737: 
  738: 	/*
  739: 	**	status fields.
  740: 	*/
  741: 
  742: 	u_char		status[8];
  743: };
  744: 
  745: /*
  746: **	The status bytes are used by the host and the script processor.
  747: **
  748: **	The first four byte are copied to the scratchb register
  749: **	(declared as scr0..scr3 in ncr_reg.h) just after the select/reselect,
  750: **	and copied back just after disconnecting.
  751: **	Inside the script the XX_REG are used.
  752: **
  753: **	The last four bytes are used inside the script by "COPY" commands.
  754: **	Because source and destination must have the same alignment
  755: **	in a longword, the fields HAVE to be at the choosen offsets.
  756: **		xerr_st	(4)	0	(0x34)	scratcha
  757: **		sync_st	(5)	1	(0x05)	sxfer
  758: **		wide_st	(7)	3	(0x03)	scntl3
  759: */
  760: 
  761: /*
  762: **	First four bytes (script)
  763: */
  764: #define  QU_REG	scr0
  765: #define  HS_REG	scr1
  766: #define  HS_PRT	nc_scr1
  767: #define  SS_REG	scr2
  768: #define  PS_REG	scr3
  769: 
  770: /*
  771: **	First four bytes (host)
  772: */
  773: #define  actualquirks  phys.header.status[0]
  774: #define  host_status   phys.header.status[1]
  775: #define  s_status      phys.header.status[2]
  776: #define  parity_status phys.header.status[3]
  777: 
  778: /*
  779: **	Last four bytes (script)
  780: */
  781: #define  xerr_st       header.status[4]	/* MUST be ==0 mod 4 */
  782: #define  sync_st       header.status[5]	/* MUST be ==1 mod 4 */
  783: #define  nego_st       header.status[6]
  784: #define  wide_st       header.status[7]	/* MUST be ==3 mod 4 */
  785: 
  786: /*
  787: **	Last four bytes (host)
  788: */
  789: #define  xerr_status   phys.xerr_st
  790: #define  sync_status   phys.sync_st
  791: #define  nego_status   phys.nego_st
  792: #define  wide_status   phys.wide_st
  793: 
  794: /*==========================================================
  795: **
  796: **      Declaration of structs:     Data structure block
  797: **
  798: **==========================================================
  799: **
  800: **	During execution of a nccb by the script processor,
  801: **	the DSA (data structure address) register points
  802: **	to this substructure of the nccb.
  803: **	This substructure contains the header with
  804: **	the script-processor-changable data and
  805: **	data blocks for the indirect move commands.
  806: **
  807: **----------------------------------------------------------
  808: */
  809: 
  810: struct dsb {
  811: 
  812: 	/*
  813: 	**	Header.
  814: 	**	Has to be the first entry,
  815: 	**	because it's jumped to by the
  816: 	**	script processor
  817: 	*/
  818: 
  819: 	struct head	header;
  820: 
  821: 	/*
  822: 	**	Table data for Script
  823: 	*/
  824: 
  825: 	struct scr_tblsel  select;
  826: 	struct scr_tblmove smsg  ;
  827: 	struct scr_tblmove smsg2 ;
  828: 	struct scr_tblmove cmd   ;
  829: 	struct scr_tblmove scmd  ;
  830: 	struct scr_tblmove sense ;
  831: 	struct scr_tblmove data [MAX_SCATTER];
  832: };
  833: 
  834: /*==========================================================
  835: **
  836: **      Declaration of structs:     Command control block.
  837: **
  838: **==========================================================
  839: **
  840: **	During execution of a nccb by the script processor,
  841: **	the DSA (data structure address) register points
  842: **	to this substructure of the nccb.
  843: **	This substructure contains the header with
  844: **	the script-processor-changable data and then
  845: **	data blocks for the indirect move commands.
  846: **
  847: **----------------------------------------------------------
  848: */
  849: 
  850: 
  851: struct nccb {
  852: 	/*
  853: 	**	This filler ensures that the global header is 
  854: 	**	cache line size aligned.
  855: 	*/
  856: 	ncrcmd	filler[4];
  857: 
  858: 	/*
  859: 	**	during reselection the ncr jumps to this point.
  860: 	**	If a "SIMPLE_TAG" message was received,
  861: 	**	then SFBR is set to the tag.
  862: 	**	else SFBR is set to 0
  863: 	**	If looking for another tag, jump to the next nccb.
  864: 	**
  865: 	**	JUMP  IF (SFBR != #TAG#)
  866: 	**	@(next nccb of this lun)
  867: 	*/
  868: 
  869: 	struct link		jump_nccb;
  870: 
  871: 	/*
  872: 	**	After execution of this call, the return address
  873: 	**	(in  the TEMP register) points to the following
  874: 	**	data structure block.
  875: 	**	So copy it to the DSA register, and start
  876: 	**	processing of this data structure.
  877: 	**
  878: 	**	CALL
  879: 	**	<RESEL_TMP>
  880: 	*/
  881: 
  882: 	struct link		call_tmp;
  883: 
  884: 	/*
  885: 	**	This is the data structure which is
  886: 	**	to be executed by the script processor.
  887: 	*/
  888: 
  889: 	struct dsb		phys;
  890: 
  891: 	/*
  892: 	**	If a data transfer phase is terminated too early
  893: 	**	(after reception of a message (i.e. DISCONNECT)),
  894: 	**	we have to prepare a mini script to transfer
  895: 	**	the rest of the data.
  896: 	*/
  897: 
  898: 	ncrcmd			patch[8];
  899: 
  900: 	/*
  901: 	**	The general SCSI driver provides a
  902: 	**	pointer to a control block.
  903: 	*/
  904: 
  905: 	union	ccb *ccb;
  906: 
  907: 	/*
  908: 	**	We prepare a message to be sent after selection,
  909: 	**	and a second one to be sent after getcc selection.
  910: 	**      Contents are IDENTIFY and SIMPLE_TAG.
  911: 	**	While negotiating sync or wide transfer,
  912: 	**	a SDTM or WDTM message is appended.
  913: 	*/
  914: 
  915: 	u_char			scsi_smsg [8];
  916: 	u_char			scsi_smsg2[8];
  917: 
  918: 	/*
  919: 	**	Lock this nccb.
  920: 	**	Flag is used while looking for a free nccb.
  921: 	*/
  922: 
  923: 	u_long		magic;
  924: 
  925: 	/*
  926: 	**	Physical address of this instance of nccb
  927: 	*/
  928: 
  929: 	u_long		p_nccb;
  930: 
  931: 	/*
  932: 	**	Completion time out for this job.
  933: 	**	It's set to time of start + allowed number of seconds.
  934: 	*/
  935: 
  936: 	time_t		tlimit;
  937: 
  938: 	/*
  939: 	**	All nccbs of one hostadapter are chained.
  940: 	*/
  941: 
  942: 	nccb_p		link_nccb;
  943: 
  944: 	/*
  945: 	**	All nccbs of one target/lun are chained.
  946: 	*/
  947: 
  948: 	nccb_p		next_nccb;
  949: 
  950: 	/*
  951: 	**	Sense command
  952: 	*/
  953: 
  954: 	u_char		sensecmd[6];
  955: 
  956: 	/*
  957: 	**	Tag for this transfer.
  958: 	**	It's patched into jump_nccb.
  959: 	**	If it's not zero, a SIMPLE_TAG
  960: 	**	message is included in smsg.
  961: 	*/
  962: 
  963: 	u_char			tag;
  964: };
  965: 
  966: #define CCB_PHYS(cp,lbl)	(cp->p_nccb + offsetof(struct nccb, lbl))
  967: 
  968: /*==========================================================
  969: **
  970: **      Declaration of structs:     NCR device descriptor
  971: **
  972: **==========================================================
  973: */
  974: 
  975: struct ncb {
  976: 	/*
  977: 	**	The global header.
  978: 	**	Accessible to both the host and the
  979: 	**	script-processor.
  980: 	**	We assume it is cache line size aligned.
  981: 	*/
  982: 	struct head     header;
  983: 
  984: 	int	unit;
  985: 
  986: 	/*-----------------------------------------------
  987: 	**	Scripts ..
  988: 	**-----------------------------------------------
  989: 	**
  990: 	**	During reselection the ncr jumps to this point.
  991: 	**	The SFBR register is loaded with the encoded target id.
  992: 	**
  993: 	**	Jump to the first target.
  994: 	**
  995: 	**	JUMP
  996: 	**	@(next tcb)
  997: 	*/
  998: 	struct link     jump_tcb;
  999: 
 1000: 	/*-----------------------------------------------
 1001: 	**	Configuration ..
 1002: 	**-----------------------------------------------
 1003: 	**
 1004: 	**	virtual and physical addresses
 1005: 	**	of the 53c810 chip.
 1006: 	*/
 1007: 	int		reg_rid;
 1008: 	struct resource *reg_res;
 1009: 	bus_space_tag_t	bst;
 1010: 	bus_space_handle_t bsh;
 1011: 
 1012: 	int		sram_rid;
 1013: 	struct resource *sram_res;
 1014: 	bus_space_tag_t	bst2;
 1015: 	bus_space_handle_t bsh2;
 1016: 
 1017: 	struct resource *irq_res;
 1018: 	void		*irq_handle;
 1019: 
 1020: 	/*
 1021: 	**	Scripts instance virtual address.
 1022: 	*/
 1023: 	struct script	*script;
 1024: 	struct scripth	*scripth;
 1025: 
 1026: 	/*
 1027: 	**	Scripts instance physical address.
 1028: 	*/
 1029: 	u_long		p_script;
 1030: 	u_long		p_scripth;
 1031: 
 1032: 	/*
 1033: 	**	The SCSI address of the host adapter.
 1034: 	*/
 1035: 	u_char		myaddr;
 1036: 
 1037: 	/*
 1038: 	**	timing parameters
 1039: 	*/
 1040: 	u_char		minsync;	/* Minimum sync period factor	*/
 1041: 	u_char		maxsync;	/* Maximum sync period factor	*/
 1042: 	u_char		maxoffs;	/* Max scsi offset		*/
 1043: 	u_char		clock_divn;	/* Number of clock divisors	*/
 1044: 	u_long		clock_khz;	/* SCSI clock frequency in KHz	*/
 1045: 	u_long		features;	/* Chip features map		*/
 1046: 	u_char		multiplier;	/* Clock multiplier (1,2,4)	*/
 1047: 
 1048: 	u_char		maxburst;	/* log base 2 of dwords burst	*/
 1049: 
 1050: 	/*
 1051: 	**	BIOS supplied PCI bus options
 1052: 	*/
 1053: 	u_char		rv_scntl3;
 1054: 	u_char		rv_dcntl;
 1055: 	u_char		rv_dmode;
 1056: 	u_char		rv_ctest3;
 1057: 	u_char		rv_ctest4;
 1058: 	u_char		rv_ctest5;
 1059: 	u_char		rv_gpcntl;
 1060: 	u_char		rv_stest2;
 1061: 
 1062: 	/*-----------------------------------------------
 1063: 	**	CAM SIM information for this instance
 1064: 	**-----------------------------------------------
 1065: 	*/
 1066: 
 1067: 	struct		cam_sim  *sim;
 1068: 	struct		cam_path *path;
 1069: 
 1070: 	/*-----------------------------------------------
 1071: 	**	Job control
 1072: 	**-----------------------------------------------
 1073: 	**
 1074: 	**	Commands from user
 1075: 	*/
 1076: 	struct usrcmd	user;
 1077: 
 1078: 	/*
 1079: 	**	Target data
 1080: 	*/
 1081: 	struct tcb	target[MAX_TARGET];
 1082: 
 1083: 	/*
 1084: 	**	Start queue.
 1085: 	*/
 1086: 	u_int32_t	squeue [MAX_START];
 1087: 	u_short		squeueput;
 1088: 
 1089: 	/*
 1090: 	**	Timeout handler
 1091: 	*/
 1092: 	time_t		heartbeat;
 1093: 	u_short		ticks;
 1094: 	u_short		latetime;
 1095: 	time_t		lasttime;
 1096: 	struct		callout_handle timeout_ch;
 1097: 
 1098: 	/*-----------------------------------------------
 1099: 	**	Debug and profiling
 1100: 	**-----------------------------------------------
 1101: 	**
 1102: 	**	register dump
 1103: 	*/
 1104: 	struct ncr_reg	regdump;
 1105: 	time_t		regtime;
 1106: 
 1107: 	/*
 1108: 	**	Profiling data
 1109: 	*/
 1110: 	struct profile	profile;
 1111: 	u_long		disc_phys;
 1112: 	u_long		disc_ref;
 1113: 
 1114: 	/*
 1115: 	**	Head of list of all nccbs for this controller.
 1116: 	*/
 1117: 	nccb_p		link_nccb;
 1118: 	
 1119: 	/*
 1120: 	**	message buffers.
 1121: 	**	Should be longword aligned,
 1122: 	**	because they're written with a
 1123: 	**	COPY script command.
 1124: 	*/
 1125: 	u_char		msgout[8];
 1126: 	u_char		msgin [8];
 1127: 	u_int32_t	lastmsg;
 1128: 
 1129: 	/*
 1130: 	**	Buffer for STATUS_IN phase.
 1131: 	*/
 1132: 	u_char		scratch;
 1133: 
 1134: 	/*
 1135: 	**	controller chip dependent maximal transfer width.
 1136: 	*/
 1137: 	u_char		maxwide;
 1138: 
 1139: #ifdef NCR_IOMAPPED
 1140: 	/*
 1141: 	**	address of the ncr control registers in io space
 1142: 	*/
 1143: 	pci_port_t	port;
 1144: #endif
 1145: };
 1146: 
 1147: #define NCB_SCRIPT_PHYS(np,lbl)	(np->p_script + offsetof (struct script, lbl))
 1148: #define NCB_SCRIPTH_PHYS(np,lbl) (np->p_scripth + offsetof (struct scripth,lbl))
 1149: 
 1150: /*==========================================================
 1151: **
 1152: **
 1153: **      Script for NCR-Processor.
 1154: **
 1155: **	Use ncr_script_fill() to create the variable parts.
 1156: **	Use ncr_script_copy_and_bind() to make a copy and
 1157: **	bind to physical addresses.
 1158: **
 1159: **
 1160: **==========================================================
 1161: **
 1162: **	We have to know the offsets of all labels before
 1163: **	we reach them (for forward jumps).
 1164: **	Therefore we declare a struct here.
 1165: **	If you make changes inside the script,
 1166: **	DONT FORGET TO CHANGE THE LENGTHS HERE!
 1167: **
 1168: **----------------------------------------------------------
 1169: */
 1170: 
 1171: /*
 1172: **	Script fragments which are loaded into the on-board RAM 
 1173: **	of 825A, 875 and 895 chips.
 1174: */
 1175: struct script {
 1176: 	ncrcmd	start		[  7];
 1177: 	ncrcmd	start0		[  2];
 1178: 	ncrcmd	start1		[  3];
 1179: 	ncrcmd  startpos	[  1];
 1180: 	ncrcmd  trysel		[  8];
 1181: 	ncrcmd	skip		[  8];
 1182: 	ncrcmd	skip2		[  3];
 1183: 	ncrcmd  idle		[  2];
 1184: 	ncrcmd	select		[ 18];
 1185: 	ncrcmd	prepare		[  4];
 1186: 	ncrcmd	loadpos		[ 14];
 1187: 	ncrcmd	prepare2	[ 24];
 1188: 	ncrcmd	setmsg		[  5];
 1189: 	ncrcmd  clrack		[  2];
 1190: 	ncrcmd  dispatch	[ 33];
 1191: 	ncrcmd	no_data		[ 17];
 1192: 	ncrcmd  checkatn	[ 10];
 1193: 	ncrcmd  command		[ 15];
 1194: 	ncrcmd  status		[ 27];
 1195: 	ncrcmd  msg_in		[ 26];
 1196: 	ncrcmd  msg_bad		[  6];
 1197: 	ncrcmd  complete	[ 13];
 1198: 	ncrcmd	cleanup		[ 12];
 1199: 	ncrcmd	cleanup0	[  9];
 1200: 	ncrcmd	signal		[ 12];
 1201: 	ncrcmd  save_dp		[  5];
 1202: 	ncrcmd  restore_dp	[  5];
 1203: 	ncrcmd  disconnect	[ 12];
 1204: 	ncrcmd  disconnect0	[  5];
 1205: 	ncrcmd  disconnect1	[ 23];
 1206: 	ncrcmd	msg_out		[  9];
 1207: 	ncrcmd	msg_out_done	[  7];
 1208: 	ncrcmd  badgetcc	[  6];
 1209: 	ncrcmd	reselect	[  8];
 1210: 	ncrcmd	reselect1	[  8];
 1211: 	ncrcmd	reselect2	[  8];
 1212: 	ncrcmd	resel_tmp	[  5];
 1213: 	ncrcmd  resel_lun	[ 18];
 1214: 	ncrcmd	resel_tag	[ 24];
 1215: 	ncrcmd  data_in		[MAX_SCATTER * 4 + 7];
 1216: 	ncrcmd  data_out	[MAX_SCATTER * 4 + 7];
 1217: };
 1218: 
 1219: /*
 1220: **	Script fragments which stay in main memory for all chips.
 1221: */
 1222: struct scripth {
 1223: 	ncrcmd  tryloop		[MAX_START*5+2];
 1224: 	ncrcmd  msg_parity	[  6];
 1225: 	ncrcmd	msg_reject	[  8];
 1226: 	ncrcmd	msg_ign_residue	[ 32];
 1227: 	ncrcmd  msg_extended	[ 18];
 1228: 	ncrcmd  msg_ext_2	[ 18];
 1229: 	ncrcmd	msg_wdtr	[ 27];
 1230: 	ncrcmd  msg_ext_3	[ 18];
 1231: 	ncrcmd	msg_sdtr	[ 27];
 1232: 	ncrcmd	msg_out_abort	[ 10];
 1233: 	ncrcmd  getcc		[  4];
 1234: 	ncrcmd  getcc1		[  5];
 1235: #ifdef NCR_GETCC_WITHMSG
 1236: 	ncrcmd	getcc2		[ 29];
 1237: #else
 1238: 	ncrcmd	getcc2		[ 14];
 1239: #endif
 1240: 	ncrcmd	getcc3		[  6];
 1241: 	ncrcmd	aborttag	[  4];
 1242: 	ncrcmd	abort		[ 22];
 1243: 	ncrcmd	snooptest	[  9];
 1244: 	ncrcmd	snoopend	[  2];
 1245: };
 1246: 
 1247: /*==========================================================
 1248: **
 1249: **
 1250: **      Function headers.
 1251: **
 1252: **
 1253: **==========================================================
 1254: */
 1255: 
 1256: #ifdef _KERNEL
 1257: static	nccb_p	ncr_alloc_nccb	(ncb_p np, u_long target, u_long lun);
 1258: static	void	ncr_complete	(ncb_p np, nccb_p cp);
 1259: static	int	ncr_delta	(int * from, int * to);
 1260: static	void	ncr_exception	(ncb_p np);
 1261: static	void	ncr_free_nccb	(ncb_p np, nccb_p cp);
 1262: static	void	ncr_freeze_devq (ncb_p np, struct cam_path *path);
 1263: static	void	ncr_selectclock	(ncb_p np, u_char scntl3);
 1264: static	void	ncr_getclock	(ncb_p np, u_char multiplier);
 1265: static	nccb_p	ncr_get_nccb	(ncb_p np, u_long t,u_long l);
 1266: #if 0
 1267: static  u_int32_t ncr_info	(int unit);
 1268: #endif
 1269: static	void	ncr_init	(ncb_p np, char * msg, u_long code);
 1270: static	void	ncr_intr	(void *vnp);
 1271: static	void	ncr_int_ma	(ncb_p np, u_char dstat);
 1272: static	void	ncr_int_sir	(ncb_p np);
 1273: static  void    ncr_int_sto     (ncb_p np);
 1274: #if 0
 1275: static	void	ncr_min_phys	(struct buf *bp);
 1276: #endif
 1277: static	void	ncr_poll	(struct cam_sim *sim);
 1278: static	void	ncb_profile	(ncb_p np, nccb_p cp);
 1279: static	void	ncr_script_copy_and_bind
 1280: 				(ncb_p np, ncrcmd *src, ncrcmd *dst, int len);
 1281: static  void    ncr_script_fill (struct script * scr, struct scripth *scrh);
 1282: static	int	ncr_scatter	(struct dsb* phys, vm_offset_t vaddr,
 1283: 				 vm_size_t datalen);
 1284: static	void	ncr_getsync	(ncb_p np, u_char sfac, u_char *fakp,
 1285: 				 u_char *scntl3p);
 1286: static	void	ncr_setsync	(ncb_p np, nccb_p cp,u_char scntl3,u_char sxfer,
 1287: 				 u_char period);
 1288: static	void	ncr_setwide	(ncb_p np, nccb_p cp, u_char wide, u_char ack);
 1289: static	int	ncr_show_msg	(u_char * msg);
 1290: static	int	ncr_snooptest	(ncb_p np);
 1291: static	void	ncr_action	(struct cam_sim *sim, union ccb *ccb);
 1292: static	void	ncr_timeout	(void *arg);
 1293: static  void    ncr_wakeup	(ncb_p np, u_long code);
 1294: 
 1295: static  int	ncr_probe	(device_t dev);
 1296: static	int	ncr_attach	(device_t dev);
 1297: 
 1298: #endif /* _KERNEL */
 1299: 
 1300: /*==========================================================
 1301: **
 1302: **
 1303: **      Global static data.
 1304: **
 1305: **
 1306: **==========================================================
 1307: */
 1308: 
 1309: 
 1310: /*
 1311:  * $FreeBSD: src/sys/pci/ncr.c,v 1.155.2.3 2001/03/05 13:09:10 obrien Exp $
 1312:  */
 1313: static const u_long	ncr_version = NCR_VERSION	* 11
 1314: 	+ (u_long) sizeof (struct ncb)	*  7
 1315: 	+ (u_long) sizeof (struct nccb)	*  5
 1316: 	+ (u_long) sizeof (struct lcb)	*  3
 1317: 	+ (u_long) sizeof (struct tcb)	*  2;
 1318: 
 1319: #ifdef _KERNEL
 1320: 
 1321: static int ncr_debug = SCSI_NCR_DEBUG;
 1322: SYSCTL_INT(_debug, OID_AUTO, ncr_debug, CTLFLAG_RW, &ncr_debug, 0, "");
 1323: 
 1324: static int ncr_cache; /* to be aligned _NOT_ static */
 1325: 
 1326: /*==========================================================
 1327: **
 1328: **
 1329: **      Global static data:	auto configure
 1330: **
 1331: **
 1332: **==========================================================
 1333: */
 1334: 
 1335: #define	NCR_810_ID	(0x00011000ul)
 1336: #define	NCR_815_ID	(0x00041000ul)
 1337: #define	NCR_820_ID	(0x00021000ul)
 1338: #define	NCR_825_ID	(0x00031000ul)
 1339: #define	NCR_860_ID	(0x00061000ul)
 1340: #define	NCR_875_ID	(0x000f1000ul)
 1341: #define	NCR_875_ID2	(0x008f1000ul)
 1342: #define	NCR_885_ID	(0x000d1000ul)
 1343: #define	NCR_895_ID	(0x000c1000ul)
 1344: #define	NCR_896_ID	(0x000b1000ul)
 1345: #define	NCR_895A_ID	(0x00121000ul)
 1346: #define	NCR_1510D_ID	(0x000a1000ul)
 1347: 
 1348: 
 1349: static char *ncr_name (ncb_p np)
 1350: {
 1351: 	static char name[10];
 1352: 	snprintf(name, sizeof(name), "ncr%d", np->unit);
 1353: 	return (name);
 1354: }
 1355: 
 1356: /*==========================================================
 1357: **
 1358: **
 1359: **      Scripts for NCR-Processor.
 1360: **
 1361: **      Use ncr_script_bind for binding to physical addresses.
 1362: **
 1363: **
 1364: **==========================================================
 1365: **
 1366: **	NADDR generates a reference to a field of the controller data.
 1367: **	PADDR generates a reference to another part of the script.
 1368: **	RADDR generates a reference to a script processor register.
 1369: **	FADDR generates a reference to a script processor register
 1370: **		with offset.
 1371: **
 1372: **----------------------------------------------------------
 1373: */
 1374: 
 1375: #define	RELOC_SOFTC	0x40000000
 1376: #define	RELOC_LABEL	0x50000000
 1377: #define	RELOC_REGISTER	0x60000000
 1378: #define	RELOC_KVAR	0x70000000
 1379: #define	RELOC_LABELH	0x80000000
 1380: #define	RELOC_MASK	0xf0000000
 1381: 
 1382: #define	NADDR(label)	(RELOC_SOFTC | offsetof(struct ncb, label))
 1383: #define PADDR(label)    (RELOC_LABEL | offsetof(struct script, label))
 1384: #define PADDRH(label)   (RELOC_LABELH | offsetof(struct scripth, label))
 1385: #define	RADDR(label)	(RELOC_REGISTER | REG(label))
 1386: #define	FADDR(label,ofs)(RELOC_REGISTER | ((REG(label))+(ofs)))
 1387: #define	KVAR(which)	(RELOC_KVAR | (which))
 1388: 
 1389: #define KVAR_SECOND			(0)
 1390: #define KVAR_TICKS			(1)
 1391: #define KVAR_NCR_CACHE			(2)
 1392: 
 1393: #define	SCRIPT_KVAR_FIRST		(0)
 1394: #define	SCRIPT_KVAR_LAST		(3)
 1395: 
 1396: /*
 1397:  * Kernel variables referenced in the scripts.
 1398:  * THESE MUST ALL BE ALIGNED TO A 4-BYTE BOUNDARY.
 1399:  */
 1400: static void *script_kvars[] =
 1401: 	{ &time_second, &ticks, &ncr_cache };
 1402: 
 1403: static	struct script script0 = {
 1404: /*--------------------------< START >-----------------------*/ {
 1405: 	/*
 1406: 	**	Claim to be still alive ...
 1407: 	*/
 1408: 	SCR_COPY (sizeof (((struct ncb *)0)->heartbeat)),
 1409: 		KVAR (KVAR_SECOND),
 1410: 		NADDR (heartbeat),
 1411: 	/*
 1412: 	**      Make data structure address invalid.
 1413: 	**      clear SIGP.
 1414: 	*/
 1415: 	SCR_LOAD_REG (dsa, 0xff),
 1416: 		0,
 1417: 	SCR_FROM_REG (ctest2),
 1418: 		0,
 1419: }/*-------------------------< START0 >----------------------*/,{
 1420: 	/*
 1421: 	**	Hook for interrupted GetConditionCode.
 1422: 	**	Will be patched to ... IFTRUE by
 1423: 	**	the interrupt handler.
 1424: 	*/
 1425: 	SCR_INT ^ IFFALSE (0),
 1426: 		SIR_SENSE_RESTART,
 1427: 
 1428: }/*-------------------------< START1 >----------------------*/,{
 1429: 	/*
 1430: 	**	Hook for stalled start queue.
 1431: 	**	Will be patched to IFTRUE by the interrupt handler.
 1432: 	*/
 1433: 	SCR_INT ^ IFFALSE (0),
 1434: 		SIR_STALL_RESTART,
 1435: 	/*
 1436: 	**	Then jump to a certain point in tryloop.
 1437: 	**	Due to the lack of indirect addressing the code
 1438: 	**	is self modifying here.
 1439: 	*/
 1440: 	SCR_JUMP,
 1441: }/*-------------------------< STARTPOS >--------------------*/,{
 1442: 		PADDRH(tryloop),
 1443: 
 1444: }/*-------------------------< TRYSEL >----------------------*/,{
 1445: 	/*
 1446: 	**	Now:
 1447: 	**	DSA: Address of a Data Structure
 1448: 	**	or   Address of the IDLE-Label.
 1449: 	**
 1450: 	**	TEMP:	Address of a script, which tries to
 1451: 	**		start the NEXT entry.
 1452: 	**
 1453: 	**	Save the TEMP register into the SCRATCHA register.
 1454: 	**	Then copy the DSA to TEMP and RETURN.
 1455: 	**	This is kind of an indirect jump.
 1456: 	**	(The script processor has NO stack, so the
 1457: 	**	CALL is actually a jump and link, and the
 1458: 	**	RETURN is an indirect jump.)
 1459: 	**
 1460: 	**	If the slot was empty, DSA contains the address
 1461: 	**	of the IDLE part of this script. The processor
 1462: 	**	jumps to IDLE and waits for a reselect.
 1463: 	**	It will wake up and try the same slot again
 1464: 	**	after the SIGP bit becomes set by the host.
 1465: 	**
 1466: 	**	If the slot was not empty, DSA contains
 1467: 	**	the address of the phys-part of a nccb.
 1468: 	**	The processor jumps to this address.
 1469: 	**	phys starts with head,
 1470: 	**	head starts with launch,
 1471: 	**	so actually the processor jumps to
 1472: 	**	the lauch part.
 1473: 	**	If the entry is scheduled for execution,
 1474: 	**	then launch contains a jump to SELECT.
 1475: 	**	If it's not scheduled, it contains a jump to IDLE.
 1476: 	*/
 1477: 	SCR_COPY (4),
 1478: 		RADDR (temp),
 1479: 		RADDR (scratcha),
 1480: 	SCR_COPY (4),
 1481: 		RADDR (dsa),
 1482: 		RADDR (temp),
 1483: 	SCR_RETURN,
 1484: 		0
 1485: 
 1486: }/*-------------------------< SKIP >------------------------*/,{
 1487: 	/*
 1488: 	**	This entry has been canceled.
 1489: 	**	Next time use the next slot.
 1490: 	*/
 1491: 	SCR_COPY (4),
 1492: 		RADDR (scratcha),
 1493: 		PADDR (startpos),
 1494: 	/*
 1495: 	**	patch the launch field.
 1496: 	**	should look like an idle process.
 1497: 	*/
 1498: 	SCR_COPY_F (4),
 1499: 		RADDR (dsa),
 1500: 		PADDR (skip2),
 1501: 	SCR_COPY (8),
 1502: 		PADDR (idle),
 1503: }/*-------------------------< SKIP2 >-----------------------*/,{
 1504: 		0,
 1505: 	SCR_JUMP,
 1506: 		PADDR(start),
 1507: }/*-------------------------< IDLE >------------------------*/,{
 1508: 	/*
 1509: 	**	Nothing to do?
 1510: 	**	Wait for reselect.
 1511: 	*/
 1512: 	SCR_JUMP,
 1513: 		PADDR(reselect),
 1514: 
 1515: }/*-------------------------< SELECT >----------------------*/,{
 1516: 	/*
 1517: 	**	DSA	contains the address of a scheduled
 1518: 	**		data structure.
 1519: 	**
 1520: 	**	SCRATCHA contains the address of the script,
 1521: 	**		which starts the next entry.
 1522: 	**
 1523: 	**	Set Initiator mode.
 1524: 	**
 1525: 	**	(Target mode is left as an exercise for the reader)
 1526: 	*/
 1527: 
 1528: 	SCR_CLR (SCR_TRG),
 1529: 		0,
 1530: 	SCR_LOAD_REG (HS_REG, 0xff),
 1531: 		0,
 1532: 
 1533: 	/*
 1534: 	**      And try to select this target.
 1535: 	*/
 1536: 	SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select),
 1537: 		PADDR (reselect),
 1538: 
 1539: 	/*
 1540: 	**	Now there are 4 possibilities:
 1541: 	**
 1542: 	**	(1) The ncr looses arbitration.
 1543: 	**	This is ok, because it will try again,
 1544: 	**	when the bus becomes idle.
 1545: 	**	(But beware of the timeout function!)
 1546: 	**
 1547: 	**	(2) The ncr is reselected.
 1548: 	**	Then the script processor takes the jump
 1549: 	**	to the RESELECT label.
 1550: 	**
 1551: 	**	(3) The ncr completes the selection.
 1552: 	**	Then it will execute the next statement.
 1553: 	**
 1554: 	**	(4) There is a selection timeout.
 1555: 	**	Then the ncr should interrupt the host and stop.
 1556: 	**	Unfortunately, it seems to continue execution
 1557: 	**	of the script. But it will fail with an
 1558: 	**	IID-interrupt on the next WHEN.
 1559: 	*/
 1560: 
 1561: 	SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)),
 1562: 		0,
 1563: 
 1564: 	/*
 1565: 	**	Send the IDENTIFY and SIMPLE_TAG messages
 1566: 	**	(and the MSG_EXT_SDTR message)
 1567: 	*/
 1568: 	SCR_MOVE_TBL ^ SCR_MSG_OUT,
 1569: 		offsetof (struct dsb, smsg),
 1570: #ifdef undef /* XXX better fail than try to deal with this ... */
 1571: 	SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_OUT)),
 1572: 		-16,
 1573: #endif
 1574: 	SCR_CLR (SCR_ATN),
 1575: 		0,
 1576: 	SCR_COPY (1),
 1577: 		RADDR (sfbr),
 1578: 		NADDR (lastmsg),
 1579: 	/*
 1580: 	**	Selection complete.
 1581: 	**	Next time use the next slot.
 1582: 	*/
 1583: 	SCR_COPY (4),
 1584: 		RADDR (scratcha),
 1585: 		PADDR (startpos),
 1586: }/*-------------------------< PREPARE >----------------------*/,{
 1587: 	/*
 1588: 	**      The ncr doesn't have an indirect load
 1589: 	**	or store command. So we have to
 1590: 	**	copy part of the control block to a
 1591: 	**	fixed place, where we can access it.
 1592: 	**
 1593: 	**	We patch the address part of a
 1594: 	**	COPY command with the DSA-register.
 1595: 	*/
 1596: 	SCR_COPY_F (4),
 1597: 		RADDR (dsa),
 1598: 		PADDR (loadpos),
 1599: 	/*
 1600: 	**	then we do the actual copy.
 1601: 	*/
 1602: 	SCR_COPY (sizeof (struct head)),
 1603: 	/*
 1604: 	**	continued after the next label ...
 1605: 	*/
 1606: 
 1607: }/*-------------------------< LOADPOS >---------------------*/,{
 1608: 		0,
 1609: 		NADDR (header),
 1610: 	/*
 1611: 	**      Mark this nccb as not scheduled.
 1612: 	*/
 1613: 	SCR_COPY (8),
 1614: 		PADDR (idle),
 1615: 		NADDR (header.launch),
 1616: 	/*
 1617: 	**      Set a time stamp for this selection
 1618: 	*/
 1619: 	SCR_COPY (sizeof (ticks)),
 1620: 		KVAR (KVAR_TICKS),
 1621: 		NADDR (header.stamp.select),
 1622: 	/*
 1623: 	**      load the savep (saved pointer) into
 1624: 	**      the TEMP register (actual pointer)
 1625: 	*/
 1626: 	SCR_COPY (4),
 1627: 		NADDR (header.savep),
 1628: 		RADDR (temp),
 1629: 	/*
 1630: 	**      Initialize the status registers
 1631: 	*/
 1632: 	SCR_COPY (4),
 1633: 		NADDR (header.status),
 1634: 		RADDR (scr0),
 1635: 
 1636: }/*-------------------------< PREPARE2 >---------------------*/,{
 1637: 	/*
 1638: 	**      Load the synchronous mode register
 1639: 	*/
 1640: 	SCR_COPY (1),
 1641: 		NADDR (sync_st),
 1642: 		RADDR (sxfer),
 1643: 	/*
 1644: 	**      Load the wide mode and timing register
 1645: 	*/
 1646: 	SCR_COPY (1),
 1647: 		NADDR (wide_st),
 1648: 		RADDR (scntl3),
 1649: 	/*
 1650: 	**	Initialize the msgout buffer with a NOOP message.
 1651: 	*/
 1652: 	SCR_LOAD_REG (scratcha, MSG_NOOP),
 1653: 		0,
 1654: 	SCR_COPY (1),
 1655: 		RADDR (scratcha),
 1656: 		NADDR (msgout),
 1657: 	SCR_COPY (1),
 1658: 		RADDR (scratcha),
 1659: 		NADDR (msgin),
 1660: 	/*
 1661: 	**	Message in phase ?
 1662: 	*/
 1663: 	SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
 1664: 		PADDR (dispatch),
 1665: 	/*
 1666: 	**	Extended or reject message ?
 1667: 	*/
 1668: 	SCR_FROM_REG (sbdl),
 1669: 		0,
 1670: 	SCR_JUMP ^ IFTRUE (DATA (MSG_EXTENDED)),
 1671: 		PADDR (msg_in),
 1672: 	SCR_JUMP ^ IFTRUE (DATA (MSG_MESSAGE_REJECT)),
 1673: 		PADDRH (msg_reject),
 1674: 	/*
 1675: 	**	normal processing
 1676: 	*/
 1677: 	SCR_JUMP,
 1678: 		PADDR (dispatch),
 1679: }/*-------------------------< SETMSG >----------------------*/,{
 1680: 	SCR_COPY (1),
 1681: 		RADDR (scratcha),
 1682: 		NADDR (msgout),
 1683: 	SCR_SET (SCR_ATN),
 1684: 		0,
 1685: }/*-------------------------< CLRACK >----------------------*/,{
 1686: 	/*
 1687: 	**	Terminate possible pending message phase.
 1688: 	*/
 1689: 	SCR_CLR (SCR_ACK),
 1690: 		0,
 1691: 
 1692: }/*-----------------------< DISPATCH >----------------------*/,{
 1693: 	SCR_FROM_REG (HS_REG),
 1694: 		0,
 1695: 	SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),
 1696: 		SIR_NEGO_FAILED,
 1697: 	/*
 1698: 	**	remove bogus output signals
 1699: 	*/
 1700: 	SCR_REG_REG (socl, SCR_AND, CACK|CATN),
 1701: 		0,
 1702: 	SCR_RETURN ^ IFTRUE (WHEN (SCR_DATA_OUT)),
 1703: 		0,
 1704: 	SCR_RETURN ^ IFTRUE (IF (SCR_DATA_IN)),
 1705: 		0,
 1706: 	SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)),
 1707: 		PADDR (msg_out),
 1708: 	SCR_JUMP ^ IFTRUE (IF (SCR_MSG_IN)),
 1709: 		PADDR (msg_in),
 1710: 	SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)),
 1711: 		PADDR (command),
 1712: 	SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)),
 1713: 		PADDR (status),
 1714: 	/*
 1715: 	**      Discard one illegal phase byte, if required.
 1716: 	*/
 1717: 	SCR_LOAD_REG (scratcha, XE_BAD_PHASE),
 1718: 		0,
 1719: 	SCR_COPY (1),
 1720: 		RADDR (scratcha),
 1721: 		NADDR (xerr_st),
 1722: 	SCR_JUMPR ^ IFFALSE (IF (SCR_ILG_OUT)),
 1723: 		8,
 1724: 	SCR_MOVE_ABS (1) ^ SCR_ILG_OUT,
 1725: 		NADDR (scratch),
 1726: 	SCR_JUMPR ^ IFFALSE (IF (SCR_ILG_IN)),
 1727: 		8,
 1728: 	SCR_MOVE_ABS (1) ^ SCR_ILG_IN,
 1729: 		NADDR (scratch),
 1730: 	SCR_JUMP,
 1731: 		PADDR (dispatch),
 1732: 
 1733: }/*-------------------------< NO_DATA >--------------------*/,{
 1734: 	/*
 1735: 	**	The target wants to tranfer too much data
 1736: 	**	or in the wrong direction.
 1737: 	**      Remember that in extended error.
 1738: 	*/
 1739: 	SCR_LOAD_REG (scratcha, XE_EXTRA_DATA),
 1740: 		0,
 1741: 	SCR_COPY (1),
 1742: 		RADDR (scratcha),
 1743: 		NADDR (xerr_st),
 1744: 	/*
 1745: 	**      Discard one data byte, if required.
 1746: 	*/
 1747: 	SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)),
 1748: 		8,
 1749: 	SCR_MOVE_ABS (1) ^ SCR_DATA_OUT,
 1750: 		NADDR (scratch),
 1751: 	SCR_JUMPR ^ IFFALSE (IF (SCR_DATA_IN)),
 1752: 		8,
 1753: 	SCR_MOVE_ABS (1) ^ SCR_DATA_IN,
 1754: 		NADDR (scratch),
 1755: 	/*
 1756: 	**      .. and repeat as required.
 1757: 	*/
 1758: 	SCR_CALL,
 1759: 		PADDR (dispatch),
 1760: 	SCR_JUMP,
 1761: 		PADDR (no_data),
 1762: }/*-------------------------< CHECKATN >--------------------*/,{
 1763: 	/*
 1764: 	**	If AAP (bit 1 of scntl0 register) is set
 1765: 	**	and a parity error is detected,
 1766: 	**	the script processor asserts ATN.
 1767: 	**
 1768: 	**	The target should switch to a MSG_OUT phase
 1769: 	**	to get the message.
 1770: 	*/
 1771: 	SCR_FROM_REG (socl),
 1772: 		0,
 1773: 	SCR_JUMP ^ IFFALSE (MASK (CATN, CATN)),
 1774: 		PADDR (dispatch),
 1775: 	/*
 1776: 	**	count it
 1777: 	*/
 1778: 	SCR_REG_REG (PS_REG, SCR_ADD, 1),
 1779: 		0,
 1780: 	/*
 1781: 	**	Prepare a MSG_INITIATOR_DET_ERR message
 1782: 	**	(initiator detected error).
 1783: 	**	The target should retry the transfer.
 1784: 	*/
 1785: 	SCR_LOAD_REG (scratcha, MSG_INITIATOR_DET_ERR),
 1786: 		0,
 1787: 	SCR_JUMP,
 1788: 		PADDR (setmsg),
 1789: 
 1790: }/*-------------------------< COMMAND >--------------------*/,{
 1791: 	/*
 1792: 	**	If this is not a GETCC transfer ...
 1793: 	*/
 1794: 	SCR_FROM_REG (SS_REG),
 1795: 		0,
 1796: /*<<<*/	SCR_JUMPR ^ IFTRUE (DATA (SCSI_STATUS_CHECK_COND)),
 1797: 		28,
 1798: 	/*
 1799: 	**	... set a timestamp ...
 1800: 	*/
 1801: 	SCR_COPY (sizeof (ticks)),
 1802: 		KVAR (KVAR_TICKS),
 1803: 		NADDR (header.stamp.command),
 1804: 	/*
 1805: 	**	... and send the command
 1806: 	*/
 1807: 	SCR_MOVE_TBL ^ SCR_COMMAND,
 1808: 		offsetof (struct dsb, cmd),
 1809: 	SCR_JUMP,
 1810: 		PADDR (dispatch),
 1811: 	/*
 1812: 	**	Send the GETCC command
 1813: 	*/
 1814: /*>>>*/	SCR_MOVE_TBL ^ SCR_COMMAND,
 1815: 		offsetof (struct dsb, scmd),
 1816: 	SCR_JUMP,
 1817: 		PADDR (dispatch),
 1818: 
 1819: }/*-------------------------< STATUS >--------------------*/,{
 1820: 	/*
 1821: 	**	set the timestamp.
 1822: 	*/
 1823: 	SCR_COPY (sizeof (ticks)),
 1824: 		KVAR (KVAR_TICKS),
 1825: 		NADDR (header.stamp.status),
 1826: 	/*
 1827: 	**	If this is a GETCC transfer,
 1828: 	*/
 1829: 	SCR_FROM_REG (SS_REG),
 1830: 		0,
 1831: /*<<<*/	SCR_JUMPR ^ IFFALSE (DATA (SCSI_STATUS_CHECK_COND)),
 1832: 		40,
 1833: 	/*
 1834: 	**	get the status
 1835: 	*/
 1836: 	SCR_MOVE_ABS (1) ^ SCR_STATUS,
 1837: 		NADDR (scratch),
 1838: 	/*
 1839: 	**	Save status to scsi_status.
 1840: 	**	Mark as complete.
 1841: 	**	And wait for disconnect.
 1842: 	*/
 1843: 	SCR_TO_REG (SS_REG),
 1844: 		0,
 1845: 	SCR_REG_REG (SS_REG, SCR_OR, SCSI_STATUS_SENSE),
 1846: 		0,
 1847: 	SCR_LOAD_REG (HS_REG, HS_COMPLETE),
 1848: 		0,
 1849: 	SCR_JUMP,
 1850: 		PADDR (checkatn),
 1851: 	/*
 1852: 	**	If it was no GETCC transfer,
 1853: 	**	save the status to scsi_status.
 1854: 	*/
 1855: /*>>>*/	SCR_MOVE_ABS (1) ^ SCR_STATUS,
 1856: 		NADDR (scratch),
 1857: 	SCR_TO_REG (SS_REG),
 1858: 		0,
 1859: 	/*
 1860: 	**	if it was no check condition ...
 1861: 	*/
 1862: 	SCR_JUMP ^ IFTRUE (DATA (SCSI_STATUS_CHECK_COND)),
 1863: 		PADDR (checkatn),
 1864: 	/*
 1865: 	**	... mark as complete.
 1866: 	*/
 1867: 	SCR_LOAD_REG (HS_REG, HS_COMPLETE),
 1868: 		0,
 1869: 	SCR_JUMP,
 1870: 		PADDR (checkatn),
 1871: 
 1872: }/*-------------------------< MSG_IN >--------------------*/,{
 1873: 	/*
 1874: 	**	Get the first byte of the message
 1875: 	**	and save it to SCRATCHA.
 1876: 	**
 1877: 	**	The script processor doesn't negate the
 1878: 	**	ACK signal after this transfer.
 1879: 	*/
 1880: 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
 1881: 		NADDR (msgin[0]),
 1882: 	/*
 1883: 	**	Check for message parity error.
 1884: 	*/
 1885: 	SCR_TO_REG (scratcha),
 1886: 		0,
 1887: 	SCR_FROM_REG (socl),
 1888: 		0,
 1889: 	SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
 1890: 		PADDRH (msg_parity),
 1891: 	SCR_FROM_REG (scratcha),
 1892: 		0,
 1893: 	/*
 1894: 	**	Parity was ok, handle this message.
 1895: 	*/
 1896: 	SCR_JUMP ^ IFTRUE (DATA (MSG_CMDCOMPLETE)),
 1897: 		PADDR (complete),
 1898: 	SCR_JUMP ^ IFTRUE (DATA (MSG_SAVEDATAPOINTER)),
 1899: 		PADDR (save_dp),
 1900: 	SCR_JUMP ^ IFTRUE (DATA (MSG_RESTOREPOINTERS)),
 1901: 		PADDR (restore_dp),
 1902: 	SCR_JUMP ^ IFTRUE (DATA (MSG_DISCONNECT)),
 1903: 		PADDR (disconnect),
 1904: 	SCR_JUMP ^ IFTRUE (DATA (MSG_EXTENDED)),
 1905: 		PADDRH (msg_extended),
 1906: 	SCR_JUMP ^ IFTRUE (DATA (MSG_NOOP)),
 1907: 		PADDR (clrack),
 1908: 	SCR_JUMP ^ IFTRUE (DATA (MSG_MESSAGE_REJECT)),
 1909: 		PADDRH (msg_reject),
 1910: 	SCR_JUMP ^ IFTRUE (DATA (MSG_IGN_WIDE_RESIDUE)),
 1911: 		PADDRH (msg_ign_residue),
 1912: 	/*
 1913: 	**	Rest of the messages left as
 1914: 	**	an exercise ...
 1915: 	**
 1916: 	**	Unimplemented messages:
 1917: 	**	fall through to MSG_BAD.
 1918: 	*/
 1919: }/*-------------------------< MSG_BAD >------------------*/,{
 1920: 	/*
 1921: 	**	unimplemented message - reject it.
 1922: 	*/
 1923: 	SCR_INT,
 1924: 		SIR_REJECT_SENT,
 1925: 	SCR_LOAD_REG (scratcha, MSG_MESSAGE_REJECT),
 1926: 		0,
 1927: 	SCR_JUMP,
 1928: 		PADDR (setmsg),
 1929: 
 1930: }/*-------------------------< COMPLETE >-----------------*/,{
 1931: 	/*
 1932: 	**	Complete message.
 1933: 	**
 1934: 	**	If it's not the get condition code,
 1935: 	**	copy TEMP register to LASTP in header.
 1936: 	*/
 1937: 	SCR_FROM_REG (SS_REG),
 1938: 		0,
 1939: /*<<<*/	SCR_JUMPR ^ IFTRUE (MASK (SCSI_STATUS_SENSE, SCSI_STATUS_SENSE)),
 1940: 		12,
 1941: 	SCR_COPY (4),
 1942: 		RADDR (temp),
 1943: 		NADDR (header.lastp),
 1944: /*>>>*/	/*
 1945: 	**	When we terminate the cycle by clearing ACK,
 1946: 	**	the target may disconnect immediately.
 1947: 	**
 1948: 	**	We don't want to be told of an
 1949: 	**	"unexpected disconnect",
 1950: 	**	so we disable this feature.
 1951: 	*/
 1952: 	SCR_REG_REG (scntl2, SCR_AND, 0x7f),
 1953: 		0,
 1954: 	/*
 1955: 	**	Terminate cycle ...
 1956: 	*/
 1957: 	SCR_CLR (SCR_ACK|SCR_ATN),
 1958: 		0,
 1959: 	/*
 1960: 	**	... and wait for the disconnect.
 1961: 	*/
 1962: 	SCR_WAIT_DISC,
 1963: 		0,
 1964: }/*-------------------------< CLEANUP >-------------------*/,{
 1965: 	/*
 1966: 	**      dsa:    Pointer to nccb
 1967: 	**	      or xxxxxxFF (no nccb)
 1968: 	**
 1969: 	**      HS_REG:   Host-Status (<>0!)
 1970: 	*/
 1971: 	SCR_FROM_REG (dsa),
 1972: 		0,
 1973: 	SCR_JUMP ^ IFTRUE (DATA (0xff)),
 1974: 		PADDR (signal),
 1975: 	/*
 1976: 	**      dsa is valid.
 1977: 	**	save the status registers
 1978: 	*/
 1979: 	SCR_COPY (4),
 1980: 		RADDR (scr0),
 1981: 		NADDR (header.status),
 1982: 	/*
 1983: 	**	and copy back the header to the nccb.
 1984: 	*/
 1985: 	SCR_COPY_F (4),
 1986: 		RADDR (dsa),
 1987: 		PADDR (cleanup0),
 1988: 	SCR_COPY (sizeof (struct head)),
 1989: 		NADDR (header),
 1990: }/*-------------------------< CLEANUP0 >--------------------*/,{
 1991: 		0,
 1992: 
 1993: 	/*
 1994: 	**	If command resulted in "check condition"
 1995: 	**	status and is not yet completed,
 1996: 	**	try to get the condition code.
 1997: 	*/
 1998: 	SCR_FROM_REG (HS_REG),
 1999: 		0,
 2000: /*<<<*/	SCR_JUMPR ^ IFFALSE (MASK (0, HS_DONEMASK)),
 2001: 		16,
 2002: 	SCR_FROM_REG (SS_REG),
 2003: 		0,
 2004: 	SCR_JUMP ^ IFTRUE (DATA (SCSI_STATUS_CHECK_COND)),
 2005: 		PADDRH(getcc2),
 2006: }/*-------------------------< SIGNAL >----------------------*/,{
 2007: 	/*
 2008: 	**	if status = queue full,
 2009: 	**	reinsert in startqueue and stall queue.
 2010: 	*/
 2011: /*>>>*/	SCR_FROM_REG (SS_REG),
 2012: 		0,
 2013: 	SCR_INT ^ IFTRUE (DATA (SCSI_STATUS_QUEUE_FULL)),
 2014: 		SIR_STALL_QUEUE,
 2015:   	/*
 2016: 	**	And make the DSA register invalid.
 2017: 	*/
 2018: 	SCR_LOAD_REG (dsa, 0xff), /* invalid */
 2019: 		0,
 2020: 	/*
 2021: 	**	if job completed ...
 2022: 	*/
 2023: 	SCR_FROM_REG (HS_REG),
 2024: 		0,
 2025: 	/*
 2026: 	**	... signal completion to the host
 2027: 	*/
 2028: 	SCR_INT_FLY ^ IFFALSE (MASK (0, HS_DONEMASK)),
 2029: 		0,
 2030: 	/*
 2031: 	**	Auf zu neuen Schandtaten!
 2032: 	*/
 2033: 	SCR_JUMP,
 2034: 		PADDR(start),
 2035: 
 2036: }/*-------------------------< SAVE_DP >------------------*/,{
 2037: 	/*
 2038: 	**	SAVE_DP message:
 2039: 	**	Copy TEMP register to SAVEP in header.
 2040: 	*/
 2041: 	SCR_COPY (4),
 2042: 		RADDR (temp),
 2043: 		NADDR (header.savep),
 2044: 	SCR_JUMP,
 2045: 		PADDR (clrack),
 2046: }/*-------------------------< RESTORE_DP >---------------*/,{
 2047: 	/*
 2048: 	**	RESTORE_DP message:
 2049: 	**	Copy SAVEP in header to TEMP register.
 2050: 	*/
 2051: 	SCR_COPY (4),
 2052: 		NADDR (header.savep),
 2053: 		RADDR (temp),
 2054: 	SCR_JUMP,
 2055: 		PADDR (clrack),
 2056: 
 2057: }/*-------------------------< DISCONNECT >---------------*/,{
 2058: 	/*
 2059: 	**	If QUIRK_AUTOSAVE is set,
 2060: 	**	do an "save pointer" operation.
 2061: 	*/
 2062: 	SCR_FROM_REG (QU_REG),
 2063: 		0,
 2064: /*<<<*/	SCR_JUMPR ^ IFFALSE (MASK (QUIRK_AUTOSAVE, QUIRK_AUTOSAVE)),
 2065: 		12,
 2066: 	/*
 2067: 	**	like SAVE_DP message:
 2068: 	**	Copy TEMP register to SAVEP in header.
 2069: 	*/
 2070: 	SCR_COPY (4),
 2071: 		RADDR (temp),
 2072: 		NADDR (header.savep),
 2073: /*>>>*/	/*
 2074: 	**	Check if temp==savep or temp==goalp:
 2075: 	**	if not, log a missing save pointer message.
 2076: 	**	In fact, it's a comparison mod 256.
 2077: 	**
 2078: 	**	Hmmm, I hadn't thought that I would be urged to
 2079: 	**	write this kind of ugly self modifying code.
 2080: 	**
 2081: 	**	It's unbelievable, but the ncr53c8xx isn't able
 2082: 	**	to subtract one register from another.
 2083: 	*/
 2084: 	SCR_FROM_REG (temp),
 2085: 		0,
 2086: 	/*
 2087: 	**	You are not expected to understand this ..
 2088: 	**
 2089: 	**	CAUTION: only little endian architectures supported! XXX
 2090: 	*/
 2091: 	SCR_COPY_F (1),
 2092: 		NADDR (header.savep),
 2093: 		PADDR (disconnect0),
 2094: }/*-------------------------< DISCONNECT0 >--------------*/,{
 2095: /*<<<*/	SCR_JUMPR ^ IFTRUE (DATA (1)),
 2096: 		20,
 2097: 	/*
 2098: 	**	neither this
 2099: 	*/
 2100: 	SCR_COPY_F (1),
 2101: 		NADDR (header.goalp),
 2102: 		PADDR (disconnect1),
 2103: }/*-------------------------< DISCONNECT1 >--------------*/,{
 2104: 	SCR_INT ^ IFFALSE (DATA (1)),
 2105: 		SIR_MISSING_SAVE,
 2106: /*>>>*/
 2107: 
 2108: 	/*
 2109: 	**	DISCONNECTing  ...
 2110: 	**
 2111: 	**	disable the "unexpected disconnect" feature,
 2112: 	**	and remove the ACK signal.
 2113: 	*/
 2114: 	SCR_REG_REG (scntl2, SCR_AND, 0x7f),
 2115: 		0,
 2116: 	SCR_CLR (SCR_ACK|SCR_ATN),
 2117: 		0,
 2118: 	/*
 2119: 	**	Wait for the disconnect.
 2120: 	*/
 2121: 	SCR_WAIT_DISC,
 2122: 		0,
 2123: 	/*
 2124: 	**	Profiling:
 2125: 	**	Set a time stamp,
 2126: 	**	and count the disconnects.
 2127: 	*/
 2128: 	SCR_COPY (sizeof (ticks)),
 2129: 		KVAR (KVAR_TICKS),
 2130: 		NADDR (header.stamp.disconnect),
 2131: 	SCR_COPY (4),
 2132: 		NADDR (disc_phys),
 2133: 		RADDR (temp),
 2134: 	SCR_REG_REG (temp, SCR_ADD, 0x01),
 2135: 		0,
 2136: 	SCR_COPY (4),
 2137: 		RADDR (temp),
 2138: 		NADDR (disc_phys),
 2139: 	/*
 2140: 	**	Status is: DISCONNECTED.
 2141: 	*/
 2142: 	SCR_LOAD_REG (HS_REG, HS_DISCONNECT),
 2143: 		0,
 2144: 	SCR_JUMP,
 2145: 		PADDR (cleanup),
 2146: 
 2147: }/*-------------------------< MSG_OUT >-------------------*/,{
 2148: 	/*
 2149: 	**	The target requests a message.
 2150: 	*/
 2151: 	SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,
 2152: 		NADDR (msgout),
 2153: 	SCR_COPY (1),
 2154: 		RADDR (sfbr),
 2155: 		NADDR (lastmsg),
 2156: 	/*
 2157: 	**	If it was no ABORT message ...
 2158: 	*/
 2159: 	SCR_JUMP ^ IFTRUE (DATA (MSG_ABORT)),
 2160: 		PADDRH (msg_out_abort),
 2161: 	/*
 2162: 	**	... wait for the next phase
 2163: 	**	if it's a message out, send it again, ...
 2164: 	*/
 2165: 	SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)),
 2166: 		PADDR (msg_out),
 2167: }/*-------------------------< MSG_OUT_DONE >--------------*/,{
 2168: 	/*
 2169: 	**	... else clear the message ...
 2170: 	*/
 2171: 	SCR_LOAD_REG (scratcha, MSG_NOOP),
 2172: 		0,
 2173: 	SCR_COPY (4),
 2174: 		RADDR (scratcha),
 2175: 		NADDR (msgout),
 2176: 	/*
 2177: 	**	... and process the next phase
 2178: 	*/
 2179: 	SCR_JUMP,
 2180: 		PADDR (dispatch),
 2181: 
 2182: }/*------------------------< BADGETCC >---------------------*/,{
 2183: 	/*
 2184: 	**	If SIGP was set, clear it and try again.
 2185: 	*/
 2186: 	SCR_FROM_REG (ctest2),
 2187: 		0,
 2188: 	SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)),
 2189: 		PADDRH (getcc2),
 2190: 	SCR_INT,
 2191: 		SIR_SENSE_FAILED,
 2192: }/*-------------------------< RESELECT >--------------------*/,{
 2193: 	/*
 2194: 	**	This NOP will be patched with LED OFF
 2195: 	**	SCR_REG_REG (gpreg, SCR_OR, 0x01)
 2196: 	*/
 2197: 	SCR_NO_OP,
 2198: 		0,
 2199: 
 2200: 	/*
 2201: 	**	make the DSA invalid.
 2202: 	*/
 2203: 	SCR_LOAD_REG (dsa, 0xff),
 2204: 		0,
 2205: 	SCR_CLR (SCR_TRG),
 2206: 		0,
 2207: 	/*
 2208: 	**	Sleep waiting for a reselection.
 2209: 	**	If SIGP is set, special treatment.
 2210: 	**
 2211: 	**	Zu allem bereit ..
 2212: 	*/
 2213: 	SCR_WAIT_RESEL,
 2214: 		PADDR(reselect2),
 2215: }/*-------------------------< RESELECT1 >--------------------*/,{
 2216: 	/*
 2217: 	**	This NOP will be patched with LED ON
 2218: 	**	SCR_REG_REG (gpreg, SCR_AND, 0xfe)
 2219: 	*/
 2220: 	SCR_NO_OP,
 2221: 		0,
 2222: 	/*
 2223: 	**	... zu nichts zu gebrauchen ?
 2224: 	**
 2225: 	**      load the target id into the SFBR
 2226: 	**	and jump to the control block.
 2227: 	**
 2228: 	**	Look at the declarations of
 2229: 	**	- struct ncb
 2230: 	**	- struct tcb
 2231: 	**	- struct lcb
 2232: 	**	- struct nccb
 2233: 	**	to understand what's going on.
 2234: 	*/
 2235: 	SCR_REG_SFBR (ssid, SCR_AND, 0x8F),
 2236: 		0,
 2237: 	SCR_TO_REG (sdid),
 2238: 		0,
 2239: 	SCR_JUMP,
 2240: 		NADDR (jump_tcb),
 2241: }/*-------------------------< RESELECT2 >-------------------*/,{
 2242: 	/*
 2243: 	**	This NOP will be patched with LED ON
 2244: 	**	SCR_REG_REG (gpreg, SCR_AND, 0xfe)
 2245: 	*/
 2246: 	SCR_NO_OP,
 2247: 		0,
 2248: 	/*
 2249: 	**	If it's not connected :(
 2250: 	**	-> interrupted by SIGP bit.
 2251: 	**	Jump to start.
 2252: 	*/
 2253: 	SCR_FROM_REG (ctest2),
 2254: 		0,
 2255: 	SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)),
 2256: 		PADDR (start),
 2257: 	SCR_JUMP,
 2258: 		PADDR (reselect),
 2259: 
 2260: }/*-------------------------< RESEL_TMP >-------------------*/,{
 2261: 	/*
 2262: 	**	The return address in TEMP
 2263: 	**	is in fact the data structure address,
 2264: 	**	so copy it to the DSA register.
 2265: 	*/
 2266: 	SCR_COPY (4),
 2267: 		RADDR (temp),
 2268: 		RADDR (dsa),
 2269: 	SCR_JUMP,
 2270: 		PADDR (prepare),
 2271: 
 2272: }/*-------------------------< RESEL_LUN >-------------------*/,{
 2273: 	/*
 2274: 	**	come back to this point
 2275: 	**	to get an IDENTIFY message
 2276: 	**	Wait for a msg_in phase.
 2277: 	*/
 2278: /*<<<*/	SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)),
 2279: 		48,
 2280: 	/*
 2281: 	**	message phase
 2282: 	**	It's not a sony, it's a trick:
 2283: 	**	read the data without acknowledging it.
 2284: 	*/
 2285: 	SCR_FROM_REG (sbdl),
 2286: 		0,
 2287: /*<<<*/	SCR_JUMPR ^ IFFALSE (MASK (MSG_IDENTIFYFLAG, 0x98)),
 2288: 		32,
 2289: 	/*
 2290: 	**	It WAS an Identify message.
 2291: 	**	get it and ack it!
 2292: 	*/
 2293: 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
 2294: 		NADDR (msgin),
 2295: 	SCR_CLR (SCR_ACK),
 2296: 		0,
 2297: 	/*
 2298: 	**	Mask out the lun.
 2299: 	*/
 2300: 	SCR_REG_REG (sfbr, SCR_AND, 0x07),
 2301: 		0,
 2302: 	SCR_RETURN,
 2303: 		0,
 2304: 	/*
 2305: 	**	No message phase or no IDENTIFY message:
 2306: 	**	return 0.
 2307: 	*/
 2308: /*>>>*/	SCR_LOAD_SFBR (0),
 2309: 		0,
 2310: 	SCR_RETURN,
 2311: 		0,
 2312: 
 2313: }/*-------------------------< RESEL_TAG >-------------------*/,{
 2314: 	/*
 2315: 	**	come back to this point
 2316: 	**	to get a SIMPLE_TAG message
 2317: 	**	Wait for a MSG_IN phase.
 2318: 	*/
 2319: /*<<<*/	SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)),
 2320: 		64,
 2321: 	/*
 2322: 	**	message phase
 2323: 	**	It's a trick - read the data
 2324: 	**	without acknowledging it.
 2325: 	*/
 2326: 	SCR_FROM_REG (sbdl),
 2327: 		0,
 2328: /*<<<*/	SCR_JUMPR ^ IFFALSE (DATA (MSG_SIMPLE_Q_TAG)),
 2329: 		48,
 2330: 	/*
 2331: 	**	It WAS a SIMPLE_TAG message.
 2332: 	**	get it and ack it!
 2333: 	*/
 2334: 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
 2335: 		NADDR (msgin),
 2336: 	SCR_CLR (SCR_ACK),
 2337: 		0,
 2338: 	/*
 2339: 	**	Wait for the second byte (the tag)
 2340: 	*/
 2341: /*<<<*/	SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)),
 2342: 		24,
 2343: 	/*
 2344: 	**	Get it and ack it!
 2345: 	*/
 2346: 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
 2347: 		NADDR (msgin),
 2348: 	SCR_CLR (SCR_ACK|SCR_CARRY),
 2349: 		0,
 2350: 	SCR_RETURN,
 2351: 		0,
 2352: 	/*
 2353: 	**	No message phase or no SIMPLE_TAG message
 2354: 	**	or no second byte: return 0.
 2355: 	*/
 2356: /*>>>*/	SCR_LOAD_SFBR (0),
 2357: 		0,
 2358: 	SCR_SET (SCR_CARRY),
 2359: 		0,
 2360: 	SCR_RETURN,
 2361: 		0,
 2362: 
 2363: }/*-------------------------< DATA_IN >--------------------*/,{
 2364: /*
 2365: **	Because the size depends on the
 2366: **	#define MAX_SCATTER parameter,
 2367: **	it is filled in at runtime.
 2368: **
 2369: **	SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),
 2370: **		PADDR (no_data),
 2371: **	SCR_COPY (sizeof (ticks)),
 2372: **		KVAR (KVAR_TICKS),
 2373: **		NADDR (header.stamp.data),
 2374: **	SCR_MOVE_TBL ^ SCR_DATA_IN,
 2375: **		offsetof (struct dsb, data[ 0]),
 2376: **
 2377: **  ##===========< i=1; i<MAX_SCATTER >=========
 2378: **  ||	SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_IN)),
 2379: **  ||		PADDR (checkatn),
 2380: **  ||	SCR_MOVE_TBL ^ SCR_DATA_IN,
 2381: **  ||		offsetof (struct dsb, data[ i]),
 2382: **  ##==========================================
 2383: **
 2384: **	SCR_CALL,
 2385: **		PADDR (checkatn),
 2386: **	SCR_JUMP,
 2387: **		PADDR (no_data),
 2388: */
 2389: 0
 2390: }/*-------------------------< DATA_OUT >-------------------*/,{
 2391: /*
 2392: **	Because the size depends on the
 2393: **	#define MAX_SCATTER parameter,
 2394: **	it is filled in at runtime.
 2395: **
 2396: **	SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_OUT)),
 2397: **		PADDR (no_data),
 2398: **	SCR_COPY (sizeof (ticks)),
 2399: **		KVAR (KVAR_TICKS),
 2400: **		NADDR (header.stamp.data),
 2401: **	SCR_MOVE_TBL ^ SCR_DATA_OUT,
 2402: **		offsetof (struct dsb, data[ 0]),
 2403: **
 2404: **  ##===========< i=1; i<MAX_SCATTER >=========
 2405: **  ||	SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_OUT)),
 2406: **  ||		PADDR (dispatch),
 2407: **  ||	SCR_MOVE_TBL ^ SCR_DATA_OUT,
 2408: **  ||		offsetof (struct dsb, data[ i]),
 2409: **  ##==========================================
 2410: **
 2411: **	SCR_CALL,
 2412: **		PADDR (dispatch),
 2413: **	SCR_JUMP,
 2414: **		PADDR (no_data),
 2415: **
 2416: **---------------------------------------------------------
 2417: */
 2418: (u_long)0
 2419: 
 2420: }/*--------------------------------------------------------*/
 2421: };
 2422: 
 2423: 
 2424: static	struct scripth scripth0 = {
 2425: /*-------------------------< TRYLOOP >---------------------*/{
 2426: /*
 2427: **	Load an entry of the start queue into dsa
 2428: **	and try to start it by jumping to TRYSEL.
 2429: **
 2430: **	Because the size depends on the
 2431: **	#define MAX_START parameter, it is filled
 2432: **	in at runtime.
 2433: **
 2434: **-----------------------------------------------------------
 2435: **
 2436: **  ##===========< I=0; i<MAX_START >===========
 2437: **  ||	SCR_COPY (4),
 2438: **  ||		NADDR (squeue[i]),
 2439: **  ||		RADDR (dsa),
 2440: **  ||	SCR_CALL,
 2441: **  ||		PADDR (trysel),
 2442: **  ##==========================================
 2443: **
 2444: **	SCR_JUMP,
 2445: **		PADDRH(tryloop),
 2446: **
 2447: **-----------------------------------------------------------
 2448: */
 2449: 0
 2450: }/*-------------------------< MSG_PARITY >---------------*/,{
 2451: 	/*
 2452: 	**	count it
 2453: 	*/
 2454: 	SCR_REG_REG (PS_REG, SCR_ADD, 0x01),
 2455: 		0,
 2456: 	/*
 2457: 	**	send a "message parity error" message.
 2458: 	*/
 2459: 	SCR_LOAD_REG (scratcha, MSG_PARITY_ERROR),
 2460: 		0,
 2461: 	SCR_JUMP,
 2462: 		PADDR (setmsg),
 2463: }/*-------------------------< MSG_MESSAGE_REJECT >---------------*/,{
 2464: 	/*
 2465: 	**	If a negotiation was in progress,
 2466: 	**	negotiation failed.
 2467: 	*/
 2468: 	SCR_FROM_REG (HS_REG),
 2469: 		0,
 2470: 	SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),
 2471: 		SIR_NEGO_FAILED,
 2472: 	/*
 2473: 	**	else make host log this message
 2474: 	*/
 2475: 	SCR_INT ^ IFFALSE (DATA (HS_NEGOTIATE)),
 2476: 		SIR_REJECT_RECEIVED,
 2477: 	SCR_JUMP,
 2478: 		PADDR (clrack),
 2479: 
 2480: }/*-------------------------< MSG_IGN_RESIDUE >----------*/,{
 2481: 	/*
 2482: 	**	Terminate cycle
 2483: 	*/
 2484: 	SCR_CLR (SCR_ACK),
 2485: 		0,
 2486: 	SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
 2487: 		PADDR (dispatch),
 2488: 	/*
 2489: 	**	get residue size.
 2490: 	*/
 2491: 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
 2492: 		NADDR (msgin[1]),
 2493: 	/*
 2494: 	**	Check for message parity error.
 2495: 	*/
 2496: 	SCR_TO_REG (scratcha),
 2497: 		0,
 2498: 	SCR_FROM_REG (socl),
 2499: 		0,
 2500: 	SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
 2501: 		PADDRH (msg_parity),
 2502: 	SCR_FROM_REG (scratcha),
 2503: 		0,
 2504: 	/*
 2505: 	**	Size is 0 .. ignore message.
 2506: 	*/
 2507: 	SCR_JUMP ^ IFTRUE (DATA (0)),
 2508: 		PADDR (clrack),
 2509: 	/*
 2510: 	**	Size is not 1 .. have to interrupt.
 2511: 	*/
 2512: /*<<<*/	SCR_JUMPR ^ IFFALSE (DATA (1)),
 2513: 		40,
 2514: 	/*
 2515: 	**	Check for residue byte in swide register
 2516: 	*/
 2517: 	SCR_FROM_REG (scntl2),
 2518: 		0,
 2519: /*<<<*/	SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)),
 2520: 		16,
 2521: 	/*
 2522: 	**	There IS data in the swide register.
 2523: 	**	Discard it.
 2524: 	*/
 2525: 	SCR_REG_REG (scntl2, SCR_OR, WSR),
 2526: 		0,
 2527: 	SCR_JUMP,
 2528: 		PADDR (clrack),
 2529: 	/*
 2530: 	**	Load again the size to the sfbr register.
 2531: 	*/
 2532: /*>>>*/	SCR_FROM_REG (scratcha),
 2533: 		0,
 2534: /*>>>*/	SCR_INT,
 2535: 		SIR_IGN_RESIDUE,
 2536: 	SCR_JUMP,
 2537: 		PADDR (clrack),
 2538: 
 2539: }/*-------------------------< MSG_EXTENDED >-------------*/,{
 2540: 	/*
 2541: 	**	Terminate cycle
 2542: 	*/
 2543: 	SCR_CLR (SCR_ACK),
 2544: 		0,
 2545: 	SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
 2546: 		PADDR (dispatch),
 2547: 	/*
 2548: 	**	get length.
 2549: 	*/
 2550: 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
 2551: 		NADDR (msgin[1]),
 2552: 	/*
 2553: 	**	Check for message parity error.
 2554: 	*/
 2555: 	SCR_TO_REG (scratcha),
 2556: 		0,
 2557: 	SCR_FROM_REG (socl),
 2558: 		0,
 2559: 	SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
 2560: 		PADDRH (msg_parity),
 2561: 	SCR_FROM_REG (scratcha),
 2562: 		0,
 2563: 	/*
 2564: 	*/
 2565: 	SCR_JUMP ^ IFTRUE (DATA (3)),
 2566: 		PADDRH (msg_ext_3),
 2567: 	SCR_JUMP ^ IFFALSE (DATA (2)),
 2568: 		PADDR (msg_bad),
 2569: }/*-------------------------< MSG_EXT_2 >----------------*/,{
 2570: 	SCR_CLR (SCR_ACK),
 2571: 		0,
 2572: 	SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
 2573: 		PADDR (dispatch),
 2574: 	/*
 2575: 	**	get extended message code.
 2576: 	*/
 2577: 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
 2578: 		NADDR (msgin[2]),
 2579: 	/*
 2580: 	**	Check for message parity error.
 2581: 	*/
 2582: 	SCR_TO_REG (scratcha),
 2583: 		0,
 2584: 	SCR_FROM_REG (socl),
 2585: 		0,
 2586: 	SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
 2587: 		PADDRH (msg_parity),
 2588: 	SCR_FROM_REG (scratcha),
 2589: 		0,
 2590: 	SCR_JUMP ^ IFTRUE (DATA (MSG_EXT_WDTR)),
 2591: 		PADDRH (msg_wdtr),
 2592: 	/*
 2593: 	**	unknown extended message
 2594: 	*/
 2595: 	SCR_JUMP,
 2596: 		PADDR (msg_bad)
 2597: }/*-------------------------< MSG_WDTR >-----------------*/,{
 2598: 	SCR_CLR (SCR_ACK),
 2599: 		0,
 2600: 	SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
 2601: 		PADDR (dispatch),
 2602: 	/*
 2603: 	**	get data bus width
 2604: 	*/
 2605: 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
 2606: 		NADDR (msgin[3]),
 2607: 	SCR_FROM_REG (socl),
 2608: 		0,
 2609: 	SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
 2610: 		PADDRH (msg_parity),
 2611: 	/*
 2612: 	**	let the host do the real work.
 2613: 	*/
 2614: 	SCR_INT,
 2615: 		SIR_NEGO_WIDE,
 2616: 	/*
 2617: 	**	let the target fetch our answer.
 2618: 	*/
 2619: 	SCR_SET (SCR_ATN),
 2620: 		0,
 2621: 	SCR_CLR (SCR_ACK),
 2622: 		0,
 2623: 
 2624: 	SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
 2625: 		SIR_NEGO_PROTO,
 2626: 	/*
 2627: 	**	Send the MSG_EXT_WDTR
 2628: 	*/
 2629: 	SCR_MOVE_ABS (4) ^ SCR_MSG_OUT,
 2630: 		NADDR (msgout),
 2631: 	SCR_CLR (SCR_ATN),
 2632: 		0,
 2633: 	SCR_COPY (1),
 2634: 		RADDR (sfbr),
 2635: 		NADDR (lastmsg),
 2636: 	SCR_JUMP,
 2637: 		PADDR (msg_out_done),
 2638: 
 2639: }/*-------------------------< MSG_EXT_3 >----------------*/,{
 2640: 	SCR_CLR (SCR_ACK),
 2641: 		0,
 2642: 	SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
 2643: 		PADDR (dispatch),
 2644: 	/*
 2645: 	**	get extended message code.
 2646: 	*/
 2647: 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
 2648: 		NADDR (msgin[2]),
 2649: 	/*
 2650: 	**	Check for message parity error.
 2651: 	*/
 2652: 	SCR_TO_REG (scratcha),
 2653: 		0,
 2654: 	SCR_FROM_REG (socl),
 2655: 		0,
 2656: 	SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
 2657: 		PADDRH (msg_parity),
 2658: 	SCR_FROM_REG (scratcha),
 2659: 		0,
 2660: 	SCR_JUMP ^ IFTRUE (DATA (MSG_EXT_SDTR)),
 2661: 		PADDRH (msg_sdtr),
 2662: 	/*
 2663: 	**	unknown extended message
 2664: 	*/
 2665: 	SCR_JUMP,
 2666: 		PADDR (msg_bad)
 2667: 
 2668: }/*-------------------------< MSG_SDTR >-----------------*/,{
 2669: 	SCR_CLR (SCR_ACK),
 2670: 		0,
 2671: 	SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
 2672: 		PADDR (dispatch),
 2673: 	/*
 2674: 	**	get period and offset
 2675: 	*/
 2676: 	SCR_MOVE_ABS (2) ^ SCR_MSG_IN,
 2677: 		NADDR (msgin[3]),
 2678: 	SCR_FROM_REG (socl),
 2679: 		0,
 2680: 	SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
 2681: 		PADDRH (msg_parity),
 2682: 	/*
 2683: 	**	let the host do the real work.
 2684: 	*/
 2685: 	SCR_INT,
 2686: 		SIR_NEGO_SYNC,
 2687: 	/*
 2688: 	**	let the target fetch our answer.
 2689: 	*/
 2690: 	SCR_SET (SCR_ATN),
 2691: 		0,
 2692: 	SCR_CLR (SCR_ACK),
 2693: 		0,
 2694: 
 2695: 	SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
 2696: 		SIR_NEGO_PROTO,
 2697: 	/*
 2698: 	**	Send the MSG_EXT_SDTR
 2699: 	*/
 2700: 	SCR_MOVE_ABS (5) ^ SCR_MSG_OUT,
 2701: 		NADDR (msgout),
 2702: 	SCR_CLR (SCR_ATN),
 2703: 		0,
 2704: 	SCR_COPY (1),
 2705: 		RADDR (sfbr),
 2706: 		NADDR (lastmsg),
 2707: 	SCR_JUMP,
 2708: 		PADDR (msg_out_done),
 2709: 
 2710: }/*-------------------------< MSG_OUT_ABORT >-------------*/,{
 2711: 	/*
 2712: 	**	After ABORT message,
 2713: 	**
 2714: 	**	expect an immediate disconnect, ...
 2715: 	*/
 2716: 	SCR_REG_REG (scntl2, SCR_AND, 0x7f),
 2717: 		0,
 2718: 	SCR_CLR (SCR_ACK|SCR_ATN),
 2719: 		0,
 2720: 	SCR_WAIT_DISC,
 2721: 		0,
 2722: 	/*
 2723: 	**	... and set the status to "ABORTED"
 2724: 	*/
 2725: 	SCR_LOAD_REG (HS_REG, HS_ABORTED),
 2726: 		0,
 2727: 	SCR_JUMP,
 2728: 		PADDR (cleanup),
 2729: 
 2730: }/*-------------------------< GETCC >-----------------------*/,{
 2731: 	/*
 2732: 	**	The ncr doesn't have an indirect load
 2733: 	**	or store command. So we have to
 2734: 	**	copy part of the control block to a
 2735: 	**	fixed place, where we can modify it.
 2736: 	**
 2737: 	**	We patch the address part of a COPY command
 2738: 	**	with the address of the dsa register ...
 2739: 	*/
 2740: 	SCR_COPY_F (4),
 2741: 		RADDR (dsa),
 2742: 		PADDRH (getcc1),
 2743: 	/*
 2744: 	**	... then we do the actual copy.
 2745: 	*/
 2746: 	SCR_COPY (sizeof (struct head)),
 2747: }/*-------------------------< GETCC1 >----------------------*/,{
 2748: 		0,
 2749: 		NADDR (header),
 2750: 	/*
 2751: 	**	Initialize the status registers
 2752: 	*/
 2753: 	SCR_COPY (4),
 2754: 		NADDR (header.status),
 2755: 		RADDR (scr0),
 2756: }/*-------------------------< GETCC2 >----------------------*/,{
 2757: 	/*
 2758: 	**	Get the condition code from a target.
 2759: 	**
 2760: 	**	DSA points to a data structure.
 2761: 	**	Set TEMP to the script location
 2762: 	**	that receives the condition code.
 2763: 	**
 2764: 	**	Because there is no script command
 2765: 	**	to load a longword into a register,
 2766: 	**	we use a CALL command.
 2767: 	*/
 2768: /*<<<*/	SCR_CALLR,
 2769: 		24,
 2770: 	/*
 2771: 	**	Get the condition code.
 2772: 	*/
 2773: 	SCR_MOVE_TBL ^ SCR_DATA_IN,
 2774: 		offsetof (struct dsb, sense),
 2775: 	/*
 2776: 	**	No data phase may follow!
 2777: 	*/
 2778: 	SCR_CALL,
 2779: 		PADDR (checkatn),
 2780: 	SCR_JUMP,
 2781: 		PADDR (no_data),
 2782: /*>>>*/
 2783: 
 2784: 	/*
 2785: 	**	The CALL jumps to this point.
 2786: 	**	Prepare for a RESTORE_POINTER message.
 2787: 	**	Save the TEMP register into the saved pointer.
 2788: 	*/
 2789: 	SCR_COPY (4),
 2790: 		RADDR (temp),
 2791: 		NADDR (header.savep),
 2792: 	/*
 2793: 	**	Load scratcha, because in case of a selection timeout,
 2794: 	**	the host will expect a new value for startpos in
 2795: 	**	the scratcha register.
 2796: 	*/
 2797: 	SCR_COPY (4),
 2798: 		PADDR (startpos),
 2799: 		RADDR (scratcha),
 2800: #ifdef NCR_GETCC_WITHMSG
 2801: 	/*
 2802: 	**	If QUIRK_NOMSG is set, select without ATN.
 2803: 	**	and don't send a message.
 2804: 	*/
 2805: 	SCR_FROM_REG (QU_REG),
 2806: 		0,
 2807: 	SCR_JUMP ^ IFTRUE (MASK (QUIRK_NOMSG, QUIRK_NOMSG)),
 2808: 		PADDRH(getcc3),
 2809: 	/*
 2810: 	**	Then try to connect to the target.
 2811: 	**	If we are reselected, special treatment
 2812: 	**	of the current job is required before
 2813: 	**	accepting the reselection.
 2814: 	*/
 2815: 	SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select),
 2816: 		PADDR(badgetcc),
 2817: 	/*
 2818: 	**	Send the IDENTIFY message.
 2819: 	**	In case of short transfer, remove ATN.
 2820: 	*/
 2821: 	SCR_MOVE_TBL ^ SCR_MSG_OUT,
 2822: 		offsetof (struct dsb, smsg2),
 2823: 	SCR_CLR (SCR_ATN),
 2824: 		0,
 2825: 	/*
 2826: 	**	save the first byte of the message.
 2827: 	*/
 2828: 	SCR_COPY (1),
 2829: 		RADDR (sfbr),
 2830: 		NADDR (lastmsg),
 2831: 	SCR_JUMP,
 2832: 		PADDR (prepare2),
 2833: 
 2834: #endif
 2835: }/*-------------------------< GETCC3 >----------------------*/,{
 2836: 	/*
 2837: 	**	Try to connect to the target.
 2838: 	**	If we are reselected, special treatment
 2839: 	**	of the current job is required before
 2840: 	**	accepting the reselection.
 2841: 	**
 2842: 	**	Silly target won't accept a message.
 2843: 	**	Select without ATN.
 2844: 	*/
 2845: 	SCR_SEL_TBL ^ offsetof (struct dsb, select),
 2846: 		PADDR(badgetcc),
 2847: 	/*
 2848: 	**	Force error if selection timeout
 2849: 	*/
 2850: 	SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)),
 2851: 		0,
 2852: 	/*
 2853: 	**	don't negotiate.
 2854: 	*/
 2855: 	SCR_JUMP,
 2856: 		PADDR (prepare2),
 2857: }/*-------------------------< ABORTTAG >-------------------*/,{
 2858: 	/*
 2859: 	**      Abort a bad reselection.
 2860: 	**	Set the message to ABORT vs. ABORT_TAG
 2861: 	*/
 2862: 	SCR_LOAD_REG (scratcha, MSG_ABORT_TAG),
 2863: 		0,
 2864: 	SCR_JUMPR ^ IFFALSE (CARRYSET),
 2865: 		8,
 2866: }/*-------------------------< ABORT >----------------------*/,{
 2867: 	SCR_LOAD_REG (scratcha, MSG_ABORT),
 2868: 		0,
 2869: 	SCR_COPY (1),
 2870: 		RADDR (scratcha),
 2871: 		NADDR (msgout),
 2872: 	SCR_SET (SCR_ATN),
 2873: 		0,
 2874: 	SCR_CLR (SCR_ACK),
 2875: 		0,
 2876: 	/*
 2877: 	**	and send it.
 2878: 	**	we expect an immediate disconnect
 2879: 	*/
 2880: 	SCR_REG_REG (scntl2, SCR_AND, 0x7f),
 2881: 		0,
 2882: 	SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,
 2883: 		NADDR (msgout),
 2884: 	SCR_COPY (1),
 2885: 		RADDR (sfbr),
 2886: 		NADDR (lastmsg),
 2887: 	SCR_CLR (SCR_ACK|SCR_ATN),
 2888: 		0,
 2889: 	SCR_WAIT_DISC,
 2890: 		0,
 2891: 	SCR_JUMP,
 2892: 		PADDR (start),
 2893: }/*-------------------------< SNOOPTEST >-------------------*/,{
 2894: 	/*
 2895: 	**	Read the variable.
 2896: 	*/
 2897: 	SCR_COPY (4),
 2898: 		KVAR (KVAR_NCR_CACHE),
 2899: 		RADDR (scratcha),
 2900: 	/*
 2901: 	**	Write the variable.
 2902: 	*/
 2903: 	SCR_COPY (4),
 2904: 		RADDR (temp),
 2905: 		KVAR (KVAR_NCR_CACHE),
 2906: 	/*
 2907: 	**	Read back the variable.
 2908: 	*/
 2909: 	SCR_COPY (4),
 2910: 		KVAR (KVAR_NCR_CACHE),
 2911: 		RADDR (temp),
 2912: }/*-------------------------< SNOOPEND >-------------------*/,{
 2913: 	/*
 2914: 	**	And stop.
 2915: 	*/
 2916: 	SCR_INT,
 2917: 		99,
 2918: }/*--------------------------------------------------------*/
 2919: };
 2920: 
 2921: 
 2922: /*==========================================================
 2923: **
 2924: **
 2925: **	Fill in #define dependent parts of the script
 2926: **
 2927: **
 2928: **==========================================================
 2929: */
 2930: 
 2931: void ncr_script_fill (struct script * scr, struct scripth * scrh)
 2932: {
 2933: 	int	i;
 2934: 	ncrcmd	*p;
 2935: 
 2936: 	p = scrh->tryloop;
 2937: 	for (i=0; i<MAX_START; i++) {
 2938: 		*p++ =SCR_COPY (4);
 2939: 		*p++ =NADDR (squeue[i]);
 2940: 		*p++ =RADDR (dsa);
 2941: 		*p++ =SCR_CALL;
 2942: 		*p++ =PADDR (trysel);
 2943: 	};
 2944: 	*p++ =SCR_JUMP;
 2945: 	*p++ =PADDRH(tryloop);
 2946: 
 2947: 	assert ((char *)p == (char *)&scrh->tryloop + sizeof (scrh->tryloop));
 2948: 
 2949: 	p = scr->data_in;
 2950: 
 2951: 	*p++ =SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN));
 2952: 	*p++ =PADDR (no_data);
 2953: 	*p++ =SCR_COPY (sizeof (ticks));
 2954: 	*p++ =(ncrcmd) KVAR (KVAR_TICKS);
 2955: 	*p++ =NADDR (header.stamp.data);
 2956: 	*p++ =SCR_MOVE_TBL ^ SCR_DATA_IN;
 2957: 	*p++ =offsetof (struct dsb, data[ 0]);
 2958: 
 2959: 	for (i=1; i<MAX_SCATTER; i++) {
 2960: 		*p++ =SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_IN));
 2961: 		*p++ =PADDR (checkatn);
 2962: 		*p++ =SCR_MOVE_TBL ^ SCR_DATA_IN;
 2963: 		*p++ =offsetof (struct dsb, data[i]);
 2964: 	};
 2965: 
 2966: 	*p++ =SCR_CALL;
 2967: 	*p++ =PADDR (checkatn);
 2968: 	*p++ =SCR_JUMP;
 2969: 	*p++ =PADDR (no_data);
 2970: 
 2971: 	assert ((char *)p == (char *)&scr->data_in + sizeof (scr->data_in));
 2972: 
 2973: 	p = scr->data_out;
 2974: 
 2975: 	*p++ =SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_OUT));
 2976: 	*p++ =PADDR (no_data);
 2977: 	*p++ =SCR_COPY (sizeof (ticks));
 2978: 	*p++ =(ncrcmd) KVAR (KVAR_TICKS);
 2979: 	*p++ =NADDR (header.stamp.data);
 2980: 	*p++ =SCR_MOVE_TBL ^ SCR_DATA_OUT;
 2981: 	*p++ =offsetof (struct dsb, data[ 0]);
 2982: 
 2983: 	for (i=1; i<MAX_SCATTER; i++) {
 2984: 		*p++ =SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_OUT));
 2985: 		*p++ =PADDR (dispatch);
 2986: 		*p++ =SCR_MOVE_TBL ^ SCR_DATA_OUT;
 2987: 		*p++ =offsetof (struct dsb, data[i]);
 2988: 	};
 2989: 
 2990: 	*p++ =SCR_CALL;
 2991: 	*p++ =PADDR (dispatch);
 2992: 	*p++ =SCR_JUMP;
 2993: 	*p++ =PADDR (no_data);
 2994: 
 2995: 	assert ((char *)p == (char *)&scr->data_out + sizeof (scr->data_out));
 2996: }
 2997: 
 2998: /*==========================================================
 2999: **
 3000: **
 3001: **	Copy and rebind a script.
 3002: **
 3003: **
 3004: **==========================================================
 3005: */
 3006: 
 3007: static void ncr_script_copy_and_bind (ncb_p np, ncrcmd *src, ncrcmd *dst, int len)
 3008: {
 3009: 	ncrcmd  opcode, new, old, tmp1, tmp2;
 3010: 	ncrcmd	*start, *end;
 3011: 	int relocs, offset;
 3012: 
 3013: 	start = src;
 3014: 	end = src + len/4;
 3015: 	offset = 0;
 3016: 
 3017: 	while (src < end) {
 3018: 
 3019: 		opcode = *src++;
 3020: 		WRITESCRIPT_OFF(dst, offset, opcode);
 3021: 		offset += 4;
 3022: 
 3023: 		/*
 3024: 		**	If we forget to change the length
 3025: 		**	in struct script, a field will be
 3026: 		**	padded with 0. This is an illegal
 3027: 		**	command.
 3028: 		*/
 3029: 
 3030: 		if (opcode == 0) {
 3031: 			printf ("%s: ERROR0 IN SCRIPT at %d.\n",
 3032: 				ncr_name(np), (int) (src-start-1));
 3033: 			DELAY (1000000);
 3034: 		};
 3035: 
 3036: 		if (DEBUG_FLAGS & DEBUG_SCRIPT)
 3037: 			printf ("%p:  <%x>\n",
 3038: 				(src-1), (unsigned)opcode);
 3039: 
 3040: 		/*
 3041: 		**	We don't have to decode ALL commands
 3042: 		*/
 3043: 		switch (opcode >> 28) {
 3044: 
 3045: 		case 0xc:
 3046: 			/*
 3047: 			**	COPY has TWO arguments.
 3048: 			*/
 3049: 			relocs = 2;
 3050: 			tmp1 = src[0];
 3051: 			if ((tmp1 & RELOC_MASK) == RELOC_KVAR)
 3052: 				tmp1 = 0;
 3053: 			tmp2 = src[1];
 3054: 			if ((tmp2 & RELOC_MASK) == RELOC_KVAR)
 3055: 				tmp2 = 0;
 3056: 			if ((tmp1 ^ tmp2) & 3) {
 3057: 				printf ("%s: ERROR1 IN SCRIPT at %d.\n",
 3058: 					ncr_name(np), (int) (src-start-1));
 3059: 				DELAY (1000000);
 3060: 			}
 3061: 			/*
 3062: 			**	If PREFETCH feature not enabled, remove 
 3063: 			**	the NO FLUSH bit if present.
 3064: 			*/
 3065: 			if ((opcode & SCR_NO_FLUSH) && !(np->features&FE_PFEN))
 3066: 				WRITESCRIPT_OFF(dst, offset - 4,
 3067: 				    (opcode & ~SCR_NO_FLUSH));
 3068: 			break;
 3069: 
 3070: 		case 0x0:
 3071: 			/*
 3072: 			**	MOVE (absolute address)
 3073: 			*/
 3074: 			relocs = 1;
 3075: 			break;
 3076: 
 3077: 		case 0x8:
 3078: 			/*
 3079: 			**	JUMP / CALL
 3080: 			**	dont't relocate if relative :-)
 3081: 			*/
 3082: 			if (opcode & 0x00800000)
 3083: 				relocs = 0;
 3084: 			else
 3085: 				relocs = 1;
 3086: 			break;
 3087: 
 3088: 		case 0x4:
 3089: 		case 0x5:
 3090: 		case 0x6:
 3091: 		case 0x7:
 3092: 			relocs = 1;
 3093: 			break;
 3094: 
 3095: 		default:
 3096: 			relocs = 0;
 3097: 			break;
 3098: 		};
 3099: 
 3100: 		if (relocs) {
 3101: 			while (relocs--) {
 3102: 				old = *src++;
 3103: 
 3104: 				switch (old & RELOC_MASK) {
 3105: 				case RELOC_REGISTER:
 3106: 					new = (old & ~RELOC_MASK) + rman_get_start(np->reg_res);
 3107: 					break;
 3108: 				case RELOC_LABEL:
 3109: 					new = (old & ~RELOC_MASK) + np->p_script;
 3110: 					break;
 3111: 				case RELOC_LABELH:
 3112: 					new = (old & ~RELOC_MASK) + np->p_scripth;
 3113: 					break;
 3114: 				case RELOC_SOFTC:
 3115: 					new = (old & ~RELOC_MASK) + vtophys(np);
 3116: 					break;
 3117: 				case RELOC_KVAR:
 3118: 					if (((old & ~RELOC_MASK) <
 3119: 					     SCRIPT_KVAR_FIRST) ||
 3120: 					    ((old & ~RELOC_MASK) >
 3121: 					     SCRIPT_KVAR_LAST))
 3122: 						panic("ncr KVAR out of range");
 3123: 					new = vtophys(script_kvars[old &
 3124: 					    ~RELOC_MASK]);
 3125: 					break;
 3126: 				case 0:
 3127: 					/* Don't relocate a 0 address. */
 3128: 					if (old == 0) {
 3129: 						new = old;
 3130: 						break;
 3131: 					}
 3132: 					/* fall through */
 3133: 				default:
 3134: 					panic("ncr_script_copy_and_bind: weird relocation %x @ %d\n", old, (int)(src - start));
 3135: 					break;
 3136: 				}
 3137: 
 3138: 				WRITESCRIPT_OFF(dst, offset, new);
 3139: 				offset += 4;
 3140: 			}
 3141: 		} else {
 3142: 			WRITESCRIPT_OFF(dst, offset, *src++);
 3143: 			offset += 4;
 3144: 		}
 3145: 
 3146: 	};
 3147: }
 3148: 
 3149: /*==========================================================
 3150: **
 3151: **
 3152: **      Auto configuration.
 3153: **
 3154: **
 3155: **==========================================================
 3156: */
 3157: 
 3158: #if 0
 3159: /*----------------------------------------------------------
 3160: **
 3161: **	Reduce the transfer length to the max value
 3162: **	we can transfer safely.
 3163: **
 3164: **      Reading a block greater then MAX_SIZE from the
 3165: **	raw (character) device exercises a memory leak
 3166: **	in the vm subsystem. This is common to ALL devices.
 3167: **	We have submitted a description of this bug to
 3168: **	<FreeBSD-bugs@freefall.cdrom.com>.
 3169: **	It should be fixed in the current release.
 3170: **
 3171: **----------------------------------------------------------
 3172: */
 3173: 
 3174: void ncr_min_phys (struct  buf *bp)
 3175: {
 3176: 	if ((unsigned long)bp->b_bcount > MAX_SIZE) bp->b_bcount = MAX_SIZE;
 3177: }
 3178: 
 3179: #endif
 3180: 
 3181: #if 0
 3182: /*----------------------------------------------------------
 3183: **
 3184: **	Maximal number of outstanding requests per target.
 3185: **
 3186: **----------------------------------------------------------
 3187: */
 3188: 
 3189: u_int32_t ncr_info (int unit)
 3190: {
 3191: 	return (1);   /* may be changed later */
 3192: }
 3193: 
 3194: #endif
 3195: 
 3196: /*----------------------------------------------------------
 3197: **
 3198: **	NCR chip devices table and chip look up function.
 3199: **	Features bit are defined in ncrreg.h. Is it the 
 3200: **	right place?
 3201: **
 3202: **----------------------------------------------------------
 3203: */
 3204: typedef struct {
 3205: 	unsigned long	device_id;
 3206: 	unsigned short	minrevid;
 3207: 	char	       *name;
 3208: 	unsigned char	maxburst;
 3209: 	unsigned char	maxoffs;
 3210: 	unsigned char	clock_divn;
 3211: 	unsigned int	features;
 3212: } ncr_chip;
 3213: 
 3214: static ncr_chip ncr_chip_table[] = {
 3215:  {NCR_810_ID, 0x00,	"ncr 53c810 fast10 scsi",		4,  8, 4,
 3216:  FE_ERL}
 3217:  ,
 3218:  {NCR_810_ID, 0x10,	"ncr 53c810a fast10 scsi",		4,  8, 4,
 3219:  FE_ERL|FE_LDSTR|FE_PFEN|FE_BOF}
 3220:  ,
 3221:  {NCR_815_ID, 0x00,	"ncr 53c815 fast10 scsi", 		4,  8, 4,
 3222:  FE_ERL|FE_BOF}
 3223:  ,
 3224:  {NCR_820_ID, 0x00,	"ncr 53c820 fast10 wide scsi", 		4,  8, 4,
 3225:  FE_WIDE|FE_ERL}
 3226:  ,
 3227:  {NCR_825_ID, 0x00,	"ncr 53c825 fast10 wide scsi",		4,  8, 4,
 3228:  FE_WIDE|FE_ERL|FE_BOF}
 3229:  ,
 3230:  {NCR_825_ID, 0x10,	"ncr 53c825a fast10 wide scsi",		7,  8, 4,
 3231:  FE_WIDE|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
 3232:  ,
 3233:  {NCR_860_ID, 0x00,	"ncr 53c860 fast20 scsi",		4,  8, 5,
 3234:  FE_ULTRA|FE_CLK80|FE_CACHE_SET|FE_LDSTR|FE_PFEN}
 3235:  ,
 3236:  {NCR_875_ID, 0x00,	"ncr 53c875 fast20 wide scsi",		7, 16, 5,
 3237:  FE_WIDE|FE_ULTRA|FE_CLK80|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
 3238:  ,
 3239:  {NCR_875_ID, 0x02,	"ncr 53c875 fast20 wide scsi",		7, 16, 5,
 3240:  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
 3241:  ,
 3242:  {NCR_875_ID2, 0x00,	"ncr 53c875j fast20 wide scsi",		7, 16, 5,
 3243:  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
 3244:  ,
 3245:  {NCR_885_ID, 0x00,	"ncr 53c885 fast20 wide scsi",		7, 16, 5,
 3246:  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
 3247:  ,
 3248:  {NCR_895_ID, 0x00,	"ncr 53c895 fast40 wide scsi",		7, 31, 7,
 3249:  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
 3250:  ,
 3251:  {NCR_896_ID, 0x00,	"ncr 53c896 fast40 wide scsi",		7, 31, 7,
 3252:  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
 3253:  ,
 3254:  {NCR_895A_ID, 0x00,	"ncr 53c895a fast40 wide scsi",		7, 31, 7,
 3255:  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
 3256:  ,
 3257:  {NCR_1510D_ID, 0x00,	"ncr 53c1510d fast40 wide scsi",	7, 31, 7,
 3258:  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}
 3259: };
 3260: 
 3261: static int ncr_chip_lookup(u_long device_id, u_char revision_id)
 3262: {
 3263: 	int i, found;
 3264: 	
 3265: 	found = -1;
 3266: 	for (i = 0; i < sizeof(ncr_chip_table)/sizeof(ncr_chip_table[0]); i++) {
 3267: 		if (device_id	== ncr_chip_table[i].device_id &&
 3268: 		    ncr_chip_table[i].minrevid <= revision_id) {
 3269: 			if (found < 0 || 
 3270: 			    ncr_chip_table[found].minrevid 
 3271: 			      < ncr_chip_table[i].minrevid) {
 3272: 				found = i;
 3273: 			}
 3274: 		}
 3275: 	}
 3276: 	return found;
 3277: }
 3278: 
 3279: /*----------------------------------------------------------
 3280: **
 3281: **	Probe the hostadapter.
 3282: **
 3283: **----------------------------------------------------------
 3284: */
 3285: 
 3286: 
 3287: 
 3288: static	int ncr_probe (device_t dev)
 3289: {
 3290: 	int i;
 3291: 
 3292: 	i = ncr_chip_lookup(pci_get_devid(dev), pci_get_revid(dev));
 3293: 	if (i >= 0) {
 3294: 		device_set_desc(dev, ncr_chip_table[i].name);
 3295: 		return (-1000);	/* Allows to use both ncr and sym */
 3296: 	}
 3297: 
 3298: 	return (ENXIO);
 3299: }
 3300: 
 3301: 
 3302: 
 3303: /*==========================================================
 3304: **
 3305: **	NCR chip clock divisor table.
 3306: **	Divisors are multiplied by 10,000,000 in order to make 
 3307: **	calculations more simple.
 3308: **
 3309: **==========================================================
 3310: */
 3311: 
 3312: #define _5M 5000000
 3313: static u_long div_10M[] =
 3314: 	{2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M};
 3315: 
 3316: /*===============================================================
 3317: **
 3318: **	NCR chips allow burst lengths of 2, 4, 8, 16, 32, 64, 128 
 3319: **	transfers. 32,64,128 are only supported by 875 and 895 chips.
 3320: **	We use log base 2 (burst length) as internal code, with 
 3321: **	value 0 meaning "burst disabled".
 3322: **
 3323: **===============================================================
 3324: */
 3325: 
 3326: /*
 3327:  *	Burst length from burst code.
 3328:  */
 3329: #define burst_length(bc) (!(bc))? 0 : 1 << (bc)
 3330: 
 3331: /*
 3332:  *	Burst code from io register bits.
 3333:  */
 3334: #define burst_code(dmode, ctest4, ctest5) \
 3335: 	(ctest4) & 0x80? 0 : (((dmode) & 0xc0) >> 6) + ((ctest5) & 0x04) + 1
 3336: 
 3337: /*
 3338:  *	Set initial io register bits from burst code.
 3339:  */
 3340: static void
 3341: ncr_init_burst(ncb_p np, u_char bc)
 3342: {
 3343: 	np->rv_ctest4	&= ~0x80;
 3344: 	np->rv_dmode	&= ~(0x3 << 6);
 3345: 	np->rv_ctest5	&= ~0x4;
 3346: 
 3347: 	if (!bc) {
 3348: 		np->rv_ctest4	|= 0x80;
 3349: 	}
 3350: 	else {
 3351: 		--bc;
 3352: 		np->rv_dmode	|= ((bc & 0x3) << 6);
 3353: 		np->rv_ctest5	|= (bc & 0x4);
 3354: 	}
 3355: }
 3356: 
 3357: /*==========================================================
 3358: **
 3359: **
 3360: **      Auto configuration:  attach and init a host adapter.
 3361: **
 3362: **
 3363: **==========================================================
 3364: */
 3365: 
 3366: 
 3367: static int
 3368: ncr_attach (device_t dev)
 3369: {
 3370: 	ncb_p np = (struct ncb*) device_get_softc(dev);
 3371: 	u_char	 rev = 0;
 3372: 	u_long	 period;
 3373: 	int	 i, rid;
 3374: 	u_int8_t usrsync;
 3375: 	u_int8_t usrwide;
 3376: 	struct cam_devq *devq;
 3377: 
 3378: 	/*
 3379: 	**	allocate and initialize structures.
 3380: 	*/
 3381: 
 3382: 	np->unit = device_get_unit(dev);
 3383: 
 3384: 	/*
 3385: 	**	Try to map the controller chip to
 3386: 	**	virtual and physical memory.
 3387: 	*/
 3388: 
 3389: 	np->reg_rid = 0x14;
 3390: 	np->reg_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &np->reg_rid,
 3391: 					 0, ~0, 1, RF_ACTIVE);
 3392: 	if (!np->reg_res) {
 3393: 		device_printf(dev, "could not map memory\n");
 3394: 		return ENXIO;
 3395: 	}
 3396: 
 3397: 	/*
 3398: 	**	Make the controller's registers available.
 3399: 	**	Now the INB INW INL OUTB OUTW OUTL macros
 3400: 	**	can be used safely.
 3401: 	*/
 3402: 
 3403: 	np->bst = rman_get_bustag(np->reg_res);
 3404: 	np->bsh = rman_get_bushandle(np->reg_res);
 3405: 
 3406: 
 3407: #ifdef NCR_IOMAPPED
 3408: 	/*
 3409: 	**	Try to map the controller chip into iospace.
 3410: 	*/
 3411: 
 3412: 	if (!pci_map_port (config_id, 0x10, &np->port))
 3413: 		return;
 3414: #endif
 3415: 
 3416: 
 3417: 	/*
 3418: 	**	Save some controller register default values
 3419: 	*/
 3420: 
 3421: 	np->rv_scntl3	= INB(nc_scntl3) & 0x77;
 3422: 	np->rv_dmode	= INB(nc_dmode)  & 0xce;
 3423: 	np->rv_dcntl	= INB(nc_dcntl)  & 0xa9;
 3424: 	np->rv_ctest3	= INB(nc_ctest3) & 0x01;
 3425: 	np->rv_ctest4	= INB(nc_ctest4) & 0x88;
 3426: 	np->rv_ctest5	= INB(nc_ctest5) & 0x24;
 3427: 	np->rv_gpcntl	= INB(nc_gpcntl);
 3428: 	np->rv_stest2	= INB(nc_stest2) & 0x20;
 3429: 
 3430: 	if (bootverbose >= 2) {
 3431: 		printf ("\tBIOS values:  SCNTL3:%02x DMODE:%02x  DCNTL:%02x\n",
 3432: 			np->rv_scntl3, np->rv_dmode, np->rv_dcntl);
 3433: 		printf ("\t              CTEST3:%02x CTEST4:%02x CTEST5:%02x\n",
 3434: 			np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
 3435: 	}
 3436: 
 3437: 	np->rv_dcntl  |= NOCOM;
 3438: 
 3439: 	/*
 3440: 	**	Do chip dependent initialization.
 3441: 	*/
 3442: 
 3443: 	rev = pci_get_revid(dev);
 3444: 
 3445: 	/*
 3446: 	**	Get chip features from chips table.
 3447: 	*/
 3448: 	i = ncr_chip_lookup(pci_get_devid(dev), rev);
 3449: 
 3450: 	if (i >= 0) {
 3451: 		np->maxburst	= ncr_chip_table[i].maxburst;
 3452: 		np->maxoffs	= ncr_chip_table[i].maxoffs;
 3453: 		np->clock_divn	= ncr_chip_table[i].clock_divn;
 3454: 		np->features	= ncr_chip_table[i].features;
 3455: 	} else {	/* Should'nt happen if probe() is ok */
 3456: 		np->maxburst	= 4;
 3457: 		np->maxoffs	= 8;
 3458: 		np->clock_divn	= 4;
 3459: 		np->features	= FE_ERL;
 3460: 	}
 3461: 
 3462: 	np->maxwide	= np->features & FE_WIDE ? 1 : 0;
 3463: 	np->clock_khz	= np->features & FE_CLK80 ? 80000 : 40000;
 3464: 	if	(np->features & FE_QUAD)	np->multiplier = 4;
 3465: 	else if	(np->features & FE_DBLR)	np->multiplier = 2;
 3466: 	else					np->multiplier = 1;
 3467: 
 3468: 	/*
 3469: 	**	Get the frequency of the chip's clock.
 3470: 	**	Find the right value for scntl3.
 3471: 	*/
 3472: 	if (np->features & (FE_ULTRA|FE_ULTRA2))
 3473: 		ncr_getclock(np, np->multiplier);
 3474: 
 3475: #ifdef NCR_TEKRAM_EEPROM
 3476: 	if (bootverbose) {
 3477: 		printf ("%s: Tekram EEPROM read %s\n",
 3478: 			ncr_name(np),
 3479: 			read_tekram_eeprom (np, NULL) ?
 3480: 			"succeeded" : "failed");
 3481: 	}
 3482: #endif /* NCR_TEKRAM_EEPROM */
 3483: 
 3484: 	/*
 3485: 	 *	If scntl3 != 0, we assume BIOS is present.
 3486: 	 */
 3487: 	if (np->rv_scntl3)
 3488: 		np->features |= FE_BIOS;
 3489: 
 3490: 	/*
 3491: 	 * Divisor to be used for async (timer pre-scaler).
 3492: 	 */
 3493: 	i = np->clock_divn - 1;
 3494: 	while (i >= 0) {
 3495: 		--i;
 3496: 		if (10ul * SCSI_NCR_MIN_ASYNC * np->clock_khz > div_10M[i]) {
 3497: 			++i;
 3498: 			break;
 3499: 		}
 3500: 	}
 3501: 	np->rv_scntl3 = i+1;
 3502: 
 3503: 	/*
 3504: 	 * Minimum synchronous period factor supported by the chip.
 3505: 	 * Btw, 'period' is in tenths of nanoseconds.
 3506: 	 */
 3507: 
 3508: 	period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;
 3509: 	if	(period <= 250)		np->minsync = 10;
 3510: 	else if	(period <= 303)		np->minsync = 11;
 3511: 	else if	(period <= 500)		np->minsync = 12;
 3512: 	else				np->minsync = (period + 40 - 1) / 40;
 3513: 
 3514: 	/*
 3515: 	 * Check against chip SCSI standard support (SCSI-2,ULTRA,ULTRA2).
 3516: 	 */
 3517: 
 3518: 	if	(np->minsync < 25 && !(np->features & (FE_ULTRA|FE_ULTRA2)))
 3519: 		np->minsync = 25;
 3520: 	else if	(np->minsync < 12 && !(np->features & FE_ULTRA2))
 3521: 		np->minsync = 12;
 3522: 
 3523: 	/*
 3524: 	 * Maximum synchronous period factor supported by the chip.
 3525: 	 */
 3526: 
 3527: 	period = (11 * div_10M[np->clock_divn - 1]) / (4 * np->clock_khz);
 3528: 	np->maxsync = period > 2540 ? 254 : period / 10;
 3529: 
 3530: 	/*
 3531: 	 * Now, some features available with Symbios compatible boards.
 3532: 	 * LED support through GPIO0 and DIFF support.
 3533: 	 */
 3534: 
 3535: #ifdef	SCSI_NCR_SYMBIOS_COMPAT
 3536: 	if (!(np->rv_gpcntl & 0x01))
 3537: 		np->features |= FE_LED0;
 3538: #if 0	/* Not safe enough without NVRAM support or user settable option */
 3539: 	if (!(INB(nc_gpreg) & 0x08))
 3540: 		np->features |= FE_DIFF;
 3541: #endif
 3542: #endif	/* SCSI_NCR_SYMBIOS_COMPAT */
 3543: 
 3544: 	/*
 3545: 	 * Prepare initial IO registers settings.
 3546: 	 * Trust BIOS only if we believe we have one and if we want to.
 3547: 	 */
 3548: #ifdef	SCSI_NCR_TRUST_BIOS
 3549: 	if (!(np->features & FE_BIOS)) {
 3550: #else
 3551: 	if (1) {
 3552: #endif
 3553: 		np->rv_dmode = 0;
 3554: 		np->rv_dcntl = NOCOM;
 3555: 		np->rv_ctest3 = 0;
 3556: 		np->rv_ctest4 = MPEE;
 3557: 		np->rv_ctest5 = 0;
 3558: 		np->rv_stest2 = 0;
 3559: 
 3560: 		if (np->features & FE_ERL)
 3561: 			np->rv_dmode 	|= ERL;	  /* Enable Read Line */
 3562: 		if (np->features & FE_BOF)
 3563: 			np->rv_dmode 	|= BOF;	  /* Burst Opcode Fetch */
 3564: 		if (np->features & FE_ERMP)
 3565: 			np->rv_dmode	|= ERMP;  /* Enable Read Multiple */
 3566: 		if (np->features & FE_CLSE)
 3567: 			np->rv_dcntl	|= CLSE;  /* Cache Line Size Enable */
 3568: 		if (np->features & FE_WRIE)
 3569: 			np->rv_ctest3	|= WRIE;  /* Write and Invalidate */
 3570: 		if (np->features & FE_PFEN)
 3571: 			np->rv_dcntl	|= PFEN;  /* Prefetch Enable */
 3572: 		if (np->features & FE_DFS)
 3573: 			np->rv_ctest5	|= DFS;	  /* Dma Fifo Size */
 3574: 		if (np->features & FE_DIFF)	
 3575: 			np->rv_stest2	|= 0x20;  /* Differential mode */
 3576: 		ncr_init_burst(np, np->maxburst); /* Max dwords burst length */
 3577: 	} else {
 3578: 		np->maxburst =
 3579: 			burst_code(np->rv_dmode, np->rv_ctest4, np->rv_ctest5);
 3580: 	}
 3581: 
 3582: 	/*
 3583: 	**	Get on-chip SRAM address, if supported
 3584: 	*/
 3585: 	if ((np->features & FE_RAM) && sizeof(struct script) <= 4096) {
 3586: 		np->sram_rid = 0x18;
 3587: 		np->sram_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
 3588: 						  &np->sram_rid,
 3589: 						  0, ~0, 1, RF_ACTIVE);
 3590: 	}
 3591: 
 3592: 	/*
 3593: 	**	Allocate structure for script relocation.
 3594: 	*/
 3595: 	if (np->sram_res != NULL) {
 3596: 		np->script = NULL;
 3597: 		np->p_script = rman_get_start(np->sram_res);
 3598: 		np->bst2 = rman_get_bustag(np->sram_res);
 3599: 		np->bsh2 = rman_get_bushandle(np->sram_res);
 3600: 	} else if (sizeof (struct script) > PAGE_SIZE) {
 3601: 		np->script  = (struct script*) vm_page_alloc_contig 
 3602: 			(round_page(sizeof (struct script)), 
 3603: 			 0, 0xffffffff, PAGE_SIZE);
 3604: 	} else {
 3605: 		np->script  = (struct script *)
 3606: 			malloc (sizeof (struct script), M_DEVBUF, M_WAITOK);
 3607: 	}
 3608: 
 3609: 	/* XXX JGibbs - Use contigmalloc */
 3610: 	if (sizeof (struct scripth) > PAGE_SIZE) {
 3611: 		np->scripth = (struct scripth*) vm_page_alloc_contig 
 3612: 			(round_page(sizeof (struct scripth)), 
 3613: 			 0, 0xffffffff, PAGE_SIZE);
 3614: 	} else 
 3615: 		{
 3616: 		np->scripth = (struct scripth *)
 3617: 			malloc (sizeof (struct scripth), M_DEVBUF, M_WAITOK);
 3618: 	}
 3619: 
 3620: #ifdef SCSI_NCR_PCI_CONFIG_FIXUP
 3621: 	/*
 3622: 	**	If cache line size is enabled, check PCI config space and 
 3623: 	**	try to fix it up if necessary.
 3624: 	*/
 3625: #ifdef PCIR_CACHELNSZ	/* To be sure that new PCI stuff is present */
 3626: 	{
 3627: 		u_char cachelnsz = pci_read_config(dev, PCIR_CACHELNSZ, 1);
 3628: 		u_short command  = pci_read_config(dev, PCIR_COMMAND, 2);
 3629: 
 3630: 		if (!cachelnsz) {
 3631: 			cachelnsz = 8;
 3632: 			printf("%s: setting PCI cache line size register to %d.\n",
 3633: 				ncr_name(np), (int)cachelnsz);
 3634: 			pci_write_config(dev, PCIR_CACHELNSZ, cachelnsz, 1);
 3635: 		}
 3636: 
 3637: 		if (!(command & (1<<4))) {
 3638: 			command |= (1<<4);
 3639: 			printf("%s: setting PCI command write and invalidate.\n",
 3640: 				ncr_name(np));
 3641: 			pci_write_config(dev, PCIR_COMMAND, command, 2);
 3642: 		}
 3643: 	}
 3644: #endif /* PCIR_CACHELNSZ */
 3645: 
 3646: #endif /* SCSI_NCR_PCI_CONFIG_FIXUP */
 3647: 
 3648: 	/* Initialize per-target user settings */
 3649: 	usrsync = 0;
 3650: 	if (SCSI_NCR_DFLT_SYNC) {
 3651: 		usrsync = SCSI_NCR_DFLT_SYNC;
 3652: 		if (usrsync > np->maxsync)
 3653: 			usrsync = np->maxsync;
 3654: 		if (usrsync < np->minsync)
 3655: 			usrsync = np->minsync;
 3656: 	};
 3657: 
 3658: 	usrwide = (SCSI_NCR_MAX_WIDE);
 3659: 	if (usrwide > np->maxwide) usrwide=np->maxwide;
 3660: 
 3661: 	for (i=0;i<MAX_TARGET;i++) {
 3662: 		tcb_p tp = &np->target[i];
 3663: 
 3664: 		tp->tinfo.user.period = usrsync;
 3665: 		tp->tinfo.user.offset = usrsync != 0 ? np->maxoffs : 0;
 3666: 		tp->tinfo.user.width = usrwide;
 3667: 		tp->tinfo.disc_tag = NCR_CUR_DISCENB
 3668: 				   | NCR_CUR_TAGENB
 3669: 				   | NCR_USR_DISCENB
 3670: 				   | NCR_USR_TAGENB;
 3671: 	}
 3672: 
 3673: 	/*
 3674: 	**	Bells and whistles   ;-)
 3675: 	*/
 3676: 	if (bootverbose)
 3677: 		printf("%s: minsync=%d, maxsync=%d, maxoffs=%d, %d dwords burst, %s dma fifo\n",
 3678: 		ncr_name(np), np->minsync, np->maxsync, np->maxoffs,
 3679: 		burst_length(np->maxburst),
 3680: 		(np->rv_ctest5 & DFS) ? "large" : "normal");
 3681: 
 3682: 	/*
 3683: 	**	Print some complementary information that can be helpfull.
 3684: 	*/
 3685: 	if (bootverbose)
 3686: 		printf("%s: %s, %s IRQ driver%s\n",
 3687: 			ncr_name(np),
 3688: 			np->rv_stest2 & 0x20 ? "differential" : "single-ended",
 3689: 			np->rv_dcntl & IRQM ? "totem pole" : "open drain",
 3690: 			np->sram_res ? ", using on-chip SRAM" : "");
 3691: 			
 3692: 	/*
 3693: 	**	Patch scripts to physical addresses
 3694: 	*/
 3695: 	ncr_script_fill (&script0, &scripth0);
 3696: 
 3697: 	if (np->script)
 3698: 		np->p_script	= vtophys(np->script);
 3699: 	np->p_scripth	= vtophys(np->scripth);
 3700: 
 3701: 	ncr_script_copy_and_bind (np, (ncrcmd *) &script0,
 3702: 			(ncrcmd *) np->script, sizeof(struct script));
 3703: 
 3704: 	ncr_script_copy_and_bind (np, (ncrcmd *) &scripth0,
 3705: 		(ncrcmd *) np->scripth, sizeof(struct scripth));
 3706: 
 3707: 	/*
 3708: 	**    Patch the script for LED support.
 3709: 	*/
 3710: 
 3711: 	if (np->features & FE_LED0) {
 3712: 		WRITESCRIPT(reselect[0],  SCR_REG_REG(gpreg, SCR_OR,  0x01));
 3713: 		WRITESCRIPT(reselect1[0], SCR_REG_REG(gpreg, SCR_AND, 0xfe));
 3714: 		WRITESCRIPT(reselect2[0], SCR_REG_REG(gpreg, SCR_AND, 0xfe));
 3715: 	}
 3716: 
 3717: 	/*
 3718: 	**	init data structure
 3719: 	*/
 3720: 
 3721: 	np->jump_tcb.l_cmd	= SCR_JUMP;
 3722: 	np->jump_tcb.l_paddr	= NCB_SCRIPTH_PHYS (np, abort);
 3723: 
 3724: 	/*
 3725: 	**  Get SCSI addr of host adapter (set by bios?).
 3726: 	*/
 3727: 
 3728: 	np->myaddr = INB(nc_scid) & 0x07;
 3729: 	if (!np->myaddr) np->myaddr = SCSI_NCR_MYADDR;
 3730: 
 3731: #ifdef NCR_DUMP_REG
 3732: 	/*
 3733: 	**	Log the initial register contents
 3734: 	*/
 3735: 	{
 3736: 		int reg;
 3737: 		for (reg=0; reg<256; reg+=4) {
 3738: 			if (reg%16==0) printf ("reg[%2x]", reg);
 3739: 			printf (" %08x", (int)pci_conf_read (config_id, reg));
 3740: 			if (reg%16==12) printf ("\n");
 3741: 		}
 3742: 	}
 3743: #endif /* NCR_DUMP_REG */
 3744: 
 3745: 	/*
 3746: 	**	Reset chip.
 3747: 	*/
 3748: 
 3749: 	OUTB (nc_istat,  SRST);
 3750: 	DELAY (1000);
 3751: 	OUTB (nc_istat,  0   );
 3752: 
 3753: 
 3754: 	/*
 3755: 	**	Now check the cache handling of the pci chipset.
 3756: 	*/
 3757: 
 3758: 	if (ncr_snooptest (np)) {
 3759: 		printf ("CACHE INCORRECTLY CONFIGURED.\n");
 3760: 		return EINVAL;
 3761: 	};
 3762: 
 3763: 	/*
 3764: 	**	Install the interrupt handler.
 3765: 	*/
 3766: 
 3767: 	rid = 0;
 3768: 	np->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
 3769: 					 RF_SHAREABLE | RF_ACTIVE);
 3770: 	if (np->irq_res == NULL) {
 3771: 		device_printf(dev,
 3772: 			      "interruptless mode: reduced performance.\n");
 3773: 	} else {
 3774: 		bus_setup_intr(dev, np->irq_res, INTR_TYPE_CAM,
 3775: 			       ncr_intr, np, &np->irq_handle);
 3776: 	}
 3777: 
 3778: 	/*
 3779: 	** Create the device queue.  We only allow MAX_START-1 concurrent
 3780: 	** transactions so we can be sure to have one element free in our
 3781: 	** start queue to reset to the idle loop.
 3782: 	*/
 3783: 	devq = cam_simq_alloc(MAX_START - 1);
 3784: 	if (devq == NULL)
 3785: 		return ENOMEM;
 3786: 
 3787: 	/*
 3788: 	**	Now tell the generic SCSI layer
 3789: 	**	about our bus.
 3790: 	*/
 3791: 	np->sim = cam_sim_alloc(ncr_action, ncr_poll, "ncr", np, np->unit,
 3792: 				1, MAX_TAGS, devq);
 3793: 	if (np->sim == NULL) {
 3794: 		cam_simq_free(devq);
 3795: 		return ENOMEM;
 3796: 	}
 3797: 
 3798: 	
 3799: 	if (xpt_bus_register(np->sim, 0) != CAM_SUCCESS) {
 3800: 		cam_sim_free(np->sim, /*free_devq*/ TRUE);
 3801: 		return ENOMEM;
 3802: 	}
 3803: 	
 3804: 	if (xpt_create_path(&np->path, /*periph*/NULL,
 3805: 			    cam_sim_path(np->sim), CAM_TARGET_WILDCARD,
 3806: 			    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
 3807: 		xpt_bus_deregister(cam_sim_path(np->sim));
 3808: 		cam_sim_free(np->sim, /*free_devq*/TRUE);
 3809: 		return ENOMEM;
 3810: 	}
 3811: 
 3812: 	/*
 3813: 	**	start the timeout daemon
 3814: 	*/
 3815: 	ncr_timeout (np);
 3816: 	np->lasttime=0;
 3817: 
 3818: 	return 0;
 3819: }
 3820: 
 3821: /*==========================================================
 3822: **
 3823: **
 3824: **	Process pending device interrupts.
 3825: **
 3826: **
 3827: **==========================================================
 3828: */
 3829: 
 3830: static void
 3831: ncr_intr(vnp)
 3832: 	void *vnp;
 3833: {
 3834: 	ncb_p np = vnp;
 3835: 	int oldspl = splcam();
 3836: 
 3837: 	if (DEBUG_FLAGS & DEBUG_TINY) printf ("[");
 3838: 
 3839: 	if (INB(nc_istat) & (INTF|SIP|DIP)) {
 3840: 		/*
 3841: 		**	Repeat until no outstanding ints
 3842: 		*/
 3843: 		do {
 3844: 			ncr_exception (np);
 3845: 		} while (INB(nc_istat) & (INTF|SIP|DIP));
 3846: 
 3847: 		np->ticks = 100;
 3848: 	};
 3849: 
 3850: 	if (DEBUG_FLAGS & DEBUG_TINY) printf ("]\n");
 3851: 
 3852: 	splx (oldspl);
 3853: }
 3854: 
 3855: /*==========================================================
 3856: **
 3857: **
 3858: **	Start execution of a SCSI command.
 3859: **	This is called from the generic SCSI driver.
 3860: **
 3861: **
 3862: **==========================================================
 3863: */
 3864: 
 3865: static void
 3866: ncr_action (struct cam_sim *sim, union ccb *ccb)
 3867: {
 3868: 	ncb_p np;
 3869: 
 3870: 	np = (ncb_p) cam_sim_softc(sim);
 3871: 
 3872: 	switch (ccb->ccb_h.func_code) {
 3873: 	/* Common cases first */
 3874: 	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
 3875: 	{
 3876: 		nccb_p cp;
 3877: 		lcb_p lp;
 3878: 		tcb_p tp;
 3879: 		int oldspl;
 3880: 		struct ccb_scsiio *csio;
 3881: 		u_int8_t *msgptr;
 3882: 		u_int msglen;
 3883: 		u_int msglen2;
 3884: 		int segments;
 3885: 		u_int8_t nego;
 3886: 		u_int8_t idmsg;
 3887: 		int qidx;
 3888: 		
 3889: 		tp = &np->target[ccb->ccb_h.target_id];
 3890: 		csio = &ccb->csio;
 3891: 
 3892: 		oldspl = splcam();
 3893: 
 3894: 		/*
 3895: 		 * Last time we need to check if this CCB needs to
 3896: 		 * be aborted.
 3897: 		 */
 3898: 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
 3899: 			xpt_done(ccb);
 3900: 			splx(oldspl);
 3901: 			return;
 3902: 		}
 3903: 		ccb->ccb_h.status |= CAM_SIM_QUEUED;
 3904: 
 3905: 		/*---------------------------------------------------
 3906: 		**
 3907: 		**	Assign an nccb / bind ccb
 3908: 		**
 3909: 		**----------------------------------------------------
 3910: 		*/
 3911: 		cp = ncr_get_nccb (np, ccb->ccb_h.target_id,
 3912: 				   ccb->ccb_h.target_lun);
 3913: 		if (cp == NULL) {
 3914: 			/* XXX JGibbs - Freeze SIMQ */
 3915: 			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 3916: 			xpt_done(ccb);
 3917: 			return;
 3918: 		};
 3919: 		
 3920: 		cp->ccb = ccb;
 3921: 		
 3922: 		/*---------------------------------------------------
 3923: 		**
 3924: 		**	timestamp
 3925: 		**
 3926: 		**----------------------------------------------------
 3927: 		*/
 3928: 		/*
 3929: 		** XXX JGibbs - Isn't this expensive
 3930: 		**		enough to be conditionalized??
 3931: 		*/
 3932: 
 3933: 		bzero (&cp->phys.header.stamp, sizeof (struct tstamp));
 3934: 		cp->phys.header.stamp.start = ticks;
 3935: 
 3936: 		nego = 0;
 3937: 		if (tp->nego_cp == NULL) {
 3938: 			
 3939: 			if (tp->tinfo.current.width
 3940: 			 != tp->tinfo.goal.width) {
 3941: 				tp->nego_cp = cp;
 3942: 				nego = NS_WIDE;
 3943: 			} else if ((tp->tinfo.current.period
 3944: 				    != tp->tinfo.goal.period)
 3945: 				|| (tp->tinfo.current.offset
 3946: 				    != tp->tinfo.goal.offset)) {
 3947: 				tp->nego_cp = cp;
 3948: 				nego = NS_SYNC;
 3949: 			};
 3950: 		};
 3951: 
 3952: 		/*---------------------------------------------------
 3953: 		**
 3954: 		**	choose a new tag ...
 3955: 		**
 3956: 		**----------------------------------------------------
 3957: 		*/
 3958: 		lp = tp->lp[ccb->ccb_h.target_lun];
 3959: 
 3960: 		if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0
 3961: 		 && (ccb->csio.tag_action != CAM_TAG_ACTION_NONE)
 3962: 		 && (nego == 0)) {
 3963: 			/*
 3964: 			**	assign a tag to this nccb
 3965: 			*/
 3966: 			while (!cp->tag) {
 3967: 				nccb_p cp2 = lp->next_nccb;
 3968: 				lp->lasttag = lp->lasttag % 255 + 1;
 3969: 				while (cp2 && cp2->tag != lp->lasttag)
 3970: 					cp2 = cp2->next_nccb;
 3971: 				if (cp2) continue;
 3972: 				cp->tag=lp->lasttag;
 3973: 				if (DEBUG_FLAGS & DEBUG_TAGS) {
 3974: 					PRINT_ADDR(ccb);
 3975: 					printf ("using tag #%d.\n", cp->tag);
 3976: 				};
 3977: 			};
 3978: 		} else {
 3979: 			cp->tag=0;
 3980: 		};
 3981: 
 3982: 		/*----------------------------------------------------
 3983: 		**
 3984: 		**	Build the identify / tag / sdtr message
 3985: 		**
 3986: 		**----------------------------------------------------
 3987: 		*/
 3988: 		idmsg = MSG_IDENTIFYFLAG | ccb->ccb_h.target_lun;
 3989: 		if (tp->tinfo.disc_tag & NCR_CUR_DISCENB)
 3990: 			idmsg |= MSG_IDENTIFY_DISCFLAG;
 3991: 
 3992: 		msgptr = cp->scsi_smsg;
 3993: 		msglen = 0;
 3994: 		msgptr[msglen++] = idmsg;
 3995: 
 3996: 		if (cp->tag) {
 3997: 	    		msgptr[msglen++] = ccb->csio.tag_action;
 3998: 			msgptr[msglen++] = cp->tag;
 3999: 		}
 4000: 
 4001: 		switch (nego) {
 4002: 		case NS_SYNC:
 4003: 			msgptr[msglen++] = MSG_EXTENDED;
 4004: 			msgptr[msglen++] = MSG_EXT_SDTR_LEN;
 4005: 			msgptr[msglen++] = MSG_EXT_SDTR;
 4006: 			msgptr[msglen++] = tp->tinfo.goal.period;
 4007: 			msgptr[msglen++] = tp->tinfo.goal.offset;;
 4008: 			if (DEBUG_FLAGS & DEBUG_NEGO) {
 4009: 				PRINT_ADDR(ccb);
 4010: 				printf ("sync msgout: ");
 4011: 				ncr_show_msg (&cp->scsi_smsg [msglen-5]);
 4012: 				printf (".\n");
 4013: 			};
 4014: 			break;
 4015: 		case NS_WIDE:
 4016: 			msgptr[msglen++] = MSG_EXTENDED;
 4017: 			msgptr[msglen++] = MSG_EXT_WDTR_LEN;
 4018: 			msgptr[msglen++] = MSG_EXT_WDTR;
 4019: 			msgptr[msglen++] = tp->tinfo.goal.width;
 4020: 			if (DEBUG_FLAGS & DEBUG_NEGO) {
 4021: 				PRINT_ADDR(ccb);
 4022: 				printf ("wide msgout: ");
 4023: 				ncr_show_msg (&cp->scsi_smsg [msglen-4]);
 4024: 				printf (".\n");
 4025: 			};
 4026: 			break;
 4027: 		};
 4028: 
 4029: 		/*----------------------------------------------------
 4030: 		**
 4031: 		**	Build the identify message for getcc.
 4032: 		**
 4033: 		**----------------------------------------------------
 4034: 		*/
 4035: 
 4036: 		cp->scsi_smsg2 [0] = idmsg;
 4037: 		msglen2 = 1;
 4038: 
 4039: 		/*----------------------------------------------------
 4040: 		**
 4041: 		**	Build the data descriptors
 4042: 		**
 4043: 		**----------------------------------------------------
 4044: 		*/
 4045: 
 4046: 		/* XXX JGibbs - Handle other types of I/O */
 4047: 		if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
 4048: 			segments = ncr_scatter(&cp->phys,
 4049: 					       (vm_offset_t)csio->data_ptr,
 4050: 					       (vm_size_t)csio->dxfer_len);
 4051: 
 4052: 			if (segments < 0) {
 4053: 				ccb->ccb_h.status = CAM_REQ_TOO_BIG;
 4054: 				ncr_free_nccb(np, cp);
 4055: 				splx(oldspl);
 4056: 				xpt_done(ccb);
 4057: 				return;
 4058: 			}
 4059: 			if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
 4060: 				cp->phys.header.savep = NCB_SCRIPT_PHYS (np, data_in);
 4061: 				cp->phys.header.goalp = cp->phys.header.savep +20 +segments*16;
 4062: 			} else { /* CAM_DIR_OUT */
 4063: 				cp->phys.header.savep = NCB_SCRIPT_PHYS (np, data_out);
 4064: 				cp->phys.header.goalp = cp->phys.header.savep +20 +segments*16;
 4065: 			}
 4066: 		} else {
 4067: 			cp->phys.header.savep = NCB_SCRIPT_PHYS (np, no_data);
 4068: 			cp->phys.header.goalp = cp->phys.header.savep;
 4069: 		}
 4070: 
 4071: 		cp->phys.header.lastp = cp->phys.header.savep;
 4072: 
 4073: 
 4074: 		/*----------------------------------------------------
 4075: 		**
 4076: 		**	fill in nccb
 4077: 		**
 4078: 		**----------------------------------------------------
 4079: 		**
 4080: 		**
 4081: 		**	physical -> virtual backlink
 4082: 		**	Generic SCSI command
 4083: 		*/
 4084: 		cp->phys.header.cp		= cp;
 4085: 		/*
 4086: 		**	Startqueue
 4087: 		*/
 4088: 		cp->phys.header.launch.l_paddr	= NCB_SCRIPT_PHYS (np, select);
 4089: 		cp->phys.header.launch.l_cmd	= SCR_JUMP;
 4090: 		/*
 4091: 		**	select
 4092: 		*/
 4093: 		cp->phys.select.sel_id		= ccb->ccb_h.target_id;
 4094: 		cp->phys.select.sel_scntl3	= tp->tinfo.wval;
 4095: 		cp->phys.select.sel_sxfer	= tp->tinfo.sval;
 4096: 		/*
 4097: 		**	message
 4098: 		*/
 4099: 		cp->phys.smsg.addr		= CCB_PHYS (cp, scsi_smsg);
 4100: 		cp->phys.smsg.size		= msglen;
 4101: 	
 4102: 		cp->phys.smsg2.addr		= CCB_PHYS (cp, scsi_smsg2);
 4103: 		cp->phys.smsg2.size		= msglen2;
 4104: 		/*
 4105: 		**	command
 4106: 		*/
 4107: 		/* XXX JGibbs - Support other command types */
 4108: 		cp->phys.cmd.addr		= vtophys (csio->cdb_io.cdb_bytes);
 4109: 		cp->phys.cmd.size		= csio->cdb_len;
 4110: 		/*
 4111: 		**	sense command
 4112: 		*/
 4113: 		cp->phys.scmd.addr		= CCB_PHYS (cp, sensecmd);
 4114: 		cp->phys.scmd.size		= 6;
 4115: 		/*
 4116: 		**	patch requested size into sense command
 4117: 		*/
 4118: 		cp->sensecmd[0]			= 0x03;
 4119: 		cp->sensecmd[1]			= ccb->ccb_h.target_lun << 5;
 4120: 		cp->sensecmd[4]			= sizeof(struct scsi_sense_data);
 4121: 		cp->sensecmd[4]			= csio->sense_len;
 4122: 		/*
 4123: 		**	sense data
 4124: 		*/
 4125: 		cp->phys.sense.addr		= vtophys (&csio->sense_data);
 4126: 		cp->phys.sense.size		= csio->sense_len;
 4127: 		/*
 4128: 		**	status
 4129: 		*/
 4130: 		cp->actualquirks		= QUIRK_NOMSG;
 4131: 		cp->host_status			= nego ? HS_NEGOTIATE : HS_BUSY;
 4132: 		cp->s_status			= SCSI_STATUS_ILLEGAL;
 4133: 		cp->parity_status		= 0;
 4134: 	
 4135: 		cp->xerr_status			= XE_OK;
 4136: 		cp->sync_status			= tp->tinfo.sval;
 4137: 		cp->nego_status			= nego;
 4138: 		cp->wide_status			= tp->tinfo.wval;
 4139: 
 4140: 		/*----------------------------------------------------
 4141: 		**
 4142: 		**	Critical region: start this job.
 4143: 		**
 4144: 		**----------------------------------------------------
 4145: 		*/
 4146: 
 4147: 		/*
 4148: 		**	reselect pattern and activate this job.
 4149: 		*/
 4150: 
 4151: 		cp->jump_nccb.l_cmd	= (SCR_JUMP ^ IFFALSE (DATA (cp->tag)));
 4152: 		cp->tlimit		= time_second
 4153: 					+ ccb->ccb_h.timeout / 1000 + 2;
 4154: 		cp->magic		= CCB_MAGIC;
 4155: 
 4156: 		/*
 4157: 		**	insert into start queue.
 4158: 		*/
 4159: 
 4160: 		qidx = np->squeueput + 1;
 4161: 		if (qidx >= MAX_START)
 4162: 			qidx = 0;
 4163: 		np->squeue [qidx	 ] = NCB_SCRIPT_PHYS (np, idle);
 4164: 		np->squeue [np->squeueput] = CCB_PHYS (cp, phys);
 4165: 		np->squeueput = qidx;
 4166: 
 4167: 		if(DEBUG_FLAGS & DEBUG_QUEUE)
 4168: 			printf("%s: queuepos=%d tryoffset=%d.\n",
 4169: 			       ncr_name (np), np->squeueput,
 4170: 			       (unsigned)(READSCRIPT(startpos[0]) - 
 4171: 			       (NCB_SCRIPTH_PHYS (np, tryloop))));
 4172: 
 4173: 		/*
 4174: 		**	Script processor may be waiting for reselect.
 4175: 		**	Wake it up.
 4176: 		*/
 4177: 		OUTB (nc_istat, SIGP);
 4178: 
 4179: 		/*
 4180: 		**	and reenable interrupts
 4181: 		*/
 4182: 		splx (oldspl);
 4183: 		break;
 4184: 	}
 4185: 	case XPT_RESET_DEV:	/* Bus Device Reset the specified SCSI device */
 4186: 	case XPT_EN_LUN:		/* Enable LUN as a target */
 4187: 	case XPT_TARGET_IO:		/* Execute target I/O request */
 4188: 	case XPT_ACCEPT_TARGET_IO:	/* Accept Host Target Mode CDB */
 4189: 	case XPT_CONT_TARGET_IO:	/* Continue Host Target I/O Connection*/
 4190: 	case XPT_ABORT:			/* Abort the specified CCB */
 4191: 		/* XXX Implement */
 4192: 		ccb->ccb_h.status = CAM_REQ_INVALID;
 4193: 		xpt_done(ccb);
 4194: 		break;
 4195: 	case XPT_SET_TRAN_SETTINGS:
 4196: 	{
 4197: 		struct	ccb_trans_settings *cts;
 4198: 		tcb_p	tp;
 4199: 		u_int	update_type;
 4200: 		int	s;
 4201: 
 4202: 		cts = &ccb->cts;
 4203: 		update_type = 0;
 4204: 		if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
 4205: 			update_type |= NCR_TRANS_GOAL;
 4206: 		if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
 4207: 			update_type |= NCR_TRANS_USER;
 4208: 		
 4209: 		s = splcam();
 4210: 		tp = &np->target[ccb->ccb_h.target_id];
 4211: 		/* Tag and disc enables */
 4212: 		if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
 4213: 			if (update_type & NCR_TRANS_GOAL) {
 4214: 				if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
 4215: 					tp->tinfo.disc_tag |= NCR_CUR_DISCENB;
 4216: 				else
 4217: 					tp->tinfo.disc_tag &= ~NCR_CUR_DISCENB;
 4218: 			}
 4219: 
 4220: 			if (update_type & NCR_TRANS_USER) {
 4221: 				if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
 4222: 					tp->tinfo.disc_tag |= NCR_USR_DISCENB;
 4223: 				else
 4224: 					tp->tinfo.disc_tag &= ~NCR_USR_DISCENB;
 4225: 			}
 4226: 
 4227: 		}
 4228: 
 4229: 		if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
 4230: 			if (update_type & NCR_TRANS_GOAL) {
 4231: 				if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
 4232: 					tp->tinfo.disc_tag |= NCR_CUR_TAGENB;
 4233: 				else
 4234: 					tp->tinfo.disc_tag &= ~NCR_CUR_TAGENB;
 4235: 			}
 4236: 
 4237: 			if (update_type & NCR_TRANS_USER) {
 4238: 				if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
 4239: 					tp->tinfo.disc_tag |= NCR_USR_TAGENB;
 4240: 				else
 4241: 					tp->tinfo.disc_tag &= ~NCR_USR_TAGENB;
 4242: 			}	
 4243: 		}
 4244: 
 4245: 		/* Filter bus width and sync negotiation settings */
 4246: 		if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
 4247: 			if (cts->bus_width > np->maxwide)
 4248: 				cts->bus_width = np->maxwide;
 4249: 		}
 4250: 
 4251: 		if (((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0)
 4252: 		 || ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)) {
 4253: 			if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
 4254: 				if (cts->sync_period != 0
 4255: 				 && (cts->sync_period < np->minsync))
 4256: 					cts->sync_period = np->minsync;
 4257: 			}
 4258: 			if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
 4259: 				if (cts->sync_offset == 0)
 4260: 					cts->sync_period = 0;
 4261: 				if (cts->sync_offset > np->maxoffs)
 4262: 					cts->sync_offset = np->maxoffs;
 4263: 			}
 4264: 		}
 4265: 		if ((update_type & NCR_TRANS_USER) != 0) {
 4266: 			if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0)
 4267: 				tp->tinfo.user.period = cts->sync_period;
 4268: 			if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)
 4269: 				tp->tinfo.user.offset = cts->sync_offset;
 4270: 			if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0)
 4271: 				tp->tinfo.user.width = cts->bus_width;
 4272: 		}
 4273: 		if ((update_type & NCR_TRANS_GOAL) != 0) {
 4274: 			if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0)
 4275: 				tp->tinfo.goal.period = cts->sync_period;
 4276: 
 4277: 			if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)
 4278: 				tp->tinfo.goal.offset = cts->sync_offset;
 4279: 
 4280: 			if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0)
 4281: 				tp->tinfo.goal.width = cts->bus_width;
 4282: 		}
 4283: 		splx(s);
 4284: 		ccb->ccb_h.status = CAM_REQ_CMP;
 4285: 		xpt_done(ccb);
 4286: 		break;
 4287: 	}
 4288: 	case XPT_GET_TRAN_SETTINGS:
 4289: 	/* Get default/user set transfer settings for the target */
 4290: 	{
 4291: 		struct	ccb_trans_settings *cts;
 4292: 		struct	ncr_transinfo *tinfo;
 4293: 		tcb_p	tp;		
 4294: 		int	s;
 4295: 
 4296: 		cts = &ccb->cts;
 4297: 		tp = &np->target[ccb->ccb_h.target_id];
 4298: 		
 4299: 		s = splcam();
 4300: 		if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
 4301: 			tinfo = &tp->tinfo.current;
 4302: 			if (tp->tinfo.disc_tag & NCR_CUR_DISCENB)
 4303: 				cts->flags |= CCB_TRANS_DISC_ENB;
 4304: 			else
 4305: 				cts->flags &= ~CCB_TRANS_DISC_ENB;
 4306: 
 4307: 			if (tp->tinfo.disc_tag & NCR_CUR_TAGENB)
 4308: 				cts->flags |= CCB_TRANS_TAG_ENB;
 4309: 			else
 4310: 				cts->flags &= ~CCB_TRANS_TAG_ENB;
 4311: 		} else {
 4312: 			tinfo = &tp->tinfo.user;
 4313: 			if (tp->tinfo.disc_tag & NCR_USR_DISCENB)
 4314: 				cts->flags |= CCB_TRANS_DISC_ENB;
 4315: 			else
 4316: 				cts->flags &= ~CCB_TRANS_DISC_ENB;
 4317: 
 4318: 			if (tp->tinfo.disc_tag & NCR_USR_TAGENB)
 4319: 				cts->flags |= CCB_TRANS_TAG_ENB;
 4320: 			else
 4321: 				cts->flags &= ~CCB_TRANS_TAG_ENB;
 4322: 		}
 4323: 
 4324: 		cts->sync_period = tinfo->period;
 4325: 		cts->sync_offset = tinfo->offset;
 4326: 		cts->bus_width = tinfo->width;
 4327: 
 4328: 		splx(s);
 4329: 
 4330: 		cts->valid = CCB_TRANS_SYNC_RATE_VALID
 4331: 			   | CCB_TRANS_SYNC_OFFSET_VALID
 4332: 			   | CCB_TRANS_BUS_WIDTH_VALID
 4333: 			   | CCB_TRANS_DISC_VALID
 4334: 			   | CCB_TRANS_TQ_VALID;
 4335: 
 4336: 		ccb->ccb_h.status = CAM_REQ_CMP;
 4337: 		xpt_done(ccb);
 4338: 		break;
 4339: 	}
 4340: 	case XPT_CALC_GEOMETRY:
 4341: 	{
 4342: 		struct	  ccb_calc_geometry *ccg;
 4343: 		u_int32_t size_mb;
 4344: 		u_int32_t secs_per_cylinder;
 4345: 		int	  extended;
 4346: 
 4347: 		/* XXX JGibbs - I'm sure the NCR uses a different strategy,
 4348: 		 *		but it should be able to deal with Adaptec
 4349: 		 *		geometry too.
 4350: 		 */
 4351: 		extended = 1;
 4352: 		ccg = &ccb->ccg;
 4353: 		size_mb = ccg->volume_size
 4354: 			/ ((1024L * 1024L) / ccg->block_size);
 4355: 		
 4356: 		if (size_mb > 1024 && extended) {
 4357: 			ccg->heads = 255;
 4358: 			ccg->secs_per_track = 63;
 4359: 		} else {
 4360: 			ccg->heads = 64;
 4361: 			ccg->secs_per_track = 32;
 4362: 		}
 4363: 		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
 4364: 		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
 4365: 		ccb->ccb_h.status = CAM_REQ_CMP;
 4366: 		xpt_done(ccb);
 4367: 		break;
 4368: 	}
 4369: 	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
 4370: 	{
 4371: 		OUTB (nc_scntl1, CRST);
 4372: 		ccb->ccb_h.status = CAM_REQ_CMP;
 4373: 		DELAY(10000);	/* Wait until our interrupt handler sees it */ 
 4374: 		xpt_done(ccb);
 4375: 		break;
 4376: 	}
 4377: 	case XPT_TERM_IO:		/* Terminate the I/O process */
 4378: 		/* XXX Implement */
 4379: 		ccb->ccb_h.status = CAM_REQ_INVALID;
 4380: 		xpt_done(ccb);
 4381: 		break;
 4382: 	case XPT_PATH_INQ:		/* Path routing inquiry */
 4383: 	{
 4384: 		struct ccb_pathinq *cpi = &ccb->cpi;
 4385: 		
 4386: 		cpi->version_num = 1; /* XXX??? */
 4387: 		cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE;
 4388: 		if ((np->features & FE_WIDE) != 0)
 4389: 			cpi->hba_inquiry |= PI_WIDE_16;
 4390: 		cpi->target_sprt = 0;
 4391: 		cpi->hba_misc = 0;
 4392: 		cpi->hba_eng_cnt = 0;
 4393: 		cpi->max_target = (np->features & FE_WIDE) ? 15 : 7;
 4394: 		cpi->max_lun = MAX_LUN - 1;
 4395: 		cpi->initiator_id = np->myaddr;
 4396: 		cpi->bus_id = cam_sim_bus(sim);
 4397: 		cpi->base_transfer_speed = 3300;
 4398: 		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 4399: 		strncpy(cpi->hba_vid, "Symbios", HBA_IDLEN);
 4400: 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
 4401: 		cpi->unit_number = cam_sim_unit(sim);
 4402: 		cpi->ccb_h.status = CAM_REQ_CMP;
 4403: 		xpt_done(ccb);
 4404: 		break;
 4405: 	}
 4406: 	default:
 4407: 		ccb->ccb_h.status = CAM_REQ_INVALID;
 4408: 		xpt_done(ccb);
 4409: 		break;
 4410: 	}
 4411: }
 4412: 
 4413: /*==========================================================
 4414: **
 4415: **
 4416: **	Complete execution of a SCSI command.
 4417: **	Signal completion to the generic SCSI driver.
 4418: **
 4419: **
 4420: **==========================================================
 4421: */
 4422: 
 4423: void
 4424: ncr_complete (ncb_p np, nccb_p cp)
 4425: {
 4426: 	union ccb *ccb;
 4427: 	tcb_p tp;
 4428: 	lcb_p lp;
 4429: 
 4430: 	/*
 4431: 	**	Sanity check
 4432: 	*/
 4433: 
 4434: 	if (!cp || (cp->magic!=CCB_MAGIC) || !cp->ccb) return;
 4435: 	cp->magic = 1;
 4436: 	cp->tlimit= 0;
 4437: 
 4438: 	/*
 4439: 	**	No Reselect anymore.
 4440: 	*/
 4441: 	cp->jump_nccb.l_cmd = (SCR_JUMP);
 4442: 
 4443: 	/*
 4444: 	**	No starting.
 4445: 	*/
 4446: 	cp->phys.header.launch.l_paddr= NCB_SCRIPT_PHYS (np, idle);
 4447: 
 4448: 	/*
 4449: 	**	timestamp
 4450: 	*/
 4451: 	ncb_profile (np, cp);
 4452: 
 4453: 	if (DEBUG_FLAGS & DEBUG_TINY)
 4454: 		printf ("CCB=%x STAT=%x/%x\n", (int)(intptr_t)cp & 0xfff,
 4455: 			cp->host_status,cp->s_status);
 4456: 
 4457: 	ccb = cp->ccb;
 4458: 	cp->ccb = NULL;
 4459: 	tp = &np->target[ccb->ccb_h.target_id];
 4460: 	lp = tp->lp[ccb->ccb_h.target_lun];
 4461: 
 4462: 	/*
 4463: 	**	We do not queue more than 1 nccb per target 
 4464: 	**	with negotiation at any time. If this nccb was 
 4465: 	**	used for negotiation, clear this info in the tcb.
 4466: 	*/
 4467: 
 4468: 	if (cp == tp->nego_cp)
 4469: 		tp->nego_cp = NULL;
 4470: 
 4471: 	/*
 4472: 	**	Check for parity errors.
 4473: 	*/
 4474: 	/* XXX JGibbs - What about reporting them??? */
 4475: 
 4476: 	if (cp->parity_status) {
 4477: 		PRINT_ADDR(ccb);
 4478: 		printf ("%d parity error(s), fallback.\n", cp->parity_status);
 4479: 		/*
 4480: 		**	fallback to asynch transfer.
 4481: 		*/
 4482: 		tp->tinfo.goal.period = 0;
 4483: 		tp->tinfo.goal.offset = 0;
 4484: 	};
 4485: 
 4486: 	/*
 4487: 	**	Check for extended errors.
 4488: 	*/
 4489: 
 4490: 	if (cp->xerr_status != XE_OK) {
 4491: 		PRINT_ADDR(ccb);
 4492: 		switch (cp->xerr_status) {
 4493: 		case XE_EXTRA_DATA:
 4494: 			printf ("extraneous data discarded.\n");
 4495: 			break;
 4496: 		case XE_BAD_PHASE:
 4497: 			printf ("illegal scsi phase (4/5).\n");
 4498: 			break;
 4499: 		default:
 4500: 			printf ("extended error %d.\n", cp->xerr_status);
 4501: 			break;
 4502: 		};
 4503: 		if (cp->host_status==HS_COMPLETE)
 4504: 			cp->host_status = HS_FAIL;
 4505: 	};
 4506: 
 4507: 	/*
 4508: 	**	Check the status.
 4509: 	*/
 4510: 	if (cp->host_status == HS_COMPLETE) {
 4511: 
 4512: 		if (cp->s_status == SCSI_STATUS_OK) {
 4513: 
 4514: 			/*
 4515: 			**	All went well.
 4516: 			*/
 4517: 			/* XXX JGibbs - Properly calculate residual */
 4518: 
 4519: 			tp->bytes     += ccb->csio.dxfer_len;
 4520: 			tp->transfers ++;
 4521: 
 4522: 			ccb->ccb_h.status = CAM_REQ_CMP;
 4523: 		} else if ((cp->s_status & SCSI_STATUS_SENSE) != 0) {
 4524: 
 4525: 			/*
 4526: 			 * XXX Could be TERMIO too.  Should record
 4527: 			 * original status.
 4528: 			 */
 4529: 			ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
 4530: 			cp->s_status &= ~SCSI_STATUS_SENSE;
 4531: 			if (cp->s_status == SCSI_STATUS_OK) {
 4532: 				ccb->ccb_h.status =
 4533: 				    CAM_AUTOSNS_VALID|CAM_SCSI_STATUS_ERROR;
 4534: 			} else {
 4535: 				ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
 4536: 			}
 4537: 		} else {
 4538: 			ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;			
 4539: 			ccb->csio.scsi_status = cp->s_status;
 4540: 		}
 4541: 		
 4542: 		
 4543: 	} else if (cp->host_status == HS_SEL_TIMEOUT) {
 4544: 
 4545: 		/*
 4546: 		**   Device failed selection
 4547: 		*/
 4548: 		ccb->ccb_h.status = CAM_SEL_TIMEOUT;
 4549: 
 4550: 	} else if (cp->host_status == HS_TIMEOUT) {
 4551: 
 4552: 		/*
 4553: 		**   No response
 4554: 		*/
 4555: 		ccb->ccb_h.status = CAM_CMD_TIMEOUT;
 4556: 	} else if (cp->host_status == HS_STALL) {
 4557: 		ccb->ccb_h.status = CAM_REQUEUE_REQ;
 4558: 	} else {
 4559: 
 4560: 		/*
 4561: 		**  Other protocol messes
 4562: 		*/
 4563: 		PRINT_ADDR(ccb);
 4564: 		printf ("COMMAND FAILED (%x %x) @%p.\n",
 4565: 			cp->host_status, cp->s_status, cp);
 4566: 
 4567: 		ccb->ccb_h.status = CAM_CMD_TIMEOUT;
 4568: 	}
 4569: 
 4570: 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 4571: 		xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
 4572: 		ccb->ccb_h.status |= CAM_DEV_QFRZN;
 4573: 	}
 4574: 
 4575: 	/*
 4576: 	**	Free this nccb
 4577: 	*/
 4578: 	ncr_free_nccb (np, cp);
 4579: 
 4580: 	/*
 4581: 	**	signal completion to generic driver.
 4582: 	*/
 4583: 	xpt_done (ccb);
 4584: }
 4585: 
 4586: /*==========================================================
 4587: **
 4588: **
 4589: **	Signal all (or one) control block done.
 4590: **
 4591: **
 4592: **==========================================================
 4593: */
 4594: 
 4595: void
 4596: ncr_wakeup (ncb_p np, u_long code)
 4597: {
 4598: 	/*
 4599: 	**	Starting at the default nccb and following
 4600: 	**	the links, complete all jobs with a
 4601: 	**	host_status greater than "disconnect".
 4602: 	**
 4603: 	**	If the "code" parameter is not zero,
 4604: 	**	complete all jobs that are not IDLE.
 4605: 	*/
 4606: 
 4607: 	nccb_p cp = np->link_nccb;
 4608: 	while (cp) {
 4609: 		switch (cp->host_status) {
 4610: 
 4611: 		case HS_IDLE:
 4612: 			break;
 4613: 
 4614: 		case HS_DISCONNECT:
 4615: 			if(DEBUG_FLAGS & DEBUG_TINY) printf ("D");
 4616: 			/* fall through */
 4617: 
 4618: 		case HS_BUSY:
 4619: 		case HS_NEGOTIATE:
 4620: 			if (!code) break;
 4621: 			cp->host_status = code;
 4622: 
 4623: 			/* fall through */
 4624: 
 4625: 		default:
 4626: 			ncr_complete (np, cp);
 4627: 			break;
 4628: 		};
 4629: 		cp = cp -> link_nccb;
 4630: 	};
 4631: }
 4632: 
 4633: static void
 4634: ncr_freeze_devq (ncb_p np, struct cam_path *path)
 4635: {
 4636: 	nccb_p	cp;
 4637: 	int	i;
 4638: 	int	count;
 4639: 	int	firstskip;
 4640: 	/*
 4641: 	**	Starting at the first nccb and following
 4642: 	**	the links, complete all jobs that match
 4643: 	**	the passed in path and are in the start queue.
 4644: 	*/
 4645: 
 4646: 	cp = np->link_nccb;
 4647: 	count = 0;
 4648: 	firstskip = 0;
 4649: 	while (cp) {
 4650: 		switch (cp->host_status) {
 4651: 
 4652: 		case HS_BUSY:
 4653: 		case HS_NEGOTIATE:
 4654: 			if ((cp->phys.header.launch.l_paddr
 4655: 			    == NCB_SCRIPT_PHYS (np, select))
 4656: 			 && (xpt_path_comp(path, cp->ccb->ccb_h.path) >= 0)) {
 4657: 
 4658: 				/* Mark for removal from the start queue */
 4659: 				for (i = 1; i < MAX_START; i++) {
 4660: 					int idx;
 4661: 
 4662: 					idx = np->squeueput - i;
 4663: 				
 4664: 					if (idx < 0)
 4665: 						idx = MAX_START + idx;
 4666: 					if (np->squeue[idx]
 4667: 					 == CCB_PHYS(cp, phys)) {
 4668: 						np->squeue[idx] =
 4669: 						    NCB_SCRIPT_PHYS (np, skip);
 4670: 						if (i > firstskip)
 4671: 							firstskip = i;
 4672: 						break;
 4673: 					}
 4674: 				}
 4675: 				cp->host_status=HS_STALL;
 4676: 				ncr_complete (np, cp);
 4677: 				count++;
 4678: 			}
 4679: 			break;
 4680: 		default:
 4681: 			break;
 4682: 		}
 4683: 		cp = cp->link_nccb;
 4684: 	}
 4685: 
 4686: 	if (count > 0) {
 4687: 		int j;
 4688: 		int bidx;
 4689: 
 4690: 		/* Compress the start queue */
 4691: 		j = 0;
 4692: 		bidx = np->squeueput;
 4693: 		i = np->squeueput - firstskip;
 4694: 		if (i < 0)
 4695: 			i = MAX_START + i;
 4696: 		for (;;) {
 4697: 
 4698: 			bidx = i - j;
 4699: 			if (bidx < 0)
 4700: 				bidx = MAX_START + bidx;
 4701: 			
 4702: 			if (np->squeue[i] == NCB_SCRIPT_PHYS (np, skip)) {
 4703: 				j++;
 4704: 			} else if (j != 0) {
 4705: 				np->squeue[bidx] = np->squeue[i];
 4706: 				if (np->squeue[bidx]
 4707: 				 == NCB_SCRIPT_PHYS(np, idle))
 4708: 					break;
 4709: 			}
 4710: 			i = (i + 1) % MAX_START;
 4711: 		}
 4712: 		np->squeueput = bidx;
 4713: 	}
 4714: }
 4715: 
 4716: /*==========================================================
 4717: **
 4718: **
 4719: **	Start NCR chip.
 4720: **
 4721: **
 4722: **==========================================================
 4723: */
 4724: 
 4725: void
 4726: ncr_init(ncb_p np, char * msg, u_long code)
 4727: {
 4728: 	int	i;
 4729: 
 4730: 	/*
 4731: 	**	Reset chip.
 4732: 	*/
 4733: 
 4734: 	OUTB (nc_istat,  SRST);
 4735: 	DELAY (1000);
 4736: 	OUTB (nc_istat, 0);
 4737: 
 4738: 	/*
 4739: 	**	Message.
 4740: 	*/
 4741: 
 4742: 	if (msg) printf ("%s: restart (%s).\n", ncr_name (np), msg);
 4743: 
 4744: 	/*
 4745: 	**	Clear Start Queue
 4746: 	*/
 4747: 
 4748: 	for (i=0;i<MAX_START;i++)
 4749: 		np -> squeue [i] = NCB_SCRIPT_PHYS (np, idle);
 4750: 
 4751: 	/*
 4752: 	**	Start at first entry.
 4753: 	*/
 4754: 
 4755: 	np->squeueput = 0;
 4756: 	WRITESCRIPT(startpos[0], NCB_SCRIPTH_PHYS (np, tryloop));
 4757: 	WRITESCRIPT(start0  [0], SCR_INT ^ IFFALSE (0));
 4758: 
 4759: 	/*
 4760: 	**	Wakeup all pending jobs.
 4761: 	*/
 4762: 
 4763: 	ncr_wakeup (np, code);
 4764: 
 4765: 	/*
 4766: 	**	Init chip.
 4767: 	*/
 4768: 
 4769: 	OUTB (nc_istat,  0x00   );      /*  Remove Reset, abort ...	     */
 4770: 	OUTB (nc_scntl0, 0xca   );      /*  full arb., ena parity, par->ATN  */
 4771: 	OUTB (nc_scntl1, 0x00	);	/*  odd parity, and remove CRST!!    */
 4772: 	ncr_selectclock(np, np->rv_scntl3); /* Select SCSI clock             */
 4773: 	OUTB (nc_scid  , RRE|np->myaddr);/*  host adapter SCSI address       */
 4774: 	OUTW (nc_respid, 1ul<<np->myaddr);/*  id to respond to		     */
 4775: 	OUTB (nc_istat , SIGP	);	/*  Signal Process		     */
 4776: 	OUTB (nc_dmode , np->rv_dmode);	/* XXX modify burstlen ??? */
 4777: 	OUTB (nc_dcntl , np->rv_dcntl);
 4778: 	OUTB (nc_ctest3, np->rv_ctest3);
 4779: 	OUTB (nc_ctest5, np->rv_ctest5);
 4780: 	OUTB (nc_ctest4, np->rv_ctest4);/*  enable master parity checking    */
 4781: 	OUTB (nc_stest2, np->rv_stest2|EXT); /* Extended Sreq/Sack filtering */
 4782: 	OUTB (nc_stest3, TE     );	/*  TolerANT enable		     */
 4783: 	OUTB (nc_stime0, 0x0b	);	/*  HTH = disabled, STO = 0.1 sec.   */
 4784: 
 4785: 	if (bootverbose >= 2) {
 4786: 		printf ("\tACTUAL values:SCNTL3:%02x DMODE:%02x  DCNTL:%02x\n",
 4787: 			np->rv_scntl3, np->rv_dmode, np->rv_dcntl);
 4788: 		printf ("\t              CTEST3:%02x CTEST4:%02x CTEST5:%02x\n",
 4789: 			np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
 4790: 	}
 4791: 
 4792: 	/*
 4793: 	**    Enable GPIO0 pin for writing if LED support.
 4794: 	*/
 4795: 
 4796: 	if (np->features & FE_LED0) {
 4797: 		OUTOFFB (nc_gpcntl, 0x01);
 4798: 	}
 4799: 
 4800: 	/*
 4801: 	**	Fill in target structure.
 4802: 	*/
 4803: 	for (i=0;i<MAX_TARGET;i++) {
 4804: 		tcb_p tp = &np->target[i];
 4805: 
 4806: 		tp->tinfo.sval    = 0;
 4807: 		tp->tinfo.wval    = np->rv_scntl3;
 4808: 
 4809: 		tp->tinfo.current.period = 0;
 4810: 		tp->tinfo.current.offset = 0;
 4811: 		tp->tinfo.current.width = MSG_EXT_WDTR_BUS_8_BIT;
 4812: 	}
 4813: 
 4814: 	/*
 4815: 	**      enable ints
 4816: 	*/
 4817: 
 4818: 	OUTW (nc_sien , STO|HTH|MA|SGE|UDC|RST);
 4819: 	OUTB (nc_dien , MDPE|BF|ABRT|SSI|SIR|IID);
 4820: 
 4821: 	/*
 4822: 	**    Start script processor.
 4823: 	*/
 4824: 
 4825: 	OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, start));
 4826: 
 4827: 	/*
 4828: 	 * Notify the XPT of the event
 4829: 	 */
 4830: 	if (code == HS_RESET)
 4831: 		xpt_async(AC_BUS_RESET, np->path, NULL);
 4832: }
 4833: 
 4834: static void
 4835: ncr_poll(struct cam_sim *sim)
 4836: {       
 4837: 	ncr_intr(cam_sim_softc(sim));  
 4838: }
 4839: 
 4840: 
 4841: /*==========================================================
 4842: **
 4843: **	Get clock factor and sync divisor for a given 
 4844: **	synchronous factor period.
 4845: **	Returns the clock factor (in sxfer) and scntl3 
 4846: **	synchronous divisor field.
 4847: **
 4848: **==========================================================
 4849: */
 4850: 
 4851: static void ncr_getsync(ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p)
 4852: {
 4853: 	u_long	clk = np->clock_khz;	/* SCSI clock frequency in kHz	*/
 4854: 	int	div = np->clock_divn;	/* Number of divisors supported	*/
 4855: 	u_long	fak;			/* Sync factor in sxfer		*/
 4856: 	u_long	per;			/* Period in tenths of ns	*/
 4857: 	u_long	kpc;			/* (per * clk)			*/
 4858: 
 4859: 	/*
 4860: 	**	Compute the synchronous period in tenths of nano-seconds
 4861: 	*/
 4862: 	if	(sfac <= 10)	per = 250;
 4863: 	else if	(sfac == 11)	per = 303;
 4864: 	else if	(sfac == 12)	per = 500;
 4865: 	else			per = 40 * sfac;
 4866: 
 4867: 	/*
 4868: 	**	Look for the greatest clock divisor that allows an 
 4869: 	**	input speed faster than the period.
 4870: 	*/
 4871: 	kpc = per * clk;
 4872: 	while (--div >= 0)
 4873: 		if (kpc >= (div_10M[div] * 4)) break;
 4874: 
 4875: 	/*
 4876: 	**	Calculate the lowest clock factor that allows an output 
 4877: 	**	speed not faster than the period.
 4878: 	*/
 4879: 	fak = (kpc - 1) / div_10M[div] + 1;
 4880: 
 4881: #if 0	/* You can #if 1 if you think this optimization is usefull */
 4882: 
 4883: 	per = (fak * div_10M[div]) / clk;
 4884: 
 4885: 	/*
 4886: 	**	Why not to try the immediate lower divisor and to choose 
 4887: 	**	the one that allows the fastest output speed ?
 4888: 	**	We dont want input speed too much greater than output speed.
 4889: 	*/
 4890: 	if (div >= 1 && fak < 6) {
 4891: 		u_long fak2, per2;
 4892: 		fak2 = (kpc - 1) / div_10M[div-1] + 1;
 4893: 		per2 = (fak2 * div_10M[div-1]) / clk;
 4894: 		if (per2 < per && fak2 <= 6) {
 4895: 			fak = fak2;
 4896: 			per = per2;
 4897: 			--div;
 4898: 		}
 4899: 	}
 4900: #endif
 4901: 
 4902: 	if (fak < 4) fak = 4;	/* Should never happen, too bad ... */
 4903: 
 4904: 	/*
 4905: 	**	Compute and return sync parameters for the ncr
 4906: 	*/
 4907: 	*fakp		= fak - 4;
 4908: 	*scntl3p	= ((div+1) << 4) + (sfac < 25 ? 0x80 : 0);
 4909: }
 4910: 
 4911: /*==========================================================
 4912: **
 4913: **	Switch sync mode for current job and its target
 4914: **
 4915: **==========================================================
 4916: */
 4917: 
 4918: static void
 4919: ncr_setsync(ncb_p np, nccb_p cp, u_char scntl3, u_char sxfer, u_char period)
 4920: {
 4921: 	union	ccb *ccb;
 4922: 	struct	ccb_trans_settings neg;	
 4923: 	tcb_p	tp;
 4924: 	int	div;
 4925: 	u_int	target = INB (nc_sdid) & 0x0f;
 4926: 	u_int	period_10ns;
 4927: 
 4928: 	assert (cp);
 4929: 	if (!cp) return;
 4930: 
 4931: 	ccb = cp->ccb;
 4932: 	assert (ccb);
 4933: 	if (!ccb) return;
 4934: 	assert (target == ccb->ccb_h.target_id);
 4935: 
 4936: 	tp = &np->target[target];
 4937: 
 4938: 	if (!scntl3 || !(sxfer & 0x1f))
 4939: 		scntl3 = np->rv_scntl3;
 4940: 	scntl3 = (scntl3 & 0xf0) | (tp->tinfo.wval & EWS)
 4941: 	       | (np->rv_scntl3 & 0x07);
 4942: 
 4943: 	/*
 4944: 	**	Deduce the value of controller sync period from scntl3.
 4945: 	**	period is in tenths of nano-seconds.
 4946: 	*/
 4947: 
 4948: 	div = ((scntl3 >> 4) & 0x7);
 4949: 	if ((sxfer & 0x1f) && div)
 4950: 		period_10ns =
 4951: 		    (((sxfer>>5)+4)*div_10M[div-1])/np->clock_khz;
 4952: 	else
 4953: 		period_10ns = 0;
 4954: 
 4955: 	tp->tinfo.goal.period = period;
 4956: 	tp->tinfo.goal.offset = sxfer & 0x1f;
 4957: 	tp->tinfo.current.period = period;
 4958: 	tp->tinfo.current.offset = sxfer & 0x1f;
 4959: 
 4960: 	/*
 4961: 	**	 Stop there if sync parameters are unchanged
 4962: 	*/
 4963: 	if (tp->tinfo.sval == sxfer && tp->tinfo.wval == scntl3) return;
 4964: 	tp->tinfo.sval = sxfer;
 4965: 	tp->tinfo.wval = scntl3;
 4966: 
 4967: 	if (sxfer & 0x1f) {
 4968: 		/*
 4969: 		**  Disable extended Sreq/Sack filtering
 4970: 		*/
 4971: 		if (period_10ns <= 2000) OUTOFFB (nc_stest2, EXT);
 4972: 	}
 4973: 
 4974: 	/*
 4975: 	** Tell the SCSI layer about the
 4976: 	** new transfer parameters.
 4977: 	*/
 4978: 	neg.sync_period = period;
 4979: 	neg.sync_offset = sxfer & 0x1f;
 4980: 	neg.valid = CCB_TRANS_SYNC_RATE_VALID
 4981: 		| CCB_TRANS_SYNC_OFFSET_VALID;
 4982: 	xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path,
 4983: 		      /*priority*/1);
 4984: 	xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg);
 4985: 	
 4986: 	/*
 4987: 	**	set actual value and sync_status
 4988: 	*/
 4989: 	OUTB (nc_sxfer, sxfer);
 4990: 	np->sync_st = sxfer;
 4991: 	OUTB (nc_scntl3, scntl3);
 4992: 	np->wide_st = scntl3;
 4993: 
 4994: 	/*
 4995: 	**	patch ALL nccbs of this target.
 4996: 	*/
 4997: 	for (cp = np->link_nccb; cp; cp = cp->link_nccb) {
 4998: 		if (!cp->ccb) continue;
 4999: 		if (cp->ccb->ccb_h.target_id != target) continue;
 5000: 		cp->sync_status = sxfer;
 5001: 		cp->wide_status = scntl3;
 5002: 	};
 5003: }
 5004: 
 5005: /*==========================================================
 5006: **
 5007: **	Switch wide mode for current job and its target
 5008: **	SCSI specs say: a SCSI device that accepts a WDTR 
 5009: **	message shall reset the synchronous agreement to 
 5010: **	asynchronous mode.
 5011: **
 5012: **==========================================================
 5013: */
 5014: 
 5015: static void ncr_setwide (ncb_p np, nccb_p cp, u_char wide, u_char ack)
 5016: {
 5017: 	union	ccb *ccb;
 5018: 	struct	ccb_trans_settings neg;		
 5019: 	u_int	target = INB (nc_sdid) & 0x0f;
 5020: 	tcb_p	tp;
 5021: 	u_char	scntl3;
 5022: 	u_char	sxfer;
 5023: 
 5024: 	assert (cp);
 5025: 	if (!cp) return;
 5026: 
 5027: 	ccb = cp->ccb;
 5028: 	assert (ccb);
 5029: 	if (!ccb) return;
 5030: 	assert (target == ccb->ccb_h.target_id);
 5031: 
 5032: 	tp = &np->target[target];
 5033: 	tp->tinfo.current.width = wide;
 5034: 	tp->tinfo.goal.width = wide;
 5035: 	tp->tinfo.current.period = 0;
 5036: 	tp->tinfo.current.offset = 0;
 5037: 
 5038: 	scntl3 = (tp->tinfo.wval & (~EWS)) | (wide ? EWS : 0);
 5039: 
 5040: 	sxfer = ack ? 0 : tp->tinfo.sval;
 5041: 
 5042: 	/*
 5043: 	**	 Stop there if sync/wide parameters are unchanged
 5044: 	*/
 5045: 	if (tp->tinfo.sval == sxfer && tp->tinfo.wval == scntl3) return;
 5046: 	tp->tinfo.sval = sxfer;
 5047: 	tp->tinfo.wval = scntl3;
 5048: 
 5049: 	/* Tell the SCSI layer about the new transfer params */
 5050: 	neg.bus_width = (scntl3 & EWS) ? MSG_EXT_WDTR_BUS_16_BIT
 5051: 		                       : MSG_EXT_WDTR_BUS_8_BIT;
 5052: 	neg.sync_period = 0;
 5053: 	neg.sync_offset = 0;
 5054: 	neg.valid = CCB_TRANS_BUS_WIDTH_VALID
 5055: 		  | CCB_TRANS_SYNC_RATE_VALID
 5056: 		  | CCB_TRANS_SYNC_OFFSET_VALID;
 5057: 	xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path,
 5058: 		      /*priority*/1);
 5059: 	xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg);	
 5060: 
 5061: 	/*
 5062: 	**	set actual value and sync_status
 5063: 	*/
 5064: 	OUTB (nc_sxfer, sxfer);
 5065: 	np->sync_st = sxfer;
 5066: 	OUTB (nc_scntl3, scntl3);
 5067: 	np->wide_st = scntl3;
 5068: 
 5069: 	/*
 5070: 	**	patch ALL nccbs of this target.
 5071: 	*/
 5072: 	for (cp = np->link_nccb; cp; cp = cp->link_nccb) {
 5073: 		if (!cp->ccb) continue;
 5074: 		if (cp->ccb->ccb_h.target_id != target) continue;
 5075: 		cp->sync_status = sxfer;
 5076: 		cp->wide_status = scntl3;
 5077: 	};
 5078: }
 5079: 
 5080: /*==========================================================
 5081: **
 5082: **
 5083: **	ncr timeout handler.
 5084: **
 5085: **
 5086: **==========================================================
 5087: **
 5088: **	Misused to keep the driver running when
 5089: **	interrupts are not configured correctly.
 5090: **
 5091: **----------------------------------------------------------
 5092: */
 5093: 
 5094: static void
 5095: ncr_timeout (void *arg)
 5096: {
 5097: 	ncb_p	np = arg;
 5098: 	time_t	thistime = time_second;
 5099: 	ticks_t	step  = np->ticks;
 5100: 	u_long	count = 0;
 5101: 	long signed   t;
 5102: 	nccb_p cp;
 5103: 
 5104: 	if (np->lasttime != thistime) {
 5105: 		/*
 5106: 		**	block ncr interrupts
 5107: 		*/
 5108: 		int oldspl = splcam();
 5109: 		np->lasttime = thistime;
 5110: 
 5111: 		/*----------------------------------------------------
 5112: 		**
 5113: 		**	handle ncr chip timeouts
 5114: 		**
 5115: 		**	Assumption:
 5116: 		**	We have a chance to arbitrate for the
 5117: 		**	SCSI bus at least every 10 seconds.
 5118: 		**
 5119: 		**----------------------------------------------------
 5120: 		*/
 5121: 
 5122: 		t = thistime - np->heartbeat;
 5123: 
 5124: 		if (t<2) np->latetime=0; else np->latetime++;
 5125: 
 5126: 		if (np->latetime>2) {
 5127: 			/*
 5128: 			**      If there are no requests, the script
 5129: 			**      processor will sleep on SEL_WAIT_RESEL.
 5130: 			**      But we have to check whether it died.
 5131: 			**      Let's try to wake it up.
 5132: 			*/
 5133: 			OUTB (nc_istat, SIGP);
 5134: 		};
 5135: 
 5136: 		/*----------------------------------------------------
 5137: 		**
 5138: 		**	handle nccb timeouts
 5139: 		**
 5140: 		**----------------------------------------------------
 5141: 		*/
 5142: 
 5143: 		for (cp=np->link_nccb; cp; cp=cp->link_nccb) {
 5144: 			/*
 5145: 			**	look for timed out nccbs.
 5146: 			*/
 5147: 			if (!cp->host_status) continue;
 5148: 			count++;
 5149: 			if (cp->tlimit > thistime) continue;
 5150: 
 5151: 			/*
 5152: 			**	Disable reselect.
 5153: 			**      Remove it from startqueue.
 5154: 			*/
 5155: 			cp->jump_nccb.l_cmd = (SCR_JUMP);
 5156: 			if (cp->phys.header.launch.l_paddr ==
 5157: 				NCB_SCRIPT_PHYS (np, select)) {
 5158: 				printf ("%s: timeout nccb=%p (skip)\n",
 5159: 					ncr_name (np), cp);
 5160: 				cp->phys.header.launch.l_paddr
 5161: 				= NCB_SCRIPT_PHYS (np, skip);
 5162: 			};
 5163: 
 5164: 			switch (cp->host_status) {
 5165: 
 5166: 			case HS_BUSY:
 5167: 			case HS_NEGOTIATE:
 5168: 				/* fall through */
 5169: 			case HS_DISCONNECT:
 5170: 				cp->host_status=HS_TIMEOUT;
 5171: 			};
 5172: 			cp->tag = 0;
 5173: 
 5174: 			/*
 5175: 			**	wakeup this nccb.
 5176: 			*/
 5177: 			ncr_complete (np, cp);
 5178: 		};
 5179: 		splx (oldspl);
 5180: 	}
 5181: 
 5182: 	np->timeout_ch =
 5183: 		timeout (ncr_timeout, (caddr_t) np, step ? step : 1);
 5184: 
 5185: 	if (INB(nc_istat) & (INTF|SIP|DIP)) {
 5186: 
 5187: 		/*
 5188: 		**	Process pending interrupts.
 5189: 		*/
 5190: 
 5191: 		int	oldspl	= splcam();
 5192: 		if (DEBUG_FLAGS & DEBUG_TINY) printf ("{");
 5193: 		ncr_exception (np);
 5194: 		if (DEBUG_FLAGS & DEBUG_TINY) printf ("}");
 5195: 		splx (oldspl);
 5196: 	};
 5197: }
 5198: 
 5199: /*==========================================================
 5200: **
 5201: **	log message for real hard errors
 5202: **
 5203: **	"ncr0 targ 0?: ERROR (ds:si) (so-si-sd) (sxfer/scntl3) @ name (dsp:dbc)."
 5204: **	"	      reg: r0 r1 r2 r3 r4 r5 r6 ..... rf."
 5205: **
 5206: **	exception register:
 5207: **		ds:	dstat
 5208: **		si:	sist
 5209: **
 5210: **	SCSI bus lines:
 5211: **		so:	control lines as driver by NCR.
 5212: **		si:	control lines as seen by NCR.
 5213: **		sd:	scsi data lines as seen by NCR.
 5214: **
 5215: **	wide/fastmode:
 5216: **		sxfer:	(see the manual)
 5217: **		scntl3:	(see the manual)
 5218: **
 5219: **	current script command:
 5220: **		dsp:	script adress (relative to start of script).
 5221: **		dbc:	first word of script command.
 5222: **
 5223: **	First 16 register of the chip:
 5224: **		r0..rf
 5225: **
 5226: **==========================================================
 5227: */
 5228: 
 5229: static void ncr_log_hard_error(ncb_p np, u_short sist, u_char dstat)
 5230: {
 5231: 	u_int32_t dsp;
 5232: 	int	script_ofs;
 5233: 	int	script_size;
 5234: 	char	*script_name;
 5235: 	u_char	*script_base;
 5236: 	int	i;
 5237: 
 5238: 	dsp	= INL (nc_dsp);
 5239: 
 5240: 	if (np->p_script < dsp && 
 5241: 	    dsp <= np->p_script + sizeof(struct script)) {
 5242: 		script_ofs	= dsp - np->p_script;
 5243: 		script_size	= sizeof(struct script);
 5244: 		script_base	= (u_char *) np->script;
 5245: 		script_name	= "script";
 5246: 	}
 5247: 	else if (np->p_scripth < dsp && 
 5248: 		 dsp <= np->p_scripth + sizeof(struct scripth)) {
 5249: 		script_ofs	= dsp - np->p_scripth;
 5250: 		script_size	= sizeof(struct scripth);
 5251: 		script_base	= (u_char *) np->scripth;
 5252: 		script_name	= "scripth";
 5253: 	} else {
 5254: 		script_ofs	= dsp;
 5255: 		script_size	= 0;
 5256: 		script_base	= 0;
 5257: 		script_name	= "mem";
 5258: 	}
 5259: 
 5260: 	printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ (%s %x:%08x).\n",
 5261: 		ncr_name (np), (unsigned)INB (nc_sdid)&0x0f, dstat, sist,
 5262: 		(unsigned)INB (nc_socl), (unsigned)INB (nc_sbcl), (unsigned)INB (nc_sbdl),
 5263: 		(unsigned)INB (nc_sxfer),(unsigned)INB (nc_scntl3), script_name, script_ofs,
 5264: 		(unsigned)INL (nc_dbc));
 5265: 
 5266: 	if (((script_ofs & 3) == 0) &&
 5267: 	    (unsigned)script_ofs < script_size) {
 5268: 		printf ("%s: script cmd = %08x\n", ncr_name(np),
 5269: 			(int)READSCRIPT_OFF(script_base, script_ofs));
 5270: 	}
 5271: 
 5272:         printf ("%s: regdump:", ncr_name(np));
 5273:         for (i=0; i<16;i++)
 5274:             printf (" %02x", (unsigned)INB_OFF(i));
 5275:         printf (".\n");
 5276: }
 5277: 
 5278: /*==========================================================
 5279: **
 5280: **
 5281: **	ncr chip exception handler.
 5282: **
 5283: **
 5284: **==========================================================
 5285: */
 5286: 
 5287: void ncr_exception (ncb_p np)
 5288: {
 5289: 	u_char	istat, dstat;
 5290: 	u_short	sist;
 5291: 
 5292: 	/*
 5293: 	**	interrupt on the fly ?
 5294: 	*/
 5295: 	while ((istat = INB (nc_istat)) & INTF) {
 5296: 		if (DEBUG_FLAGS & DEBUG_TINY) printf ("F ");
 5297: 		OUTB (nc_istat, INTF);
 5298: 		np->profile.num_fly++;
 5299: 		ncr_wakeup (np, 0);
 5300: 	};
 5301: 	if (!(istat & (SIP|DIP))) {
 5302: 		return;
 5303: 	}
 5304: 
 5305: 	/*
 5306: 	**	Steinbach's Guideline for Systems Programming:
 5307: 	**	Never test for an error condition you don't know how to handle.
 5308: 	*/
 5309: 
 5310: 	sist  = (istat & SIP) ? INW (nc_sist)  : 0;
 5311: 	dstat = (istat & DIP) ? INB (nc_dstat) : 0;
 5312: 	np->profile.num_int++;
 5313: 
 5314: 	if (DEBUG_FLAGS & DEBUG_TINY)
 5315: 		printf ("<%d|%x:%x|%x:%x>",
 5316: 			INB(nc_scr0),
 5317: 			dstat,sist,
 5318: 			(unsigned)INL(nc_dsp),
 5319: 			(unsigned)INL(nc_dbc));
 5320: 	if ((dstat==DFE) && (sist==PAR)) return;
 5321: 
 5322: /*==========================================================
 5323: **
 5324: **	First the normal cases.
 5325: **
 5326: **==========================================================
 5327: */
 5328: 	/*-------------------------------------------
 5329: 	**	SCSI reset
 5330: 	**-------------------------------------------
 5331: 	*/
 5332: 
 5333: 	if (sist & RST) {
 5334: 		ncr_init (np, bootverbose ? "scsi reset" : NULL, HS_RESET);
 5335: 		return;
 5336: 	};
 5337: 
 5338: 	/*-------------------------------------------
 5339: 	**	selection timeout
 5340: 	**
 5341: 	**	IID excluded from dstat mask!
 5342: 	**	(chip bug)
 5343: 	**-------------------------------------------
 5344: 	*/
 5345: 
 5346: 	if ((sist  & STO) &&
 5347: 		!(sist  & (GEN|HTH|MA|SGE|UDC|RST|PAR)) &&
 5348: 		!(dstat & (MDPE|BF|ABRT|SIR))) {
 5349: 		ncr_int_sto (np);
 5350: 		return;
 5351: 	};
 5352: 
 5353: 	/*-------------------------------------------
 5354: 	**      Phase mismatch.
 5355: 	**-------------------------------------------
 5356: 	*/
 5357: 
 5358: 	if ((sist  & MA) &&
 5359: 		!(sist  & (STO|GEN|HTH|SGE|UDC|RST|PAR)) &&
 5360: 		!(dstat & (MDPE|BF|ABRT|SIR|IID))) {
 5361: 		ncr_int_ma (np, dstat);
 5362: 		return;
 5363: 	};
 5364: 
 5365: 	/*----------------------------------------
 5366: 	**	move command with length 0
 5367: 	**----------------------------------------
 5368: 	*/
 5369: 
 5370: 	if ((dstat & IID) &&
 5371: 		!(sist  & (STO|GEN|HTH|MA|SGE|UDC|RST|PAR)) &&
 5372: 		!(dstat & (MDPE|BF|ABRT|SIR)) &&
 5373: 		((INL(nc_dbc) & 0xf8000000) == SCR_MOVE_TBL)) {
 5374: 		/*
 5375: 		**      Target wants more data than available.
 5376: 		**	The "no_data" script will do it.
 5377: 		*/
 5378: 		OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, no_data));
 5379: 		return;
 5380: 	};
 5381: 
 5382: 	/*-------------------------------------------
 5383: 	**	Programmed interrupt
 5384: 	**-------------------------------------------
 5385: 	*/
 5386: 
 5387: 	if ((dstat & SIR) &&
 5388: 		!(sist  & (STO|GEN|HTH|MA|SGE|UDC|RST|PAR)) &&
 5389: 		!(dstat & (MDPE|BF|ABRT|IID)) &&
 5390: 		(INB(nc_dsps) <= SIR_MAX)) {
 5391: 		ncr_int_sir (np);
 5392: 		return;
 5393: 	};
 5394: 
 5395: 	/*========================================
 5396: 	**	log message for real hard errors
 5397: 	**========================================
 5398: 	*/
 5399: 
 5400: 	ncr_log_hard_error(np, sist, dstat);
 5401: 
 5402: 	/*========================================
 5403: 	**	do the register dump
 5404: 	**========================================
 5405: 	*/
 5406: 
 5407: 	if (time_second - np->regtime > 10) {
 5408: 		int i;
 5409: 		np->regtime = time_second;
 5410: 		for (i=0; i<sizeof(np->regdump); i++)
 5411: 			((volatile char*)&np->regdump)[i] = INB_OFF(i);
 5412: 		np->regdump.nc_dstat = dstat;
 5413: 		np->regdump.nc_sist  = sist;
 5414: 	};
 5415: 
 5416: 
 5417: 	/*----------------------------------------
 5418: 	**	clean up the dma fifo
 5419: 	**----------------------------------------
 5420: 	*/
 5421: 
 5422: 	if ( (INB(nc_sstat0) & (ILF|ORF|OLF)   ) ||
 5423: 	     (INB(nc_sstat1) & (FF3210)	) ||
 5424: 	     (INB(nc_sstat2) & (ILF1|ORF1|OLF1)) ||	/* wide .. */
 5425: 	     !(dstat & DFE)) {
 5426: 		printf ("%s: have to clear fifos.\n", ncr_name (np));
 5427: 		OUTB (nc_stest3, TE|CSF);	/* clear scsi fifo */
 5428: 		OUTB (nc_ctest3, np->rv_ctest3 | CLF);
 5429: 						/* clear dma fifo  */
 5430: 	}
 5431: 
 5432: 	/*----------------------------------------
 5433: 	**	handshake timeout
 5434: 	**----------------------------------------
 5435: 	*/
 5436: 
 5437: 	if (sist & HTH) {
 5438: 		printf ("%s: handshake timeout\n", ncr_name(np));
 5439: 		OUTB (nc_scntl1, CRST);
 5440: 		DELAY (1000);
 5441: 		OUTB (nc_scntl1, 0x00);
 5442: 		OUTB (nc_scr0, HS_FAIL);
 5443: 		OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, cleanup));
 5444: 		return;
 5445: 	}
 5446: 
 5447: 	/*----------------------------------------
 5448: 	**	unexpected disconnect
 5449: 	**----------------------------------------
 5450: 	*/
 5451: 
 5452: 	if ((sist  & UDC) &&
 5453: 		!(sist  & (STO|GEN|HTH|MA|SGE|RST|PAR)) &&
 5454: 		!(dstat & (MDPE|BF|ABRT|SIR|IID))) {
 5455: 		OUTB (nc_scr0, HS_UNEXPECTED);
 5456: 		OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, cleanup));
 5457: 		return;
 5458: 	};
 5459: 
 5460: 	/*----------------------------------------
 5461: 	**	cannot disconnect
 5462: 	**----------------------------------------
 5463: 	*/
 5464: 
 5465: 	if ((dstat & IID) &&
 5466: 		!(sist  & (STO|GEN|HTH|MA|SGE|UDC|RST|PAR)) &&
 5467: 		!(dstat & (MDPE|BF|ABRT|SIR)) &&
 5468: 		((INL(nc_dbc) & 0xf8000000) == SCR_WAIT_DISC)) {
 5469: 		/*
 5470: 		**      Unexpected data cycle while waiting for disconnect.
 5471: 		*/
 5472: 		if (INB(nc_sstat2) & LDSC) {
 5473: 			/*
 5474: 			**	It's an early reconnect.
 5475: 			**	Let's continue ...
 5476: 			*/
 5477: 			OUTB (nc_dcntl, np->rv_dcntl | STD);
 5478: 			/*
 5479: 			**	info message
 5480: 			*/
 5481: 			printf ("%s: INFO: LDSC while IID.\n",
 5482: 				ncr_name (np));
 5483: 			return;
 5484: 		};
 5485: 		printf ("%s: target %d doesn't release the bus.\n",
 5486: 			ncr_name (np), INB (nc_sdid)&0x0f);
 5487: 		/*
 5488: 		**	return without restarting the NCR.
 5489: 		**	timeout will do the real work.
 5490: 		*/
 5491: 		return;
 5492: 	};
 5493: 
 5494: 	/*----------------------------------------
 5495: 	**	single step
 5496: 	**----------------------------------------
 5497: 	*/
 5498: 
 5499: 	if ((dstat & SSI) &&
 5500: 		!(sist  & (STO|GEN|HTH|MA|SGE|UDC|RST|PAR)) &&
 5501: 		!(dstat & (MDPE|BF|ABRT|SIR|IID))) {
 5502: 		OUTB (nc_dcntl, np->rv_dcntl | STD);
 5503: 		return;
 5504: 	};
 5505: 
 5506: /*
 5507: **	@RECOVER@ HTH, SGE, ABRT.
 5508: **
 5509: **	We should try to recover from these interrupts.
 5510: **	They may occur if there are problems with synch transfers, or 
 5511: **	if targets are switched on or off while the driver is running.
 5512: */
 5513: 
 5514: 	if (sist & SGE) {
 5515: 		/* clear scsi offsets */
 5516: 		OUTB (nc_ctest3, np->rv_ctest3 | CLF);
 5517: 	}
 5518: 
 5519: 	/*
 5520: 	**	Freeze controller to be able to read the messages.
 5521: 	*/
 5522: 
 5523: 	if (DEBUG_FLAGS & DEBUG_FREEZE) {
 5524: 		int i;
 5525: 		unsigned char val;
 5526: 		for (i=0; i<0x60; i++) {
 5527: 			switch (i%16) {
 5528: 
 5529: 			case 0:
 5530: 				printf ("%s: reg[%d0]: ",
 5531: 					ncr_name(np),i/16);
 5532: 				break;
 5533: 			case 4:
 5534: 			case 8:
 5535: 			case 12:
 5536: 				printf (" ");
 5537: 				break;
 5538: 			};
 5539: 			val = bus_space_read_1(np->bst, np->bsh, i);
 5540: 			printf (" %x%x", val/16, val%16);
 5541: 			if (i%16==15) printf (".\n");
 5542: 		};
 5543: 
 5544: 		untimeout (ncr_timeout, (caddr_t) np, np->timeout_ch);
 5545: 
 5546: 		printf ("%s: halted!\n", ncr_name(np));
 5547: 		/*
 5548: 		**	don't restart controller ...
 5549: 		*/
 5550: 		OUTB (nc_istat,  SRST);
 5551: 		return;
 5552: 	};
 5553: 
 5554: #ifdef NCR_FREEZE
 5555: 	/*
 5556: 	**	Freeze system to be able to read the messages.
 5557: 	*/
 5558: 	printf ("ncr: fatal error: system halted - press reset to reboot ...");
 5559: 	(void) splhigh();
 5560: 	for (;;);
 5561: #endif
 5562: 
 5563: 	/*
 5564: 	**	sorry, have to kill ALL jobs ...
 5565: 	*/
 5566: 
 5567: 	ncr_init (np, "fatal error", HS_FAIL);
 5568: }
 5569: 
 5570: /*==========================================================
 5571: **
 5572: **	ncr chip exception handler for selection timeout
 5573: **
 5574: **==========================================================
 5575: **
 5576: **	There seems to be a bug in the 53c810.
 5577: **	Although a STO-Interrupt is pending,
 5578: **	it continues executing script commands.
 5579: **	But it will fail and interrupt (IID) on
 5580: **	the next instruction where it's looking
 5581: **	for a valid phase.
 5582: **
 5583: **----------------------------------------------------------
 5584: */
 5585: 
 5586: void ncr_int_sto (ncb_p np)
 5587: {
 5588: 	u_long dsa, scratcha, diff;
 5589: 	nccb_p cp;
 5590: 	if (DEBUG_FLAGS & DEBUG_TINY) printf ("T");
 5591: 
 5592: 	/*
 5593: 	**	look for nccb and set the status.
 5594: 	*/
 5595: 
 5596: 	dsa = INL (nc_dsa);
 5597: 	cp = np->link_nccb;
 5598: 	while (cp && (CCB_PHYS (cp, phys) != dsa))
 5599: 		cp = cp->link_nccb;
 5600: 
 5601: 	if (cp) {
 5602: 		cp-> host_status = HS_SEL_TIMEOUT;
 5603: 		ncr_complete (np, cp);
 5604: 	};
 5605: 
 5606: 	/*
 5607: 	**	repair start queue
 5608: 	*/
 5609: 
 5610: 	scratcha = INL (nc_scratcha);
 5611: 	diff = scratcha - NCB_SCRIPTH_PHYS (np, tryloop);
 5612: 
 5613: /*	assert ((diff <= MAX_START * 20) && !(diff % 20));*/
 5614: 
 5615: 	if ((diff <= MAX_START * 20) && !(diff % 20)) {
 5616: 		WRITESCRIPT(startpos[0], scratcha);
 5617: 		OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, start));
 5618: 		return;
 5619: 	};
 5620: 	ncr_init (np, "selection timeout", HS_FAIL);
 5621: }
 5622: 
 5623: /*==========================================================
 5624: **
 5625: **
 5626: **	ncr chip exception handler for phase errors.
 5627: **
 5628: **
 5629: **==========================================================
 5630: **
 5631: **	We have to construct a new transfer descriptor,
 5632: **	to transfer the rest of the current block.
 5633: **
 5634: **----------------------------------------------------------
 5635: */
 5636: 
 5637: static void ncr_int_ma (ncb_p np, u_char dstat)
 5638: {
 5639: 	u_int32_t	dbc;
 5640: 	u_int32_t	rest;
 5641: 	u_int32_t	dsa;
 5642: 	u_int32_t	dsp;
 5643: 	u_int32_t	nxtdsp;
 5644: 	volatile void	*vdsp_base;
 5645: 	size_t		vdsp_off;
 5646: 	u_int32_t	oadr, olen;
 5647: 	u_int32_t	*tblp, *newcmd;
 5648: 	u_char	cmd, sbcl, ss0, ss2, ctest5;
 5649: 	u_short	delta;
 5650: 	nccb_p	cp;
 5651: 
 5652: 	dsp = INL (nc_dsp);
 5653: 	dsa = INL (nc_dsa);
 5654: 	dbc = INL (nc_dbc);
 5655: 	ss0 = INB (nc_sstat0);
 5656: 	ss2 = INB (nc_sstat2);
 5657: 	sbcl= INB (nc_sbcl);
 5658: 
 5659: 	cmd = dbc >> 24;
 5660: 	rest= dbc & 0xffffff;
 5661: 
 5662: 	ctest5 = (np->rv_ctest5 & DFS) ? INB (nc_ctest5) : 0;
 5663: 	if (ctest5 & DFS)
 5664: 		delta=(((ctest5<<8) | (INB (nc_dfifo) & 0xff)) - rest) & 0x3ff;
 5665: 	else
 5666: 		delta=(INB (nc_dfifo) - rest) & 0x7f;
 5667: 
 5668: 
 5669: 	/*
 5670: 	**	The data in the dma fifo has not been transfered to
 5671: 	**	the target -> add the amount to the rest
 5672: 	**	and clear the data.
 5673: 	**	Check the sstat2 register in case of wide transfer.
 5674: 	*/
 5675: 
 5676: 	if (!(dstat & DFE)) rest += delta;
 5677: 	if (ss0 & OLF) rest++;
 5678: 	if (ss0 & ORF) rest++;
 5679: 	if (INB(nc_scntl3) & EWS) {
 5680: 		if (ss2 & OLF1) rest++;
 5681: 		if (ss2 & ORF1) rest++;
 5682: 	};
 5683: 	OUTB (nc_ctest3, np->rv_ctest3 | CLF);	/* clear dma fifo  */
 5684: 	OUTB (nc_stest3, TE|CSF);		/* clear scsi fifo */
 5685: 
 5686: 	/*
 5687: 	**	locate matching cp
 5688: 	*/
 5689: 	cp = np->link_nccb;
 5690: 	while (cp && (CCB_PHYS (cp, phys) != dsa))
 5691: 		cp = cp->link_nccb;
 5692: 
 5693: 	if (!cp) {
 5694: 	    printf ("%s: SCSI phase error fixup: CCB already dequeued (%p)\n", 
 5695: 		    ncr_name (np), (void *) np->header.cp);
 5696: 	    return;
 5697: 	}
 5698: 	if (cp != np->header.cp) {
 5699: 	    printf ("%s: SCSI phase error fixup: CCB address mismatch "
 5700: 		    "(%p != %p) np->nccb = %p\n", 
 5701: 		    ncr_name (np), (void *)cp, (void *)np->header.cp,
 5702: 		    (void *)np->link_nccb);
 5703: /*	    return;*/
 5704: 	}
 5705: 
 5706: 	/*
 5707: 	**	find the interrupted script command,
 5708: 	**	and the address at which to continue.
 5709: 	*/
 5710: 
 5711: 	if (dsp == vtophys (&cp->patch[2])) {
 5712: 		vdsp_base = cp;
 5713: 		vdsp_off = offsetof(struct nccb, patch[0]);
 5714: 		nxtdsp = READSCRIPT_OFF(vdsp_base, vdsp_off + 3*4);
 5715: 	} else if (dsp == vtophys (&cp->patch[6])) {
 5716: 		vdsp_base = cp;
 5717: 		vdsp_off = offsetof(struct nccb, patch[4]);
 5718: 		nxtdsp = READSCRIPT_OFF(vdsp_base, vdsp_off + 3*4);
 5719: 	} else if (dsp > np->p_script &&
 5720: 		   dsp <= np->p_script + sizeof(struct script)) {
 5721: 		vdsp_base = np->script;
 5722: 		vdsp_off = dsp - np->p_script - 8;
 5723: 		nxtdsp = dsp;
 5724: 	} else {
 5725: 		vdsp_base = np->scripth;
 5726: 		vdsp_off = dsp - np->p_scripth - 8;
 5727: 		nxtdsp = dsp;
 5728: 	};
 5729: 
 5730: 	/*
 5731: 	**	log the information
 5732: 	*/
 5733: 	if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_PHASE)) {
 5734: 		printf ("P%x%x ",cmd&7, sbcl&7);
 5735: 		printf ("RL=%d D=%d SS0=%x ",
 5736: 			(unsigned) rest, (unsigned) delta, ss0);
 5737: 	};
 5738: 	if (DEBUG_FLAGS & DEBUG_PHASE) {
 5739: 		printf ("\nCP=%p CP2=%p DSP=%x NXT=%x VDSP=%p CMD=%x ",
 5740: 			cp, np->header.cp,
 5741: 			dsp,
 5742: 			nxtdsp, (volatile char*)vdsp_base+vdsp_off, cmd);
 5743: 	};
 5744: 
 5745: 	/*
 5746: 	**	get old startaddress and old length.
 5747: 	*/
 5748: 
 5749: 	oadr = READSCRIPT_OFF(vdsp_base, vdsp_off + 1*4);
 5750: 
 5751: 	if (cmd & 0x10) {	/* Table indirect */
 5752: 		tblp = (u_int32_t *) ((char*) &cp->phys + oadr);
 5753: 		olen = tblp[0];
 5754: 		oadr = tblp[1];
 5755: 	} else {
 5756: 		tblp = (u_int32_t *) 0;
 5757: 		olen = READSCRIPT_OFF(vdsp_base, vdsp_off) & 0xffffff;
 5758: 	};
 5759: 
 5760: 	if (DEBUG_FLAGS & DEBUG_PHASE) {
 5761: 		printf ("OCMD=%x\nTBLP=%p OLEN=%lx OADR=%lx\n",
 5762: 			(unsigned) (READSCRIPT_OFF(vdsp_base, vdsp_off) >> 24),
 5763: 			(void *) tblp,
 5764: 			(u_long) olen,
 5765: 			(u_long) oadr);
 5766: 	};
 5767: 
 5768: 	/*
 5769: 	**	if old phase not dataphase, leave here.
 5770: 	*/
 5771: 
 5772: 	if (cmd != (READSCRIPT_OFF(vdsp_base, vdsp_off) >> 24)) {
 5773: 		PRINT_ADDR(cp->ccb);
 5774: 		printf ("internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n",
 5775: 			(unsigned)cmd,
 5776: 			(unsigned)READSCRIPT_OFF(vdsp_base, vdsp_off) >> 24);
 5777: 		
 5778: 		return;
 5779: 	}
 5780: 	if (cmd & 0x06) {
 5781: 		PRINT_ADDR(cp->ccb);
 5782: 		printf ("phase change %x-%x %d@%08x resid=%d.\n",
 5783: 			cmd&7, sbcl&7, (unsigned)olen,
 5784: 			(unsigned)oadr, (unsigned)rest);
 5785: 
 5786: 		OUTB (nc_dcntl, np->rv_dcntl | STD);
 5787: 		return;
 5788: 	};
 5789: 
 5790: 	/*
 5791: 	**	choose the correct patch area.
 5792: 	**	if savep points to one, choose the other.
 5793: 	*/
 5794: 
 5795: 	newcmd = cp->patch;
 5796: 	if (cp->phys.header.savep == vtophys (newcmd)) newcmd+=4;
 5797: 
 5798: 	/*
 5799: 	**	fillin the commands
 5800: 	*/
 5801: 
 5802: 	newcmd[0] = ((cmd & 0x0f) << 24) | rest;
 5803: 	newcmd[1] = oadr + olen - rest;
 5804: 	newcmd[2] = SCR_JUMP;
 5805: 	newcmd[3] = nxtdsp;
 5806: 
 5807: 	if (DEBUG_FLAGS & DEBUG_PHASE) {
 5808: 		PRINT_ADDR(cp->ccb);
 5809: 		printf ("newcmd[%d] %x %x %x %x.\n",
 5810: 			(int)(newcmd - cp->patch),
 5811: 			(unsigned)newcmd[0],
 5812: 			(unsigned)newcmd[1],
 5813: 			(unsigned)newcmd[2],
 5814: 			(unsigned)newcmd[3]);
 5815: 	}
 5816: 	/*
 5817: 	**	fake the return address (to the patch).
 5818: 	**	and restart script processor at dispatcher.
 5819: 	*/
 5820: 	np->profile.num_break++;
 5821: 	OUTL (nc_temp, vtophys (newcmd));
 5822: 	if ((cmd & 7) == 0)
 5823: 		OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, dispatch));
 5824: 	else
 5825: 		OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, checkatn));
 5826: }
 5827: 
 5828: /*==========================================================
 5829: **
 5830: **
 5831: **      ncr chip exception handler for programmed interrupts.
 5832: **
 5833: **
 5834: **==========================================================
 5835: */
 5836: 
 5837: static int ncr_show_msg (u_char * msg)
 5838: {
 5839: 	u_char i;
 5840: 	printf ("%x",*msg);
 5841: 	if (*msg==MSG_EXTENDED) {
 5842: 		for (i=1;i<8;i++) {
 5843: 			if (i-1>msg[1]) break;
 5844: 			printf ("-%x",msg[i]);
 5845: 		};
 5846: 		return (i+1);
 5847: 	} else if ((*msg & 0xf0) == 0x20) {
 5848: 		printf ("-%x",msg[1]);
 5849: 		return (2);
 5850: 	};
 5851: 	return (1);
 5852: }
 5853: 
 5854: void ncr_int_sir (ncb_p np)
 5855: {
 5856: 	u_char scntl3;
 5857: 	u_char chg, ofs, per, fak, wide;
 5858: 	u_char num = INB (nc_dsps);
 5859: 	nccb_p	cp=0;
 5860: 	u_long	dsa;
 5861: 	u_int	target = INB (nc_sdid) & 0x0f;
 5862: 	tcb_p	tp     = &np->target[target];
 5863: 	int     i;
 5864: 	if (DEBUG_FLAGS & DEBUG_TINY) printf ("I#%d", num);
 5865: 
 5866: 	switch (num) {
 5867: 	case SIR_SENSE_RESTART:
 5868: 	case SIR_STALL_RESTART:
 5869: 		break;
 5870: 
 5871: 	default:
 5872: 		/*
 5873: 		**	lookup the nccb
 5874: 		*/
 5875: 		dsa = INL (nc_dsa);
 5876: 		cp = np->link_nccb;
 5877: 		while (cp && (CCB_PHYS (cp, phys) != dsa))
 5878: 			cp = cp->link_nccb;
 5879: 
 5880: 		assert (cp);
 5881: 		if (!cp)
 5882: 			goto out;
 5883: 		assert (cp == np->header.cp);
 5884: 		if (cp != np->header.cp)
 5885: 			goto out;
 5886: 	}
 5887: 
 5888: 	switch (num) {
 5889: 
 5890: /*--------------------------------------------------------------------
 5891: **
 5892: **	Processing of interrupted getcc selects
 5893: **
 5894: **--------------------------------------------------------------------
 5895: */
 5896: 
 5897: 	case SIR_SENSE_RESTART:
 5898: 		/*------------------------------------------
 5899: 		**	Script processor is idle.
 5900: 		**	Look for interrupted "check cond"
 5901: 		**------------------------------------------
 5902: 		*/
 5903: 
 5904: 		if (DEBUG_FLAGS & DEBUG_RESTART)
 5905: 			printf ("%s: int#%d",ncr_name (np),num);
 5906: 		cp = (nccb_p) 0;
 5907: 		for (i=0; i<MAX_TARGET; i++) {
 5908: 			if (DEBUG_FLAGS & DEBUG_RESTART) printf (" t%d", i);
 5909: 			tp = &np->target[i];
 5910: 			if (DEBUG_FLAGS & DEBUG_RESTART) printf ("+");
 5911: 			cp = tp->hold_cp;
 5912: 			if (!cp) continue;
 5913: 			if (DEBUG_FLAGS & DEBUG_RESTART) printf ("+");
 5914: 			if ((cp->host_status==HS_BUSY) &&
 5915: 				(cp->s_status==SCSI_STATUS_CHECK_COND))
 5916: 				break;
 5917: 			if (DEBUG_FLAGS & DEBUG_RESTART) printf ("- (remove)");
 5918: 			tp->hold_cp = cp = (nccb_p) 0;
 5919: 		};
 5920: 
 5921: 		if (cp) {
 5922: 			if (DEBUG_FLAGS & DEBUG_RESTART)
 5923: 				printf ("+ restart job ..\n");
 5924: 			OUTL (nc_dsa, CCB_PHYS (cp, phys));
 5925: 			OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, getcc));
 5926: 			return;
 5927: 		};
 5928: 
 5929: 		/*
 5930: 		**	no job, resume normal processing
 5931: 		*/
 5932: 		if (DEBUG_FLAGS & DEBUG_RESTART) printf (" -- remove trap\n");
 5933: 		WRITESCRIPT(start0[0], SCR_INT ^ IFFALSE (0));
 5934: 		break;
 5935: 
 5936: 	case SIR_SENSE_FAILED:
 5937: 		/*-------------------------------------------
 5938: 		**	While trying to select for
 5939: 		**	getting the condition code,
 5940: 		**	a target reselected us.
 5941: 		**-------------------------------------------
 5942: 		*/
 5943: 		if (DEBUG_FLAGS & DEBUG_RESTART) {
 5944: 			PRINT_ADDR(cp->ccb);
 5945: 			printf ("in getcc reselect by t%d.\n",
 5946: 				INB(nc_ssid) & 0x0f);
 5947: 		}
 5948: 
 5949: 		/*
 5950: 		**	Mark this job
 5951: 		*/
 5952: 		cp->host_status = HS_BUSY;
 5953: 		cp->s_status = SCSI_STATUS_CHECK_COND;
 5954: 		np->target[cp->ccb->ccb_h.target_id].hold_cp = cp;
 5955: 
 5956: 		/*
 5957: 		**	And patch code to restart it.
 5958: 		*/
 5959: 		WRITESCRIPT(start0[0], SCR_INT);
 5960: 		break;
 5961: 
 5962: /*-----------------------------------------------------------------------------
 5963: **
 5964: **	Was Sie schon immer ueber transfermode negotiation wissen wollten ...
 5965: **
 5966: **	We try to negotiate sync and wide transfer only after
 5967: **	a successfull inquire command. We look at byte 7 of the
 5968: **	inquire data to determine the capabilities if the target.
 5969: **
 5970: **	When we try to negotiate, we append the negotiation message
 5971: **	to the identify and (maybe) simple tag message.
 5972: **	The host status field is set to HS_NEGOTIATE to mark this
 5973: **	situation.
 5974: **
 5975: **	If the target doesn't answer this message immidiately
 5976: **	(as required by the standard), the SIR_NEGO_FAIL interrupt
 5977: **	will be raised eventually.
 5978: **	The handler removes the HS_NEGOTIATE status, and sets the
 5979: **	negotiated value to the default (async / nowide).
 5980: **
 5981: **	If we receive a matching answer immediately, we check it
 5982: **	for validity, and set the values.
 5983: **
 5984: **	If we receive a Reject message immediately, we assume the
 5985: **	negotiation has failed, and fall back to standard values.
 5986: **
 5987: **	If we receive a negotiation message while not in HS_NEGOTIATE
 5988: **	state, it's a target initiated negotiation. We prepare a
 5989: **	(hopefully) valid answer, set our parameters, and send back 
 5990: **	this answer to the target.
 5991: **
 5992: **	If the target doesn't fetch the answer (no message out phase),
 5993: **	we assume the negotiation has failed, and fall back to default
 5994: **	settings.
 5995: **
 5996: **	When we set the values, we adjust them in all nccbs belonging 
 5997: **	to this target, in the controller's register, and in the "phys"
 5998: **	field of the controller's struct ncb.
 5999: **
 6000: **	Possible cases:		   hs  sir   msg_in value  send   goto
 6001: **	We try try to negotiate:
 6002: **	-> target doesnt't msgin   NEG FAIL  noop   defa.  -      dispatch
 6003: **	-> target rejected our msg NEG FAIL  reject defa.  -      dispatch
 6004: **	-> target answered  (ok)   NEG SYNC  sdtr   set    -      clrack
 6005: **	-> target answered (!ok)   NEG SYNC  sdtr   defa.  REJ--->msg_bad
 6006: **	-> target answered  (ok)   NEG WIDE  wdtr   set    -      clrack
 6007: **	-> target answered (!ok)   NEG WIDE  wdtr   defa.  REJ--->msg_bad
 6008: **	-> any other msgin	   NEG FAIL  noop   defa.  -      dispatch
 6009: **
 6010: **	Target tries to negotiate:
 6011: **	-> incoming message	   --- SYNC  sdtr   set    SDTR   -
 6012: **	-> incoming message	   --- WIDE  wdtr   set    WDTR   -
 6013: **      We sent our answer:
 6014: **	-> target doesn't msgout   --- PROTO ?      defa.  -      dispatch
 6015: **
 6016: **-----------------------------------------------------------------------------
 6017: */
 6018: 
 6019: 	case SIR_NEGO_FAILED:
 6020: 		/*-------------------------------------------------------
 6021: 		**
 6022: 		**	Negotiation failed.
 6023: 		**	Target doesn't send an answer message,
 6024: 		**	or target rejected our message.
 6025: 		**
 6026: 		**      Remove negotiation request.
 6027: 		**
 6028: 		**-------------------------------------------------------
 6029: 		*/
 6030: 		OUTB (HS_PRT, HS_BUSY);
 6031: 
 6032: 		/* fall through */
 6033: 
 6034: 	case SIR_NEGO_PROTO:
 6035: 		/*-------------------------------------------------------
 6036: 		**
 6037: 		**	Negotiation failed.
 6038: 		**	Target doesn't fetch the answer message.
 6039: 		**
 6040: 		**-------------------------------------------------------
 6041: 		*/
 6042: 
 6043: 		if (DEBUG_FLAGS & DEBUG_NEGO) {
 6044: 			PRINT_ADDR(cp->ccb);
 6045: 			printf ("negotiation failed sir=%x status=%x.\n",
 6046: 				num, cp->nego_status);
 6047: 		};
 6048: 
 6049: 		/*
 6050: 		**	any error in negotiation:
 6051: 		**	fall back to default mode.
 6052: 		*/
 6053: 		switch (cp->nego_status) {
 6054: 
 6055: 		case NS_SYNC:
 6056: 			ncr_setsync (np, cp, 0, 0xe0, 0);
 6057: 			break;
 6058: 
 6059: 		case NS_WIDE:
 6060: 			ncr_setwide (np, cp, 0, 0);
 6061: 			break;
 6062: 
 6063: 		};
 6064: 		np->msgin [0] = MSG_NOOP;
 6065: 		np->msgout[0] = MSG_NOOP;
 6066: 		cp->nego_status = 0;
 6067: 		OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, dispatch));
 6068: 		break;
 6069: 
 6070: 	case SIR_NEGO_SYNC:
 6071: 		/*
 6072: 		**	Synchronous request message received.
 6073: 		*/
 6074: 
 6075: 		if (DEBUG_FLAGS & DEBUG_NEGO) {
 6076: 			PRINT_ADDR(cp->ccb);
 6077: 			printf ("sync msgin: ");
 6078: 			(void) ncr_show_msg (np->msgin);
 6079: 			printf (".\n");
 6080: 		};
 6081: 
 6082: 		/*
 6083: 		**	get requested values.
 6084: 		*/
 6085: 
 6086: 		chg = 0;
 6087: 		per = np->msgin[3];
 6088: 		ofs = np->msgin[4];
 6089: 		if (ofs==0) per=255;
 6090: 
 6091: 		/*
 6092: 		**	check values against driver limits.
 6093: 		*/
 6094: 		if (per < np->minsync)
 6095: 			{chg = 1; per = np->minsync;}
 6096: 		if (per < tp->tinfo.user.period)
 6097: 			{chg = 1; per = tp->tinfo.user.period;}
 6098: 		if (ofs > tp->tinfo.user.offset)
 6099: 			{chg = 1; ofs = tp->tinfo.user.offset;}
 6100: 
 6101: 		/*
 6102: 		**	Check against controller limits.
 6103: 		*/
 6104: 
 6105: 		fak	= 7;
 6106: 		scntl3	= 0;
 6107: 		if (ofs != 0) {
 6108: 			ncr_getsync(np, per, &fak, &scntl3);
 6109: 			if (fak > 7) {
 6110: 				chg = 1;
 6111: 				ofs = 0;
 6112: 			}
 6113: 		}
 6114: 		if (ofs == 0) {
 6115: 			fak	= 7;
 6116: 			per	= 0;
 6117: 			scntl3	= 0;
 6118: 		}
 6119: 
 6120: 		if (DEBUG_FLAGS & DEBUG_NEGO) {
 6121: 			PRINT_ADDR(cp->ccb);
 6122: 			printf ("sync: per=%d scntl3=0x%x ofs=%d fak=%d chg=%d.\n",
 6123: 				per, scntl3, ofs, fak, chg);
 6124: 		}
 6125: 
 6126: 		if (INB (HS_PRT) == HS_NEGOTIATE) {
 6127: 			OUTB (HS_PRT, HS_BUSY);
 6128: 			switch (cp->nego_status) {
 6129: 
 6130: 			case NS_SYNC:
 6131: 				/*
 6132: 				**      This was an answer message
 6133: 				*/
 6134: 				if (chg) {
 6135: 					/*
 6136: 					**	Answer wasn't acceptable.
 6137: 					*/
 6138: 					ncr_setsync (np, cp, 0, 0xe0, 0);
 6139: 					OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad));
 6140: 				} else {
 6141: 					/*
 6142: 					**	Answer is ok.
 6143: 					*/
 6144: 					ncr_setsync (np,cp,scntl3,(fak<<5)|ofs, per);
 6145: 					OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack));
 6146: 				};
 6147: 				return;
 6148: 
 6149: 			case NS_WIDE:
 6150: 				ncr_setwide (np, cp, 0, 0);
 6151: 				break;
 6152: 			};
 6153: 		};
 6154: 
 6155: 		/*
 6156: 		**	It was a request. Set value and
 6157: 		**      prepare an answer message
 6158: 		*/
 6159: 
 6160: 		ncr_setsync (np, cp, scntl3, (fak<<5)|ofs, per);
 6161: 
 6162: 		np->msgout[0] = MSG_EXTENDED;
 6163: 		np->msgout[1] = 3;
 6164: 		np->msgout[2] = MSG_EXT_SDTR;
 6165: 		np->msgout[3] = per;
 6166: 		np->msgout[4] = ofs;
 6167: 
 6168: 		cp->nego_status = NS_SYNC;
 6169: 
 6170: 		if (DEBUG_FLAGS & DEBUG_NEGO) {
 6171: 			PRINT_ADDR(cp->ccb);
 6172: 			printf ("sync msgout: ");
 6173: 			(void) ncr_show_msg (np->msgout);
 6174: 			printf (".\n");
 6175: 		}
 6176: 
 6177: 		if (!ofs) {
 6178: 			OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad));
 6179: 			return;
 6180: 		}
 6181: 		np->msgin [0] = MSG_NOOP;
 6182: 
 6183: 		break;
 6184: 
 6185: 	case SIR_NEGO_WIDE:
 6186: 		/*
 6187: 		**	Wide request message received.
 6188: 		*/
 6189: 		if (DEBUG_FLAGS & DEBUG_NEGO) {
 6190: 			PRINT_ADDR(cp->ccb);
 6191: 			printf ("wide msgin: ");
 6192: 			(void) ncr_show_msg (np->msgin);
 6193: 			printf (".\n");
 6194: 		};
 6195: 
 6196: 		/*
 6197: 		**	get requested values.
 6198: 		*/
 6199: 
 6200: 		chg  = 0;
 6201: 		wide = np->msgin[3];
 6202: 
 6203: 		/*
 6204: 		**	check values against driver limits.
 6205: 		*/
 6206: 
 6207: 		if (wide > tp->tinfo.user.width)
 6208: 			{chg = 1; wide = tp->tinfo.user.width;}
 6209: 
 6210: 		if (DEBUG_FLAGS & DEBUG_NEGO) {
 6211: 			PRINT_ADDR(cp->ccb);
 6212: 			printf ("wide: wide=%d chg=%d.\n", wide, chg);
 6213: 		}
 6214: 
 6215: 		if (INB (HS_PRT) == HS_NEGOTIATE) {
 6216: 			OUTB (HS_PRT, HS_BUSY);
 6217: 			switch (cp->nego_status) {
 6218: 
 6219: 			case NS_WIDE:
 6220: 				/*
 6221: 				**      This was an answer message
 6222: 				*/
 6223: 				if (chg) {
 6224: 					/*
 6225: 					**	Answer wasn't acceptable.
 6226: 					*/
 6227: 					ncr_setwide (np, cp, 0, 1);
 6228: 					OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad));
 6229: 				} else {
 6230: 					/*
 6231: 					**	Answer is ok.
 6232: 					*/
 6233: 					ncr_setwide (np, cp, wide, 1);
 6234: 					OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack));
 6235: 				};
 6236: 				return;
 6237: 
 6238: 			case NS_SYNC:
 6239: 				ncr_setsync (np, cp, 0, 0xe0, 0);
 6240: 				break;
 6241: 			};
 6242: 		};
 6243: 
 6244: 		/*
 6245: 		**	It was a request, set value and
 6246: 		**      prepare an answer message
 6247: 		*/
 6248: 
 6249: 		ncr_setwide (np, cp, wide, 1);
 6250: 
 6251: 		np->msgout[0] = MSG_EXTENDED;
 6252: 		np->msgout[1] = 2;
 6253: 		np->msgout[2] = MSG_EXT_WDTR;
 6254: 		np->msgout[3] = wide;
 6255: 
 6256: 		np->msgin [0] = MSG_NOOP;
 6257: 
 6258: 		cp->nego_status = NS_WIDE;
 6259: 
 6260: 		if (DEBUG_FLAGS & DEBUG_NEGO) {
 6261: 			PRINT_ADDR(cp->ccb);
 6262: 			printf ("wide msgout: ");
 6263: 			(void) ncr_show_msg (np->msgout);
 6264: 			printf (".\n");
 6265: 		}
 6266: 		break;
 6267: 
 6268: /*--------------------------------------------------------------------
 6269: **
 6270: **	Processing of special messages
 6271: **
 6272: **--------------------------------------------------------------------
 6273: */
 6274: 
 6275: 	case SIR_REJECT_RECEIVED:
 6276: 		/*-----------------------------------------------
 6277: 		**
 6278: 		**	We received a MSG_MESSAGE_REJECT message.
 6279: 		**
 6280: 		**-----------------------------------------------
 6281: 		*/
 6282: 
 6283: 		PRINT_ADDR(cp->ccb);
 6284: 		printf ("MSG_MESSAGE_REJECT received (%x:%x).\n",
 6285: 			(unsigned)np->lastmsg, np->msgout[0]);
 6286: 		break;
 6287: 
 6288: 	case SIR_REJECT_SENT:
 6289: 		/*-----------------------------------------------
 6290: 		**
 6291: 		**	We received an unknown message
 6292: 		**
 6293: 		**-----------------------------------------------
 6294: 		*/
 6295: 
 6296: 		PRINT_ADDR(cp->ccb);
 6297: 		printf ("MSG_MESSAGE_REJECT sent for ");
 6298: 		(void) ncr_show_msg (np->msgin);
 6299: 		printf (".\n");
 6300: 		break;
 6301: 
 6302: /*--------------------------------------------------------------------
 6303: **
 6304: **	Processing of special messages
 6305: **
 6306: **--------------------------------------------------------------------
 6307: */
 6308: 
 6309: 	case SIR_IGN_RESIDUE:
 6310: 		/*-----------------------------------------------
 6311: 		**
 6312: 		**	We received an IGNORE RESIDUE message,
 6313: 		**	which couldn't be handled by the script.
 6314: 		**
 6315: 		**-----------------------------------------------
 6316: 		*/
 6317: 
 6318: 		PRINT_ADDR(cp->ccb);
 6319: 		printf ("MSG_IGN_WIDE_RESIDUE received, but not yet implemented.\n");
 6320: 		break;
 6321: 
 6322: 	case SIR_MISSING_SAVE:
 6323: 		/*-----------------------------------------------
 6324: 		**
 6325: 		**	We received an DISCONNECT message,
 6326: 		**	but the datapointer wasn't saved before.
 6327: 		**
 6328: 		**-----------------------------------------------
 6329: 		*/
 6330: 
 6331: 		PRINT_ADDR(cp->ccb);
 6332: 		printf ("MSG_DISCONNECT received, but datapointer not saved:\n"
 6333: 			"\tdata=%x save=%x goal=%x.\n",
 6334: 			(unsigned) INL (nc_temp),
 6335: 			(unsigned) np->header.savep,
 6336: 			(unsigned) np->header.goalp);
 6337: 		break;
 6338: 
 6339: /*--------------------------------------------------------------------
 6340: **
 6341: **	Processing of a "SCSI_STATUS_QUEUE_FULL" status.
 6342: **
 6343: **	XXX JGibbs - We should do the same thing for BUSY status.
 6344: **
 6345: **	The current command has been rejected,
 6346: **	because there are too many in the command queue.
 6347: **	We have started too many commands for that target.
 6348: **
 6349: **--------------------------------------------------------------------
 6350: */
 6351: 	case SIR_STALL_QUEUE:
 6352: 		cp->xerr_status = XE_OK;
 6353: 		cp->host_status = HS_COMPLETE;
 6354: 		cp->s_status = SCSI_STATUS_QUEUE_FULL;
 6355: 		ncr_freeze_devq(np, cp->ccb->ccb_h.path);
 6356: 		ncr_complete(np, cp);
 6357: 
 6358: 		/* FALL THROUGH */
 6359: 
 6360: 	case SIR_STALL_RESTART:
 6361: 		/*-----------------------------------------------
 6362: 		**
 6363: 		**	Enable selecting again,
 6364: 		**	if NO disconnected jobs.
 6365: 		**
 6366: 		**-----------------------------------------------
 6367: 		*/
 6368: 		/*
 6369: 		**	Look for a disconnected job.
 6370: 		*/
 6371: 		cp = np->link_nccb;
 6372: 		while (cp && cp->host_status != HS_DISCONNECT)
 6373: 			cp = cp->link_nccb;
 6374: 
 6375: 		/*
 6376: 		**	if there is one, ...
 6377: 		*/
 6378: 		if (cp) {
 6379: 			/*
 6380: 			**	wait for reselection
 6381: 			*/
 6382: 			OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, reselect));
 6383: 			return;
 6384: 		};
 6385: 
 6386: 		/*
 6387: 		**	else remove the interrupt.
 6388: 		*/
 6389: 
 6390: 		printf ("%s: queue empty.\n", ncr_name (np));
 6391: 		WRITESCRIPT(start1[0], SCR_INT ^ IFFALSE (0));
 6392: 		break;
 6393: 	};
 6394: 
 6395: out:
 6396: 	OUTB (nc_dcntl, np->rv_dcntl | STD);
 6397: }
 6398: 
 6399: /*==========================================================
 6400: **
 6401: **
 6402: **	Aquire a control block
 6403: **
 6404: **
 6405: **==========================================================
 6406: */
 6407: 
 6408: static	nccb_p ncr_get_nccb
 6409: 	(ncb_p np, u_long target, u_long lun)
 6410: {
 6411: 	lcb_p lp;
 6412: 	int s;
 6413: 	nccb_p cp = NULL;
 6414: 
 6415: 	/* Keep our timeout handler out */
 6416: 	s = splsoftclock();
 6417: 	
 6418: 	/*
 6419: 	**	Lun structure available ?
 6420: 	*/
 6421: 
 6422: 	lp = np->target[target].lp[lun];
 6423: 	if (lp) {
 6424: 		cp = lp->next_nccb;
 6425: 
 6426: 		/*
 6427: 		**	Look for free CCB
 6428: 		*/
 6429: 
 6430: 		while (cp && cp->magic) {
 6431: 			cp = cp->next_nccb;
 6432: 		}
 6433: 	}
 6434: 
 6435: 	/*
 6436: 	**	if nothing available, create one.
 6437: 	*/
 6438: 
 6439: 	if (cp == NULL)
 6440: 		cp = ncr_alloc_nccb(np, target, lun);
 6441: 
 6442: 	if (cp != NULL) {
 6443: 		if (cp->magic) {
 6444: 			printf("%s: Bogus free cp found\n", ncr_name(np));
 6445: 			splx(s);
 6446: 			return (NULL);
 6447: 		}
 6448: 		cp->magic = 1;
 6449: 	}
 6450: 	splx(s);
 6451: 	return (cp);
 6452: }
 6453: 
 6454: /*==========================================================
 6455: **
 6456: **
 6457: **	Release one control block
 6458: **
 6459: **
 6460: **==========================================================
 6461: */
 6462: 
 6463: void ncr_free_nccb (ncb_p np, nccb_p cp)
 6464: {
 6465: 	/*
 6466: 	**    sanity
 6467: 	*/
 6468: 
 6469: 	assert (cp != NULL);
 6470: 
 6471: 	cp -> host_status = HS_IDLE;
 6472: 	cp -> magic = 0;
 6473: }
 6474: 
 6475: /*==========================================================
 6476: **
 6477: **
 6478: **      Allocation of resources for Targets/Luns/Tags.
 6479: **
 6480: **
 6481: **==========================================================
 6482: */
 6483: 
 6484: static nccb_p
 6485: ncr_alloc_nccb (ncb_p np, u_long target, u_long lun)
 6486: {
 6487: 	tcb_p tp;
 6488: 	lcb_p lp;
 6489: 	nccb_p cp;
 6490: 
 6491: 	assert (np != NULL);
 6492: 
 6493: 	if (target>=MAX_TARGET) return(NULL);
 6494: 	if (lun   >=MAX_LUN   ) return(NULL);
 6495: 
 6496: 	tp=&np->target[target];
 6497: 
 6498: 	if (!tp->jump_tcb.l_cmd) {
 6499: 
 6500: 		/*
 6501: 		**	initialize it.
 6502: 		*/
 6503: 		tp->jump_tcb.l_cmd   = (SCR_JUMP^IFFALSE (DATA (0x80 + target)));
 6504: 		tp->jump_tcb.l_paddr = np->jump_tcb.l_paddr;
 6505: 
 6506: 		tp->getscr[0] =
 6507: 			(np->features & FE_PFEN)? SCR_COPY(1) : SCR_COPY_F(1);
 6508: 		tp->getscr[1] = vtophys (&tp->tinfo.sval);
 6509: 		tp->getscr[2] = rman_get_start(np->reg_res) + offsetof (struct ncr_reg, nc_sxfer);
 6510: 		tp->getscr[3] =
 6511: 			(np->features & FE_PFEN)? SCR_COPY(1) : SCR_COPY_F(1);
 6512: 		tp->getscr[4] = vtophys (&tp->tinfo.wval);
 6513: 		tp->getscr[5] = rman_get_start(np->reg_res) + offsetof (struct ncr_reg, nc_scntl3);
 6514: 
 6515: 		assert (((offsetof(struct ncr_reg, nc_sxfer) ^
 6516: 			 (offsetof(struct tcb ,tinfo)
 6517: 			+ offsetof(struct ncr_target_tinfo, sval))) & 3) == 0);
 6518: 		assert (((offsetof(struct ncr_reg, nc_scntl3) ^
 6519: 			 (offsetof(struct tcb, tinfo)
 6520: 			+ offsetof(struct ncr_target_tinfo, wval))) &3) == 0);
 6521: 
 6522: 		tp->call_lun.l_cmd   = (SCR_CALL);
 6523: 		tp->call_lun.l_paddr = NCB_SCRIPT_PHYS (np, resel_lun);
 6524: 
 6525: 		tp->jump_lcb.l_cmd   = (SCR_JUMP);
 6526: 		tp->jump_lcb.l_paddr = NCB_SCRIPTH_PHYS (np, abort);
 6527: 		np->jump_tcb.l_paddr = vtophys (&tp->jump_tcb);
 6528: 	}
 6529: 
 6530: 	/*
 6531: 	**	Logic unit control block
 6532: 	*/
 6533: 	lp = tp->lp[lun];
 6534: 	if (!lp) {
 6535: 		/*
 6536: 		**	Allocate a lcb
 6537: 		*/
 6538: 		lp = (lcb_p) malloc (sizeof (struct lcb), M_DEVBUF, M_NOWAIT);
 6539: 		if (!lp) return(NULL);
 6540: 
 6541: 		/*
 6542: 		**	Initialize it
 6543: 		*/
 6544: 		bzero (lp, sizeof (*lp));
 6545: 		lp->jump_lcb.l_cmd   = (SCR_JUMP ^ IFFALSE (DATA (lun)));
 6546: 		lp->jump_lcb.l_paddr = tp->jump_lcb.l_paddr;
 6547: 
 6548: 		lp->call_tag.l_cmd   = (SCR_CALL);
 6549: 		lp->call_tag.l_paddr = NCB_SCRIPT_PHYS (np, resel_tag);
 6550: 
 6551: 		lp->jump_nccb.l_cmd   = (SCR_JUMP);
 6552: 		lp->jump_nccb.l_paddr = NCB_SCRIPTH_PHYS (np, aborttag);
 6553: 
 6554: 		lp->actlink = 1;
 6555: 
 6556: 		/*
 6557: 		**   Chain into LUN list
 6558: 		*/
 6559: 		tp->jump_lcb.l_paddr = vtophys (&lp->jump_lcb);
 6560: 		tp->lp[lun] = lp;
 6561: 
 6562: 	}
 6563: 
 6564: 	/*
 6565: 	**	Allocate a nccb
 6566: 	*/
 6567: 	cp = (nccb_p) malloc (sizeof (struct nccb), M_DEVBUF, M_NOWAIT);
 6568: 
 6569: 	if (!cp)
 6570: 		return (NULL);
 6571: 
 6572: 	if (DEBUG_FLAGS & DEBUG_ALLOC) { 
 6573: 		printf ("new nccb @%p.\n", cp);
 6574: 	}
 6575: 
 6576: 	/*
 6577: 	**	Initialize it
 6578: 	*/
 6579: 	bzero (cp, sizeof (*cp));
 6580: 
 6581: 	/*
 6582: 	**	Fill in physical addresses
 6583: 	*/
 6584: 
 6585: 	cp->p_nccb	     = vtophys (cp);
 6586: 
 6587: 	/*
 6588: 	**	Chain into reselect list
 6589: 	*/
 6590: 	cp->jump_nccb.l_cmd   = SCR_JUMP;
 6591: 	cp->jump_nccb.l_paddr = lp->jump_nccb.l_paddr;
 6592: 	lp->jump_nccb.l_paddr = CCB_PHYS (cp, jump_nccb);
 6593: 	cp->call_tmp.l_cmd   = SCR_CALL;
 6594: 	cp->call_tmp.l_paddr = NCB_SCRIPT_PHYS (np, resel_tmp);
 6595: 
 6596: 	/*
 6597: 	**	Chain into wakeup list
 6598: 	*/
 6599: 	cp->link_nccb      = np->link_nccb;
 6600: 	np->link_nccb	   = cp;
 6601: 
 6602: 	/*
 6603: 	**	Chain into CCB list
 6604: 	*/
 6605: 	cp->next_nccb	= lp->next_nccb;
 6606: 	lp->next_nccb	= cp;
 6607: 
 6608: 	return (cp);
 6609: }
 6610: 
 6611: /*==========================================================
 6612: **
 6613: **
 6614: **	Build Scatter Gather Block
 6615: **
 6616: **
 6617: **==========================================================
 6618: **
 6619: **	The transfer area may be scattered among
 6620: **	several non adjacent physical pages.
 6621: **
 6622: **	We may use MAX_SCATTER blocks.
 6623: **
 6624: **----------------------------------------------------------
 6625: */
 6626: 
 6627: static	int	ncr_scatter
 6628: 	(struct dsb* phys, vm_offset_t vaddr, vm_size_t datalen)
 6629: {
 6630: 	u_long	paddr, pnext;
 6631: 
 6632: 	u_short	segment  = 0;
 6633: 	u_long	segsize, segaddr;
 6634: 	u_long	size, csize    = 0;
 6635: 	u_long	chunk = MAX_SIZE;
 6636: 	int	free;
 6637: 
 6638: 	bzero (&phys->data, sizeof (phys->data));
 6639: 	if (!datalen) return (0);
 6640: 
 6641: 	paddr = vtophys (vaddr);
 6642: 
 6643: 	/*
 6644: 	**	insert extra break points at a distance of chunk.
 6645: 	**	We try to reduce the number of interrupts caused
 6646: 	**	by unexpected phase changes due to disconnects.
 6647: 	**	A typical harddisk may disconnect before ANY block.
 6648: 	**	If we wanted to avoid unexpected phase changes at all
 6649: 	**	we had to use a break point every 512 bytes.
 6650: 	**	Of course the number of scatter/gather blocks is
 6651: 	**	limited.
 6652: 	*/
 6653: 
 6654: 	free = MAX_SCATTER - 1;
 6655: 
 6656: 	if (vaddr & PAGE_MASK) free -= datalen / PAGE_SIZE;
 6657: 
 6658: 	if (free>1)
 6659: 		while ((chunk * free >= 2 * datalen) && (chunk>=1024))
 6660: 			chunk /= 2;
 6661: 
 6662: 	if(DEBUG_FLAGS & DEBUG_SCATTER)
 6663: 		printf("ncr?:\tscattering virtual=%p size=%d chunk=%d.\n",
 6664: 		       (void *) vaddr, (unsigned) datalen, (unsigned) chunk);
 6665: 
 6666: 	/*
 6667: 	**   Build data descriptors.
 6668: 	*/
 6669: 	while (datalen && (segment < MAX_SCATTER)) {
 6670: 
 6671: 		/*
 6672: 		**	this segment is empty
 6673: 		*/
 6674: 		segsize = 0;
 6675: 		segaddr = paddr;
 6676: 		pnext   = paddr;
 6677: 
 6678: 		if (!csize) csize = chunk;
 6679: 
 6680: 		while ((datalen) && (paddr == pnext) && (csize)) {
 6681: 
 6682: 			/*
 6683: 			**	continue this segment
 6684: 			*/
 6685: 			pnext = (paddr & (~PAGE_MASK)) + PAGE_SIZE;
 6686: 
 6687: 			/*
 6688: 			**	Compute max size
 6689: 			*/
 6690: 
 6691: 			size = pnext - paddr;		/* page size */
 6692: 			if (size > datalen) size = datalen;  /* data size */
 6693: 			if (size > csize  ) size = csize  ;  /* chunksize */
 6694: 
 6695: 			segsize += size;
 6696: 			vaddr   += size;
 6697: 			csize   -= size;
 6698: 			datalen -= size;
 6699: 			paddr    = vtophys (vaddr);
 6700: 		};
 6701: 
 6702: 		if(DEBUG_FLAGS & DEBUG_SCATTER)
 6703: 			printf ("\tseg #%d  addr=%x  size=%d  (rest=%d).\n",
 6704: 			segment,
 6705: 			(unsigned) segaddr,
 6706: 			(unsigned) segsize,
 6707: 			(unsigned) datalen);
 6708: 
 6709: 		phys->data[segment].addr = segaddr;
 6710: 		phys->data[segment].size = segsize;
 6711: 		segment++;
 6712: 	}
 6713: 
 6714: 	if (datalen) {
 6715: 		printf("ncr?: scatter/gather failed (residue=%d).\n",
 6716: 			(unsigned) datalen);
 6717: 		return (-1);
 6718: 	};
 6719: 
 6720: 	return (segment);
 6721: }
 6722: 
 6723: /*==========================================================
 6724: **
 6725: **
 6726: **	Test the pci bus snoop logic :-(
 6727: **
 6728: **	Has to be called with interrupts disabled.
 6729: **
 6730: **
 6731: **==========================================================
 6732: */
 6733: 
 6734: #ifndef NCR_IOMAPPED
 6735: static int ncr_regtest (struct ncb* np)
 6736: {
 6737: 	volatile u_int32_t data;
 6738: 	/*
 6739: 	**	ncr registers may NOT be cached.
 6740: 	**	write 0xffffffff to a read only register area,
 6741: 	**	and try to read it back.
 6742: 	*/
 6743: 	data = 0xffffffff;
 6744: 	OUTL_OFF(offsetof(struct ncr_reg, nc_dstat), data);
 6745: 	data = INL_OFF(offsetof(struct ncr_reg, nc_dstat));
 6746: #if 1
 6747: 	if (data == 0xffffffff) {
 6748: #else
 6749: 	if ((data & 0xe2f0fffd) != 0x02000080) {
 6750: #endif
 6751: 		printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n",
 6752: 			(unsigned) data);
 6753: 		return (0x10);
 6754: 	};
 6755: 	return (0);
 6756: }
 6757: #endif
 6758: 
 6759: static int ncr_snooptest (struct ncb* np)
 6760: {
 6761: 	u_int32_t ncr_rd, ncr_wr, ncr_bk, host_rd, host_wr, pc;
 6762: 	int	i, err=0;
 6763: #ifndef NCR_IOMAPPED
 6764: 	err |= ncr_regtest (np);
 6765: 	if (err) return (err);
 6766: #endif
 6767: 	/*
 6768: 	**	init
 6769: 	*/
 6770: 	pc  = NCB_SCRIPTH_PHYS (np, snooptest);
 6771: 	host_wr = 1;
 6772: 	ncr_wr  = 2;
 6773: 	/*
 6774: 	**	Set memory and register.
 6775: 	*/
 6776: 	ncr_cache = host_wr;
 6777: 	OUTL (nc_temp, ncr_wr);
 6778: 	/*
 6779: 	**	Start script (exchange values)
 6780: 	*/
 6781: 	OUTL (nc_dsp, pc);
 6782: 	/*
 6783: 	**	Wait 'til done (with timeout)
 6784: 	*/
 6785: 	for (i=0; i<NCR_SNOOP_TIMEOUT; i++)
 6786: 		if (INB(nc_istat) & (INTF|SIP|DIP))
 6787: 			break;
 6788: 	/*
 6789: 	**	Save termination position.
 6790: 	*/
 6791: 	pc = INL (nc_dsp);
 6792: 	/*
 6793: 	**	Read memory and register.
 6794: 	*/
 6795: 	host_rd = ncr_cache;
 6796: 	ncr_rd  = INL (nc_scratcha);
 6797: 	ncr_bk  = INL (nc_temp);
 6798: 	/*
 6799: 	**	Reset ncr chip
 6800: 	*/
 6801: 	OUTB (nc_istat,  SRST);
 6802: 	DELAY (1000);
 6803: 	OUTB (nc_istat,  0   );
 6804: 	/*
 6805: 	**	check for timeout
 6806: 	*/
 6807: 	if (i>=NCR_SNOOP_TIMEOUT) {
 6808: 		printf ("CACHE TEST FAILED: timeout.\n");
 6809: 		return (0x20);
 6810: 	};
 6811: 	/*
 6812: 	**	Check termination position.
 6813: 	*/
 6814: 	if (pc != NCB_SCRIPTH_PHYS (np, snoopend)+8) {
 6815: 		printf ("CACHE TEST FAILED: script execution failed.\n");
 6816: 		printf ("start=%08lx, pc=%08lx, end=%08lx\n", 
 6817: 			(u_long) NCB_SCRIPTH_PHYS (np, snooptest), (u_long) pc,
 6818: 			(u_long) NCB_SCRIPTH_PHYS (np, snoopend) +8);
 6819: 		return (0x40);
 6820: 	};
 6821: 	/*
 6822: 	**	Show results.
 6823: 	*/
 6824: 	if (host_wr != ncr_rd) {
 6825: 		printf ("CACHE TEST FAILED: host wrote %d, ncr read %d.\n",
 6826: 			(int) host_wr, (int) ncr_rd);
 6827: 		err |= 1;
 6828: 	};
 6829: 	if (host_rd != ncr_wr) {
 6830: 		printf ("CACHE TEST FAILED: ncr wrote %d, host read %d.\n",
 6831: 			(int) ncr_wr, (int) host_rd);
 6832: 		err |= 2;
 6833: 	};
 6834: 	if (ncr_bk != ncr_wr) {
 6835: 		printf ("CACHE TEST FAILED: ncr wrote %d, read back %d.\n",
 6836: 			(int) ncr_wr, (int) ncr_bk);
 6837: 		err |= 4;
 6838: 	};
 6839: 	return (err);
 6840: }
 6841: 
 6842: /*==========================================================
 6843: **
 6844: **
 6845: **	Profiling the drivers and targets performance.
 6846: **
 6847: **
 6848: **==========================================================
 6849: */
 6850: 
 6851: /*
 6852: **	Compute the difference in milliseconds.
 6853: **/
 6854: 
 6855: static	int ncr_delta (int *from, int *to)
 6856: {
 6857: 	if (!from) return (-1);
 6858: 	if (!to)   return (-2);
 6859: 	return ((to - from) * 1000 / hz);
 6860: }
 6861: 
 6862: #define PROFILE  cp->phys.header.stamp
 6863: static	void ncb_profile (ncb_p np, nccb_p cp)
 6864: {
 6865: 	int co, da, st, en, di, se, post,work,disc;
 6866: 	u_long diff;
 6867: 
 6868: 	PROFILE.end = ticks;
 6869: 
 6870: 	st = ncr_delta (&PROFILE.start,&PROFILE.status);
 6871: 	if (st<0) return;	/* status  not reached  */
 6872: 
 6873: 	da = ncr_delta (&PROFILE.start,&PROFILE.data);
 6874: 	if (da<0) return;	/* No data transfer phase */
 6875: 
 6876: 	co = ncr_delta (&PROFILE.start,&PROFILE.command);
 6877: 	if (co<0) return;	/* command not executed */
 6878: 
 6879: 	en = ncr_delta (&PROFILE.start,&PROFILE.end),
 6880: 	di = ncr_delta (&PROFILE.start,&PROFILE.disconnect),
 6881: 	se = ncr_delta (&PROFILE.start,&PROFILE.select);
 6882: 	post = en - st;
 6883: 
 6884: 	/*
 6885: 	**	@PROFILE@  Disconnect time invalid if multiple disconnects
 6886: 	*/
 6887: 
 6888: 	if (di>=0) disc = se-di; else  disc = 0;
 6889: 
 6890: 	work = (st - co) - disc;
 6891: 
 6892: 	diff = (np->disc_phys - np->disc_ref) & 0xff;
 6893: 	np->disc_ref += diff;
 6894: 
 6895: 	np->profile.num_trans	+= 1;
 6896: 	if (cp->ccb)
 6897: 		np->profile.num_bytes	+= cp->ccb->csio.dxfer_len;
 6898: 	np->profile.num_disc	+= diff;
 6899: 	np->profile.ms_setup	+= co;
 6900: 	np->profile.ms_data	+= work;
 6901: 	np->profile.ms_disc	+= disc;
 6902: 	np->profile.ms_post	+= post;
 6903: }
 6904: #undef PROFILE
 6905: 
 6906: /*==========================================================
 6907: **
 6908: **	Determine the ncr's clock frequency.
 6909: **	This is essential for the negotiation
 6910: **	of the synchronous transfer rate.
 6911: **
 6912: **==========================================================
 6913: **
 6914: **	Note: we have to return the correct value.
 6915: **	THERE IS NO SAVE DEFAULT VALUE.
 6916: **
 6917: **	Most NCR/SYMBIOS boards are delivered with a 40 Mhz clock.
 6918: **	53C860 and 53C875 rev. 1 support fast20 transfers but 
 6919: **	do not have a clock doubler and so are provided with a 
 6920: **	80 MHz clock. All other fast20 boards incorporate a doubler 
 6921: **	and so should be delivered with a 40 MHz clock.
 6922: **	The future fast40 chips (895/895) use a 40 Mhz base clock 
 6923: **	and provide a clock quadrupler (160 Mhz). The code below 
 6924: **	tries to deal as cleverly as possible with all this stuff.
 6925: **
 6926: **----------------------------------------------------------
 6927: */
 6928: 
 6929: /*
 6930:  *	Select NCR SCSI clock frequency
 6931:  */
 6932: static void ncr_selectclock(ncb_p np, u_char scntl3)
 6933: {
 6934: 	if (np->multiplier < 2) {
 6935: 		OUTB(nc_scntl3,	scntl3);
 6936: 		return;
 6937: 	}
 6938: 
 6939: 	if (bootverbose >= 2)
 6940: 		printf ("%s: enabling clock multiplier\n", ncr_name(np));
 6941: 
 6942: 	OUTB(nc_stest1, DBLEN);	   /* Enable clock multiplier		  */
 6943: 	if (np->multiplier > 2) {  /* Poll bit 5 of stest4 for quadrupler */
 6944: 		int i = 20;
 6945: 		while (!(INB(nc_stest4) & LCKFRQ) && --i > 0)
 6946: 			DELAY(20);
 6947: 		if (!i)
 6948: 			printf("%s: the chip cannot lock the frequency\n", ncr_name(np));
 6949: 	} else			/* Wait 20 micro-seconds for doubler	*/
 6950: 		DELAY(20);
 6951: 	OUTB(nc_stest3, HSC);		/* Halt the scsi clock		*/
 6952: 	OUTB(nc_scntl3,	scntl3);
 6953: 	OUTB(nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier	*/
 6954: 	OUTB(nc_stest3, 0x00);		/* Restart scsi clock 		*/
 6955: }
 6956: 
 6957: /*
 6958:  *	calculate NCR SCSI clock frequency (in KHz)
 6959:  */
 6960: static unsigned
 6961: ncrgetfreq (ncb_p np, int gen)
 6962: {
 6963: 	int ms = 0;
 6964: 	/*
 6965: 	 * Measure GEN timer delay in order 
 6966: 	 * to calculate SCSI clock frequency
 6967: 	 *
 6968: 	 * This code will never execute too
 6969: 	 * many loop iterations (if DELAY is 
 6970: 	 * reasonably correct). It could get
 6971: 	 * too low a delay (too high a freq.)
 6972: 	 * if the CPU is slow executing the 
 6973: 	 * loop for some reason (an NMI, for
 6974: 	 * example). For this reason we will
 6975: 	 * if multiple measurements are to be 
 6976: 	 * performed trust the higher delay 
 6977: 	 * (lower frequency returned).
 6978: 	 */
 6979: 	OUTB (nc_stest1, 0);	/* make sure clock doubler is OFF	    */
 6980: 	OUTW (nc_sien , 0);	/* mask all scsi interrupts		    */
 6981: 	(void) INW (nc_sist);	/* clear pending scsi interrupt		    */
 6982: 	OUTB (nc_dien , 0);	/* mask all dma interrupts		    */
 6983: 	(void) INW (nc_sist);	/* another one, just to be sure :)	    */
 6984: 	OUTB (nc_scntl3, 4);	/* set pre-scaler to divide by 3	    */
 6985: 	OUTB (nc_stime1, 0);	/* disable general purpose timer	    */
 6986: 	OUTB (nc_stime1, gen);	/* set to nominal delay of (1<<gen) * 125us */
 6987: 	while (!(INW(nc_sist) & GEN) && ms++ < 1000)
 6988: 		DELAY(1000);	/* count ms				    */
 6989: 	OUTB (nc_stime1, 0);	/* disable general purpose timer	    */
 6990: 	OUTB (nc_scntl3, 0);
 6991: 	/*
 6992: 	 * Set prescaler to divide by whatever "0" means.
 6993: 	 * "0" ought to choose divide by 2, but appears
 6994: 	 * to set divide by 3.5 mode in my 53c810 ...
 6995: 	 */
 6996: 	OUTB (nc_scntl3, 0);
 6997: 
 6998: 	if (bootverbose >= 2)
 6999: 	  	printf ("\tDelay (GEN=%d): %u msec\n", gen, ms);
 7000: 	/*
 7001: 	 * adjust for prescaler, and convert into KHz 
 7002: 	 */
 7003: 	return ms ? ((1 << gen) * 4440) / ms : 0;
 7004: }
 7005: 
 7006: static void ncr_getclock (ncb_p np, u_char multiplier)
 7007: {
 7008: 	unsigned char scntl3;
 7009: 	unsigned char stest1;
 7010: 	scntl3 = INB(nc_scntl3);
 7011: 	stest1 = INB(nc_stest1);
 7012: 	  
 7013: 	np->multiplier = 1;
 7014: 
 7015: 	if (multiplier > 1) {
 7016: 		np->multiplier	= multiplier;
 7017: 		np->clock_khz	= 40000 * multiplier;
 7018: 	} else {
 7019: 		if ((scntl3 & 7) == 0) {
 7020: 			unsigned f1, f2;
 7021: 			/* throw away first result */
 7022: 			(void) ncrgetfreq (np, 11);
 7023: 			f1 = ncrgetfreq (np, 11);
 7024: 			f2 = ncrgetfreq (np, 11);
 7025: 
 7026: 			if (bootverbose >= 2)
 7027: 			  printf ("\tNCR clock is %uKHz, %uKHz\n", f1, f2);
 7028: 			if (f1 > f2) f1 = f2;	/* trust lower result	*/
 7029: 			if (f1 > 45000) {
 7030: 				scntl3 = 5;	/* >45Mhz: assume 80MHz	*/
 7031: 			} else {
 7032: 				scntl3 = 3;	/* <45Mhz: assume 40MHz	*/
 7033: 			}
 7034: 		}
 7035: 		else if ((scntl3 & 7) == 5)
 7036: 			np->clock_khz = 80000;	/* Probably a 875 rev. 1 ? */
 7037: 	}
 7038: }
 7039: 
 7040: /*=========================================================================*/
 7041: 
 7042: #ifdef NCR_TEKRAM_EEPROM
 7043: 
 7044: struct tekram_eeprom_dev {
 7045:   u_char	devmode;
 7046: #define	TKR_PARCHK	0x01
 7047: #define	TKR_TRYSYNC	0x02
 7048: #define	TKR_ENDISC	0x04
 7049: #define	TKR_STARTUNIT	0x08
 7050: #define	TKR_USETAGS	0x10
 7051: #define	TKR_TRYWIDE	0x20
 7052:   u_char	syncparam;	/* max. sync transfer rate (table ?) */
 7053:   u_char	filler1;
 7054:   u_char	filler2;
 7055: };
 7056: 
 7057: 
 7058: struct tekram_eeprom {
 7059:   struct tekram_eeprom_dev 
 7060: 		dev[16];
 7061:   u_char	adaptid;
 7062:   u_char	adaptmode;
 7063: #define	TKR_ADPT_GT2DRV	0x01
 7064: #define	TKR_ADPT_GT1GB	0x02
 7065: #define	TKR_ADPT_RSTBUS	0x04
 7066: #define	TKR_ADPT_ACTNEG	0x08
 7067: #define	TKR_ADPT_NOSEEK	0x10
 7068: #define	TKR_ADPT_MORLUN	0x20
 7069:   u_char	delay;		/* unit ? ( table ??? ) */
 7070:   u_char	tags;		/* use 4 times as many ... */
 7071:   u_char	filler[60];
 7072: };
 7073: 
 7074: static void
 7075: tekram_write_bit (ncb_p np, int bit)
 7076: {
 7077: 	u_char val = 0x10 + ((bit & 1) << 1);
 7078: 
 7079: 	DELAY(10);
 7080: 	OUTB (nc_gpreg, val);
 7081: 	DELAY(10);
 7082: 	OUTB (nc_gpreg, val | 0x04);
 7083: 	DELAY(10);
 7084: 	OUTB (nc_gpreg, val);
 7085: 	DELAY(10);
 7086: }
 7087: 
 7088: static int
 7089: tekram_read_bit (ncb_p np)
 7090: {
 7091: 	OUTB (nc_gpreg, 0x10);
 7092: 	DELAY(10);
 7093: 	OUTB (nc_gpreg, 0x14);
 7094: 	DELAY(10);
 7095: 	return INB (nc_gpreg) & 1;
 7096: }
 7097: 
 7098: static u_short
 7099: read_tekram_eeprom_reg (ncb_p np, int reg)
 7100: {
 7101: 	int bit;
 7102: 	u_short result = 0;
 7103: 	int cmd = 0x80 | reg;
 7104: 
 7105: 	OUTB (nc_gpreg, 0x10);
 7106: 
 7107: 	tekram_write_bit (np, 1);
 7108: 	for (bit = 7; bit >= 0; bit--)
 7109: 	{
 7110: 		tekram_write_bit (np, cmd >> bit);
 7111: 	}
 7112: 
 7113: 	for (bit = 0; bit < 16; bit++)
 7114: 	{
 7115: 		result <<= 1;
 7116: 		result |= tekram_read_bit (np);
 7117: 	}
 7118: 
 7119: 	OUTB (nc_gpreg, 0x00);
 7120: 	return result;
 7121: }
 7122: 
 7123: static int 
 7124: read_tekram_eeprom(ncb_p np, struct tekram_eeprom *buffer)
 7125: {
 7126: 	u_short *p = (u_short *) buffer;
 7127: 	u_short sum = 0;
 7128: 	int i;
 7129: 
 7130: 	if (INB (nc_gpcntl) != 0x09)
 7131: 	{
 7132: 		return 0;
 7133:         }
 7134: 	for (i = 0; i < 64; i++)
 7135: 	{
 7136: 		u_short val;
 7137: if((i&0x0f) == 0) printf ("%02x:", i*2);
 7138: 		val = read_tekram_eeprom_reg (np, i);
 7139: 		if (p)
 7140: 			*p++ = val;
 7141: 		sum += val;
 7142: if((i&0x01) == 0x00) printf (" ");
 7143: 		printf ("%02x%02x", val & 0xff, (val >> 8) & 0xff);
 7144: if((i&0x0f) == 0x0f) printf ("\n");
 7145: 	}
 7146: printf ("Sum = %04x\n", sum);
 7147: 	return sum == 0x1234;
 7148: }
 7149: #endif /* NCR_TEKRAM_EEPROM */
 7150: 
 7151: static device_method_t ncr_methods[] = {
 7152: 	/* Device interface */
 7153: 	DEVMETHOD(device_probe,		ncr_probe),
 7154: 	DEVMETHOD(device_attach,	ncr_attach),
 7155: 
 7156: 	{ 0, 0 }
 7157: };
 7158: 
 7159: static driver_t ncr_driver = {
 7160: 	"ncr",
 7161: 	ncr_methods,
 7162: 	sizeof(struct ncb),
 7163: };
 7164: 
 7165: static devclass_t ncr_devclass;
 7166: 
 7167: DRIVER_MODULE(if_ncr, pci, ncr_driver, ncr_devclass, 0, 0);
 7168: 
 7169: /*=========================================================================*/
 7170: #endif /* _KERNEL */