File:  [DragonFly] / src / sys / dev / disk / ncr / ncr.c
Revision 1.6: download - view: text, annotated - select for diffs
Fri Feb 13 01:04:15 2004 UTC (10 years, 6 months ago) by joerg
Branches: MAIN
CVS tags: HEAD
Add __DragonFly__

    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.6 2004/02/13 01:04:15 joerg 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(__DragonFly__) || 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 */