ia64/xen-unstable

changeset 344:8c63ec842aca

bitkeeper revision 1.158 (3e7f35efVNlyrwE0DBZroZDSrpov-Q)

Merge cairnwell.research:/home/jws/projects/xen/xeno.bk
into cairnwell.research:/home/jws/projects/xen/scsichanges/xeno.bk
author jws@cairnwell.research
date Mon Mar 24 16:44:31 2003 +0000 (2003-03-24)
parents 3426ef69b9dc 6c0d4e714b9c
children dc2e4de1850f
files .rootkeys BitKeeper/etc/logging_ok xen/common/lib.c xen/common/string.c xen/drivers/scsi/Makefile xen/drivers/scsi/aic7xxx/Makefile xen/drivers/scsi/aic7xxx/aic7770.c xen/drivers/scsi/aic7xxx/aic7770_osm.c xen/drivers/scsi/aic7xxx/aic79xx.h xen/drivers/scsi/aic7xxx/aic79xx.reg xen/drivers/scsi/aic7xxx/aic79xx.seq xen/drivers/scsi/aic7xxx/aic79xx_core.c xen/drivers/scsi/aic7xxx/aic79xx_host.h xen/drivers/scsi/aic7xxx/aic79xx_inline.h xen/drivers/scsi/aic7xxx/aic79xx_osm.c xen/drivers/scsi/aic7xxx/aic79xx_osm.h xen/drivers/scsi/aic7xxx/aic79xx_osm_pci.c xen/drivers/scsi/aic7xxx/aic79xx_pci.c xen/drivers/scsi/aic7xxx/aic79xx_proc.c xen/drivers/scsi/aic7xxx/aic79xx_reg.h xen/drivers/scsi/aic7xxx/aic79xx_seq.h xen/drivers/scsi/aic7xxx/aic7xxx.h xen/drivers/scsi/aic7xxx/aic7xxx.reg xen/drivers/scsi/aic7xxx/aic7xxx.seq xen/drivers/scsi/aic7xxx/aic7xxx_93cx6.c xen/drivers/scsi/aic7xxx/aic7xxx_93cx6.h xen/drivers/scsi/aic7xxx/aic7xxx_core.c xen/drivers/scsi/aic7xxx/aic7xxx_host.h xen/drivers/scsi/aic7xxx/aic7xxx_inline.h xen/drivers/scsi/aic7xxx/aic7xxx_osm.c xen/drivers/scsi/aic7xxx/aic7xxx_osm.h xen/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c xen/drivers/scsi/aic7xxx/aic7xxx_pci.c xen/drivers/scsi/aic7xxx/aic7xxx_proc.c xen/drivers/scsi/aic7xxx/aic7xxx_reg.h xen/drivers/scsi/aic7xxx/aic7xxx_seq.h xen/drivers/scsi/aic7xxx/aicasm/Makefile xen/drivers/scsi/aic7xxx/aicasm/aicasm.c xen/drivers/scsi/aic7xxx/aicasm/aicasm.h xen/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y xen/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h xen/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y xen/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l xen/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l xen/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c xen/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h xen/drivers/scsi/aic7xxx/cam.h xen/drivers/scsi/aic7xxx/queue.h xen/drivers/scsi/aic7xxx/scsi_iu.h xen/drivers/scsi/aic7xxx/scsi_message.h xen/include/asm-i386/string.h xen/include/xeno/lib.h xen/include/xeno/string.h
line diff
     1.1 --- a/.rootkeys	Sun Mar 23 21:43:43 2003 +0000
     1.2 +++ b/.rootkeys	Mon Mar 24 16:44:31 2003 +0000
     1.3 @@ -246,6 +246,7 @@ 3ddb79bdHqdQpATqC0rmUZNbsb6L6A xen/commo
     1.4  3e397e6619PgAfBbw2XFbXkewvUWgw xen/common/schedule.c
     1.5  3ddb79bdB9RNMnkQnUyZ5C9hhMSQQw xen/common/slab.c
     1.6  3ddb79bd0gVQYmL2zvuJnldvD0AGxQ xen/common/softirq.c
     1.7 +3e7f358awXBC3Vw-wFRwPw18qL1khg xen/common/string.c
     1.8  3ddb79bdQqFHtHRGEO2dsxGgo6eAhw xen/common/timer.c
     1.9  3ddb79bd3zgV33PHdt-cgh3sxcb1hw xen/common/vsprintf.c
    1.10  3ddb79c0ppNeJtjC4va8j41ADCnchA xen/drivers/Makefile
    1.11 @@ -316,6 +317,51 @@ 3e564137iEHmY_e6xGZ7TLsjy5yS-g xen/drive
    1.12  3e564137taxQbEVa39h3mEVLFxRydQ xen/drivers/scsi/aacraid/linit.c
    1.13  3e564137vmALxpfK7vNINqEklSmQ1A xen/drivers/scsi/aacraid/rx.c
    1.14  3e564137EuYUJgvqnOunPERWxnp_mw xen/drivers/scsi/aacraid/sa.c
    1.15 +3e7f358amV8HBe1Cyges2wsBHfh-cw xen/drivers/scsi/aic7xxx/Makefile
    1.16 +3e7f358al_wJbBvERr7NzW5mLuTRpQ xen/drivers/scsi/aic7xxx/aic7770.c
    1.17 +3e7f358aCCSVBMcmsh64S7CCVIgVQg xen/drivers/scsi/aic7xxx/aic7770_osm.c
    1.18 +3e7f358aLNpSseMxk_DY6a-Ln9OyGg xen/drivers/scsi/aic7xxx/aic79xx.h
    1.19 +3e7f358ad7OR21rmyDNJfKyE1X1sxg xen/drivers/scsi/aic7xxx/aic79xx.reg
    1.20 +3e7f358a9Z39hG2enFVrNWjizvwthg xen/drivers/scsi/aic7xxx/aic79xx.seq
    1.21 +3e7f358aKzcs8L8XYcLD0bF8FrmtVg xen/drivers/scsi/aic7xxx/aic79xx_core.c
    1.22 +3e7f358ayrUAqJ9b8GxdRJQr5Po1zg xen/drivers/scsi/aic7xxx/aic79xx_host.h
    1.23 +3e7f358aVDB0b6qAf__XSDPubVM1RA xen/drivers/scsi/aic7xxx/aic79xx_inline.h
    1.24 +3e7f358aQFjWLEqUzd98Gy8z86vk2g xen/drivers/scsi/aic7xxx/aic79xx_osm.c
    1.25 +3e7f358adsO2cSMKATR_r9hPZ9KCUg xen/drivers/scsi/aic7xxx/aic79xx_osm.h
    1.26 +3e7f358avC9liKFAUFFRyWlVIIGZ2g xen/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
    1.27 +3e7f358aQ0ZpnmwtiT16raQb1QSGKQ xen/drivers/scsi/aic7xxx/aic79xx_pci.c
    1.28 +3e7f358af6BTct89-TCB31Rtw8NzQg xen/drivers/scsi/aic7xxx/aic79xx_proc.c
    1.29 +3e7f358aK54-KV7Wj014Yf5FnWo2VQ xen/drivers/scsi/aic7xxx/aic79xx_reg.h
    1.30 +3e7f358aZiCJAqEBttlmEDCMFcM-aA xen/drivers/scsi/aic7xxx/aic79xx_seq.h
    1.31 +3e7f358aPZhHGnMNAM3YCQcBIAnCfw xen/drivers/scsi/aic7xxx/aic7xxx.h
    1.32 +3e7f358aZRO8yoMXVLyDUyoFhsFnBw xen/drivers/scsi/aic7xxx/aic7xxx.reg
    1.33 +3e7f358aADKO4MLsWISX0-d2hpru0g xen/drivers/scsi/aic7xxx/aic7xxx.seq
    1.34 +3e7f358aB5x1ljQE7yWp63nvcfp4Mg xen/drivers/scsi/aic7xxx/aic7xxx_93cx6.c
    1.35 +3e7f358aDCmrU2Q35Ay765z7gWTSmQ xen/drivers/scsi/aic7xxx/aic7xxx_93cx6.h
    1.36 +3e7f358aXOqteLTeEH8XOlAeLPbXuQ xen/drivers/scsi/aic7xxx/aic7xxx_core.c
    1.37 +3e7f358adzSPC6RFtP4NyHB2PoT-Ew xen/drivers/scsi/aic7xxx/aic7xxx_host.h
    1.38 +3e7f358asCAiwyDZ1fBaiIxABh30BA xen/drivers/scsi/aic7xxx/aic7xxx_inline.h
    1.39 +3e7f358aDwj6BY9tJ4spPuZnQqBiew xen/drivers/scsi/aic7xxx/aic7xxx_osm.c
    1.40 +3e7f358anOWiWoFl7baNMWjqsPiYzg xen/drivers/scsi/aic7xxx/aic7xxx_osm.h
    1.41 +3e7f358a1sRjg-XkczIXH7dUX8K1ZA xen/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
    1.42 +3e7f358aj6uST9miAVmB9WNLqAGkCA xen/drivers/scsi/aic7xxx/aic7xxx_pci.c
    1.43 +3e7f358aCwRu3fI3NP7MQsLRpWV73w xen/drivers/scsi/aic7xxx/aic7xxx_proc.c
    1.44 +3e7f358aW8xbofV6VW2L8FPphmAXvg xen/drivers/scsi/aic7xxx/aic7xxx_reg.h
    1.45 +3e7f358ayQSlIZBIAGWYXBM5dtAFrA xen/drivers/scsi/aic7xxx/aic7xxx_seq.h
    1.46 +3e7f358acS9V8TbKLuyxvw-0SlgYmQ xen/drivers/scsi/aic7xxx/aicasm/Makefile
    1.47 +3e7f358arkcPw6k1oC2Wrp5TXFbovg xen/drivers/scsi/aic7xxx/aicasm/aicasm.c
    1.48 +3e7f358aF_JURnGn6q5V951k1TTnLg xen/drivers/scsi/aic7xxx/aicasm/aicasm.h
    1.49 +3e7f358a2aopdml6zsS1HF9oibF5RQ xen/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
    1.50 +3e7f358a2JQOz8ASFfi2oV5-k127RA xen/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
    1.51 +3e7f358a5kU_nwzMFh0xbG96yLgJKA xen/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
    1.52 +3e7f358a4FjmeDBfwgynM1InqFQ2nA xen/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l
    1.53 +3e7f358aoXDwp6vozr1x2Fwvb7x5BQ xen/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
    1.54 +3e7f358aUYJHOx790PiwQiJIlYECbA xen/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
    1.55 +3e7f358aPn8RK1slOgqrXC12x0FlgQ xen/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
    1.56 +3e7f358a6BujWXsqDmuts6N_A8dGhw xen/drivers/scsi/aic7xxx/cam.h
    1.57 +3e7f358anzaPhN49caB9AqMVw0_XKQ xen/drivers/scsi/aic7xxx/queue.h
    1.58 +3e7f358a3ggaLCNsnuArANSmNT1t2A xen/drivers/scsi/aic7xxx/scsi_iu.h
    1.59 +3e7f358arKN4VFRDcEasaM6Wj_VwTg xen/drivers/scsi/aic7xxx/scsi_message.h
    1.60  3e56411aOLzeD5CRbuXquOrX0lRijw xen/drivers/scsi/constants.c
    1.61  3ddb79beXZxwKh7cGyPfr40bhDyRrA xen/drivers/scsi/constants.h
    1.62  3e564120ZeinH9nf3IVSerB80T7dHg xen/drivers/scsi/hosts.c
    1.63 @@ -375,6 +421,7 @@ 3ddb79c3Hgbb2g8CyWLMCK-6_ZVQSQ xen/inclu
    1.64  3ddb79c3jn8ALV_S9W5aeTYUQRKBpg xen/include/asm-i386/smpboot.h
    1.65  3ddb79c3e9DCEoR-WzNxcOQDzLu7BQ xen/include/asm-i386/softirq.h
    1.66  3ddb79c3NiyQE2vQnyGiaBnNjBO1rA xen/include/asm-i386/spinlock.h
    1.67 +3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-i386/string.h
    1.68  3ddb79c3ezddh34MdelJpa5tNR00Dw xen/include/asm-i386/system.h
    1.69  3e397e66xPNc8eaSqC9pPbyAtRGzHA xen/include/asm-i386/time.h
    1.70  3e450943TfE-iovQIY_tMO_VdGsPhA xen/include/asm-i386/timex.h
    1.71 @@ -453,6 +500,7 @@ 3ddb79c09xbS-xxfKxuV3JETIhBzmg xen/inclu
    1.72  3ddb79c1-yIt89RT02wIPp2xDR8YjQ xen/include/xeno/socket.h
    1.73  3ddb79c2V2P9F2xMCzDJ9vbUofSg_Q xen/include/xeno/sockios.h
    1.74  3ddb79c2iIcESrDAB8samy_yAh6olQ xen/include/xeno/spinlock.h
    1.75 +3e7f358aMtFMUVvN_Zjg5qvEJIqEBA xen/include/xeno/string.h
    1.76  3ddb79c0BnA20PbgmuMPSGIBljNRQw xen/include/xeno/time.h
    1.77  3ddb79c2HFkXuRxi1CriJtSFmY6Ybw xen/include/xeno/timer.h
    1.78  3ddb79c2_m8lT9jDKse_tePj7zcnNQ xen/include/xeno/timex.h
     2.1 --- a/BitKeeper/etc/logging_ok	Sun Mar 23 21:43:43 2003 +0000
     2.2 +++ b/BitKeeper/etc/logging_ok	Mon Mar 24 16:44:31 2003 +0000
     2.3 @@ -5,6 +5,7 @@ akw27@plucky.localdomain
     2.4  bd240@boulderdash.cl.cam.ac.uk
     2.5  bd240@labyrinth.cl.cam.ac.uk
     2.6  iap10@labyrinth.cl.cam.ac.uk
     2.7 +jws@cairnwell.research
     2.8  kaf24@labyrinth.cl.cam.ac.uk
     2.9  kaf24@plym.cl.cam.ac.uk
    2.10  kaf24@scramble.cl.cam.ac.uk
     3.1 --- a/xen/common/lib.c	Sun Mar 23 21:43:43 2003 +0000
     3.2 +++ b/xen/common/lib.c	Mon Mar 24 16:44:31 2003 +0000
     3.3 @@ -2,6 +2,7 @@
     3.4  #include <xeno/ctype.h>
     3.5  #include <xeno/lib.h>
     3.6  
     3.7 +#if 0 // jws - now in string.c, string.h, asm/string.h 
     3.8  int memcmp(const void * cs,const void * ct,size_t count)
     3.9  {
    3.10  	const unsigned char *su1, *su2;
    3.11 @@ -119,7 +120,7 @@ char * strstr(const char * s1,const char
    3.12          }
    3.13          return NULL;
    3.14  }
    3.15 -
    3.16 +#endif
    3.17  
    3.18  /* for inc/ctype.h */
    3.19  unsigned char _ctype[] = {
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/common/string.c	Mon Mar 24 16:44:31 2003 +0000
     4.3 @@ -0,0 +1,535 @@
     4.4 +/*
     4.5 + *  linux/lib/string.c
     4.6 + *
     4.7 + *  Copyright (C) 1991, 1992  Linus Torvalds
     4.8 + */
     4.9 +
    4.10 +/*
    4.11 + * stupid library routines.. The optimized versions should generally be found
    4.12 + * as inline code in <asm-xx/string.h>
    4.13 + *
    4.14 + * These are buggy as well..
    4.15 + *
    4.16 + * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
    4.17 + * -  Added strsep() which will replace strtok() soon (because strsep() is
    4.18 + *    reentrant and should be faster). Use only strsep() in new code, please.
    4.19 + */
    4.20 + 
    4.21 +#include <linux/types.h>
    4.22 +#include <linux/string.h>
    4.23 +#include <linux/ctype.h>
    4.24 +
    4.25 +#ifndef __HAVE_ARCH_STRNICMP
    4.26 +/**
    4.27 + * strnicmp - Case insensitive, length-limited string comparison
    4.28 + * @s1: One string
    4.29 + * @s2: The other string
    4.30 + * @len: the maximum number of characters to compare
    4.31 + */
    4.32 +int strnicmp(const char *s1, const char *s2, size_t len)
    4.33 +{
    4.34 +	/* Yes, Virginia, it had better be unsigned */
    4.35 +	unsigned char c1, c2;
    4.36 +
    4.37 +	c1 = 0;	c2 = 0;
    4.38 +	if (len) {
    4.39 +		do {
    4.40 +			c1 = *s1; c2 = *s2;
    4.41 +			s1++; s2++;
    4.42 +			if (!c1)
    4.43 +				break;
    4.44 +			if (!c2)
    4.45 +				break;
    4.46 +			if (c1 == c2)
    4.47 +				continue;
    4.48 +			c1 = tolower(c1);
    4.49 +			c2 = tolower(c2);
    4.50 +			if (c1 != c2)
    4.51 +				break;
    4.52 +		} while (--len);
    4.53 +	}
    4.54 +	return (int)c1 - (int)c2;
    4.55 +}
    4.56 +#endif
    4.57 +
    4.58 +char * ___strtok;
    4.59 +
    4.60 +#ifndef __HAVE_ARCH_STRCPY
    4.61 +/**
    4.62 + * strcpy - Copy a %NUL terminated string
    4.63 + * @dest: Where to copy the string to
    4.64 + * @src: Where to copy the string from
    4.65 + */
    4.66 +char * strcpy(char * dest,const char *src)
    4.67 +{
    4.68 +	char *tmp = dest;
    4.69 +
    4.70 +	while ((*dest++ = *src++) != '\0')
    4.71 +		/* nothing */;
    4.72 +	return tmp;
    4.73 +}
    4.74 +#endif
    4.75 +
    4.76 +#ifndef __HAVE_ARCH_STRNCPY
    4.77 +/**
    4.78 + * strncpy - Copy a length-limited, %NUL-terminated string
    4.79 + * @dest: Where to copy the string to
    4.80 + * @src: Where to copy the string from
    4.81 + * @count: The maximum number of bytes to copy
    4.82 + *
    4.83 + * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
    4.84 + * However, the result is not %NUL-terminated if the source exceeds
    4.85 + * @count bytes.
    4.86 + */
    4.87 +char * strncpy(char * dest,const char *src,size_t count)
    4.88 +{
    4.89 +	char *tmp = dest;
    4.90 +
    4.91 +	while (count-- && (*dest++ = *src++) != '\0')
    4.92 +		/* nothing */;
    4.93 +
    4.94 +	return tmp;
    4.95 +}
    4.96 +#endif
    4.97 +
    4.98 +#ifndef __HAVE_ARCH_STRCAT
    4.99 +/**
   4.100 + * strcat - Append one %NUL-terminated string to another
   4.101 + * @dest: The string to be appended to
   4.102 + * @src: The string to append to it
   4.103 + */
   4.104 +char * strcat(char * dest, const char * src)
   4.105 +{
   4.106 +	char *tmp = dest;
   4.107 +
   4.108 +	while (*dest)
   4.109 +		dest++;
   4.110 +	while ((*dest++ = *src++) != '\0')
   4.111 +		;
   4.112 +
   4.113 +	return tmp;
   4.114 +}
   4.115 +#endif
   4.116 +
   4.117 +#ifndef __HAVE_ARCH_STRNCAT
   4.118 +/**
   4.119 + * strncat - Append a length-limited, %NUL-terminated string to another
   4.120 + * @dest: The string to be appended to
   4.121 + * @src: The string to append to it
   4.122 + * @count: The maximum numbers of bytes to copy
   4.123 + *
   4.124 + * Note that in contrast to strncpy, strncat ensures the result is
   4.125 + * terminated.
   4.126 + */
   4.127 +char * strncat(char *dest, const char *src, size_t count)
   4.128 +{
   4.129 +	char *tmp = dest;
   4.130 +
   4.131 +	if (count) {
   4.132 +		while (*dest)
   4.133 +			dest++;
   4.134 +		while ((*dest++ = *src++)) {
   4.135 +			if (--count == 0) {
   4.136 +				*dest = '\0';
   4.137 +				break;
   4.138 +			}
   4.139 +		}
   4.140 +	}
   4.141 +
   4.142 +	return tmp;
   4.143 +}
   4.144 +#endif
   4.145 +
   4.146 +#ifndef __HAVE_ARCH_STRCMP
   4.147 +/**
   4.148 + * strcmp - Compare two strings
   4.149 + * @cs: One string
   4.150 + * @ct: Another string
   4.151 + */
   4.152 +int strcmp(const char * cs,const char * ct)
   4.153 +{
   4.154 +	register signed char __res;
   4.155 +
   4.156 +	while (1) {
   4.157 +		if ((__res = *cs - *ct++) != 0 || !*cs++)
   4.158 +			break;
   4.159 +	}
   4.160 +
   4.161 +	return __res;
   4.162 +}
   4.163 +#endif
   4.164 +
   4.165 +#ifndef __HAVE_ARCH_STRNCMP
   4.166 +/**
   4.167 + * strncmp - Compare two length-limited strings
   4.168 + * @cs: One string
   4.169 + * @ct: Another string
   4.170 + * @count: The maximum number of bytes to compare
   4.171 + */
   4.172 +int strncmp(const char * cs,const char * ct,size_t count)
   4.173 +{
   4.174 +	register signed char __res = 0;
   4.175 +
   4.176 +	while (count) {
   4.177 +		if ((__res = *cs - *ct++) != 0 || !*cs++)
   4.178 +			break;
   4.179 +		count--;
   4.180 +	}
   4.181 +
   4.182 +	return __res;
   4.183 +}
   4.184 +#endif
   4.185 +
   4.186 +#ifndef __HAVE_ARCH_STRCHR
   4.187 +/**
   4.188 + * strchr - Find the first occurrence of a character in a string
   4.189 + * @s: The string to be searched
   4.190 + * @c: The character to search for
   4.191 + */
   4.192 +char * strchr(const char * s, int c)
   4.193 +{
   4.194 +	for(; *s != (char) c; ++s)
   4.195 +		if (*s == '\0')
   4.196 +			return NULL;
   4.197 +	return (char *) s;
   4.198 +}
   4.199 +#endif
   4.200 +
   4.201 +#ifndef __HAVE_ARCH_STRRCHR
   4.202 +/**
   4.203 + * strrchr - Find the last occurrence of a character in a string
   4.204 + * @s: The string to be searched
   4.205 + * @c: The character to search for
   4.206 + */
   4.207 +char * strrchr(const char * s, int c)
   4.208 +{
   4.209 +       const char *p = s + strlen(s);
   4.210 +       do {
   4.211 +           if (*p == (char)c)
   4.212 +               return (char *)p;
   4.213 +       } while (--p >= s);
   4.214 +       return NULL;
   4.215 +}
   4.216 +#endif
   4.217 +
   4.218 +#ifndef __HAVE_ARCH_STRLEN
   4.219 +/**
   4.220 + * strlen - Find the length of a string
   4.221 + * @s: The string to be sized
   4.222 + */
   4.223 +size_t strlen(const char * s)
   4.224 +{
   4.225 +	const char *sc;
   4.226 +
   4.227 +	for (sc = s; *sc != '\0'; ++sc)
   4.228 +		/* nothing */;
   4.229 +	return sc - s;
   4.230 +}
   4.231 +#endif
   4.232 +
   4.233 +#ifndef __HAVE_ARCH_STRNLEN
   4.234 +/**
   4.235 + * strnlen - Find the length of a length-limited string
   4.236 + * @s: The string to be sized
   4.237 + * @count: The maximum number of bytes to search
   4.238 + */
   4.239 +size_t strnlen(const char * s, size_t count)
   4.240 +{
   4.241 +	const char *sc;
   4.242 +
   4.243 +	for (sc = s; count-- && *sc != '\0'; ++sc)
   4.244 +		/* nothing */;
   4.245 +	return sc - s;
   4.246 +}
   4.247 +#endif
   4.248 +
   4.249 +#ifndef __HAVE_ARCH_STRSPN
   4.250 +/**
   4.251 + * strspn - Calculate the length of the initial substring of @s which only
   4.252 + * 	contain letters in @accept
   4.253 + * @s: The string to be searched
   4.254 + * @accept: The string to search for
   4.255 + */
   4.256 +size_t strspn(const char *s, const char *accept)
   4.257 +{
   4.258 +	const char *p;
   4.259 +	const char *a;
   4.260 +	size_t count = 0;
   4.261 +
   4.262 +	for (p = s; *p != '\0'; ++p) {
   4.263 +		for (a = accept; *a != '\0'; ++a) {
   4.264 +			if (*p == *a)
   4.265 +				break;
   4.266 +		}
   4.267 +		if (*a == '\0')
   4.268 +			return count;
   4.269 +		++count;
   4.270 +	}
   4.271 +
   4.272 +	return count;
   4.273 +}
   4.274 +#endif
   4.275 +
   4.276 +#ifndef __HAVE_ARCH_STRPBRK
   4.277 +/**
   4.278 + * strpbrk - Find the first occurrence of a set of characters
   4.279 + * @cs: The string to be searched
   4.280 + * @ct: The characters to search for
   4.281 + */
   4.282 +char * strpbrk(const char * cs,const char * ct)
   4.283 +{
   4.284 +	const char *sc1,*sc2;
   4.285 +
   4.286 +	for( sc1 = cs; *sc1 != '\0'; ++sc1) {
   4.287 +		for( sc2 = ct; *sc2 != '\0'; ++sc2) {
   4.288 +			if (*sc1 == *sc2)
   4.289 +				return (char *) sc1;
   4.290 +		}
   4.291 +	}
   4.292 +	return NULL;
   4.293 +}
   4.294 +#endif
   4.295 +
   4.296 +#ifndef __HAVE_ARCH_STRTOK
   4.297 +/**
   4.298 + * strtok - Split a string into tokens
   4.299 + * @s: The string to be searched
   4.300 + * @ct: The characters to search for
   4.301 + *
   4.302 + * WARNING: strtok is deprecated, use strsep instead.
   4.303 + */
   4.304 +char * strtok(char * s,const char * ct)
   4.305 +{
   4.306 +	char *sbegin, *send;
   4.307 +
   4.308 +	sbegin  = s ? s : ___strtok;
   4.309 +	if (!sbegin) {
   4.310 +		return NULL;
   4.311 +	}
   4.312 +	sbegin += strspn(sbegin,ct);
   4.313 +	if (*sbegin == '\0') {
   4.314 +		___strtok = NULL;
   4.315 +		return( NULL );
   4.316 +	}
   4.317 +	send = strpbrk( sbegin, ct);
   4.318 +	if (send && *send != '\0')
   4.319 +		*send++ = '\0';
   4.320 +	___strtok = send;
   4.321 +	return (sbegin);
   4.322 +}
   4.323 +#endif
   4.324 +
   4.325 +#ifndef __HAVE_ARCH_STRSEP
   4.326 +/**
   4.327 + * strsep - Split a string into tokens
   4.328 + * @s: The string to be searched
   4.329 + * @ct: The characters to search for
   4.330 + *
   4.331 + * strsep() updates @s to point after the token, ready for the next call.
   4.332 + *
   4.333 + * It returns empty tokens, too, behaving exactly like the libc function
   4.334 + * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
   4.335 + * Same semantics, slimmer shape. ;)
   4.336 + */
   4.337 +char * strsep(char **s, const char *ct)
   4.338 +{
   4.339 +	char *sbegin = *s, *end;
   4.340 +
   4.341 +	if (sbegin == NULL)
   4.342 +		return NULL;
   4.343 +
   4.344 +	end = strpbrk(sbegin, ct);
   4.345 +	if (end)
   4.346 +		*end++ = '\0';
   4.347 +	*s = end;
   4.348 +
   4.349 +	return sbegin;
   4.350 +}
   4.351 +#endif
   4.352 +
   4.353 +#ifndef __HAVE_ARCH_MEMSET
   4.354 +/**
   4.355 + * memset - Fill a region of memory with the given value
   4.356 + * @s: Pointer to the start of the area.
   4.357 + * @c: The byte to fill the area with
   4.358 + * @count: The size of the area.
   4.359 + *
   4.360 + * Do not use memset() to access IO space, use memset_io() instead.
   4.361 + */
   4.362 +void * memset(void * s,int c,size_t count)
   4.363 +{
   4.364 +	char *xs = (char *) s;
   4.365 +
   4.366 +	while (count--)
   4.367 +		*xs++ = c;
   4.368 +
   4.369 +	return s;
   4.370 +}
   4.371 +#endif
   4.372 +
   4.373 +#ifndef __HAVE_ARCH_BCOPY
   4.374 +/**
   4.375 + * bcopy - Copy one area of memory to another
   4.376 + * @src: Where to copy from
   4.377 + * @dest: Where to copy to
   4.378 + * @count: The size of the area.
   4.379 + *
   4.380 + * Note that this is the same as memcpy(), with the arguments reversed.
   4.381 + * memcpy() is the standard, bcopy() is a legacy BSD function.
   4.382 + *
   4.383 + * You should not use this function to access IO space, use memcpy_toio()
   4.384 + * or memcpy_fromio() instead.
   4.385 + */
   4.386 +char * bcopy(const char * src, char * dest, int count)
   4.387 +{
   4.388 +	char *tmp = dest;
   4.389 +
   4.390 +	while (count--)
   4.391 +		*tmp++ = *src++;
   4.392 +
   4.393 +	return dest;
   4.394 +}
   4.395 +#endif
   4.396 +
   4.397 +#ifndef __HAVE_ARCH_MEMCPY
   4.398 +/**
   4.399 + * memcpy - Copy one area of memory to another
   4.400 + * @dest: Where to copy to
   4.401 + * @src: Where to copy from
   4.402 + * @count: The size of the area.
   4.403 + *
   4.404 + * You should not use this function to access IO space, use memcpy_toio()
   4.405 + * or memcpy_fromio() instead.
   4.406 + */
   4.407 +void * memcpy(void * dest,const void *src,size_t count)
   4.408 +{
   4.409 +	char *tmp = (char *) dest, *s = (char *) src;
   4.410 +
   4.411 +	while (count--)
   4.412 +		*tmp++ = *s++;
   4.413 +
   4.414 +	return dest;
   4.415 +}
   4.416 +#endif
   4.417 +
   4.418 +#ifndef __HAVE_ARCH_MEMMOVE
   4.419 +/**
   4.420 + * memmove - Copy one area of memory to another
   4.421 + * @dest: Where to copy to
   4.422 + * @src: Where to copy from
   4.423 + * @count: The size of the area.
   4.424 + *
   4.425 + * Unlike memcpy(), memmove() copes with overlapping areas.
   4.426 + */
   4.427 +void * memmove(void * dest,const void *src,size_t count)
   4.428 +{
   4.429 +	char *tmp, *s;
   4.430 +
   4.431 +	if (dest <= src) {
   4.432 +		tmp = (char *) dest;
   4.433 +		s = (char *) src;
   4.434 +		while (count--)
   4.435 +			*tmp++ = *s++;
   4.436 +		}
   4.437 +	else {
   4.438 +		tmp = (char *) dest + count;
   4.439 +		s = (char *) src + count;
   4.440 +		while (count--)
   4.441 +			*--tmp = *--s;
   4.442 +		}
   4.443 +
   4.444 +	return dest;
   4.445 +}
   4.446 +#endif
   4.447 +
   4.448 +#ifndef __HAVE_ARCH_MEMCMP
   4.449 +/**
   4.450 + * memcmp - Compare two areas of memory
   4.451 + * @cs: One area of memory
   4.452 + * @ct: Another area of memory
   4.453 + * @count: The size of the area.
   4.454 + */
   4.455 +/*
   4.456 +int memcmp(const void * cs,const void * ct,size_t count)
   4.457 +{
   4.458 +	const unsigned char *su1, *su2;
   4.459 +	int res = 0;
   4.460 +
   4.461 +	for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
   4.462 +		if ((res = *su1 - *su2) != 0)
   4.463 +			break;
   4.464 +	return res;
   4.465 +}
   4.466 +*/
   4.467 +#endif
   4.468 +
   4.469 +#ifndef __HAVE_ARCH_MEMSCAN
   4.470 +/**
   4.471 + * memscan - Find a character in an area of memory.
   4.472 + * @addr: The memory area
   4.473 + * @c: The byte to search for
   4.474 + * @size: The size of the area.
   4.475 + *
   4.476 + * returns the address of the first occurrence of @c, or 1 byte past
   4.477 + * the area if @c is not found
   4.478 + */
   4.479 +void * memscan(void * addr, int c, size_t size)
   4.480 +{
   4.481 +	unsigned char * p = (unsigned char *) addr;
   4.482 +
   4.483 +	while (size) {
   4.484 +		if (*p == c)
   4.485 +			return (void *) p;
   4.486 +		p++;
   4.487 +		size--;
   4.488 +	}
   4.489 +  	return (void *) p;
   4.490 +}
   4.491 +#endif
   4.492 +
   4.493 +#ifndef __HAVE_ARCH_STRSTR
   4.494 +/**
   4.495 + * strstr - Find the first substring in a %NUL terminated string
   4.496 + * @s1: The string to be searched
   4.497 + * @s2: The string to search for
   4.498 + */
   4.499 +char * strstr(const char * s1,const char * s2)
   4.500 +{
   4.501 +	int l1, l2;
   4.502 +
   4.503 +	l2 = strlen(s2);
   4.504 +	if (!l2)
   4.505 +		return (char *) s1;
   4.506 +	l1 = strlen(s1);
   4.507 +	while (l1 >= l2) {
   4.508 +		l1--;
   4.509 +		if (!memcmp(s1,s2,l2))
   4.510 +			return (char *) s1;
   4.511 +		s1++;
   4.512 +	}
   4.513 +	return NULL;
   4.514 +}
   4.515 +#endif
   4.516 +
   4.517 +#ifndef __HAVE_ARCH_MEMCHR
   4.518 +/**
   4.519 + * memchr - Find a character in an area of memory.
   4.520 + * @s: The memory area
   4.521 + * @c: The byte to search for
   4.522 + * @n: The size of the area.
   4.523 + *
   4.524 + * returns the address of the first occurrence of @c, or %NULL
   4.525 + * if @c is not found
   4.526 + */
   4.527 +void *memchr(const void *s, int c, size_t n)
   4.528 +{
   4.529 +	const unsigned char *p = s;
   4.530 +	while (n-- != 0) {
   4.531 +        	if ((unsigned char)c == *p++) {
   4.532 +			return (void *)(p-1);
   4.533 +		}
   4.534 +	}
   4.535 +	return NULL;
   4.536 +}
   4.537 +
   4.538 +#endif
     5.1 --- a/xen/drivers/scsi/Makefile	Sun Mar 23 21:43:43 2003 +0000
     5.2 +++ b/xen/drivers/scsi/Makefile	Mon Mar 24 16:44:31 2003 +0000
     5.3 @@ -3,9 +3,11 @@ include $(BASEDIR)/Rules.mk
     5.4  
     5.5  default: $(OBJS)
     5.6  	$(MAKE) -C aacraid
     5.7 -	$(LD) -r -o driver.o $(OBJS) aacraid/aacraid.o
     5.8 +	$(MAKE) -C aic7xxx
     5.9 +	$(LD) -r -o driver.o $(OBJS) aacraid/aacraid.o aic7xxx/aic7xxx.o
    5.10  #	$(LD) -r -o driver.o $(OBJS) 
    5.11  
    5.12  clean:
    5.13  	$(MAKE) -C aacraid clean
    5.14 +	$(MAKE) -C aic7xxx clean
    5.15  	rm -f *.o *~ core
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xen/drivers/scsi/aic7xxx/Makefile	Mon Mar 24 16:44:31 2003 +0000
     6.3 @@ -0,0 +1,69 @@
     6.4 +#
     6.5 +# drivers/scsi/aic7xxx/Makefile
     6.6 +#
     6.7 +# Makefile for the Linux aic7xxx SCSI driver.
     6.8 +#
     6.9 +
    6.10 +O_TARGET := aic7xxx_drv.o
    6.11 +
    6.12 +include $(BASEDIR)/Rules.mk
    6.13 +#CFLAGS += -I$(BASEDIR)/drivers/scsi
    6.14 +
    6.15 +#list-multi	:= aic7xxx.o aic79xx.o
    6.16 +
    6.17 +#obj-$(CONFIG_SCSI_AIC7XXX)	+= aic7xxx.o
    6.18 +#ifeq ($(CONFIG_PCI),y)
    6.19 +#obj-$(CONFIG_SCSI_AIC79XX)	+= aic79xx.o
    6.20 +#endif
    6.21 +
    6.22 +#EXTRA_CFLAGS += -g
    6.23 +
    6.24 +# Platform Specific Files
    6.25 +obj-aic7xxx = aic7xxx_osm.o aic7xxx_proc.o aic7770_osm.o
    6.26 +#PCI Specific Platform Files
    6.27 +#ifeq ($(CONFIG_PCI),y)
    6.28 +obj-aic7xxx += aic7xxx_osm_pci.o
    6.29 +#endif
    6.30 +# Core Files
    6.31 +obj-aic7xxx += aic7xxx_core.o aic7xxx_93cx6.o aic7770.o
    6.32 +#PCI Specific Core Files
    6.33 +#ifeq ($(CONFIG_PCI),y)
    6.34 +obj-aic7xxx += aic7xxx_pci.o
    6.35 +#endif
    6.36 +
    6.37 +# Platform Specific U320 Files
    6.38 +#obj-aic79xx = aic79xx_osm.o 
    6.39 +#obj-aic79xx += aic79xx_proc.o
    6.40 +#obj-aic79xx += aic79xx_osm_pci.o
    6.41 +# Core Files
    6.42 +#obj-aic79xx += aic79xx_core.o
    6.43 +#obj-aic79xx += aic79xx_pci.o
    6.44 +
    6.45 +default: aic7xxx.o
    6.46 +
    6.47 +aic7xxx_core.o: aic7xxx_seq.h
    6.48 +$(obj-aic7xxx): aic7xxx_reg.h
    6.49 +aic7xxx.o: aic7xxx_seq.h aic7xxx_reg.h $(obj-aic7xxx)
    6.50 +	$(LD) $(LD_RFLAG) -r -o $@ $(obj-aic7xxx)
    6.51 +
    6.52 +aic79xx_core.o: aic79xx_seq.h
    6.53 +$(obj-aic79xx): aic79xx_reg.h
    6.54 +aic79xx.o: aic79xx_seq.h aic79xx_reg.h $(obj-aic79xx)
    6.55 +	$(LD) $(LD_RFLAG) -r -o $@ $(obj-aic79xx)
    6.56 +
    6.57 +#ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y)
    6.58 +#aic7xxx_seq.h aic7xxx_reg.h: aic7xxx.seq aic7xxx.reg aicasm/aicasm
    6.59 +#	aicasm/aicasm -I. -r aic7xxx_reg.h -o aic7xxx_seq.h aic7xxx.seq
    6.60 +#endif
    6.61 +
    6.62 +#ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y)
    6.63 +#aic79xx_seq.h aic79xx_reg.h: aic79xx.seq aic79xx.reg aicasm/aicasm
    6.64 +#	aicasm/aicasm -I. -r aic79xx_reg.h -o aic79xx_seq.h aic79xx.seq
    6.65 +#endif
    6.66 +
    6.67 +#aicasm/aicasm: aicasm/*.[chyl]
    6.68 +#	$(MAKE) -C aicasm
    6.69 +
    6.70 +clean:
    6.71 +	rm -f *.o *~ core
    6.72 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/xen/drivers/scsi/aic7xxx/aic7770.c	Mon Mar 24 16:44:31 2003 +0000
     7.3 @@ -0,0 +1,369 @@
     7.4 +/*
     7.5 + * Product specific probe and attach routines for:
     7.6 + * 	27/284X and aic7770 motherboard SCSI controllers
     7.7 + *
     7.8 + * Copyright (c) 1994-1998, 2000, 2001 Justin T. Gibbs.
     7.9 + * All rights reserved.
    7.10 + *
    7.11 + * Redistribution and use in source and binary forms, with or without
    7.12 + * modification, are permitted provided that the following conditions
    7.13 + * are met:
    7.14 + * 1. Redistributions of source code must retain the above copyright
    7.15 + *    notice, this list of conditions, and the following disclaimer,
    7.16 + *    without modification.
    7.17 + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    7.18 + *    substantially similar to the "NO WARRANTY" disclaimer below
    7.19 + *    ("Disclaimer") and any redistribution must be conditioned upon
    7.20 + *    including a substantially similar Disclaimer requirement for further
    7.21 + *    binary redistribution.
    7.22 + * 3. Neither the names of the above-listed copyright holders nor the names
    7.23 + *    of any contributors may be used to endorse or promote products derived
    7.24 + *    from this software without specific prior written permission.
    7.25 + *
    7.26 + * Alternatively, this software may be distributed under the terms of the
    7.27 + * GNU General Public License ("GPL") version 2 as published by the Free
    7.28 + * Software Foundation.
    7.29 + *
    7.30 + * NO WARRANTY
    7.31 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    7.32 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    7.33 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
    7.34 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    7.35 + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    7.36 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    7.37 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    7.38 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    7.39 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    7.40 + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    7.41 + * POSSIBILITY OF SUCH DAMAGES.
    7.42 + *
    7.43 + * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#21 $
    7.44 + *
    7.45 + * $FreeBSD: src/sys/dev/aic7xxx/aic7770.c,v 1.1 2000/09/16 20:02:27 gibbs Exp $
    7.46 + */
    7.47 +
    7.48 +#ifdef __linux__
    7.49 +#include "aic7xxx_osm.h"
    7.50 +#include "aic7xxx_inline.h"
    7.51 +#include "aic7xxx_93cx6.h"
    7.52 +#else
    7.53 +#include <dev/aic7xxx/aic7xxx_osm.h>
    7.54 +#include <dev/aic7xxx/aic7xxx_inline.h>
    7.55 +#include <dev/aic7xxx/aic7xxx_93cx6.h>
    7.56 +#endif
    7.57 +
    7.58 +#define ID_AIC7770	0x04907770
    7.59 +#define ID_AHA_274x	0x04907771
    7.60 +#define ID_AHA_284xB	0x04907756 /* BIOS enabled */
    7.61 +#define ID_AHA_284x	0x04907757 /* BIOS disabled*/
    7.62 +
    7.63 +static int aha2840_load_seeprom(struct ahc_softc *ahc);
    7.64 +static ahc_device_setup_t ahc_aic7770_VL_setup;
    7.65 +static ahc_device_setup_t ahc_aic7770_EISA_setup;;
    7.66 +static ahc_device_setup_t ahc_aic7770_setup;
    7.67 +
    7.68 +
    7.69 +struct aic7770_identity aic7770_ident_table [] =
    7.70 +{
    7.71 +	{
    7.72 +		ID_AHA_274x,
    7.73 +		0xFFFFFFFF,
    7.74 +		"Adaptec 274X SCSI adapter",
    7.75 +		ahc_aic7770_EISA_setup
    7.76 +	},
    7.77 +	{
    7.78 +		ID_AHA_284xB,
    7.79 +		0xFFFFFFFE,
    7.80 +		"Adaptec 284X SCSI adapter",
    7.81 +		ahc_aic7770_VL_setup
    7.82 +	},
    7.83 +	/* Generic chip probes for devices we don't know 'exactly' */
    7.84 +	{
    7.85 +		ID_AIC7770,
    7.86 +		0xFFFFFFFF,
    7.87 +		"Adaptec aic7770 SCSI adapter",
    7.88 +		ahc_aic7770_EISA_setup
    7.89 +	}
    7.90 +};
    7.91 +const int ahc_num_aic7770_devs = NUM_ELEMENTS(aic7770_ident_table);
    7.92 +
    7.93 +struct aic7770_identity *
    7.94 +aic7770_find_device(uint32_t id)
    7.95 +{
    7.96 +	struct	aic7770_identity *entry;
    7.97 +	int	i;
    7.98 +
    7.99 +	for (i = 0; i < ahc_num_aic7770_devs; i++) {
   7.100 +		entry = &aic7770_ident_table[i];
   7.101 +		if (entry->full_id == (id & entry->id_mask))
   7.102 +			return (entry);
   7.103 +	}
   7.104 +	return (NULL);
   7.105 +}
   7.106 +
   7.107 +int
   7.108 +aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
   7.109 +{
   7.110 +	u_long	l;
   7.111 +	u_long	s;
   7.112 +	int	error;
   7.113 +	int	have_seeprom;
   7.114 +	u_int	hostconf;
   7.115 +	u_int   irq;
   7.116 +	u_int	intdef;
   7.117 +
   7.118 +	error = entry->setup(ahc);
   7.119 +	have_seeprom = 0;
   7.120 +	if (error != 0)
   7.121 +		return (error);
   7.122 +
   7.123 +	error = aic7770_map_registers(ahc, io);
   7.124 +	if (error != 0)
   7.125 +		return (error);
   7.126 +
   7.127 +	/*
   7.128 +	 * Before we continue probing the card, ensure that
   7.129 +	 * its interrupts are *disabled*.  We don't want
   7.130 +	 * a misstep to hang the machine in an interrupt
   7.131 +	 * storm.
   7.132 +	 */
   7.133 +	ahc_intr_enable(ahc, FALSE);
   7.134 +
   7.135 +	ahc->description = entry->name;
   7.136 +	error = ahc_softc_init(ahc);
   7.137 +
   7.138 +	error = ahc_reset(ahc);
   7.139 +	if (error != 0)
   7.140 +		return (error);
   7.141 +
   7.142 +	/* Make sure we have a valid interrupt vector */
   7.143 +	intdef = ahc_inb(ahc, INTDEF);
   7.144 +	irq = intdef & VECTOR;
   7.145 +	switch (irq) {
   7.146 +	case 9:
   7.147 +	case 10:
   7.148 +	case 11:
   7.149 +	case 12:
   7.150 +	case 14:
   7.151 +	case 15:
   7.152 +		break;
   7.153 +	default:
   7.154 +		printf("aic7770_config: illegal irq setting %d\n", intdef);
   7.155 +		return (ENXIO);
   7.156 +	}
   7.157 +
   7.158 +	if ((intdef & EDGE_TRIG) != 0)
   7.159 +		ahc->flags |= AHC_EDGE_INTERRUPT;
   7.160 +
   7.161 +	switch (ahc->chip & (AHC_EISA|AHC_VL)) {
   7.162 +	case AHC_EISA:
   7.163 +	{
   7.164 +		u_int biosctrl;
   7.165 +		u_int scsiconf;
   7.166 +		u_int scsiconf1;
   7.167 +
   7.168 +		biosctrl = ahc_inb(ahc, HA_274_BIOSCTRL);
   7.169 +		scsiconf = ahc_inb(ahc, SCSICONF);
   7.170 +		scsiconf1 = ahc_inb(ahc, SCSICONF + 1);
   7.171 +
   7.172 +		/* Get the primary channel information */
   7.173 +		if ((biosctrl & CHANNEL_B_PRIMARY) != 0)
   7.174 +			ahc->flags |= 1;
   7.175 +
   7.176 +		if ((biosctrl & BIOSMODE) == BIOSDISABLED) {
   7.177 +			ahc->flags |= AHC_USEDEFAULTS;
   7.178 +		} else {
   7.179 +			if ((ahc->features & AHC_WIDE) != 0) {
   7.180 +				ahc->our_id = scsiconf1 & HWSCSIID;
   7.181 +				if (scsiconf & TERM_ENB)
   7.182 +					ahc->flags |= AHC_TERM_ENB_A;
   7.183 +			} else {
   7.184 +				ahc->our_id = scsiconf & HSCSIID;
   7.185 +				ahc->our_id_b = scsiconf1 & HSCSIID;
   7.186 +				if (scsiconf & TERM_ENB)
   7.187 +					ahc->flags |= AHC_TERM_ENB_A;
   7.188 +				if (scsiconf1 & TERM_ENB)
   7.189 +					ahc->flags |= AHC_TERM_ENB_B;
   7.190 +			}
   7.191 +		}
   7.192 +		if ((ahc_inb(ahc, HA_274_BIOSGLOBAL) & HA_274_EXTENDED_TRANS))
   7.193 +			ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
   7.194 +		break;
   7.195 +	}
   7.196 +	case AHC_VL:
   7.197 +	{
   7.198 +		have_seeprom = aha2840_load_seeprom(ahc);
   7.199 +		break;
   7.200 +	}
   7.201 +	default:
   7.202 +		break;
   7.203 +	}
   7.204 +	if (have_seeprom == 0) {
   7.205 +		free(ahc->seep_config, M_DEVBUF);
   7.206 +		ahc->seep_config = NULL;
   7.207 +	}
   7.208 +
   7.209 +	/*
   7.210 +	 * Ensure autoflush is enabled
   7.211 +	 */
   7.212 +	ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS);
   7.213 +
   7.214 +	/* Setup the FIFO threshold and the bus off time */
   7.215 +	hostconf = ahc_inb(ahc, HOSTCONF);
   7.216 +	ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH);
   7.217 +	ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF);
   7.218 +
   7.219 +	/*
   7.220 +	 * Generic aic7xxx initialization.
   7.221 +	 */
   7.222 +	error = ahc_init(ahc);
   7.223 +	if (error != 0)
   7.224 +		return (error);
   7.225 +
   7.226 +	error = aic7770_map_int(ahc, irq);
   7.227 +	if (error != 0)
   7.228 +		return (error);
   7.229 +
   7.230 +	ahc_list_lock(&l);
   7.231 +	/*
   7.232 +	 * Link this softc in with all other ahc instances.
   7.233 +	 */
   7.234 +	ahc_softc_insert(ahc);
   7.235 +
   7.236 +	/*
   7.237 +	 * Enable the board's BUS drivers
   7.238 +	 */
   7.239 +	ahc_outb(ahc, BCTL, ENABLE);
   7.240 +
   7.241 +	/*
   7.242 +	 * Allow interrupts.
   7.243 +	 */
   7.244 +	ahc_lock(ahc, &s);
   7.245 +	ahc_intr_enable(ahc, TRUE);
   7.246 +	ahc_unlock(ahc, &s);
   7.247 +
   7.248 +	ahc_list_unlock(&l);
   7.249 +
   7.250 +	return (0);
   7.251 +}
   7.252 +
   7.253 +/*
   7.254 + * Read the 284x SEEPROM.
   7.255 + */
   7.256 +static int
   7.257 +aha2840_load_seeprom(struct ahc_softc *ahc)
   7.258 +{
   7.259 +	struct	seeprom_descriptor sd;
   7.260 +	struct	seeprom_config *sc;
   7.261 +	int	have_seeprom;
   7.262 +	uint8_t scsi_conf;
   7.263 +
   7.264 +	sd.sd_ahc = ahc;
   7.265 +	sd.sd_control_offset = SEECTL_2840;
   7.266 +	sd.sd_status_offset = STATUS_2840;
   7.267 +	sd.sd_dataout_offset = STATUS_2840;		
   7.268 +	sd.sd_chip = C46;
   7.269 +	sd.sd_MS = 0;
   7.270 +	sd.sd_RDY = EEPROM_TF;
   7.271 +	sd.sd_CS = CS_2840;
   7.272 +	sd.sd_CK = CK_2840;
   7.273 +	sd.sd_DO = DO_2840;
   7.274 +	sd.sd_DI = DI_2840;
   7.275 +	sc = ahc->seep_config;
   7.276 +
   7.277 +	if (bootverbose)
   7.278 +		printf("%s: Reading SEEPROM...", ahc_name(ahc));
   7.279 +	have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)&sc,
   7.280 +					/*start_addr*/0, sizeof(sc)/2);
   7.281 +
   7.282 +	if (have_seeprom) {
   7.283 +
   7.284 +		if (ahc_verify_cksum(sc) == 0) {
   7.285 +			if(bootverbose)
   7.286 +				printf ("checksum error\n");
   7.287 +			have_seeprom = 0;
   7.288 +		} else if (bootverbose) {
   7.289 +			printf("done.\n");
   7.290 +		}
   7.291 +	}
   7.292 +
   7.293 +	if (!have_seeprom) {
   7.294 +		if (bootverbose)
   7.295 +			printf("%s: No SEEPROM available\n", ahc_name(ahc));
   7.296 +		ahc->flags |= AHC_USEDEFAULTS;
   7.297 +	} else {
   7.298 +		/*
   7.299 +		 * Put the data we've collected down into SRAM
   7.300 +		 * where ahc_init will find it.
   7.301 +		 */
   7.302 +		int	 i;
   7.303 +		int	 max_targ;
   7.304 +		uint16_t discenable;
   7.305 +
   7.306 +		max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
   7.307 +		discenable = 0;
   7.308 +		for (i = 0; i < max_targ; i++){
   7.309 +			uint8_t target_settings;
   7.310 +
   7.311 +			target_settings = (sc->device_flags[i] & CFXFER) << 4;
   7.312 +			if (sc->device_flags[i] & CFSYNCH)
   7.313 +				target_settings |= SOFS;
   7.314 +			if (sc->device_flags[i] & CFWIDEB)
   7.315 +				target_settings |= WIDEXFER;
   7.316 +			if (sc->device_flags[i] & CFDISC)
   7.317 +				discenable |= (0x01 << i);
   7.318 +			ahc_outb(ahc, TARG_SCSIRATE + i, target_settings);
   7.319 +		}
   7.320 +		ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
   7.321 +		ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
   7.322 +
   7.323 +		ahc->our_id = sc->brtime_id & CFSCSIID;
   7.324 +
   7.325 +		scsi_conf = (ahc->our_id & 0x7);
   7.326 +		if (sc->adapter_control & CFSPARITY)
   7.327 +			scsi_conf |= ENSPCHK;
   7.328 +		if (sc->adapter_control & CFRESETB)
   7.329 +			scsi_conf |= RESET_SCSI;
   7.330 +
   7.331 +		if (sc->bios_control & CF284XEXTEND)		
   7.332 +			ahc->flags |= AHC_EXTENDED_TRANS_A;
   7.333 +		/* Set SCSICONF info */
   7.334 +		ahc_outb(ahc, SCSICONF, scsi_conf);
   7.335 +
   7.336 +		if (sc->adapter_control & CF284XSTERM)
   7.337 +			ahc->flags |= AHC_TERM_ENB_A;
   7.338 +	}
   7.339 +	return (have_seeprom);
   7.340 +}
   7.341 +
   7.342 +static int
   7.343 +ahc_aic7770_VL_setup(struct ahc_softc *ahc)
   7.344 +{
   7.345 +	int error;
   7.346 +
   7.347 +	error = ahc_aic7770_setup(ahc);
   7.348 +	ahc->chip |= AHC_VL;
   7.349 +	return (error);
   7.350 +}
   7.351 +
   7.352 +static int
   7.353 +ahc_aic7770_EISA_setup(struct ahc_softc *ahc)
   7.354 +{
   7.355 +	int error;
   7.356 +
   7.357 +	error = ahc_aic7770_setup(ahc);
   7.358 +	ahc->chip |= AHC_EISA;
   7.359 +	return (error);
   7.360 +}
   7.361 +
   7.362 +static int
   7.363 +ahc_aic7770_setup(struct ahc_softc *ahc)
   7.364 +{
   7.365 +	ahc->channel = 'A';
   7.366 +	ahc->channel_b = 'B';
   7.367 +	ahc->chip = AHC_AIC7770;
   7.368 +	ahc->features = AHC_AIC7770_FE;
   7.369 +	ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
   7.370 +	ahc->flags |= AHC_PAGESCBS;
   7.371 +	return (0);
   7.372 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xen/drivers/scsi/aic7xxx/aic7770_osm.c	Mon Mar 24 16:44:31 2003 +0000
     8.3 @@ -0,0 +1,150 @@
     8.4 +/*
     8.5 + * Linux driver attachment glue for aic7770 based controllers.
     8.6 + *
     8.7 + * Copyright (c) 2000-2001 Adaptec Inc.
     8.8 + * All rights reserved.
     8.9 + *
    8.10 + * Redistribution and use in source and binary forms, with or without
    8.11 + * modification, are permitted provided that the following conditions
    8.12 + * are met:
    8.13 + * 1. Redistributions of source code must retain the above copyright
    8.14 + *    notice, this list of conditions, and the following disclaimer,
    8.15 + *    without modification.
    8.16 + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    8.17 + *    substantially similar to the "NO WARRANTY" disclaimer below
    8.18 + *    ("Disclaimer") and any redistribution must be conditioned upon
    8.19 + *    including a substantially similar Disclaimer requirement for further
    8.20 + *    binary redistribution.
    8.21 + * 3. Neither the names of the above-listed copyright holders nor the names
    8.22 + *    of any contributors may be used to endorse or promote products derived
    8.23 + *    from this software without specific prior written permission.
    8.24 + *
    8.25 + * Alternatively, this software may be distributed under the terms of the
    8.26 + * GNU General Public License ("GPL") version 2 as published by the Free
    8.27 + * Software Foundation.
    8.28 + *
    8.29 + * NO WARRANTY
    8.30 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    8.31 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    8.32 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
    8.33 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    8.34 + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    8.35 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    8.36 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    8.37 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    8.38 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    8.39 + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    8.40 + * POSSIBILITY OF SUCH DAMAGES.
    8.41 + *
    8.42 + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#11 $
    8.43 + */
    8.44 +
    8.45 +#include "aic7xxx_osm.h"
    8.46 +
    8.47 +#define MINSLOT			1
    8.48 +#define NUMSLOTS		16
    8.49 +#define IDOFFSET		0x80
    8.50 +
    8.51 +int
    8.52 +aic7770_linux_probe(Scsi_Host_Template *template)
    8.53 +{
    8.54 +#if defined(__i386__) || defined(__alpha__)
    8.55 +	struct aic7770_identity *entry;
    8.56 +	struct ahc_softc *ahc;
    8.57 +	int i, slot;
    8.58 +	int eisaBase;
    8.59 +	int found;
    8.60 +
    8.61 +	eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
    8.62 +	found = 0;
    8.63 +	for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
    8.64 +		uint32_t eisa_id;
    8.65 +		size_t	 id_size;
    8.66 +
    8.67 +		if (check_region(eisaBase, AHC_EISA_IOSIZE) != 0)
    8.68 +			continue;
    8.69 +
    8.70 +		eisa_id = 0;
    8.71 +		id_size = sizeof(eisa_id);
    8.72 +		for (i = 0; i < 4; i++) {
    8.73 +			/* VLcards require priming*/
    8.74 +			outb(0x80 + i, eisaBase + IDOFFSET);
    8.75 +			eisa_id |= inb(eisaBase + IDOFFSET + i)
    8.76 +				   << ((id_size-i-1) * 8);
    8.77 +		}
    8.78 +		if (eisa_id & 0x80000000)
    8.79 +			continue;  /* no EISA card in slot */
    8.80 +
    8.81 +		entry = aic7770_find_device(eisa_id);
    8.82 +		if (entry != NULL) {
    8.83 +			char	 buf[80];
    8.84 +			char	*name;
    8.85 +			int	 error;
    8.86 +
    8.87 +			/*
    8.88 +			 * Allocate a softc for this card and
    8.89 +			 * set it up for attachment by our
    8.90 +			 * common detect routine.
    8.91 +			 */
    8.92 +			sprintf(buf, "ahc_eisa:%d", slot);
    8.93 +			name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
    8.94 +			if (name == NULL)
    8.95 +				break;
    8.96 +			strcpy(name, buf);
    8.97 +			ahc = ahc_alloc(template, name);
    8.98 +			if (ahc == NULL) {
    8.99 +				/*
   8.100 +				 * If we can't allocate this one,
   8.101 +				 * chances are we won't be able to
   8.102 +				 * allocate future card structures.
   8.103 +				 */
   8.104 +				break;
   8.105 +			}
   8.106 +			error = aic7770_config(ahc, entry, eisaBase);
   8.107 +			if (error != 0) {
   8.108 +				ahc->bsh.ioport = 0;
   8.109 +				ahc_free(ahc);
   8.110 +				continue;
   8.111 +			}
   8.112 +			found++;
   8.113 +		}
   8.114 +	}
   8.115 +	return (found);
   8.116 +#else
   8.117 +	return (0);
   8.118 +#endif
   8.119 +}
   8.120 +
   8.121 +int
   8.122 +aic7770_map_registers(struct ahc_softc *ahc, u_int port)
   8.123 +{
   8.124 +	/*
   8.125 +	 * Lock out other contenders for our i/o space.
   8.126 +	 */
   8.127 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
   8.128 +	request_region(port, AHC_EISA_IOSIZE, "aic7xxx");
   8.129 +#else
   8.130 +	if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0)
   8.131 +		return (ENOMEM);
   8.132 +#endif
   8.133 +	ahc->tag = BUS_SPACE_PIO;
   8.134 +	ahc->bsh.ioport = port;
   8.135 +	return (0);
   8.136 +}
   8.137 +
   8.138 +int
   8.139 +aic7770_map_int(struct ahc_softc *ahc, u_int irq)
   8.140 +{
   8.141 +	int error;
   8.142 +	int shared;
   8.143 +
   8.144 +	shared = 0;
   8.145 +	if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
   8.146 +		shared = SA_SHIRQ;
   8.147 +
   8.148 +	error = request_irq(irq, ahc_linux_isr, shared, "aic7xxx", ahc);
   8.149 +	if (error == 0)
   8.150 +		ahc->platform_data->irq = irq;
   8.151 +	
   8.152 +	return (-error);
   8.153 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/xen/drivers/scsi/aic7xxx/aic79xx.h	Mon Mar 24 16:44:31 2003 +0000
     9.3 @@ -0,0 +1,1297 @@
     9.4 +/*
     9.5 + * Core definitions and data structures shareable across OS platforms.
     9.6 + *
     9.7 + * Copyright (c) 1994-2001 Justin T. Gibbs.
     9.8 + * Copyright (c) 2000-2001 Adaptec Inc.
     9.9 + * All rights reserved.
    9.10 + *
    9.11 + * Redistribution and use in source and binary forms, with or without
    9.12 + * modification, are permitted provided that the following conditions
    9.13 + * are met:
    9.14 + * 1. Redistributions of source code must retain the above copyright
    9.15 + *    notice, this list of conditions, and the following disclaimer,
    9.16 + *    without modification.
    9.17 + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    9.18 + *    substantially similar to the "NO WARRANTY" disclaimer below
    9.19 + *    ("Disclaimer") and any redistribution must be conditioned upon
    9.20 + *    including a substantially similar Disclaimer requirement for further
    9.21 + *    binary redistribution.
    9.22 + * 3. Neither the names of the above-listed copyright holders nor the names
    9.23 + *    of any contributors may be used to endorse or promote products derived
    9.24 + *    from this software without specific prior written permission.
    9.25 + *
    9.26 + * Alternatively, this software may be distributed under the terms of the
    9.27 + * GNU General Public License ("GPL") version 2 as published by the Free
    9.28 + * Software Foundation.
    9.29 + *
    9.30 + * NO WARRANTY
    9.31 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    9.32 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    9.33 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
    9.34 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    9.35 + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    9.36 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    9.37 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    9.38 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    9.39 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    9.40 + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    9.41 + * POSSIBILITY OF SUCH DAMAGES.
    9.42 + *
    9.43 + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#46 $
    9.44 + *
    9.45 + * $FreeBSD$
    9.46 + */
    9.47 +
    9.48 +#ifndef _AIC79XX_H_
    9.49 +#define _AIC79XX_H_
    9.50 +
    9.51 +/* Register Definitions */
    9.52 +#include "aic79xx_reg.h"
    9.53 +
    9.54 +/************************* Forward Declarations *******************************/
    9.55 +struct ahd_platform_data;
    9.56 +struct scb_platform_data;
    9.57 +
    9.58 +/****************************** Useful Macros *********************************/
    9.59 +#ifndef MAX
    9.60 +#define MAX(a,b) (((a) > (b)) ? (a) : (b))
    9.61 +#endif
    9.62 +
    9.63 +#ifndef MIN
    9.64 +#define MIN(a,b) (((a) < (b)) ? (a) : (b))
    9.65 +#endif
    9.66 +
    9.67 +#ifndef TRUE
    9.68 +#define TRUE 1
    9.69 +#endif
    9.70 +#ifndef FALSE
    9.71 +#define FALSE 0
    9.72 +#endif
    9.73 +
    9.74 +#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array))
    9.75 +
    9.76 +#define ALL_CHANNELS '\0'
    9.77 +#define ALL_TARGETS_MASK 0xFFFF
    9.78 +#define INITIATOR_WILDCARD	(~0)
    9.79 +#define	SCB_LIST_NULL		0xFF00
    9.80 +#define	SCB_LIST_NULL_LE	(ahd_htole16(SCB_LIST_NULL))
    9.81 +#define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL)
    9.82 +
    9.83 +#define SCSIID_TARGET(ahd, scsiid)	\
    9.84 +	(((scsiid) & TID) >> TID_SHIFT)
    9.85 +#define SCSIID_OUR_ID(scsiid)		\
    9.86 +	((scsiid) & OID)
    9.87 +#define SCSIID_CHANNEL(ahd, scsiid) ('A')
    9.88 +#define	SCB_IS_SCSIBUS_B(ahd, scb) (0)
    9.89 +#define	SCB_GET_OUR_ID(scb) \
    9.90 +	SCSIID_OUR_ID((scb)->hscb->scsiid)
    9.91 +#define	SCB_GET_TARGET(ahd, scb) \
    9.92 +	SCSIID_TARGET((ahd), (scb)->hscb->scsiid)
    9.93 +#define	SCB_GET_CHANNEL(ahd, scb) \
    9.94 +	SCSIID_CHANNEL(ahd, (scb)->hscb->scsiid)
    9.95 +#define	SCB_GET_LUN(scb) \
    9.96 +	((scb)->hscb->lun)
    9.97 +#define SCB_GET_TARGET_OFFSET(ahd, scb)	\
    9.98 +	SCB_GET_TARGET(ahd, scb)
    9.99 +#define SCB_GET_TARGET_MASK(ahd, scb) \
   9.100 +	(0x01 << (SCB_GET_TARGET_OFFSET(ahd, scb)))
   9.101 +/*
   9.102 + * TCLs have the following format: TTTTLLLLLLLL
   9.103 + */
   9.104 +#define TCL_TARGET_OFFSET(tcl) \
   9.105 +	((((tcl) >> 4) & TID) >> 4)
   9.106 +#define TCL_LUN(tcl) \
   9.107 +	(tcl & (AHD_NUM_LUNS_NONPKT - 1))
   9.108 +#define BUILD_TCL(scsiid, lun) \
   9.109 +	((lun) | (((scsiid) & TID) << 4))
   9.110 +#define BUILD_TCL_RAW(target, channel, lun) \
   9.111 +	((lun) | ((target) << 8))
   9.112 +
   9.113 +#define SCB_GET_TAG(scb) \
   9.114 +	ahd_le16toh(scb->hscb->tag)
   9.115 +
   9.116 +#ifndef	AHD_TARGET_MODE
   9.117 +#undef	AHD_TMODE_ENABLE
   9.118 +#define	AHD_TMODE_ENABLE 0
   9.119 +#endif
   9.120 +
   9.121 +/**************************** Driver Constants ********************************/
   9.122 +/*
   9.123 + * The maximum number of supported targets.
   9.124 + */
   9.125 +#define AHD_NUM_TARGETS 16
   9.126 +
   9.127 +/*
   9.128 + * The maximum number of supported luns.
   9.129 + * The identify message only supports 64 luns in non-packetized transfers.
   9.130 + * You can have 2^64 luns when information unit transfers are enabled,
   9.131 + * but until we see a need to support that many, we support 256.
   9.132 + */
   9.133 +#define AHD_NUM_LUNS_NONPKT 64
   9.134 +#define AHD_NUM_LUNS 256
   9.135 +
   9.136 +/*
   9.137 + * The maximum transfer per S/G segment.
   9.138 + */
   9.139 +#define AHD_MAXTRANSFER_SIZE	 0x00ffffff	/* limited by 24bit counter */
   9.140 +
   9.141 +/*
   9.142 + * The maximum amount of SCB storage in hardware on a controller.
   9.143 + * This value represents an upper bound.  Due to software design,
   9.144 + * we may not be able to use this number.
   9.145 + */
   9.146 +#define AHD_SCB_MAX	512
   9.147 +
   9.148 +/*
   9.149 + * The maximum number of concurrent transactions supported per driver instance.
   9.150 + * Sequencer Control Blocks (SCBs) store per-transaction information.
   9.151 + * We are limited to 510 because:
   9.152 + * 	1) SCB storage space holds us to at most 512.
   9.153 + *	2) Our input queue scheme requires one SCB to always be reserved
   9.154 + *	   in advance of queuing any SCBs.  This takes us down to 511.
   9.155 + *	3) To handle our output queue correctly on machines that only
   9.156 + * 	   support 32bit stores, we must clear the array 4 bytes at a
   9.157 + *	   time.  To avoid colliding with a DMA write from the sequencer,
   9.158 + *	   we must be sure that 2, 16bit slots are empty when we write to
   9.159 + * 	   clear the queue.  This restricts us to only 511 SCBs: 1 that
   9.160 + *	   just completed and the known additional empty slot in the queue
   9.161 + *	   that precedes it.
   9.162 +#define AHD_MAX_QUEUE	510
   9.163 + */
   9.164 +#define AHD_MAX_QUEUE	255
   9.165 +
   9.166 +/*
   9.167 + * Define the size of our QIN and QOUT FIFOs.  They must be a power of 2
   9.168 + * in size and accomodate as many transactions as can be queued concurrently.
   9.169 + */
   9.170 +#define	AHD_QIN_SIZE	512
   9.171 +#define	AHD_QOUT_SIZE	512
   9.172 +
   9.173 +#define AHD_QIN_WRAP(x) ((x) & (AHD_QIN_SIZE-1))
   9.174 +#define AHD_QOUT_WRAP(x) ((x) & (AHD_QOUT_SIZE-1))
   9.175 +
   9.176 +/*
   9.177 + * The maximum amount of SCB storage we allocate in host memory.  This
   9.178 + * number should reflect the 1 additional SCB we require to handle our
   9.179 + * qinfifo mechanism.
   9.180 + */
   9.181 +#define AHD_SCB_MAX_ALLOC (AHD_MAX_QUEUE+1)
   9.182 +
   9.183 +/*
   9.184 + * Ring Buffer of incoming target commands.
   9.185 + * We allocate 256 to simplify the logic in the sequencer
   9.186 + * by using the natural wrap point of an 8bit counter.
   9.187 + */
   9.188 +#define AHD_TMODE_CMDS	256
   9.189 +
   9.190 +/* Reset line assertion time in us */
   9.191 +#define AHD_BUSRESET_DELAY	250
   9.192 +
   9.193 +/******************* Chip Characteristics/Operating Settings  *****************/
   9.194 +/*
   9.195 + * Chip Type
   9.196 + * The chip order is from least sophisticated to most sophisticated.
   9.197 + */
   9.198 +typedef enum {
   9.199 +	AHD_NONE	= 0x0000,
   9.200 +	AHD_CHIPID_MASK	= 0x00FF,
   9.201 +	AHD_AIC7901	= 0x0001,
   9.202 +	AHD_AIC7902	= 0x0002,
   9.203 +	AHD_PCI		= 0x0100,	/* Bus type PCI */
   9.204 +	AHD_PCIX	= 0x0200,	/* Bus type PCIX */
   9.205 +	AHD_BUS_MASK	= 0x0F00
   9.206 +} ahd_chip;
   9.207 +
   9.208 +/*
   9.209 + * Features available in each chip type.
   9.210 + */
   9.211 +typedef enum {
   9.212 +	AHD_FENONE	= 0x00000,
   9.213 +	AHD_WIDE  	= 0x00001,	/* Wide Channel */
   9.214 +	AHD_MULTI_FUNC	= 0x00100,	/* Multi-Function Twin Channel Device */
   9.215 +	AHD_TARGETMODE	= 0x01000,	/* Has tested target mode support */
   9.216 +	AHD_MULTIROLE	= 0x02000,	/* Space for two roles at a time */
   9.217 +	AHD_REMOVABLE	= 0x00000,	/* Hot-Swap supported - None so far*/
   9.218 +	AHD_AIC7901_FE	= AHD_FENONE,
   9.219 +	AHD_AIC7902_FE	= AHD_MULTI_FUNC
   9.220 +} ahd_feature;
   9.221 +
   9.222 +/*
   9.223 + * Bugs in the silicon that we work around in software.
   9.224 + */
   9.225 +typedef enum {
   9.226 +	AHD_BUGNONE		= 0x0000,
   9.227 +	AHD_SENT_SCB_UPDATE_BUG	= 0x0001,
   9.228 +	AHD_ABORT_LQI_BUG	= 0x0002,
   9.229 +	AHD_PKT_BITBUCKET_BUG	= 0x0004,
   9.230 +	AHD_LONG_SETIMO_BUG	= 0x0008,
   9.231 +	AHD_NLQICRC_DELAYED_BUG	= 0x0010,
   9.232 +	AHD_SCSIRST_BUG		= 0x0020,
   9.233 +	AHD_PCIX_ARBITER_BUG	= 0x0040,
   9.234 +	AHD_PCIX_SPLIT_BUG	= 0x0080,
   9.235 +	AHD_PCIX_CHIPRST_BUG	= 0x0100,
   9.236 +	AHD_PCIX_MMAPIO_BUG	= 0x0200,
   9.237 +	/* Bug workarounds that can be disabled on non-PCIX busses. */
   9.238 +	AHD_PCIX_BUG_MASK	= AHD_PCIX_ARBITER_BUG
   9.239 +				| AHD_PCIX_SPLIT_BUG
   9.240 +				| AHD_PCIX_CHIPRST_BUG
   9.241 +				| AHD_PCIX_MMAPIO_BUG,
   9.242 +	AHD_LQO_ATNO_BUG	= 0x0400,
   9.243 +	AHD_AUTOFLUSH_BUG	= 0x0800,
   9.244 +	AHD_CLRLQO_AUTOCLR_BUG	= 0x1000,
   9.245 +	AHD_PKTIZED_STATUS_BUG  = 0x2000
   9.246 +} ahd_bug;
   9.247 +
   9.248 +/*
   9.249 + * Configuration specific settings.
   9.250 + * The driver determines these settings by probing the
   9.251 + * chip/controller's configuration.
   9.252 + */
   9.253 +typedef enum {
   9.254 +	AHD_FNONE	      = 0x00000,
   9.255 +	AHD_PRIMARY_CHANNEL   = 0x00003,/*
   9.256 +					 * The channel that should
   9.257 +					 * be probed first.
   9.258 +					 */
   9.259 +	AHD_USEDEFAULTS	      = 0x00004,/*
   9.260 +					 * For cards without an seeprom
   9.261 +					 * or a BIOS to initialize the chip's
   9.262 +					 * SRAM, we use the default target
   9.263 +					 * settings.
   9.264 +					 */
   9.265 +	AHD_SEQUENCER_DEBUG   = 0x00008,
   9.266 +	AHD_RESET_BUS_A	      = 0x00010,
   9.267 +	AHD_EXTENDED_TRANS_A  = 0x00020,
   9.268 +	AHD_TERM_ENB_A	      = 0x00040,
   9.269 +	AHD_SPCHK_ENB_A	      = 0x00080,
   9.270 +	AHD_STPWLEVEL_A	      = 0x00100,
   9.271 +	AHD_INITIATORROLE     = 0x00200,/*
   9.272 +					 * Allow initiator operations on
   9.273 +					 * this controller.
   9.274 +					 */
   9.275 +	AHD_TARGETROLE	      = 0x00400,/*
   9.276 +					 * Allow target operations on this
   9.277 +					 * controller.
   9.278 +					 */
   9.279 +	AHD_RESOURCE_SHORTAGE = 0x00800,
   9.280 +	AHD_TQINFIFO_BLOCKED  = 0x01000,/* Blocked waiting for ATIOs */
   9.281 +	AHD_INT50_SPEEDFLEX   = 0x02000,/*
   9.282 +					 * Internal 50pin connector
   9.283 +					 * sits behind an aic3860
   9.284 +					 */
   9.285 +	AHD_BIOS_ENABLED      = 0x04000,
   9.286 +	AHD_ALL_INTERRUPTS    = 0x08000,
   9.287 +	AHD_39BIT_ADDRESSING  = 0x10000,/* Use 39 bit addressing scheme. */
   9.288 +	AHD_64BIT_ADDRESSING  = 0x20000,/* Use 64 bit addressing scheme. */
   9.289 +	AHD_CURRENT_SENSING   = 0x40000,
   9.290 +	AHD_SCB_CONFIG_USED   = 0x80000,/* No SEEPROM but SCB had info. */
   9.291 +	AHD_CPQ_BOARD	      = 0x100000
   9.292 +} ahd_flag;
   9.293 +
   9.294 +/************************* Hardware  SCB Definition ***************************/
   9.295 +
   9.296 +/*
   9.297 + * The driver keeps up to MAX_SCB scb structures per card in memory.  The SCB
   9.298 + * consists of a "hardware SCB" mirroring the fields availible on the card
   9.299 + * and additional information the kernel stores for each transaction.
   9.300 + *
   9.301 + * To minimize space utilization, a portion of the hardware scb stores
   9.302 + * different data during different portions of a SCSI transaction.
   9.303 + * As initialized by the host driver for the initiator role, this area
   9.304 + * contains the SCSI cdb (or a pointer to the  cdb) to be executed.  After
   9.305 + * the cdb has been presented to the target, this area serves to store
   9.306 + * residual transfer information and the SCSI status byte.
   9.307 + * For the target role, the contents of this area do not change, but
   9.308 + * still serve a different purpose than for the initiator role.  See
   9.309 + * struct target_data for details.
   9.310 + */
   9.311 +
   9.312 +/*
   9.313 + * Status information embedded in the shared poriton of
   9.314 + * an SCB after passing the cdb to the target.  The kernel
   9.315 + * driver will only read this data for transactions that
   9.316 + * complete abnormally.
   9.317 + */
   9.318 +struct initiator_status {
   9.319 +	uint32_t residual_datacnt;	/* Residual in the current S/G seg */
   9.320 +	uint32_t residual_sgptr;	/* The next S/G for this transfer */
   9.321 +	uint8_t	 scsi_status;		/* Standard SCSI status byte */
   9.322 +};
   9.323 +
   9.324 +struct target_status {
   9.325 +	uint32_t residual_datacnt;	/* Residual in the current S/G seg */
   9.326 +	uint32_t residual_sgptr;	/* The next S/G for this transfer */
   9.327 +	uint8_t  scsi_status;		/* SCSI status to give to initiator */
   9.328 +	uint8_t  target_phases;		/* Bitmap of phases to execute */
   9.329 +	uint8_t  data_phase;		/* Data-In or Data-Out */
   9.330 +	uint8_t  initiator_tag;		/* Initiator's transaction tag */
   9.331 +};
   9.332 +
   9.333 +/*
   9.334 + * Initiator mode SCB shared data area.
   9.335 + * If the embedded CDB is 12 bytes or less, we embed
   9.336 + * the sense buffer address in the SCB.  This allows
   9.337 + * us to retrieve sense information without interupting
   9.338 + * the host in packetized mode.
   9.339 + */
   9.340 +typedef uint32_t sense_addr_t;
   9.341 +#define MAX_CDB_LEN 16
   9.342 +#define MAX_CDB_LEN_WITH_SENSE_ADDR (MAX_CDB_LEN - sizeof(sense_addr_t))
   9.343 +union initiator_data {
   9.344 +	uint64_t cdbptr;
   9.345 +	uint8_t	 cdb[MAX_CDB_LEN];
   9.346 +	struct {
   9.347 +		uint8_t	 cdb[MAX_CDB_LEN_WITH_SENSE_ADDR];
   9.348 +		sense_addr_t sense_addr;
   9.349 +	} cdb_plus_saddr;
   9.350 +};
   9.351 +
   9.352 +/*
   9.353 + * Target mode version of the shared data SCB segment.
   9.354 + */
   9.355 +struct target_data {
   9.356 +	uint32_t spare[2];	
   9.357 +	uint8_t  scsi_status;		/* SCSI status to give to initiator */
   9.358 +	uint8_t  target_phases;		/* Bitmap of phases to execute */
   9.359 +	uint8_t  data_phase;		/* Data-In or Data-Out */
   9.360 +	uint8_t  initiator_tag;		/* Initiator's transaction tag */
   9.361 +};
   9.362 +
   9.363 +struct hardware_scb {
   9.364 +/*0*/	union {
   9.365 +		union	initiator_data idata;
   9.366 +		struct	target_data tdata;
   9.367 +		struct	initiator_status istatus;
   9.368 +		struct	target_status tstatus;
   9.369 +	} shared_data;
   9.370 +/*
   9.371 + * A word about residuals.
   9.372 + * The scb is presented to the sequencer with the dataptr and datacnt
   9.373 + * fields initialized to the contents of the first S/G element to
   9.374 + * transfer.  The sgptr field is initialized to the bus address for
   9.375 + * the S/G element that follows the first in the in core S/G array
   9.376 + * or'ed with the SG_FULL_RESID flag.  Sgptr may point to an invalid
   9.377 + * S/G entry for this transfer (single S/G element transfer with the
   9.378 + * first elements address and length preloaded in the dataptr/datacnt
   9.379 + * fields).  If no transfer is to occur, sgptr is set to SG_LIST_NULL.
   9.380 + * The SG_FULL_RESID flag ensures that the residual will be correctly
   9.381 + * noted even if no data transfers occur.  Once the data phase is entered,
   9.382 + * the residual sgptr and datacnt are loaded from the sgptr and the
   9.383 + * datacnt fields.  After each S/G element's dataptr and length are
   9.384 + * loaded into the hardware, the residual sgptr is advanced.  After
   9.385 + * each S/G element is expired, its datacnt field is checked to see
   9.386 + * if the LAST_SEG flag is set.  If so, SG_LIST_NULL is set in the
   9.387 + * residual sg ptr and the transfer is considered complete.  If the
   9.388 + * sequencer determines that there is a residual in the tranfer, or
   9.389 + * there is non-zero status, it will set the SG_STATUS_VALID flag in
   9.390 + * sgptr and dma the scb back into host memory.  To sumarize:
   9.391 + *
   9.392 + * Sequencer:
   9.393 + *	o A residual has occurred if SG_FULL_RESID is set in sgptr,
   9.394 + *	  or residual_sgptr does not have SG_LIST_NULL set.
   9.395 + *
   9.396 + *	o We are transfering the last segment if residual_datacnt has
   9.397 + *	  the SG_LAST_SEG flag set.
   9.398 + *
   9.399 + * Host:
   9.400 + *	o A residual can only have occurred if a completed scb has the
   9.401 + *	  SG_STATUS_VALID flag set.  Inspection of the SCSI status field,
   9.402 + *	  the residual_datacnt, and the residual_sgptr field will tell
   9.403 + *	  for sure.
   9.404 + *
   9.405 + *	o residual_sgptr and sgptr refer to the "next" sg entry
   9.406 + *	  and so may point beyond the last valid sg entry for the
   9.407 + *	  transfer.
   9.408 + */ 
   9.409 +#define SG_PTR_MASK	0xFFFFFFF8
   9.410 +/*16*/	uint8_t  cdb_len;
   9.411 +/*17*/	uint8_t  task_management;
   9.412 +/*18*/	uint16_t tag;
   9.413 +/*20*/	uint32_t next_hscb_busaddr;
   9.414 +/*24*/	uint64_t dataptr;
   9.415 +/*32*/	uint32_t datacnt;	/* Byte 3 is spare. */
   9.416 +/*36*/	uint32_t sgptr;
   9.417 +/*40*/	uint8_t  control;	/* See SCB_CONTROL in aic79xx.reg for details */
   9.418 +/*41*/	uint8_t	 scsiid;	/*
   9.419 +				 * Selection out Id
   9.420 +				 * Our Id (bits 0-3) Their ID (bits 4-7)
   9.421 +				 */
   9.422 +/*42*/	uint8_t  lun;
   9.423 +/*43*/	uint8_t  task_attribute_nonpkt_tag;
   9.424 +/*44*/	uint32_t hscb_busaddr;
   9.425 +/******* Fields below are not Downloaded (Sequencer may use for scratch) ******/
   9.426 +/*48*/  uint8_t	 spare[16];
   9.427 +};
   9.428 +
   9.429 +/************************ Kernel SCB Definitions ******************************/
   9.430 +/*
   9.431 + * Some fields of the SCB are OS dependent.  Here we collect the
   9.432 + * definitions for elements that all OS platforms need to include
   9.433 + * in there SCB definition.
   9.434 + */
   9.435 +
   9.436 +/*
   9.437 + * Definition of a scatter/gather element as transfered to the controller.
   9.438 + * The aic7xxx chips only support a 24bit length.  We use the top byte of
   9.439 + * the length to store additional address bits and a flag to indicate
   9.440 + * that a given segment terminates the transfer.  This gives us an
   9.441 + * addressable range of 512GB on machines with 64bit PCI or with chips
   9.442 + * that can support dual address cycles on 32bit PCI busses.
   9.443 + */
   9.444 +struct ahd_dma_seg {
   9.445 +	uint32_t	addr;
   9.446 +	uint32_t	len;
   9.447 +#define	AHD_DMA_LAST_SEG	0x80000000
   9.448 +#define	AHD_SG_HIGH_ADDR_MASK	0x7F000000
   9.449 +#define	AHD_SG_LEN_MASK		0x00FFFFFF
   9.450 +};
   9.451 +
   9.452 +struct ahd_dma64_seg {
   9.453 +	uint64_t	addr;
   9.454 +	uint32_t	len;
   9.455 +	uint32_t	pad;
   9.456 +};
   9.457 +
   9.458 +struct map_node {
   9.459 +	bus_dmamap_t		 dmamap;
   9.460 +	bus_addr_t		 physaddr;
   9.461 +	uint8_t			*vaddr;
   9.462 +	SLIST_ENTRY(map_node)	 links;
   9.463 +};
   9.464 +
   9.465 +/*
   9.466 + * The current state of this SCB.
   9.467 + */
   9.468 +typedef enum {
   9.469 +	SCB_FREE		= 0x0000,
   9.470 +	SCB_TRANSMISSION_ERROR	= 0x0001,/*
   9.471 +					  * We detected a parity or CRC
   9.472 +					  * error that has effected the
   9.473 +					  * payload of the command.  This
   9.474 +					  * flag is checked when normal
   9.475 +					  * status is returned to catch
   9.476 +					  * the case of a target not
   9.477 +					  * responding to our attempt
   9.478 +					  * to report the error.
   9.479 +					  */
   9.480 +	SCB_OTHERTCL_TIMEOUT	= 0x0002,/*
   9.481 +					  * Another device was active
   9.482 +					  * during the first timeout for
   9.483 +					  * this SCB so we gave ourselves
   9.484 +					  * an additional timeout period
   9.485 +					  * in case it was hogging the
   9.486 +					  * bus.
   9.487 +				          */
   9.488 +	SCB_DEVICE_RESET	= 0x0004,
   9.489 +	SCB_SENSE		= 0x0008,
   9.490 +	SCB_CDB32_PTR		= 0x0010,
   9.491 +	SCB_RECOVERY_SCB	= 0x0020,
   9.492 +	SCB_AUTO_NEGOTIATE	= 0x0040,/* Negotiate to achieve goal. */
   9.493 +	SCB_NEGOTIATE		= 0x0080,/* Negotiation forced for command. */
   9.494 +	SCB_ABORT		= 0x0100,
   9.495 +	SCB_UNTAGGEDQ		= 0x0200,
   9.496 +	SCB_ACTIVE		= 0x0400,
   9.497 +	SCB_TARGET_IMMEDIATE	= 0x0800,
   9.498 +	SCB_PACKETIZED		= 0x1000,
   9.499 +	SCB_EXPECT_PPR_BUSFREE	= 0x2000,
   9.500 +	SCB_PKT_SENSE		= 0x4000,
   9.501 +	SCB_CMDPHASE_ABORT	= 0x8000
   9.502 +} scb_flag;
   9.503 +
   9.504 +struct scb {
   9.505 +	struct	hardware_scb	 *hscb;
   9.506 +	union {
   9.507 +		SLIST_ENTRY(scb)  sle;
   9.508 +		TAILQ_ENTRY(scb)  tqe;
   9.509 +	} links;
   9.510 +	LIST_ENTRY(scb)		  pending_links;
   9.511 +	ahd_io_ctx_t		  io_ctx;
   9.512 +	struct ahd_softc	 *ahd_softc;
   9.513 +	scb_flag		  flags;
   9.514 +#ifndef __linux__
   9.515 +	bus_dmamap_t		  dmamap;
   9.516 +#endif
   9.517 +	struct scb_platform_data *platform_data;
   9.518 +	struct map_node	 	 *hscb_map;
   9.519 +	struct map_node	 	 *sg_map;
   9.520 +	struct map_node	 	 *sense_map;
   9.521 +	void			 *sg_list;
   9.522 +	uint8_t			 *sense_data;
   9.523 +	bus_addr_t		  sg_list_busaddr;
   9.524 +	bus_addr_t		  sense_busaddr;
   9.525 +	u_int			  sg_count;/* How full ahd_dma_seg is */
   9.526 +};
   9.527 +
   9.528 +struct scb_data {
   9.529 +	SLIST_HEAD(, scb) free_scbs;	/*
   9.530 +					 * Pool of SCBs ready to be assigned
   9.531 +					 * commands to execute.
   9.532 +					 */
   9.533 +	struct	scb *scbindex[AHD_SCB_MAX];
   9.534 +					/*
   9.535 +					 * Mapping from tag to SCB.
   9.536 +					 */
   9.537 +	/*
   9.538 +	 * "Bus" addresses of our data structures.
   9.539 +	 */
   9.540 +	bus_dma_tag_t	 hscb_dmat;	/* dmat for our hardware SCB array */
   9.541 +	bus_dma_tag_t	 sg_dmat;	/* dmat for our sg segments */
   9.542 +	bus_dma_tag_t	 sense_dmat;	/* dmat for our sense buffers */
   9.543 +	SLIST_HEAD(, map_node) hscb_maps;
   9.544 +	SLIST_HEAD(, map_node) sg_maps;
   9.545 +	SLIST_HEAD(, map_node) sense_maps;
   9.546 +	int		 scbs_left;	/* unallocated scbs in head map_node */
   9.547 +	int		 sgs_left;	/* unallocated sgs in head map_node */
   9.548 +	int		 sense_left;	/* unallocated sense in head map_node */
   9.549 +	uint16_t	 numscbs;
   9.550 +	uint16_t	 maxhscbs;	/* Number of SCBs on the card */
   9.551 +	uint8_t		 init_level;	/*
   9.552 +					 * How far we've initialized
   9.553 +					 * this structure.
   9.554 +					 */
   9.555 +};
   9.556 +
   9.557 +/************************ Target Mode Definitions *****************************/
   9.558 +
   9.559 +/*
   9.560 + * Connection desciptor for select-in requests in target mode.
   9.561 + */
   9.562 +struct target_cmd {
   9.563 +	uint8_t scsiid;		/* Our ID and the initiator's ID */
   9.564 +	uint8_t identify;	/* Identify message */
   9.565 +	uint8_t bytes[22];	/* 
   9.566 +				 * Bytes contains any additional message
   9.567 +				 * bytes terminated by 0xFF.  The remainder
   9.568 +				 * is the cdb to execute.
   9.569 +				 */
   9.570 +	uint8_t cmd_valid;	/*
   9.571 +				 * When a command is complete, the firmware
   9.572 +				 * will set cmd_valid to all bits set.
   9.573 +				 * After the host has seen the command,
   9.574 +				 * the bits are cleared.  This allows us
   9.575 +				 * to just peek at host memory to determine
   9.576 +				 * if more work is complete. cmd_valid is on
   9.577 +				 * an 8 byte boundary to simplify setting
   9.578 +				 * it on aic7880 hardware which only has
   9.579 +				 * limited direct access to the DMA FIFO.
   9.580 +				 */
   9.581 +	uint8_t pad[7];
   9.582 +};
   9.583 +
   9.584 +/*
   9.585 + * Number of events we can buffer up if we run out
   9.586 + * of immediate notify ccbs.
   9.587 + */
   9.588 +#define AHD_TMODE_EVENT_BUFFER_SIZE 8
   9.589 +struct ahd_tmode_event {
   9.590 +	uint8_t initiator_id;
   9.591 +	uint8_t event_type;	/* MSG type or EVENT_TYPE_BUS_RESET */
   9.592 +#define	EVENT_TYPE_BUS_RESET 0xFF
   9.593 +	uint8_t event_arg;
   9.594 +};
   9.595 +
   9.596 +/*
   9.597 + * Per enabled lun target mode state.
   9.598 + * As this state is directly influenced by the host OS'es target mode
   9.599 + * environment, we let the OS module define it.  Forward declare the
   9.600 + * structure here so we can store arrays of them, etc. in OS neutral
   9.601 + * data structures.
   9.602 + */
   9.603 +#ifdef AHD_TARGET_MODE 
   9.604 +struct ahd_tmode_lstate {
   9.605 +	struct cam_path *path;
   9.606 +	struct ccb_hdr_slist accept_tios;
   9.607 +	struct ccb_hdr_slist immed_notifies;
   9.608 +	struct ahd_tmode_event event_buffer[AHD_TMODE_EVENT_BUFFER_SIZE];
   9.609 +	uint8_t event_r_idx;
   9.610 +	uint8_t event_w_idx;
   9.611 +};
   9.612 +#else
   9.613 +struct ahd_tmode_lstate;
   9.614 +#endif
   9.615 +
   9.616 +/******************** Transfer Negotiation Datastructures *********************/
   9.617 +#define AHD_TRANS_CUR		0x01	/* Modify current neogtiation status */
   9.618 +#define AHD_TRANS_ACTIVE	0x03	/* Assume this target is on the bus */
   9.619 +#define AHD_TRANS_GOAL		0x04	/* Modify negotiation goal */
   9.620 +#define AHD_TRANS_USER		0x08	/* Modify user negotiation settings */
   9.621 +#define AHD_PERIOD_ASYNC	0xFF
   9.622 +#define AHD_PERIOD_10MHz	0x19
   9.623 +
   9.624 +/*
   9.625 + * Transfer Negotiation Information.
   9.626 + */
   9.627 +struct ahd_transinfo {
   9.628 +	uint8_t protocol_version;	/* SCSI Revision level */
   9.629 +	uint8_t transport_version;	/* SPI Revision level */
   9.630 +	uint8_t width;			/* Bus width */
   9.631 +	uint8_t period;			/* Sync rate factor */
   9.632 +	uint8_t offset;			/* Sync offset */
   9.633 +	uint8_t ppr_options;		/* Parallel Protocol Request options */
   9.634 +};
   9.635 +
   9.636 +/*
   9.637 + * Per-initiator current, goal and user transfer negotiation information. */
   9.638 +struct ahd_initiator_tinfo {
   9.639 +	struct ahd_transinfo curr;
   9.640 +	struct ahd_transinfo goal;
   9.641 +	struct ahd_transinfo user;
   9.642 +};
   9.643 +
   9.644 +/*
   9.645 + * Per enabled target ID state.
   9.646 + * Pointers to lun target state as well as sync/wide negotiation information
   9.647 + * for each initiator<->target mapping.  For the initiator role we pretend
   9.648 + * that we are the target and the targets are the initiators since the
   9.649 + * negotiation is the same regardless of role.
   9.650 + */
   9.651 +struct ahd_tmode_tstate {
   9.652 +	struct ahd_tmode_lstate*	enabled_luns[AHD_NUM_LUNS];
   9.653 +	struct ahd_initiator_tinfo	transinfo[AHD_NUM_TARGETS];
   9.654 +
   9.655 +	/*
   9.656 +	 * Per initiator state bitmasks.
   9.657 +	 */
   9.658 +	uint16_t	 auto_negotiate;/* Auto Negotiation Required */
   9.659 +	uint16_t	 discenable;	/* Disconnection allowed  */
   9.660 +	uint16_t	 tagenable;	/* Tagged Queuing allowed */
   9.661 +};
   9.662 +
   9.663 +/*
   9.664 + * Points of interest along the negotiated transfer scale.
   9.665 + */
   9.666 +#define AHD_SYNCRATE_MAX	0x8
   9.667 +#define AHD_SYNCRATE_160	0x8
   9.668 +#define AHD_SYNCRATE_PACED	0x8
   9.669 +#define AHD_SYNCRATE_DT		0x9
   9.670 +#define AHD_SYNCRATE_ULTRA2	0xa
   9.671 +#define AHD_SYNCRATE_ULTRA	0xc
   9.672 +#define AHD_SYNCRATE_FAST	0x19
   9.673 +#define AHD_SYNCRATE_MIN_DT	AHD_SYNCRATE_FAST
   9.674 +#define AHD_SYNCRATE_SYNC	0x32
   9.675 +#define AHD_SYNCRATE_MIN	0x60
   9.676 +#define	AHD_SYNCRATE_ASYNC	0xFF
   9.677 +
   9.678 +/*
   9.679 + * In RevA, the synctable uses a 120MHz rate for the period
   9.680 + * factor 8 and 160MHz for the period factor 7.  The 120MHz
   9.681 + * rate never made it into the official SCSI spec, so we must
   9.682 + * compensate when setting the negotiation table for Rev A
   9.683 + * parts.
   9.684 + */
   9.685 +#define AHD_SYNCRATE_REVA_120	0x8
   9.686 +#define AHD_SYNCRATE_REVA_160	0x7
   9.687 +
   9.688 +/***************************** Lookup Tables **********************************/
   9.689 +/*
   9.690 + * Phase -> name and message out response
   9.691 + * to parity errors in each phase table. 
   9.692 + */
   9.693 +struct ahd_phase_table_entry {
   9.694 +        uint8_t phase;
   9.695 +        uint8_t mesg_out; /* Message response to parity errors */
   9.696 +	char *phasemsg;
   9.697 +};
   9.698 +
   9.699 +/************************** Serial EEPROM Format ******************************/
   9.700 +
   9.701 +struct seeprom_config {
   9.702 +/*
   9.703 + * Per SCSI ID Configuration Flags
   9.704 + */
   9.705 +	uint16_t device_flags[16];	/* words 0-15 */
   9.706 +#define		CFXFER		0x003F	/* synchronous transfer rate */
   9.707 +#define			CFXFER_ASYNC	0x3F
   9.708 +#define		CFQAS		0x0040	/* Negotiate QAS */
   9.709 +#define		CFPACKETIZED	0x0080	/* Negotiate Packetized Transfers */
   9.710 +#define		CFSTART		0x0100	/* send start unit SCSI command */
   9.711 +#define		CFINCBIOS	0x0200	/* include in BIOS scan */
   9.712 +#define		CFDISC		0x0400	/* enable disconnection */
   9.713 +#define		CFMULTILUNDEV	0x0800	/* Probe multiple luns in BIOS scan */
   9.714 +#define		CFWIDEB		0x1000	/* wide bus device */
   9.715 +#define		CFHOSTMANAGED	0x8000	/* Managed by a RAID controller */
   9.716 +
   9.717 +/*
   9.718 + * BIOS Control Bits
   9.719 + */
   9.720 +	uint16_t bios_control;		/* word 16 */
   9.721 +#define		CFSUPREM	0x0001	/* support all removeable drives */
   9.722 +#define		CFSUPREMB	0x0002	/* support removeable boot drives */
   9.723 +#define		CFBIOSSTATE	0x000C	/* BIOS Action State */
   9.724 +#define		    CFBS_DISABLED	0x00
   9.725 +#define		    CFBS_ENABLED	0x04
   9.726 +#define		    CFBS_DISABLED_SCAN	0x08
   9.727 +#define		CFENABLEDV	0x0010	/* Perform Domain Validation */
   9.728 +#define		CFCTRL_A	0x0020	/* BIOS displays Ctrl-A message */	
   9.729 +#define		CFSPARITY	0x0040	/* SCSI parity */
   9.730 +#define		CFEXTEND	0x0080	/* extended translation enabled */
   9.731 +#define		CFBOOTCD	0x0100  /* Support Bootable CD-ROM */
   9.732 +#define		CFMSG_LEVEL	0x0600	/* BIOS Message Level */
   9.733 +#define			CFMSG_VERBOSE	0x0000
   9.734 +#define			CFMSG_SILENT	0x0200
   9.735 +#define			CFMSG_DIAG	0x0400
   9.736 +#define		CFRESETB	0x0800	/* reset SCSI bus at boot */
   9.737 +/*		UNUSED		0xf000	*/
   9.738 +
   9.739 +/*
   9.740 + * Host Adapter Control Bits
   9.741 + */
   9.742 +	uint16_t adapter_control;	/* word 17 */	
   9.743 +#define		CFAUTOTERM	0x0001	/* Perform Auto termination */
   9.744 +#define		CFSTERM		0x0002	/* SCSI low byte termination */
   9.745 +#define		CFWSTERM	0x0004	/* SCSI high byte termination */
   9.746 +#define		CFSEAUTOTERM	0x0008	/* Ultra2 Perform secondary Auto Term*/
   9.747 +#define		CFSELOWTERM	0x0010	/* Ultra2 secondary low term */
   9.748 +#define		CFSEHIGHTERM	0x0020	/* Ultra2 secondary high term */
   9.749 +#define		CFSTPWLEVEL	0x0040	/* Termination level control */
   9.750 +#define		CFBIOSAUTOTERM	0x0080	/* Perform Auto termination */
   9.751 +#define		CFTERM_MENU	0x0100	/* BIOS displays termination menu */	
   9.752 +#define		CFCLUSTERENB	0x8000	/* Cluster Enable */
   9.753 +
   9.754 +/*
   9.755 + * Bus Release Time, Host Adapter ID
   9.756 + */
   9.757 +	uint16_t brtime_id;		/* word 18 */
   9.758 +#define		CFSCSIID	0x000f	/* host adapter SCSI ID */
   9.759 +/*		UNUSED		0x00f0	*/
   9.760 +#define		CFBRTIME	0xff00	/* bus release time/PCI Latency Time */
   9.761 +
   9.762 +/*
   9.763 + * Maximum targets
   9.764 + */
   9.765 +	uint16_t max_targets;		/* word 19 */	
   9.766 +#define		CFMAXTARG	0x00ff	/* maximum targets */
   9.767 +#define		CFBOOTLUN	0x0f00	/* Lun to boot from */
   9.768 +#define		CFBOOTID	0xf000	/* Target to boot from */
   9.769 +	uint16_t res_1[10];		/* words 20-29 */
   9.770 +	uint16_t signature;		/* BIOS Signature */
   9.771 +#define		CFSIGNATURE	0x400
   9.772 +	uint16_t checksum;		/* word 31 */
   9.773 +};
   9.774 +
   9.775 +/****************************** Flexport Logic ********************************/
   9.776 +#define FLXADDR_TERMCTL			0x0
   9.777 +#define		FLX_TERMCTL_ENSECHIGH	0x8
   9.778 +#define		FLX_TERMCTL_ENSECLOW	0x4
   9.779 +#define		FLX_TERMCTL_ENPRIHIGH	0x2
   9.780 +#define		FLX_TERMCTL_ENPRILOW	0x1
   9.781 +#define FLXADDR_ROMSTAT_CURSENSECTL	0x1
   9.782 +#define		FLX_ROMSTAT_SEECFG	0xF0
   9.783 +#define		FLX_ROMSTAT_EECFG	0x0F
   9.784 +#define		FLX_ROMSTAT_SEE_93C66	0x00
   9.785 +#define		FLX_ROMSTAT_SEE_NONE	0xF0
   9.786 +#define		FLX_ROMSTAT_EE_512x8	0x0
   9.787 +#define		FLX_ROMSTAT_EE_1MBx8	0x1
   9.788 +#define		FLX_ROMSTAT_EE_2MBx8	0x2
   9.789 +#define		FLX_ROMSTAT_EE_4MBx8	0x3
   9.790 +#define		FLX_ROMSTAT_EE_16MBx8	0x4
   9.791 +#define 		CURSENSE_ENB	0x1
   9.792 +#define	FLXADDR_FLEXSTAT		0x2
   9.793 +#define		FLX_FSTAT_BUSY		0x1
   9.794 +#define FLXADDR_CURRENT_STAT		0x4
   9.795 +#define		FLX_CSTAT_SEC_HIGH	0xC0
   9.796 +#define		FLX_CSTAT_SEC_LOW	0x30
   9.797 +#define		FLX_CSTAT_PRI_HIGH	0x0C
   9.798 +#define		FLX_CSTAT_PRI_LOW	0x03
   9.799 +#define		FLX_CSTAT_MASK		0x03
   9.800 +#define		FLX_CSTAT_SHIFT		2
   9.801 +#define		FLX_CSTAT_OKAY		0x0
   9.802 +#define		FLX_CSTAT_OVER		0x1
   9.803 +#define		FLX_CSTAT_UNDER		0x2
   9.804 +#define		FLX_CSTAT_INVALID	0x3
   9.805 +
   9.806 +int		ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
   9.807 +				 u_int start_addr, u_int count);
   9.808 +
   9.809 +int		ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
   9.810 +				  u_int start_addr, u_int count);
   9.811 +int		ahd_wait_seeprom(struct ahd_softc *ahd);
   9.812 +int		ahd_verify_cksum(struct seeprom_config *sc);
   9.813 +int		ahd_acquire_seeprom(struct ahd_softc *ahd);
   9.814 +void		ahd_release_seeprom(struct ahd_softc *ahd);
   9.815 +
   9.816 +/****************************  Message Buffer *********************************/
   9.817 +typedef enum {
   9.818 +	MSG_FLAG_NONE			= 0x00,
   9.819 +	MSG_FLAG_EXPECT_PPR_BUSFREE	= 0x01,
   9.820 +	MSG_FLAG_IU_REQ_CHANGED		= 0x02,
   9.821 +	MSG_FLAG_EXPECT_IDE_BUSFREE	= 0x04,
   9.822 +	MSG_FLAG_PACKETIZED		= 0x08
   9.823 +} ahd_msg_flags;
   9.824 +
   9.825 +typedef enum {
   9.826 +	MSG_TYPE_NONE			= 0x00,
   9.827 +	MSG_TYPE_INITIATOR_MSGOUT	= 0x01,
   9.828 +	MSG_TYPE_INITIATOR_MSGIN	= 0x02,
   9.829 +	MSG_TYPE_TARGET_MSGOUT		= 0x03,
   9.830 +	MSG_TYPE_TARGET_MSGIN		= 0x04
   9.831 +} ahd_msg_type;
   9.832 +
   9.833 +typedef enum {
   9.834 +	MSGLOOP_IN_PROG,
   9.835 +	MSGLOOP_MSGCOMPLETE,
   9.836 +	MSGLOOP_TERMINATED
   9.837 +} msg_loop_stat;
   9.838 +
   9.839 +/*********************** Software Configuration Structure *********************/
   9.840 +TAILQ_HEAD(scb_tailq, scb);
   9.841 +
   9.842 +struct ahd_suspend_channel_state {
   9.843 +	uint8_t	scsiseq;
   9.844 +	uint8_t	sxfrctl0;
   9.845 +	uint8_t	sxfrctl1;
   9.846 +	uint8_t	simode0;
   9.847 +	uint8_t	simode1;
   9.848 +	uint8_t	seltimer;
   9.849 +	uint8_t	seqctl;
   9.850 +};
   9.851 +
   9.852 +struct ahd_suspend_state {
   9.853 +	struct	ahd_suspend_channel_state channel[2];
   9.854 +	uint8_t	optionmode;
   9.855 +	uint8_t	dscommand0;
   9.856 +	uint8_t	dspcistatus;
   9.857 +	/* hsmailbox */
   9.858 +	uint8_t	crccontrol1;
   9.859 +	uint8_t	scbbaddr;
   9.860 +	/* Host and sequencer SCB counts */
   9.861 +	uint8_t	dff_thrsh;
   9.862 +	uint8_t	*scratch_ram;
   9.863 +	uint8_t	*btt;
   9.864 +};
   9.865 +
   9.866 +typedef void (*ahd_bus_intr_t)(struct ahd_softc *);
   9.867 +
   9.868 +typedef enum {
   9.869 +	AHD_MODE_DFF0,
   9.870 +	AHD_MODE_DFF1,
   9.871 +	AHD_MODE_CCHAN,
   9.872 +	AHD_MODE_SCSI,
   9.873 +	AHD_MODE_CFG,
   9.874 +	AHD_MODE_UNKNOWN
   9.875 +} ahd_mode;
   9.876 +
   9.877 +#define AHD_MK_MSK(x) (0x01 << (x))
   9.878 +#define AHD_MODE_DFF0_MSK	AHD_MK_MSK(AHD_MODE_DFF0)
   9.879 +#define AHD_MODE_DFF1_MSK	AHD_MK_MSK(AHD_MODE_DFF1)
   9.880 +#define AHD_MODE_CCHAN_MSK	AHD_MK_MSK(AHD_MODE_CCHAN)
   9.881 +#define AHD_MODE_SCSI_MSK	AHD_MK_MSK(AHD_MODE_SCSI)
   9.882 +#define AHD_MODE_CFG_MSK	AHD_MK_MSK(AHD_MODE_CFG)
   9.883 +#define AHD_MODE_UNKNOWN_MSK	AHD_MK_MSK(AHD_MODE_UNKNOWN)
   9.884 +#define AHD_MODE_ANY_MSK (~0)
   9.885 +
   9.886 +typedef uint8_t ahd_mode_state;
   9.887 +
   9.888 +typedef void ahd_callback_t (void *);
   9.889 +
   9.890 +struct ahd_softc {
   9.891 +	bus_space_tag_t           tags[2];
   9.892 +	bus_space_handle_t        bshs[2];
   9.893 +#ifndef __linux__
   9.894 +	bus_dma_tag_t		  buffer_dmat;   /* dmat for buffer I/O */
   9.895 +#endif
   9.896 +	struct scb_data		  scb_data;
   9.897 +
   9.898 +	struct scb		 *next_queued_scb;
   9.899 +
   9.900 +	/*
   9.901 +	 * SCBs that have been sent to the controller
   9.902 +	 */
   9.903 +	LIST_HEAD(, scb)	  pending_scbs;
   9.904 +
   9.905 +	/*
   9.906 +	 * Current register window mode information.
   9.907 +	 */
   9.908 +	ahd_mode		  dst_mode;
   9.909 +	ahd_mode		  src_mode;
   9.910 +
   9.911 +	/*
   9.912 +	 * Saved register window mode information
   9.913 +	 * used for restore on next unpause.
   9.914 +	 */
   9.915 +	ahd_mode		  saved_dst_mode;
   9.916 +	ahd_mode		  saved_src_mode;
   9.917 +
   9.918 +	/*
   9.919 +	 * Counting lock for deferring the release of additional
   9.920 +	 * untagged transactions from the untagged_queues.  When
   9.921 +	 * the lock is decremented to 0, all queues in the
   9.922 +	 * untagged_queues array are run.
   9.923 +	 */
   9.924 +	u_int			  untagged_queue_lock;
   9.925 +
   9.926 +	/*
   9.927 +	 * Per-target queue of untagged-transactions.  The
   9.928 +	 * transaction at the head of the queue is the
   9.929 +	 * currently pending untagged transaction for the
   9.930 +	 * target.  The driver only allows a single untagged
   9.931 +	 * transaction per target.
   9.932 +	 */
   9.933 +	struct scb_tailq	  untagged_queues[AHD_NUM_TARGETS];
   9.934 +
   9.935 +	/*
   9.936 +	 * Platform specific data.
   9.937 +	 */
   9.938 +	struct ahd_platform_data *platform_data;
   9.939 +
   9.940 +	/*
   9.941 +	 * Platform specific device information.
   9.942 +	 */
   9.943 +	ahd_dev_softc_t		  dev_softc;
   9.944 +
   9.945 +	/*
   9.946 +	 * Bus specific device information.
   9.947 +	 */
   9.948 +	ahd_bus_intr_t		  bus_intr;
   9.949 +
   9.950 +	/*
   9.951 +	 * Target mode related state kept on a per enabled lun basis.
   9.952 +	 * Targets that are not enabled will have null entries.
   9.953 +	 * As an initiator, we keep one target entry for our initiator
   9.954 +	 * ID to store our sync/wide transfer settings.
   9.955 +	 */
   9.956 +	struct ahd_tmode_tstate  *enabled_targets[AHD_NUM_TARGETS];
   9.957 +
   9.958 +	/*
   9.959 +	 * The black hole device responsible for handling requests for
   9.960 +	 * disabled luns on enabled targets.
   9.961 +	 */
   9.962 +	struct ahd_tmode_lstate  *black_hole;
   9.963 +
   9.964 +	/*
   9.965 +	 * Device instance currently on the bus awaiting a continue TIO
   9.966 +	 * for a command that was not given the disconnect priveledge.
   9.967 +	 */
   9.968 +	struct ahd_tmode_lstate  *pending_device;
   9.969 +
   9.970 +	/*
   9.971 +	 * Timer handles for timer driven callbacks.
   9.972 +	 */
   9.973 +	ahd_timer_t		  reset_timer;
   9.974 +
   9.975 +	/*
   9.976 +	 * Card characteristics
   9.977 +	 */
   9.978 +	ahd_chip		  chip;
   9.979 +	ahd_feature		  features;
   9.980 +	ahd_bug			  bugs;
   9.981 +	ahd_flag		  flags;
   9.982 +	struct seeprom_config	 *seep_config;
   9.983 +
   9.984 +	/* Values to store in the SEQCTL register for pause and unpause */
   9.985 +	uint8_t			  unpause;
   9.986 +	uint8_t			  pause;
   9.987 +
   9.988 +	/* Command Queues */
   9.989 +	uint16_t		  qoutfifonext;
   9.990 +	uint16_t		  qinfifonext;
   9.991 +	uint16_t		  qinfifo[AHD_SCB_MAX];
   9.992 +	uint16_t		 *qoutfifo;
   9.993 +
   9.994 +	/* Critical Section Data */
   9.995 +	struct cs		 *critical_sections;
   9.996 +	u_int			  num_critical_sections;
   9.997 +
   9.998 +	/* Buffer for handling packetized bitbucket. */
   9.999 +	uint8_t			 *overrun_buf;
  9.1000 +
  9.1001 +	/* Links for chaining softcs */
  9.1002 +	TAILQ_ENTRY(ahd_softc)	  links;
  9.1003 +
  9.1004 +	/* Channel Names ('A', 'B', etc.) */
  9.1005 +	char			  channel;
  9.1006 +
  9.1007 +	/* Initiator Bus ID */
  9.1008 +	uint8_t			  our_id;
  9.1009 +
  9.1010 +	/*
  9.1011 +	 * PCI error detection.
  9.1012 +	 */
  9.1013 +	int			  unsolicited_ints;
  9.1014 +
  9.1015 +	/*
  9.1016 +	 * Target incoming command FIFO.
  9.1017 +	 */
  9.1018 +	struct target_cmd	 *targetcmds;
  9.1019 +	uint8_t			  tqinfifonext;
  9.1020 +
  9.1021 +	/*
  9.1022 +	 * Incoming and outgoing message handling.
  9.1023 +	 */
  9.1024 +	uint8_t			  send_msg_perror;
  9.1025 +	ahd_msg_flags		  msg_flags;
  9.1026 +	ahd_msg_type		  msg_type;
  9.1027 +	uint8_t			  msgout_buf[12];/* Message we are sending */
  9.1028 +	uint8_t			  msgin_buf[12];/* Message we are receiving */
  9.1029 +	u_int			  msgout_len;	/* Length of message to send */
  9.1030 +	u_int			  msgout_index;	/* Current index in msgout */
  9.1031 +	u_int			  msgin_index;	/* Current index in msgin */
  9.1032 +
  9.1033 +	/*
  9.1034 +	 * Mapping information for data structures shared
  9.1035 +	 * between the sequencer and kernel.
  9.1036 +	 */
  9.1037 +	bus_dma_tag_t		  parent_dmat;
  9.1038 +	bus_dma_tag_t		  shared_data_dmat;
  9.1039 +	bus_dmamap_t		  shared_data_dmamap;
  9.1040 +	bus_addr_t		  shared_data_busaddr;
  9.1041 +
  9.1042 +	/* Information saved through suspend/resume cycles */
  9.1043 +	struct ahd_suspend_state  suspend_state;
  9.1044 +
  9.1045 +	/* Number of enabled target mode device on this card */
  9.1046 +	u_int			  enabled_luns;
  9.1047 +
  9.1048 +	/* Initialization level of this data structure */
  9.1049 +	u_int			  init_level;
  9.1050 +
  9.1051 +	/* PCI cacheline size. */
  9.1052 +	u_int			  pci_cachesize;
  9.1053 +
  9.1054 +	/* Per-Unit descriptive information */
  9.1055 +	const char		 *description;
  9.1056 +	const char		 *bus_description;
  9.1057 +	char			 *name;
  9.1058 +	int			  unit;
  9.1059 +
  9.1060 +	/* Selection Timer settings */
  9.1061 +	int			  seltime;
  9.1062 +
  9.1063 +	uint16_t	 	  user_discenable;/* Disconnection allowed  */
  9.1064 +	uint16_t		  user_tagenable;/* Tagged Queuing allowed */
  9.1065 +};
  9.1066 +
  9.1067 +TAILQ_HEAD(ahd_softc_tailq, ahd_softc);
  9.1068 +extern struct ahd_softc_tailq ahd_tailq;
  9.1069 +
  9.1070 +/************************ Active Device Information ***************************/
  9.1071 +typedef enum {
  9.1072 +	ROLE_UNKNOWN,
  9.1073 +	ROLE_INITIATOR,
  9.1074 +	ROLE_TARGET
  9.1075 +} role_t;
  9.1076 +
  9.1077 +struct ahd_devinfo {
  9.1078 +	int	 our_scsiid;
  9.1079 +	int	 target_offset;
  9.1080 +	uint16_t target_mask;
  9.1081 +	u_int	 target;
  9.1082 +	u_int	 lun;
  9.1083 +	char	 channel;
  9.1084 +	role_t	 role;		/*
  9.1085 +				 * Only guaranteed to be correct if not
  9.1086 +				 * in the busfree state.
  9.1087 +				 */
  9.1088 +};
  9.1089 +
  9.1090 +/****************************** PCI Structures ********************************/
  9.1091 +#define AHD_PCI_IOADDR0	PCIR_MAPS	/* I/O BAR*/
  9.1092 +#define AHD_PCI_MEMADDR	(PCIR_MAPS + 4)	/* Memory BAR */
  9.1093 +#define AHD_PCI_IOADDR1	(PCIR_MAPS + 12)/* Second I/O BAR */
  9.1094 +
  9.1095 +typedef int (ahd_device_setup_t)(struct ahd_softc *);
  9.1096 +
  9.1097 +struct ahd_pci_identity {
  9.1098 +	uint64_t		 full_id;
  9.1099 +	uint64_t		 id_mask;
  9.1100 +	char			*name;
  9.1101 +	ahd_device_setup_t	*setup;
  9.1102 +};
  9.1103 +extern struct ahd_pci_identity ahd_pci_ident_table [];
  9.1104 +extern const u_int ahd_num_pci_devs;
  9.1105 +
  9.1106 +/***************************** VL/EISA Declarations ***************************/
  9.1107 +struct aic7770_identity {
  9.1108 +	uint32_t		 full_id;
  9.1109 +	uint32_t		 id_mask;
  9.1110 +	char			*name;
  9.1111 +	ahd_device_setup_t	*setup;
  9.1112 +};
  9.1113 +extern struct aic7770_identity aic7770_ident_table [];
  9.1114 +extern const int ahd_num_aic7770_devs;
  9.1115 +
  9.1116 +#define AHD_EISA_SLOT_OFFSET	0xc00
  9.1117 +#define AHD_EISA_IOSIZE		0x100
  9.1118 +
  9.1119 +/*************************** Function Declarations ****************************/
  9.1120 +/******************************************************************************/
  9.1121 +u_int			ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl);
  9.1122 +void			ahd_set_disconnected_list(struct ahd_softc *ahd,
  9.1123 +						  u_int target, u_int lun,
  9.1124 +						  u_int scbid);
  9.1125 +void			ahd_busy_tcl(struct ahd_softc *ahd,
  9.1126 +				     u_int tcl, u_int busyid);
  9.1127 +static __inline void	ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl);
  9.1128 +static __inline void
  9.1129 +ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
  9.1130 +{
  9.1131 +	ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL);
  9.1132 +}
  9.1133 +
  9.1134 +/***************************** PCI Front End *********************************/
  9.1135 +struct ahd_pci_identity	*ahd_find_pci_device(ahd_dev_softc_t);
  9.1136 +int			 ahd_pci_config(struct ahd_softc *,
  9.1137 +					struct ahd_pci_identity *);
  9.1138 +
  9.1139 +/*************************** EISA/VL Front End ********************************/
  9.1140 +struct aic7770_identity *aic7770_find_device(uint32_t);
  9.1141 +int			 aic7770_config(struct ahd_softc *ahd,
  9.1142 +					struct aic7770_identity *);
  9.1143 +
  9.1144 +/************************** SCB and SCB queue management **********************/
  9.1145 +int		ahd_probe_scbs(struct ahd_softc *);
  9.1146 +void		ahd_run_untagged_queues(struct ahd_softc *ahd);
  9.1147 +void		ahd_run_untagged_queue(struct ahd_softc *ahd,
  9.1148 +				       struct scb_tailq *queue);
  9.1149 +void		ahd_qinfifo_requeue_tail(struct ahd_softc *ahd,
  9.1150 +					 struct scb *scb);
  9.1151 +int		ahd_match_scb(struct ahd_softc *ahd, struct scb *scb,
  9.1152 +			      int target, char channel, int lun,
  9.1153 +			      u_int tag, role_t role);
  9.1154 +
  9.1155 +/****************************** Initialization ********************************/
  9.1156 +struct ahd_softc	*ahd_alloc(void *platform_arg, char *name);
  9.1157 +int			 ahd_softc_init(struct ahd_softc *);
  9.1158 +void			 ahd_controller_info(struct ahd_softc *ahd, char *buf);
  9.1159 +int			 ahd_init(struct ahd_softc *ahd);
  9.1160 +int			 ahd_default_config(struct ahd_softc *ahd);
  9.1161 +int			 ahd_parse_cfgdata(struct ahd_softc *ahd,
  9.1162 +					   struct seeprom_config *sc);
  9.1163 +void			 ahd_intr_enable(struct ahd_softc *ahd, int enable);
  9.1164 +void			 ahd_pause_and_flushwork(struct ahd_softc *ahd);
  9.1165 +int			 ahd_suspend(struct ahd_softc *ahd); 
  9.1166 +int			 ahd_resume(struct ahd_softc *ahd);
  9.1167 +void			 ahd_softc_insert(struct ahd_softc *);
  9.1168 +struct ahd_softc	*ahd_find_softc(struct ahd_softc *ahd);
  9.1169 +void			 ahd_set_unit(struct ahd_softc *, int);
  9.1170 +void			 ahd_set_name(struct ahd_softc *, char *);
  9.1171 +void			 ahd_alloc_scbs(struct ahd_softc *ahd);
  9.1172 +void			 ahd_free(struct ahd_softc *ahd);
  9.1173 +int			 ahd_reset(struct ahd_softc *ahd);
  9.1174 +void			 ahd_shutdown(void *arg);
  9.1175 +int			ahd_write_flexport(struct ahd_softc *ahd,
  9.1176 +					   u_int addr, u_int value);
  9.1177 +int			ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
  9.1178 +					  uint8_t *value);
  9.1179 +int			ahd_wait_flexport(struct ahd_softc *ahd);
  9.1180 +
  9.1181 +/*************************** Interrupt Services *******************************/
  9.1182 +void			ahd_pci_intr(struct ahd_softc *ahd);
  9.1183 +void			ahd_clear_intstat(struct ahd_softc *ahd);
  9.1184 +void			ahd_run_qoutfifo(struct ahd_softc *ahd);
  9.1185 +#ifdef AHD_TARGET_MODE
  9.1186 +void			ahd_run_tqinfifo(struct ahd_softc *ahd, int paused);
  9.1187 +#endif
  9.1188 +void			ahd_handle_hwerrint(struct ahd_softc *ahd);
  9.1189 +void			ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat);
  9.1190 +void			ahd_handle_scsiint(struct ahd_softc *ahd,
  9.1191 +					   u_int intstat);
  9.1192 +void			ahd_clear_critical_section(struct ahd_softc *ahd);
  9.1193 +
  9.1194 +/***************************** Error Recovery *********************************/
  9.1195 +typedef enum {
  9.1196 +	SEARCH_COMPLETE,
  9.1197 +	SEARCH_COUNT,
  9.1198 +	SEARCH_REMOVE,
  9.1199 +	SEARCH_PRINT
  9.1200 +} ahd_search_action;
  9.1201 +int			ahd_search_qinfifo(struct ahd_softc *ahd, int target,
  9.1202 +					   char channel, int lun, u_int tag,
  9.1203 +					   role_t role, uint32_t status,
  9.1204 +					   ahd_search_action action);
  9.1205 +int			ahd_search_disc_list(struct ahd_softc *ahd, int target,
  9.1206 +					     char channel, int lun, u_int tag,
  9.1207 +					     int stop_on_first, int remove,
  9.1208 +					     int save_state);
  9.1209 +void			ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
  9.1210 +int			ahd_reset_channel(struct ahd_softc *ahd, char channel,
  9.1211 +					  int initiate_reset);
  9.1212 +int			ahd_abort_scbs(struct ahd_softc *ahd, int target,
  9.1213 +				       char channel, int lun, u_int tag,
  9.1214 +				       role_t role, uint32_t status);
  9.1215 +void			ahd_restart(struct ahd_softc *ahd);
  9.1216 +void			ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo);
  9.1217 +void			ahd_handle_scb_status(struct ahd_softc *ahd,
  9.1218 +					      struct scb *scb);
  9.1219 +void			ahd_handle_scsi_status(struct ahd_softc *ahd,
  9.1220 +					       struct scb *scb);
  9.1221 +void			ahd_calc_residual(struct ahd_softc *ahd,
  9.1222 +					  struct scb *scb);
  9.1223 +/*************************** Utility Functions ********************************/
  9.1224 +struct ahd_phase_table_entry*
  9.1225 +			ahd_lookup_phase_entry(int phase);
  9.1226 +void			ahd_compile_devinfo(struct ahd_devinfo *devinfo,
  9.1227 +					    u_int our_id, u_int target,
  9.1228 +					    u_int lun, char channel,
  9.1229 +					    role_t role);
  9.1230 +/************************** Transfer Negotiation ******************************/
  9.1231 +void			ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
  9.1232 +					  u_int *ppr_options, u_int maxsync);
  9.1233 +void			ahd_validate_offset(struct ahd_softc *ahd,
  9.1234 +					    struct ahd_initiator_tinfo *tinfo,
  9.1235 +					    u_int period, u_int *offset,
  9.1236 +					    int wide, role_t role);
  9.1237 +void			ahd_validate_width(struct ahd_softc *ahd,
  9.1238 +					   struct ahd_initiator_tinfo *tinfo,
  9.1239 +					   u_int *bus_width,
  9.1240 +					   role_t role);
  9.1241 +int			ahd_update_neg_request(struct ahd_softc*,
  9.1242 +					       struct ahd_devinfo*,
  9.1243 +					       struct ahd_tmode_tstate*,
  9.1244 +					       struct ahd_initiator_tinfo*,
  9.1245 +					       int /*force*/);
  9.1246 +void			ahd_set_width(struct ahd_softc *ahd,
  9.1247 +				      struct ahd_devinfo *devinfo,
  9.1248 +				      u_int width, u_int type, int paused);
  9.1249 +void			ahd_set_syncrate(struct ahd_softc *ahd,
  9.1250 +					 struct ahd_devinfo *devinfo,
  9.1251 +					 u_int period, u_int offset,
  9.1252 +					 u_int ppr_options,
  9.1253 +					 u_int type, int paused);
  9.1254 +typedef enum {
  9.1255 +	AHD_QUEUE_NONE,
  9.1256 +	AHD_QUEUE_BASIC,
  9.1257 +	AHD_QUEUE_TAGGED
  9.1258 +} ahd_queue_alg;
  9.1259 +
  9.1260 +void			ahd_set_tags(struct ahd_softc *ahd,
  9.1261 +				     struct ahd_devinfo *devinfo,
  9.1262 +				     ahd_queue_alg alg);
  9.1263 +
  9.1264 +/**************************** Target Mode *************************************/
  9.1265 +#ifdef AHD_TARGET_MODE
  9.1266 +void		ahd_send_lstate_events(struct ahd_softc *,
  9.1267 +				       struct ahd_tmode_lstate *);
  9.1268 +void		ahd_handle_en_lun(struct ahd_softc *ahd,
  9.1269 +				  struct cam_sim *sim, union ccb *ccb);
  9.1270 +cam_status	ahd_find_tmode_devs(struct ahd_softc *ahd,
  9.1271 +				    struct cam_sim *sim, union ccb *ccb,
  9.1272 +				    struct ahd_tmode_tstate **tstate,
  9.1273 +				    struct ahd_tmode_lstate **lstate,
  9.1274 +				    int notfound_failure);
  9.1275 +#ifndef AHD_TMODE_ENABLE
  9.1276 +#define AHD_TMODE_ENABLE 0
  9.1277 +#endif
  9.1278 +#endif
  9.1279 +/******************************* Debug ***************************************/
  9.1280 +#ifdef AHD_DEBUG
  9.1281 +extern uint32_t ahd_debug;
  9.1282 +#define AHD_SHOW_MISC		0x001
  9.1283 +#define AHD_SHOW_SENSE		0x002
  9.1284 +#define AHD_DUMP_SEEPROM	0x004
  9.1285 +#define AHD_SHOW_TERMCTL	0x008
  9.1286 +#define AHD_SHOW_MEMORY		0x010
  9.1287 +#define AHD_SHOW_MESSAGES	0x020
  9.1288 +#define AHD_SHOW_MODEPTR	0x040
  9.1289 +#define AHD_SHOW_SELTO		0x080
  9.1290 +#define AHD_SHOW_FIFOS		0x100
  9.1291 +#define AHD_SHOW_QFULL		0x200
  9.1292 +#define AHD_SHOW_QUEUE		0x400
  9.1293 +#define AHD_SHOW_TQIN		0x800
  9.1294 +#endif
  9.1295 +void			ahd_print_scb(struct scb *scb);
  9.1296 +void			ahd_dump_sglist(struct scb *scb);
  9.1297 +void			ahd_dump_all_cards_state(void);
  9.1298 +void			ahd_dump_card_state(struct ahd_softc *ahd);
  9.1299 +void			ahd_dump_scbs(struct ahd_softc *ahd);
  9.1300 +#endif /* _AIC79XX_H_ */
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/xen/drivers/scsi/aic7xxx/aic79xx.reg	Mon Mar 24 16:44:31 2003 +0000
    10.3 @@ -0,0 +1,3716 @@
    10.4 +/*
    10.5 + * Aic79xx register and scratch ram definitions.
    10.6 + *
    10.7 + * Copyright (c) 1994-2001 Justin T. Gibbs.
    10.8 + * Copyright (c) 2000-2001 Adaptec Inc.
    10.9 + * All rights reserved.
   10.10 + *
   10.11 + * Redistribution and use in source and binary forms, with or without
   10.12 + * modification, are permitted provided that the following conditions
   10.13 + * are met:
   10.14 + * 1. Redistributions of source code must retain the above copyright
   10.15 + *    notice, this list of conditions, and the following disclaimer,
   10.16 + *    without modification.
   10.17 + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   10.18 + *    substantially similar to the "NO WARRANTY" disclaimer below
   10.19 + *    ("Disclaimer") and any redistribution must be conditioned upon
   10.20 + *    including a substantially similar Disclaimer requirement for further
   10.21 + *    binary redistribution.
   10.22 + * 3. Neither the names of the above-listed copyright holders nor the names
   10.23 + *    of any contributors may be used to endorse or promote products derived
   10.24 + *    from this software without specific prior written permission.
   10.25 + *
   10.26 + * Alternatively, this software may be distributed under the terms of the
   10.27 + * GNU General Public License ("GPL") version 2 as published by the Free
   10.28 + * Software Foundation.
   10.29 + *
   10.30 + * NO WARRANTY
   10.31 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   10.32 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   10.33 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   10.34 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   10.35 + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   10.36 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   10.37 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   10.38 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   10.39 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   10.40 + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   10.41 + * POSSIBILITY OF SUCH DAMAGES.
   10.42 + *
   10.43 + * $FreeBSD$
   10.44 + */
   10.45 +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#34 $"
   10.46 +
   10.47 +/*
   10.48 + * This file is processed by the aic7xxx_asm utility for use in assembling
   10.49 + * firmware for the aic79xx family of SCSI host adapters as well as to generate
   10.50 + * a C header file for use in the kernel portion of the Aic79xx driver.
   10.51 + */
   10.52 +
   10.53 +/* Register window Modes */
   10.54 +#define M_DFF0		0
   10.55 +#define M_DFF1		1
   10.56 +#define M_CCHAN		2
   10.57 +#define M_SCSI		3
   10.58 +#define M_CFG		4
   10.59 +#define M_DST_SHIFT	4
   10.60 +
   10.61 +#define MK_MODE(src, dst) ((src) | ((dst) << M_DST_SHIFT))
   10.62 +#define SET_MODE(src, dst)					\
   10.63 +	SET_SRC_MODE	src;					\
   10.64 +	SET_DST_MODE	dst;					\
   10.65 +	mvi	MK_MODE(src, dst) call set_mode_work_around
   10.66 +
   10.67 +/*
   10.68 + * Mode Pointer
   10.69 + * Controls which of the 5, 512byte, address spaces should be used
   10.70 + * as the source and destination of any register accesses in our
   10.71 + * register window.
   10.72 + */
   10.73 +register MODE_PTR {
   10.74 +	address			0x000
   10.75 +	access_mode	RW
   10.76 +	mask	DST_MODE	0x70
   10.77 +	mask	SRC_MODE	0x07
   10.78 +	mode_pointer
   10.79 +}
   10.80 +
   10.81 +const SRC_MODE_SHIFT	0
   10.82 +const DST_MODE_SHIFT	4
   10.83 +
   10.84 +/*
   10.85 + * Host Interrupt Status
   10.86 + */
   10.87 +register INTSTAT {
   10.88 +	address			0x001
   10.89 +	access_mode	RW
   10.90 +	bit	HWERRINT	0x80
   10.91 +	bit	BRKADRINT	0x40
   10.92 +	bit	SWTMINT		0x20
   10.93 +	bit	PCIINT		0x10
   10.94 +	bit	SCSIINT		0x08
   10.95 +	bit	SEQINT		0x04
   10.96 +	bit	CMDCMPLT	0x02
   10.97 +	bit	SPLTINT		0x01
   10.98 +	mask	INT_PEND 0xFF
   10.99 +}
  10.100 +
  10.101 +/*
  10.102 + * Sequencer Interrupt Code
  10.103 + */
  10.104 +register SEQINTCODE {
  10.105 +	address			0x002
  10.106 +	access_mode	RW
  10.107 +	mask	BAD_PHASE	1		/* unknown scsi bus phase */
  10.108 +	mask	SEND_REJECT	2		/* sending a message reject */
  10.109 +	mask	PROTO_VIOLATION 3		/* Protocol Violation */
  10.110 +	mask	NO_MATCH	4		/* no cmd match for reconnect */
  10.111 +	mask	IGN_WIDE_RES	5		/* Complex IGN Wide Res Msg */
  10.112 +	mask	PDATA_REINIT	6		/*
  10.113 +						 * Returned to data phase
  10.114 +						 * that requires data
  10.115 +						 * transfer pointers to be
  10.116 +						 * recalculated from the
  10.117 +						 * transfer residual.
  10.118 +						 */
  10.119 +	mask	HOST_MSG_LOOP	7		/*
  10.120 +						 * The bus is ready for the
  10.121 +						 * host to perform another
  10.122 +						 * message transaction.  This
  10.123 +						 * mechanism is used for things
  10.124 +						 * like sync/wide negotiation
  10.125 +						 * that require a kernel based
  10.126 +						 * message state engine.
  10.127 +						 */
  10.128 +	mask	BAD_STATUS	8		/* Bad status from target */
  10.129 +	mask	DATA_OVERRUN	9		/*
  10.130 +						 * Target attempted to write
  10.131 +						 * beyond the bounds of its
  10.132 +						 * command.
  10.133 +						 */
  10.134 +	mask	MKMSG_FAILED	10		/*
  10.135 +						 * Target completed command
  10.136 +						 * without honoring our ATN
  10.137 +						 * request to issue a message. 
  10.138 +						 */
  10.139 +	mask	MISSED_BUSFREE	11		/*
  10.140 +						 * The sequencer never saw
  10.141 +						 * the bus go free after
  10.142 +						 * either a command complete
  10.143 +						 * or disconnect message.
  10.144 +						 */
  10.145 +	mask	SCB_MISMATCH	12		/*
  10.146 +						 * Downloaded SCB's tag does
  10.147 +						 * not match the entry we
  10.148 +						 * intended to download.
  10.149 +						 */
  10.150 +	mask	NO_FREE_SCB	13		/*
  10.151 +						 * get_free_or_disc_scb failed.
  10.152 +						 */
  10.153 +	mask	OUT_OF_RANGE	14
  10.154 +	mask	NO_FREE_FIFO	15
  10.155 +	mask	DUMP_CARD_STATE	16
  10.156 +	mask	ILLEGAL_PHASE	17
  10.157 +	mask	INVALID_SEQINT	18
  10.158 +	mask	CFG4ISTAT_INTR	19
  10.159 +	mask	STATUS_OVERRUN	20
  10.160 +	mask	CFG4OVERRUN	21
  10.161 +	mask	SNAPSHOTCLRCHN	22
  10.162 +	mask	MONITORDRAIN	23
  10.163 +	mask	ENTERING_NONPACK 24
  10.164 +	mask	PCIX_ARBITOR_WW 25
  10.165 +}
  10.166 +
  10.167 +/*
  10.168 + * Clear Host Interrupt
  10.169 + */
  10.170 +register CLRINT {
  10.171 +	address			0x003
  10.172 +	access_mode	WO
  10.173 +	bit	CLRBRKADRINT	0x40
  10.174 +	bit	CLRSWTMINT	0x20
  10.175 +	bit	CLRSCSIINT	0x08
  10.176 +	bit	CLRSEQINT	0x04
  10.177 +	bit	CLRCMDINT	0x02
  10.178 +	bit	CLRSPLTINT	0x01
  10.179 +}
  10.180 +
  10.181 +/*
  10.182 + * Error Register
  10.183 + */
  10.184 +register ERROR {
  10.185 +	address			0x004
  10.186 +	access_mode	RO
  10.187 +	bit	CIOPARERR	0x80
  10.188 +	bit	MPARERR		0x20
  10.189 +	bit	DPARERR		0x10
  10.190 +	bit	SQPARERR	0x08
  10.191 +	bit	ILLOPCODE	0x04
  10.192 +	bit	DSCTMOUT	0x02
  10.193 +}
  10.194 +
  10.195 +/*
  10.196 + * Clear Error
  10.197 + */
  10.198 +register CLRERR {
  10.199 +	address			0x004
  10.200 +	access_mode 	WO
  10.201 +	bit	CLRCIOPARERR	0x80
  10.202 +	bit	CLRMPARERR	0x20
  10.203 +	bit	CLRDPARERR	0x10
  10.204 +	bit	CLRSQPARERR	0x08
  10.205 +	bit	CLRILLOPCODE	0x04
  10.206 +	bit	CLRDSCTMOUT	0x02
  10.207 +}
  10.208 +
  10.209 +/*
  10.210 + * Host Control Register
  10.211 + * Overall host control of the device.
  10.212 + */
  10.213 +register HCNTRL {
  10.214 +	address			0x005
  10.215 +	access_mode	RW
  10.216 +	bit	POWRDN		0x40
  10.217 +	bit	SWINT		0x10
  10.218 +	bit	HCNTRL3		0x08
  10.219 +	bit	PAUSE		0x04
  10.220 +	bit	INTEN		0x02
  10.221 +	bit	CHIPRST		0x01
  10.222 +	bit	CHIPRSTACK	0x01
  10.223 +}
  10.224 +
  10.225 +/*
  10.226 + * Host New SCB Queue Offset
  10.227 + */
  10.228 +register HNSCB_QOFF {
  10.229 +	address			0x006
  10.230 +	access_mode	RW
  10.231 +	size		2
  10.232 +}
  10.233 +
  10.234 +/*
  10.235 + * Host Empty SCB Queue Offset
  10.236 + */
  10.237 +register HESCB_QOFF {
  10.238 +	address			0x008
  10.239 +	access_mode	RW
  10.240 +}
  10.241 +
  10.242 +/*
  10.243 + * Host Mailbox
  10.244 + */
  10.245 +register HS_MAILBOX {
  10.246 +	address			0x0B
  10.247 +	access_mode	RW
  10.248 +	mask	HOST_TQINPOS	0x80	/* Boundary at either 0 or 128 */
  10.249 +}
  10.250 +
  10.251 +/*
  10.252 + * Sequencer Interupt Status
  10.253 + */
  10.254 +register SEQINTSTAT {
  10.255 +	address			0x0C
  10.256 +	access_mode	RO
  10.257 +	bit	SEQ_SWTMRTO	0x10
  10.258 +	bit	SEQ_SEQINT	0x08
  10.259 +	bit	SEQ_SCSIINT	0x04
  10.260 +	bit	SEQ_PCIINT	0x02
  10.261 +	bit	SEQ_SPLTINT	0x01
  10.262 +}
  10.263 +
  10.264 +/*
  10.265 + * Clear SEQ Interrupt
  10.266 + */
  10.267 +register CLRSEQINTSTAT {
  10.268 +	address			0x0C0
  10.269 +	access_mode	WO
  10.270 +	bit	CLRSEQ_SWTMRTO	0x10
  10.271 +	bit	CLRSEQ_SEQINT	0x08
  10.272 +	bit	CLRSEQ_SCSIINT	0x04
  10.273 +	bit	CLRSEQ_PCIINT	0x02
  10.274 +	bit	CLRSEQ_SPLTINT	0x01
  10.275 +}
  10.276 +
  10.277 +/*
  10.278 + * Software Timer
  10.279 + */
  10.280 +register SWTIMER {
  10.281 +	address			0x0E0
  10.282 +	access_mode	RW
  10.283 +	size		2
  10.284 +}
  10.285 +
  10.286 +/*
  10.287 + * SEQ New SCB Queue Offset
  10.288 + */
  10.289 +register SNSCB_QOFF {
  10.290 +	address			0x010
  10.291 +	access_mode	RW
  10.292 +	size		2
  10.293 +	modes		M_CCHAN
  10.294 +}
  10.295 +
  10.296 +/*
  10.297 + * SEQ Empty SCB Queue Offset
  10.298 + */
  10.299 +register SESCB_QOFF {
  10.300 +	address			0x012
  10.301 +	access_mode	RW
  10.302 +	modes		M_CCHAN
  10.303 +}
  10.304 +
  10.305 +/*
  10.306 + * SEQ Done SCB Queue Offset
  10.307 + */
  10.308 +register SDSCB_QOFF {
  10.309 +	address			0x014
  10.310 +	access_mode	RW
  10.311 +	modes		M_CCHAN
  10.312 +	size		2
  10.313 +}
  10.314 +
  10.315 +/*
  10.316 + * Queue Offset Control & Status
  10.317 + */
  10.318 +register QOFF_CTLSTA {
  10.319 +	address			0x016
  10.320 +	access_mode	RW
  10.321 +	modes		M_CCHAN
  10.322 +	bit	EMPTY_SCB_AVAIL	0x80
  10.323 +	bit	NEW_SCB_AVAIL	0x40
  10.324 +	bit	SDSCB_ROLLOVR	0x20
  10.325 +	bit	HS_MAILBOX_ACT	0x10
  10.326 +	mask	SCB_QSIZE	0x0F
  10.327 +	mask	SCB_QSIZE_4	0x00
  10.328 +	mask	SCB_QSIZE_8	0x01
  10.329 +	mask	SCB_QSIZE_16	0x02
  10.330 +	mask	SCB_QSIZE_32	0x03
  10.331 +	mask	SCB_QSIZE_64	0x04
  10.332 +	mask	SCB_QSIZE_128	0x05
  10.333 +	mask	SCB_QSIZE_256	0x06
  10.334 +	mask	SCB_QSIZE_512	0x07
  10.335 +	mask	SCB_QSIZE_1024	0x08
  10.336 +	mask	SCB_QSIZE_2048	0x09
  10.337 +	mask	SCB_QSIZE_4096	0x0A
  10.338 +	mask	SCB_QSIZE_8192	0x0B
  10.339 +	mask	SCB_QSIZE_16384	0x0C
  10.340 +}
  10.341 +
  10.342 +/*
  10.343 + * Interrupt Control
  10.344 + */
  10.345 +register INTCTL {
  10.346 +	address			0x018
  10.347 +	access_mode	RW
  10.348 +	bit	SWTMINTMASK	0x80
  10.349 +	bit	SWTMINTEN	0x40
  10.350 +	bit	SWTIMER_START	0x20
  10.351 +	bit	AUTOCLRCMDINT	0x10
  10.352 +	bit	PCIINTEN	0x08
  10.353 +	bit	SCSIINTEN	0x04
  10.354 +	bit	SEQINTEN	0x02
  10.355 +	bit	SPLTINTEN	0x01
  10.356 +}
  10.357 +
  10.358 +/*
  10.359 + * Data FIFO Control
  10.360 + */
  10.361 +register DFCNTRL {
  10.362 +	address			0x019
  10.363 +	access_mode	RW
  10.364 +	modes		M_DFF0, M_DFF1
  10.365 +	bit	PRELOADEN	0x80
  10.366 +	bit	SCSIEN		0x20
  10.367 +	bit	SCSIENACK	0x20
  10.368 +	bit	HDMAEN		0x08
  10.369 +	bit	HDMAENACK	0x08
  10.370 +	bit	DIRECTION	0x04
  10.371 +	bit	DIRECTIONACK	0x04
  10.372 +	bit	FIFOFLUSH	0x02
  10.373 +	bit	FIFOFLUSHACK	0x02
  10.374 +	bit	DIRECTIONEN	0x01
  10.375 +}
  10.376 +
  10.377 +/*
  10.378 + * Device Space Command 0
  10.379 + */
  10.380 +register DSCOMMAND0 {
  10.381 +	address			0x019
  10.382 +	access_mode	RW
  10.383 +	modes		M_CFG
  10.384 +	bit	CACHETHEN	0x80	/* Cache Threshold enable */
  10.385 +	bit	DPARCKEN	0x40	/* Data Parity Check Enable */
  10.386 +	bit	MPARCKEN	0x20	/* Memory Parity Check Enable */
  10.387 +	bit	EXTREQLCK	0x10	/* External Request Lock */
  10.388 +	bit	CIOPARCKEN	0x01	/* Internal bus parity error enable */
  10.389 +}
  10.390 +
  10.391 +/*
  10.392 + * Data FIFO Status
  10.393 + */
  10.394 +register DFSTATUS {
  10.395 +	address			0x01A
  10.396 +	access_mode	RO
  10.397 +	modes		M_DFF0, M_DFF1
  10.398 +	bit	PRELOAD_AVAIL		0x80
  10.399 +	bit	PKT_PRELOAD_AVAIL	0x40
  10.400 +	bit	MREQPEND		0x10
  10.401 +	bit	HDONE			0x08
  10.402 +	bit	DFTHRESH		0x04
  10.403 +	bit	FIFOFULL		0x02
  10.404 +	bit	FIFOEMP			0x01
  10.405 +}
  10.406 +
  10.407 +/*
  10.408 + * S/G Cache Pointer
  10.409 + */
  10.410 +register SG_CACHE_PRE {
  10.411 +	address			0x01B
  10.412 +	access_mode	WO
  10.413 +	modes		M_DFF0, M_DFF1
  10.414 +	mask	SG_ADDR_MASK	0xf8
  10.415 +	bit	ODD_SEG		0x04
  10.416 +	bit	LAST_SEG	0x02
  10.417 +}
  10.418 +
  10.419 +register SG_CACHE_SHADOW {
  10.420 +	address			0x01B
  10.421 +	access_mode	RO
  10.422 +	modes		M_DFF0, M_DFF1
  10.423 +	mask	SG_ADDR_MASK	0xf8
  10.424 +	bit	ODD_SEG		0x04
  10.425 +	bit	LAST_SEG	0x02
  10.426 +	bit	LAST_SEG_DONE	0x01
  10.427 +}
  10.428 +
  10.429 +/*
  10.430 + * Arbiter Control
  10.431 + */
  10.432 +register ARBCTL {
  10.433 +	address			0x01B
  10.434 +	access_mode	RW
  10.435 +	modes		M_CFG
  10.436 +	bit	RESET_HARB	0x80
  10.437 +	bit	RETRY_SWEN	0x08
  10.438 +	mask	USE_TIME	0x07
  10.439 +}
  10.440 +
  10.441 +/*
  10.442 + * Data Channel Host Address
  10.443 + */
  10.444 +register HADDR {
  10.445 +	address			0x070
  10.446 +	access_mode	RW
  10.447 +	size		8
  10.448 +	modes		M_DFF0, M_DFF1
  10.449 +}
  10.450 +
  10.451 +/*
  10.452 + * Host Overlay DMA Address
  10.453 + */
  10.454 +register HODMAADR {
  10.455 +	address			0x070
  10.456 +	access_mode	RW
  10.457 +	size		8
  10.458 +	modes		M_SCSI
  10.459 +}
  10.460 +
  10.461 +/*
  10.462 + * Data Channel Host Count
  10.463 + */
  10.464 +register HCNT {
  10.465 +	address			0x078
  10.466 +	access_mode	RW
  10.467 +	size		3
  10.468 +	modes		M_DFF0, M_DFF1
  10.469 +}
  10.470 +
  10.471 +/*
  10.472 + * Host Overlay DMA Count
  10.473 + */
  10.474 +register HODMACNT {
  10.475 +	address			0x078
  10.476 +	access_mode	RW
  10.477 +	size		2
  10.478 +	modes		M_SCSI
  10.479 +}
  10.480 +
  10.481 +/*
  10.482 + * Host Overlay DMA Enable
  10.483 + */
  10.484 +register HODMAEN {
  10.485 +	address			0x07A
  10.486 +	access_mode	RW
  10.487 +	modes		M_SCSI
  10.488 +}
  10.489 +
  10.490 +/*
  10.491 + * Scatter/Gather Host Address
  10.492 + */
  10.493 +register SGHADDR {
  10.494 +	address			0x07C
  10.495 +	access_mode	RW
  10.496 +	size		8
  10.497 +	modes		M_DFF0, M_DFF1
  10.498 +}
  10.499 +
  10.500 +/*
  10.501 + * SCB Host Address
  10.502 + */
  10.503 +register SCBHADDR {
  10.504 +	address			0x07C
  10.505 +	access_mode	RW
  10.506 +	size		8
  10.507 +	modes		M_CCHAN
  10.508 +}
  10.509 +
  10.510 +/*
  10.511 + * Scatter/Gather Host Count
  10.512 + */
  10.513 +register SGHCNT {
  10.514 +	address			0x084
  10.515 +	access_mode	RW
  10.516 +	modes		M_DFF0, M_DFF1
  10.517 +}
  10.518 +
  10.519 +/*
  10.520 + * SCB Host Count
  10.521 + */
  10.522 +register SCBHCNT {
  10.523 +	address			0x084
  10.524 +	access_mode	RW
  10.525 +	modes		M_CCHAN
  10.526 +}
  10.527 +
  10.528 +/*
  10.529 + * Data FIFO Threshold
  10.530 + */
  10.531 +register DFF_THRSH {
  10.532 +	address			0x088
  10.533 +	access_mode	RW
  10.534 +	modes		M_CFG
  10.535 +	mask	WR_DFTHRSH	0x70
  10.536 +	mask	RD_DFTHRSH	0x07
  10.537 +	mask	RD_DFTHRSH_MIN	0x00
  10.538 +	mask	RD_DFTHRSH_25	0x01
  10.539 +	mask	RD_DFTHRSH_50	0x02
  10.540 +	mask	RD_DFTHRSH_63	0x03
  10.541 +	mask	RD_DFTHRSH_75	0x04
  10.542 +	mask	RD_DFTHRSH_85	0x05
  10.543 +	mask	RD_DFTHRSH_90	0x06
  10.544 +	mask	RD_DFTHRSH_MAX	0x07
  10.545 +	mask	WR_DFTHRSH_MIN	0x00
  10.546 +	mask	WR_DFTHRSH_25	0x10
  10.547 +	mask	WR_DFTHRSH_50	0x20
  10.548 +	mask	WR_DFTHRSH_63	0x30
  10.549 +	mask	WR_DFTHRSH_75	0x40
  10.550 +	mask	WR_DFTHRSH_85	0x50
  10.551 +	mask	WR_DFTHRSH_90	0x60
  10.552 +	mask	WR_DFTHRSH_MAX	0x70
  10.553 +}
  10.554 +
  10.555 +/*
  10.556 + * ROM Address
  10.557 + */
  10.558 +register ROMADDR {
  10.559 +	address			0x08A
  10.560 +	access_mode	RW
  10.561 +	size		3
  10.562 +}
  10.563 +
  10.564 +/*
  10.565 + * ROM Control
  10.566 + */
  10.567 +register ROMCNTRL {
  10.568 +	address			0x08D
  10.569 +	access_mode	RW
  10.570 +	mask	ROMOP		0xE0
  10.571 +	mask	ROMSPD		0x18
  10.572 +	bit	REPEAT		0x02
  10.573 +	bit	RDY		0x01
  10.574 +}
  10.575 +
  10.576 +/*
  10.577 + * ROM Data
  10.578 + */
  10.579 +register ROMDATA {
  10.580 +	address			0x08E
  10.581 +	access_mode	RW
  10.582 +}
  10.583 +
  10.584 +/*
  10.585 + * Data Channel Receive Message 0
  10.586 + */
  10.587 +register DCHRXMSG0 {
  10.588 +	address			0x090
  10.589 +	access_mode	RO
  10.590 +	modes		M_DFF0, M_DFF1
  10.591 +	mask		CDNUM	0xF8
  10.592 +	mask		CFNUM	0x07
  10.593 +}
  10.594 +
  10.595 +/*
  10.596 + * CMC Recieve Message 0
  10.597 + */
  10.598 +register CMCRXMSG0 {
  10.599 +	address			0x090
  10.600 +	access_mode	RO
  10.601 +	modes		M_CCHAN
  10.602 +	mask		CDNUM	0xF8
  10.603 +	mask		CFNUM	0x07
  10.604 +}
  10.605 +
  10.606 +/*
  10.607 + * Overlay Recieve Message 0
  10.608 + */
  10.609 +register OVLYRXMSG0 {
  10.610 +	address			0x090
  10.611 +	access_mode	RO
  10.612 +	modes		M_SCSI
  10.613 +	mask		CDNUM	0xF8
  10.614 +	mask		CFNUM	0x07
  10.615 +}
  10.616 +
  10.617 +/*
  10.618 + * Relaxed Order Enable
  10.619 + */
  10.620 +register ROENABLE {
  10.621 +	address			0x090
  10.622 +	access_mode	RW
  10.623 +	modes		M_CFG
  10.624 +	bit	MSIROEN		0x20
  10.625 +	bit	OVLYROEN	0x10
  10.626 +	bit	CMCROEN		0x08
  10.627 +	bit	SGROEN		0x04
  10.628 +	bit	DCH1ROEN	0x02
  10.629 +	bit	DCH0ROEN	0x01
  10.630 +}
  10.631 +
  10.632 +/*
  10.633 + * Data Channel Receive Message 1
  10.634 + */
  10.635 +register DCHRXMSG1 {
  10.636 +	address			0x091
  10.637 +	access_mode	RO
  10.638 +	modes		M_DFF0, M_DFF1
  10.639 +	mask	CBNUM		0xFF
  10.640 +}
  10.641 +
  10.642 +/*
  10.643 + * CMC Recieve Message 1
  10.644 + */
  10.645 +register CMCRXMSG1 {
  10.646 +	address			0x091
  10.647 +	access_mode	RO
  10.648 +	modes		M_CCHAN
  10.649 +	mask	CBNUM		0xFF
  10.650 +}
  10.651 +
  10.652 +/*
  10.653 + * Overlay Recieve Message 1
  10.654 + */
  10.655 +register OVLYRXMSG1 {
  10.656 +	address			0x091
  10.657 +	access_mode	RO
  10.658 +	modes		M_SCSI
  10.659 +	mask	CBNUM		0xFF
  10.660 +}
  10.661 +
  10.662 +/*
  10.663 + * No Snoop Enable
  10.664 + */
  10.665 +register NSENABLE {
  10.666 +	address			0x091
  10.667 +	access_mode	RW
  10.668 +	modes		M_CFG
  10.669 +	bit	MSINSEN		0x20
  10.670 +	bit	OVLYNSEN	0x10
  10.671 +	bit	CMCNSEN		0x08
  10.672 +	bit	SGNSEN		0x04
  10.673 +	bit	DCH1NSEN	0x02
  10.674 +	bit	DCH0NSEN	0x01
  10.675 +}
  10.676 +
  10.677 +/*
  10.678 + * Data Channel Receive Message 2
  10.679 + */
  10.680 +register DCHRXMSG2 {
  10.681 +	address			0x092
  10.682 +	access_mode	RO
  10.683 +	modes		M_DFF0, M_DFF1
  10.684 +	mask	MINDEX		0xFF
  10.685 +}
  10.686 +
  10.687 +/*
  10.688 + * CMC Recieve Message 2
  10.689 + */
  10.690 +register CMCRXMSG2 {
  10.691 +	address			0x092
  10.692 +	access_mode	RO
  10.693 +	modes		M_CCHAN
  10.694 +	mask	MINDEX		0xFF
  10.695 +}
  10.696 +
  10.697 +/*
  10.698 + * Overlay Recieve Message 2
  10.699 + */
  10.700 +register OVLYRXMSG2 {
  10.701 +	address			0x092
  10.702 +	access_mode	RO
  10.703 +	modes		M_SCSI
  10.704 +	mask	MINDEX		0xFF
  10.705 +}
  10.706 +
  10.707 +/*
  10.708 + * Outstanding Split Transactions
  10.709 + */
  10.710 +register OST {
  10.711 +	address			0x092
  10.712 +	access_mode	RW
  10.713 +	modes		M_CFG
  10.714 +}
  10.715 +
  10.716 +/*
  10.717 + * Data Channel Receive Message 3
  10.718 + */
  10.719 +register DCHRXMSG3 {
  10.720 +	address			0x093
  10.721 +	access_mode	RO
  10.722 +	modes		M_DFF0, M_DFF1
  10.723 +	mask	MCLASS		0x0F
  10.724 +}
  10.725 +
  10.726 +/*
  10.727 + * CMC Recieve Message 3
  10.728 + */
  10.729 +register CMCRXMSG3 {
  10.730 +	address			0x093
  10.731 +	access_mode	RO
  10.732 +	modes		M_CCHAN
  10.733 +	mask	MCLASS		0x0F
  10.734 +}
  10.735 +
  10.736 +/*
  10.737 + * Overlay Recieve Message 3
  10.738 + */
  10.739 +register OVLYRXMSG3 {
  10.740 +	address			0x093
  10.741 +	access_mode	RO
  10.742 +	modes		M_SCSI
  10.743 +	mask	MCLASS		0x0F
  10.744 +}
  10.745 +
  10.746 +/*
  10.747 + * PCI-X Control
  10.748 + */
  10.749 +register PCIXCTL {
  10.750 +	address			0x093
  10.751 +	access_mode	RW
  10.752 +	modes		M_CFG
  10.753 +	bit	SERRPULSE	0x80
  10.754 +	bit	UNEXPSCIEN	0x20
  10.755 +	bit	SPLTSMADIS	0x10
  10.756 +	bit	SPLTSTADIS	0x08
  10.757 +	bit	SRSPDPEEN	0x04
  10.758 +	bit	TSCSERREN	0x02
  10.759 +	bit	CMPABCDIS	0x01
  10.760 +}
  10.761 +
  10.762 +/*
  10.763 + * CMC Sequencer Byte Count
  10.764 + */
  10.765 +register CMCSEQBCNT {
  10.766 +	address			0x094
  10.767 +	access_mode	RO
  10.768 +	modes		M_CCHAN
  10.769 +}
  10.770 +
  10.771 +/*
  10.772 + * Overlay Sequencer Byte Count
  10.773 + */
  10.774 +register OVLYSEQBCNT {
  10.775 +	address			0x094
  10.776 +	access_mode	RO
  10.777 +	modes		M_SCSI
  10.778 +}
  10.779 +
  10.780 +/*
  10.781 + * Data Channel Sequencer Byte Count
  10.782 + */
  10.783 +register DCHSEQBCNT {
  10.784 +	address			0x094
  10.785 +	access_mode	RO
  10.786 +	size		2
  10.787 +	modes		M_DFF0, M_DFF1
  10.788 +}
  10.789 +
  10.790 +/*
  10.791 + * Data Channel Split Status 0
  10.792 + */
  10.793 +register DCHSPLTSTAT0 {
  10.794 +	address			0x096
  10.795 +	access_mode	RW
  10.796 +	modes		M_DFF0, M_DFF1
  10.797 +	bit	STAETERM	0x80
  10.798 +	bit	SCBCERR		0x40
  10.799 +	bit	SCADERR		0x20
  10.800 +	bit	SCDATBUCKET	0x10
  10.801 +	bit	CNTNOTCMPLT	0x08
  10.802 +	bit	RXOVRUN		0x04
  10.803 +	bit	RXSCEMSG	0x02
  10.804 +	bit	RXSPLTRSP	0x01
  10.805 +}
  10.806 +
  10.807 +/*
  10.808 + * CMC Split Status 0
  10.809 + */
  10.810 +register CMCSPLTSTAT0 {
  10.811 +	address			0x096
  10.812 +	access_mode	RW
  10.813 +	modes		M_CCHAN
  10.814 +	bit	STAETERM	0x80
  10.815 +	bit	SCBCERR		0x40
  10.816 +	bit	SCADERR		0x20
  10.817 +	bit	SCDATBUCKET	0x10
  10.818 +	bit	CNTNOTCMPLT	0x08
  10.819 +	bit	RXOVRUN		0x04
  10.820 +	bit	RXSCEMSG	0x02
  10.821 +	bit	RXSPLTRSP	0x01
  10.822 +}
  10.823 +
  10.824 +/*
  10.825 + * Overlay Split Status 0
  10.826 + */
  10.827 +register OVLYSPLTSTAT0 {
  10.828 +	address			0x096
  10.829 +	access_mode	RW
  10.830 +	modes		M_SCSI
  10.831 +	bit	STAETERM	0x80
  10.832 +	bit	SCBCERR		0x40
  10.833 +	bit	SCADERR		0x20
  10.834 +	bit	SCDATBUCKET	0x10
  10.835 +	bit	CNTNOTCMPLT	0x08
  10.836 +	bit	RXOVRUN		0x04
  10.837 +	bit	RXSCEMSG	0x02
  10.838 +	bit	RXSPLTRSP	0x01
  10.839 +}
  10.840 +
  10.841 +/*
  10.842 + * Data Channel Split Status 1
  10.843 + */
  10.844 +register DCHSPLTSTAT1 {
  10.845 +	address			0x097
  10.846 +	access_mode	RW
  10.847 +	modes		M_DFF0, M_DFF1
  10.848 +	bit	RXDATABUCKET	0x01
  10.849 +}
  10.850 +
  10.851 +/*
  10.852 + * CMC Split Status 1
  10.853 + */
  10.854 +register CMCSPLTSTAT1 {
  10.855 +	address			0x097
  10.856 +	access_mode	RW
  10.857 +	modes		M_CCHAN
  10.858 +	bit	RXDATABUCKET	0x01
  10.859 +}
  10.860 +
  10.861 +/*
  10.862 + * Overlay Split Status 1
  10.863 + */
  10.864 +register OVLYSPLTSTAT1 {
  10.865 +	address			0x097
  10.866 +	access_mode	RW
  10.867 +	modes		M_SCSI
  10.868 +	bit	RXDATABUCKET	0x01
  10.869 +}
  10.870 +
  10.871 +/*
  10.872 + * S/G Receive Message 0
  10.873 + */
  10.874 +register SGRXMSG0 {
  10.875 +	address			0x098
  10.876 +	access_mode	RO
  10.877 +	modes		M_DFF0, M_DFF1
  10.878 +	mask		CDNUM	0xF8
  10.879 +	mask		CFNUM	0x07
  10.880 +}
  10.881 +
  10.882 +/*
  10.883 + * S/G Receive Message 1
  10.884 + */
  10.885 +register SGRXMSG1 {
  10.886 +	address			0x099
  10.887 +	access_mode	RO
  10.888 +	modes		M_DFF0, M_DFF1
  10.889 +	mask	CBNUM		0xFF
  10.890 +}
  10.891 +
  10.892 +/*
  10.893 + * S/G Receive Message 2
  10.894 + */
  10.895 +register SGRXMSG2 {
  10.896 +	address			0x09A
  10.897 +	access_mode	RO
  10.898 +	modes		M_DFF0, M_DFF1
  10.899 +	mask	MINDEX		0xFF
  10.900 +}
  10.901 +
  10.902 +/*
  10.903 + * S/G Receive Message 3
  10.904 + */
  10.905 +register SGRXMSG3 {
  10.906 +	address			0x09B
  10.907 +	access_mode	RO
  10.908 +	modes		M_DFF0, M_DFF1
  10.909 +	mask	MCLASS		0x0F
  10.910 +}
  10.911 +
  10.912 +/*
  10.913 + * Slave Split Out Address 0
  10.914 + */
  10.915 +register SLVSPLTOUTADR0 {
  10.916 +	address			0x098
  10.917 +	access_mode	RO
  10.918 +	modes		M_SCSI
  10.919 +	mask	LOWER_ADDR	0x7F
  10.920 +}
  10.921 +
  10.922 +/*
  10.923 + * Slave Split Out Address 1
  10.924 + */
  10.925 +register SLVSPLTOUTADR1 {
  10.926 +	address			0x099
  10.927 +	access_mode	RO
  10.928 +	modes		M_SCSI
  10.929 +	mask	REQ_DNUM	0xF8
  10.930 +	mask	REQ_FNUM	0x07
  10.931 +}
  10.932 +
  10.933 +/*
  10.934 + * Slave Split Out Address 2
  10.935 + */
  10.936 +register SLVSPLTOUTADR2 {
  10.937 +	address			0x09A
  10.938 +	access_mode	RO
  10.939 +	modes		M_SCSI
  10.940 +	mask	REQ_BNUM	0xFF
  10.941 +}
  10.942 +
  10.943 +/*
  10.944 + * Slave Split Out Address 3
  10.945 + */
  10.946 +register SLVSPLTOUTADR3 {
  10.947 +	address			0x09B
  10.948 +	access_mode	RO
  10.949 +	modes		M_SCSI
  10.950 +	bit	RLXORD		020
  10.951 +	mask	TAG_NUM		0x1F
  10.952 +}
  10.953 +
  10.954 +/*
  10.955 + * SG Sequencer Byte Count
  10.956 + */
  10.957 +register SGSEQBCNT {
  10.958 +	address			0x09C
  10.959 +	access_mode	RO
  10.960 +	modes		M_DFF0, M_DFF1
  10.961 +}
  10.962 +
  10.963 +/*
  10.964 + * Slave Split Out Attribute 0
  10.965 + */
  10.966 +register SLVSPLTOUTATTR0 {
  10.967 +	address			0x09C
  10.968 +	access_mode	RO
  10.969 +	modes		M_SCSI
  10.970 +	mask	LOWER_BCNT	0xFF
  10.971 +}
  10.972 +
  10.973 +/*
  10.974 + * Slave Split Out Attribute 1
  10.975 + */
  10.976 +register SLVSPLTOUTATTR1 {
  10.977 +	address			0x09D
  10.978 +	access_mode	RO
  10.979 +	modes		M_SCSI
  10.980 +	mask	CMPLT_DNUM	0xF8
  10.981 +	mask	CMPLT_FNUM	0x07
  10.982 +}
  10.983 +
  10.984 +/*
  10.985 + * Slave Split Out Attribute 2
  10.986 + */
  10.987 +register SLVSPLTOUTATTR2 {
  10.988 +	address			0x09E
  10.989 +	access_mode	RO
  10.990 +	size		2
  10.991 +	modes		M_SCSI
  10.992 +	mask	CMPLT_BNUM	0xFF
  10.993 +}
  10.994 +/*
  10.995 + * S/G Split Status 0
  10.996 + */
  10.997 +register SGSPLTSTAT0 {
  10.998 +	address			0x09E
  10.999 +	access_mode	RW
 10.1000 +	modes		M_DFF0, M_DFF1
 10.1001 +	bit	STAETERM	0x80
 10.1002 +	bit	SCBCERR		0x40
 10.1003 +	bit	SCADERR		0x20
 10.1004 +	bit	SCDATBUCKET	0x10
 10.1005 +	bit	CNTNOTCMPLT	0x08
 10.1006 +	bit	RXOVRUN		0x04
 10.1007 +	bit	RXSCEMSG	0x02
 10.1008 +	bit	RXSPLTRSP	0x01
 10.1009 +}
 10.1010 +
 10.1011 +/*
 10.1012 + * S/G Split Status 1
 10.1013 + */
 10.1014 +register SGSPLTSTAT1 {
 10.1015 +	address			0x09F
 10.1016 +	access_mode	RW
 10.1017 +	modes		M_DFF0, M_DFF1
 10.1018 +	bit	RXDATABUCKET	0x01
 10.1019 +}
 10.1020 +
 10.1021 +/*
 10.1022 + * Special Function
 10.1023 + */
 10.1024 +register SFUNCT {
 10.1025 +	address			0x09f
 10.1026 +	access_mode	RW
 10.1027 +	modes		M_CFG
 10.1028 +	mask	TEST_GROUP	0xF0
 10.1029 +	mask	TEST_NUM	0x0F
 10.1030 +}
 10.1031 +
 10.1032 +/*
 10.1033 + * Data FIFO 0 PCI Status 
 10.1034 + */
 10.1035 +register DF0PCISTAT {
 10.1036 +	address			0x0A0
 10.1037 +	access_mode	RW
 10.1038 +	modes		M_CFG
 10.1039 +	bit	DPE		0x80
 10.1040 +	bit	SSE		0x40
 10.1041 +	bit	RMA		0x20
 10.1042 +	bit	RTA		0x10
 10.1043 +	bit	SCAAPERR	0x08
 10.1044 +	bit	RDPERR		0x04
 10.1045 +	bit	TWATERR		0x02
 10.1046 +	bit	DPR		0x01
 10.1047 +}
 10.1048 +
 10.1049 +/*
 10.1050 + * Data FIFO 1 PCI Status 
 10.1051 + */
 10.1052 +register DF1PCISTAT {
 10.1053 +	address			0x0A1
 10.1054 +	access_mode	RW
 10.1055 +	modes		M_CFG
 10.1056 +	bit	DPE		0x80
 10.1057 +	bit	SSE		0x40
 10.1058 +	bit	RMA		0x20
 10.1059 +	bit	RTA		0x10
 10.1060 +	bit	SCAAPERR	0x08
 10.1061 +	bit	RDPERR		0x04
 10.1062 +	bit	TWATERR		0x02
 10.1063 +	bit	DPR		0x01
 10.1064 +}
 10.1065 +
 10.1066 +/*
 10.1067 + * S/G PCI Status 
 10.1068 + */
 10.1069 +register SGPCISTAT {
 10.1070 +	address			0x0A2
 10.1071 +	access_mode	RW
 10.1072 +	modes		M_CFG
 10.1073 +	bit	DPE		0x80
 10.1074 +	bit	SSE		0x40
 10.1075 +	bit	RMA		0x20
 10.1076 +	bit	RTA		0x10
 10.1077 +	bit	SCAAPERR	0x08
 10.1078 +	bit	RDPERR		0x04
 10.1079 +	bit	DPR		0x01
 10.1080 +}
 10.1081 +
 10.1082 +/*
 10.1083 + * CMC PCI Status 
 10.1084 + */
 10.1085 +register CMCPCISTAT {
 10.1086 +	address			0x0A3
 10.1087 +	access_mode	RW
 10.1088 +	modes		M_CFG
 10.1089 +	bit	DPE		0x80
 10.1090 +	bit	SSE		0x40
 10.1091 +	bit	RMA		0x20
 10.1092 +	bit	RTA		0x10
 10.1093 +	bit	SCAAPERR	0x08
 10.1094 +	bit	RDPERR		0x04
 10.1095 +	bit	TWATERR		0x02
 10.1096 +	bit	DPR		0x01
 10.1097 +}
 10.1098 +
 10.1099 +/*
 10.1100 + * Overlay PCI Status 
 10.1101 + */
 10.1102 +register OVLYPCISTAT {
 10.1103 +	address			0x0A4
 10.1104 +	access_mode	RW
 10.1105 +	modes		M_CFG
 10.1106 +	bit	DPE		0x80
 10.1107 +	bit	SSE		0x40
 10.1108 +	bit	RMA		0x20
 10.1109 +	bit	RTA		0x10
 10.1110 +	bit	SCAAPERR	0x08
 10.1111 +	bit	RDPERR		0x04
 10.1112 +	bit	DPR		0x01
 10.1113 +}
 10.1114 +
 10.1115 +/*
 10.1116 + * PCI Status for MSI Master DMA Transfer
 10.1117 + */
 10.1118 +register MSIPCISTAT {
 10.1119 +	address			0x0A6
 10.1120 +	access_mode	RW
 10.1121 +	modes		M_CFG
 10.1122 +	bit	SSE		0x40
 10.1123 +	bit	RMA		0x20
 10.1124 +	bit	RTA		0x10
 10.1125 +	bit	CLRPENDMSI	0x08
 10.1126 +	bit	TWATERR		0x02
 10.1127 +	bit	DPR		0x01
 10.1128 +}
 10.1129 +
 10.1130 +/*
 10.1131 + * PCI Status for Target
 10.1132 + */
 10.1133 +register TARGPCISTAT {
 10.1134 +	address			0x0A6
 10.1135 +	access_mode	RW
 10.1136 +	modes		M_CFG
 10.1137 +	bit	DPE		0x80
 10.1138 +	bit	SSE		0x40
 10.1139 +	bit	STA		0x08
 10.1140 +	bit	TWATERR		0x02
 10.1141 +}
 10.1142 +
 10.1143 +/*
 10.1144 + * LQ Packet In
 10.1145 + * The last LQ Packet recieved
 10.1146 + */
 10.1147 +register LQIN {
 10.1148 +	address			0x020
 10.1149 +	access_mode	RW
 10.1150 +	size		20
 10.1151 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1152 +}
 10.1153 +
 10.1154 +/*
 10.1155 + * SCB Type Pointer
 10.1156 + * SCB offset for Target Mode SCB type information
 10.1157 + */
 10.1158 +register TYPEPTR {
 10.1159 +	address			0x020
 10.1160 +	access_mode	RW
 10.1161 +	modes		M_CFG
 10.1162 +}
 10.1163 +
 10.1164 +/*
 10.1165 + * Queue Tag Pointer
 10.1166 + * SCB offset to the Two Byte tag identifier used for target mode.
 10.1167 + */
 10.1168 +register TAGPTR {
 10.1169 +	address			0x021
 10.1170 +	access_mode	RW
 10.1171 +	modes		M_CFG
 10.1172 +}
 10.1173 +
 10.1174 +/*
 10.1175 + * Logical Unit Number Pointer
 10.1176 + * SCB offset to the LSB (little endian) of the lun field.
 10.1177 + */
 10.1178 +register LUNPTR {
 10.1179 +	address			0x022
 10.1180 +	access_mode	RW
 10.1181 +	modes		M_CFG
 10.1182 +}
 10.1183 +
 10.1184 +/*
 10.1185 + * Data Length Pointer
 10.1186 + * SCB offset for the 4 byte data length field in target mode.
 10.1187 + */
 10.1188 +register DATALENPTR {
 10.1189 +	address			0x023
 10.1190 +	access_mode	RW
 10.1191 +	modes		M_CFG
 10.1192 +}
 10.1193 +
 10.1194 +/*
 10.1195 + * Status Length Pointer
 10.1196 + * SCB offset to the two byte status field in target SCBs.
 10.1197 + */
 10.1198 +register STATLENPTR {
 10.1199 +	address			0x024
 10.1200 +	access_mode	RW
 10.1201 +	modes		M_CFG
 10.1202 +}
 10.1203 +
 10.1204 +/*
 10.1205 + * Command Length Pointer
 10.1206 + * Scb offset for the CDB length field in initiator SCBs.
 10.1207 + */
 10.1208 +register CMDLENPTR {
 10.1209 +	address			0x025
 10.1210 +	access_mode	RW
 10.1211 +	modes		M_CFG
 10.1212 +}
 10.1213 +
 10.1214 +/*
 10.1215 + * Task Attribute Pointer
 10.1216 + * Scb offset for the byte field specifying the attribute byte
 10.1217 + * to be used in command packets.
 10.1218 + */ 
 10.1219 +register ATTRPTR {
 10.1220 +	address			0x026
 10.1221 +	access_mode	RW
 10.1222 +	modes		M_CFG
 10.1223 +}
 10.1224 +
 10.1225 +/*
 10.1226 + * Task Management Flags Pointer
 10.1227 + * Scb offset for the byte field specifying the attribute flags
 10.1228 + * byte to be used in command packets.
 10.1229 + */ 
 10.1230 +register FLAGPTR {
 10.1231 +	address			0x027
 10.1232 +	access_mode	RW
 10.1233 +	modes		M_CFG
 10.1234 +}
 10.1235 +
 10.1236 +/*
 10.1237 + * Command Pointer
 10.1238 + * Scb offset for the first byte in the CDB for initiator SCBs.
 10.1239 + */
 10.1240 +register CMDPTR {
 10.1241 +	address			0x028
 10.1242 +	access_mode	RW
 10.1243 +	modes		M_CFG
 10.1244 +}
 10.1245 +
 10.1246 +/*
 10.1247 + * Queue Next Pointer
 10.1248 + * Scb offset for the 2 byte "next scb link".
 10.1249 + */
 10.1250 +register QNEXTPTR {
 10.1251 +	address			0x029
 10.1252 +	access_mode	RW
 10.1253 +	modes		M_CFG
 10.1254 +}
 10.1255 +
 10.1256 +/*
 10.1257 + * SCSI ID Pointer
 10.1258 + * Scb offset to the value to place in the SCSIID register
 10.1259 + * during target mode connections.
 10.1260 + */
 10.1261 +register IDPTR {
 10.1262 +	address			0x02A
 10.1263 +	access_mode	RW
 10.1264 +	modes		M_CFG
 10.1265 +}
 10.1266 +
 10.1267 +/*
 10.1268 + * Command Aborted Byte Pointer
 10.1269 + * Offset to the SCB flags field that includes the
 10.1270 + * "SCB aborted" status bit.
 10.1271 + */
 10.1272 +register ABRTBYTEPTR {
 10.1273 +	address			0x02B
 10.1274 +	access_mode	RW
 10.1275 +	modes		M_CFG
 10.1276 +}
 10.1277 +
 10.1278 +/*
 10.1279 + * Command Aborted Bit Pointer
 10.1280 + * Bit offset in the SCB flags field for "SCB aborted" status.
 10.1281 + */
 10.1282 +register ABRTBITPTR {
 10.1283 +	address			0x02C
 10.1284 +	access_mode	RW
 10.1285 +	modes		M_CFG
 10.1286 +}
 10.1287 +
 10.1288 +/*
 10.1289 + * Logical Unit Number Length
 10.1290 + * The length, in bytes, of the SCB lun field.
 10.1291 + */
 10.1292 +register LUNLEN {
 10.1293 +	address			0x030
 10.1294 +	access_mode	RW
 10.1295 +	modes		M_CFG
 10.1296 +}
 10.1297 +
 10.1298 +/*
 10.1299 + * CDB Limit
 10.1300 + * The size, in bytes, of the embedded CDB field in initator SCBs.
 10.1301 + */
 10.1302 +register CDBLIMIT {
 10.1303 +	address			0x031
 10.1304 +	access_mode	RW
 10.1305 +	modes		M_CFG
 10.1306 +}
 10.1307 +
 10.1308 +/*
 10.1309 + * Maximum Commands
 10.1310 + * The maximum number of commands to issue during a
 10.1311 + * single packetized connection.
 10.1312 + */
 10.1313 +register MAXCMD {
 10.1314 +	address			0x032
 10.1315 +	access_mode	RW
 10.1316 +	modes		M_CFG
 10.1317 +}
 10.1318 +
 10.1319 +/*
 10.1320 + * Maximum Command Counter
 10.1321 + * The number of commands already sent during this connection
 10.1322 + */
 10.1323 +register MAXCMDCNT {
 10.1324 +	address			0x033
 10.1325 +	access_mode	RW
 10.1326 +	modes		M_CFG
 10.1327 +}
 10.1328 +
 10.1329 +/*
 10.1330 + * LQ Packet Reserved Bytes
 10.1331 + * The bytes to be sent in the currently reserved fileds
 10.1332 + * of all LQ packets.
 10.1333 + */
 10.1334 +register LQRSVD01 {
 10.1335 +	address			0x034
 10.1336 +	access_mode	RW
 10.1337 +	modes		M_SCSI
 10.1338 +}
 10.1339 +register LQRSVD16 {
 10.1340 +	address			0x035
 10.1341 +	access_mode	RW
 10.1342 +	modes		M_SCSI
 10.1343 +}
 10.1344 +register LQRSVD17 {
 10.1345 +	address			0x036
 10.1346 +	access_mode	RW
 10.1347 +	modes		M_SCSI
 10.1348 +}
 10.1349 +
 10.1350 +/*
 10.1351 + * Command Reserved 0
 10.1352 + * The byte to be sent for the reserved byte 0 of
 10.1353 + * outgoing command packets.
 10.1354 + */
 10.1355 +register CMDRSVD0 {
 10.1356 +	address			0x037
 10.1357 +	access_mode	RW
 10.1358 +	modes		M_CFG
 10.1359 +}
 10.1360 +
 10.1361 +/*
 10.1362 + * LQ Manager Control 0
 10.1363 + */
 10.1364 +register LQCTL0 {
 10.1365 +	address			0x038
 10.1366 +	access_mode	RW
 10.1367 +	modes		M_CFG
 10.1368 +	mask	LQITARGCLT	0xC0
 10.1369 +	mask	LQIINITGCLT	0x30
 10.1370 +	mask	LQ0TARGCLT	0x0C
 10.1371 +	mask	LQ0INITGCLT	0x03
 10.1372 +}
 10.1373 +
 10.1374 +/*
 10.1375 + * LQ Manager Control 1
 10.1376 + */
 10.1377 +register LQCTL1 {
 10.1378 +	address			0x038
 10.1379 +	access_mode	RW
 10.1380 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1381 +	bit	PCI2PCI		0x04
 10.1382 +	bit	SINGLECMD	0x02
 10.1383 +	bit	ABORTPENDING	0x01
 10.1384 +}
 10.1385 +
 10.1386 +/*
 10.1387 + * LQ Manager Control 2
 10.1388 + */
 10.1389 +register LQCTL2 {
 10.1390 +	address			0x039
 10.1391 +	access_mode	RW
 10.1392 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1393 +	bit	LQIRETRY	0x80
 10.1394 +	bit	LQICONTINUE	0x40
 10.1395 +	bit	LQITOIDLE	0x20
 10.1396 +	bit	LQIPAUSE	0x10
 10.1397 +	bit	LQORETRY	0x08
 10.1398 +	bit	LQOCONTINUE	0x04
 10.1399 +	bit	LQOTOIDLE	0x02
 10.1400 +	bit	LQOPAUSE	0x01
 10.1401 +}
 10.1402 +
 10.1403 +/*
 10.1404 + * SCSI RAM BIST0
 10.1405 + */
 10.1406 +register SCSBIST0 {
 10.1407 +	address			0x039
 10.1408 +	access_mode	RW
 10.1409 +	modes		M_CFG
 10.1410 +	bit	GSBISTERR	0x40
 10.1411 +	bit	GSBISTDONE	0x20
 10.1412 +	bit	GSBISTRUN	0x10
 10.1413 +	bit	OSBISTERR	0x04
 10.1414 +	bit	OSBISTDONE	0x02
 10.1415 +	bit	OSBISTRUN	0x01
 10.1416 +}
 10.1417 +
 10.1418 +/*
 10.1419 + * SCSI Sequence Control0
 10.1420 + */
 10.1421 +register SCSISEQ0 {
 10.1422 +	address			0x03A
 10.1423 +	access_mode	RW
 10.1424 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1425 +	bit	TEMODEO		0x80
 10.1426 +	bit	ENSELO		0x40
 10.1427 +	bit	ENARBO		0x20
 10.1428 +	bit	FORCEBUSFREE	0x10
 10.1429 +	bit	SCSIRSTO	0x01
 10.1430 +}
 10.1431 +
 10.1432 +/*
 10.1433 + * SCSI RAM BIST 1
 10.1434 + */
 10.1435 +register SCSBIST1 {
 10.1436 +	address			0x03A
 10.1437 +	access_mode	RW
 10.1438 +	modes		M_CFG
 10.1439 +	bit	NTBISTERR	0x04
 10.1440 +	bit	NTBISTDONE	0x02
 10.1441 +	bit	NTBISTRUN	0x01
 10.1442 +}
 10.1443 +
 10.1444 +/*
 10.1445 + * SCSI Sequence Control 1
 10.1446 + */
 10.1447 +register SCSISEQ1 {
 10.1448 +	address			0x03B
 10.1449 +	access_mode	RW
 10.1450 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1451 +	bit	MANUALCTL	0x40
 10.1452 +	bit	ENSELI		0x20
 10.1453 +	bit	ENRSELI		0x10
 10.1454 +	mask	MANUALP		0x0C
 10.1455 +	bit	ENAUTOATNP	0x02
 10.1456 +	bit	ALTSTIM		0x01
 10.1457 +}
 10.1458 +
 10.1459 +/*
 10.1460 + * SCSI Transfer Control 0
 10.1461 + */
 10.1462 +register SXFRCTL0 {
 10.1463 +	address			0x03C
 10.1464 +	access_mode	RW
 10.1465 +	modes		M_SCSI
 10.1466 +	bit	DFON		0x80
 10.1467 +	bit	DFPEXP		0x40
 10.1468 +	bit	BIOSCANCELEN	0x10
 10.1469 +	bit	SPIOEN		0x08
 10.1470 +}
 10.1471 +
 10.1472 +/*
 10.1473 + * SCSI Transfer Control 1
 10.1474 + */
 10.1475 +register SXFRCTL1 {
 10.1476 +	address			0x03D
 10.1477 +	access_mode	RW
 10.1478 +	modes		M_SCSI
 10.1479 +	bit	BITBUCKET	0x80
 10.1480 +	bit	ENSACHK		0x40
 10.1481 +	bit	ENSPCHK		0x20
 10.1482 +	mask	STIMESEL	0x18
 10.1483 +	bit	ENSTIMER	0x04
 10.1484 +	bit	ACTNEGEN	0x02
 10.1485 +	bit	STPWEN		0x01
 10.1486 +}
 10.1487 +
 10.1488 +/*
 10.1489 + * SCSI Transfer Control 2
 10.1490 + */
 10.1491 +register SXFRCTL2 {
 10.1492 +	address			0x03E
 10.1493 +	access_mode	RW
 10.1494 +	modes		M_SCSI
 10.1495 +	bit	AUTORSTDIS	0x10
 10.1496 +	bit	CMDDMAEN	0x08
 10.1497 +	mask	ASU		0x07
 10.1498 +}
 10.1499 +
 10.1500 +/*
 10.1501 + * SCSI Bus Initiator IDs
 10.1502 + * Bitmask of observed initiators on the bus.
 10.1503 + */
 10.1504 +register BUSINITID {
 10.1505 +	address			0x03C
 10.1506 +	access_mode	RW
 10.1507 +	modes		M_CFG
 10.1508 +	size		2
 10.1509 +}
 10.1510 +
 10.1511 +/*
 10.1512 + * Data Length Counters
 10.1513 + * Packet byte counter.
 10.1514 + */
 10.1515 +register DLCOUNT {
 10.1516 +	address			0x03C
 10.1517 +	access_mode	RW
 10.1518 +	modes		M_DFF0, M_DFF1
 10.1519 +	size		3
 10.1520 +}
 10.1521 +
 10.1522 +/*
 10.1523 + * Data FIFO Status
 10.1524 + */
 10.1525 +register DFFSTAT {
 10.1526 +	address			0x03F
 10.1527 +	access_mode	RW
 10.1528 +	modes		M_SCSI
 10.1529 +	bit	FIFO1FREE	0x20
 10.1530 +	bit	FIFO0FREE	0x10
 10.1531 +	bit	CURRFIFO	0x01
 10.1532 +}
 10.1533 +
 10.1534 +/*
 10.1535 + * SCSI Bus Target IDs
 10.1536 + * Bitmask of observed targets on the bus.
 10.1537 + */
 10.1538 +register BUSTARGID {
 10.1539 +	address			0x03E
 10.1540 +	access_mode	RW
 10.1541 +	modes		M_CFG
 10.1542 +	size		2
 10.1543 +}
 10.1544 +
 10.1545 +/*
 10.1546 + * SCSI Control Signal Out
 10.1547 + */
 10.1548 +register SCSISIGO {
 10.1549 +	address			0x040
 10.1550 +	access_mode	RW
 10.1551 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1552 +	bit	CDO		0x80
 10.1553 +	bit	IOO		0x40
 10.1554 +	bit	MSGO		0x20
 10.1555 +	bit	ATNO		0x10
 10.1556 +	bit	SELO		0x08
 10.1557 +	bit	BSYO		0x04
 10.1558 +	bit	REQO		0x02
 10.1559 +	bit	ACKO		0x01
 10.1560 +/*
 10.1561 + * Possible phases to write into SCSISIG0
 10.1562 + */
 10.1563 +	mask	PHASE_MASK	CDO|IOO|MSGO
 10.1564 +	mask	P_DATAOUT	0x00
 10.1565 +	mask	P_DATAIN	IOO
 10.1566 +	mask	P_DATAOUT_DT	P_DATAOUT|MSGO
 10.1567 +	mask	P_DATAIN_DT	P_DATAIN|MSGO
 10.1568 +	mask	P_COMMAND	CDO
 10.1569 +	mask	P_MESGOUT	CDO|MSGO
 10.1570 +	mask	P_STATUS	CDO|IOO
 10.1571 +	mask	P_MESGIN	CDO|IOO|MSGO
 10.1572 +}
 10.1573 +
 10.1574 +register SCSISIGI {
 10.1575 +	address			0x041
 10.1576 +	access_mode	RO
 10.1577 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1578 +	bit	CDI		0x80
 10.1579 +	bit	IOI		0x40
 10.1580 +	bit	MSGI		0x20
 10.1581 +	bit	ATNI		0x10
 10.1582 +	bit	SELI		0x08
 10.1583 +	bit	BSYI		0x04
 10.1584 +	bit	REQI		0x02
 10.1585 +	bit	ACKI		0x01
 10.1586 +/*
 10.1587 + * Possible phases in SCSISIGI
 10.1588 + */
 10.1589 +	mask	PHASE_MASK	CDI|IOI|MSGI
 10.1590 +	mask	P_DATAOUT	0x00
 10.1591 +	mask	P_DATAIN	IOI
 10.1592 +	mask	P_DATAOUT_DT	P_DATAOUT|MSGI
 10.1593 +	mask	P_DATAIN_DT	P_DATAIN|MSGI
 10.1594 +	mask	P_COMMAND	CDI
 10.1595 +	mask	P_MESGOUT	CDI|MSGI
 10.1596 +	mask	P_STATUS	CDI|IOI
 10.1597 +	mask	P_MESGIN	CDI|IOI|MSGI
 10.1598 +}
 10.1599 +
 10.1600 +/*
 10.1601 + * Multiple Target IDs
 10.1602 + * Bitmask of ids to respond as a target.
 10.1603 + */
 10.1604 +register MULTARGID {
 10.1605 +	address			0x040
 10.1606 +	access_mode	RW
 10.1607 +	modes		M_CFG
 10.1608 +	size		2
 10.1609 +}
 10.1610 +
 10.1611 +/*
 10.1612 + * SCSI Phase
 10.1613 + */
 10.1614 +register SCSIPHASE {
 10.1615 +	address			0x042
 10.1616 +	access_mode	RO
 10.1617 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1618 +	bit	STATUS_PHASE	0x20
 10.1619 +	bit	COMMAND_PHASE	0x10
 10.1620 +	bit	MSG_IN_PHASE	0x08
 10.1621 +	bit	MSG_OUT_PHASE	0x04
 10.1622 +	bit	DATA_IN_PHASE	0x02
 10.1623 +	bit	DATA_OUT_PHASE	0x01
 10.1624 +	mask	DATA_PHASE_MASK	0x03
 10.1625 +}
 10.1626 +
 10.1627 +/*
 10.1628 + * SCSI Data 0 Image
 10.1629 + */
 10.1630 +register SCSIDAT0_IMG {
 10.1631 +	address			0x043
 10.1632 +	access_mode	RW
 10.1633 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1634 +}
 10.1635 +
 10.1636 +/*
 10.1637 + * SCSI Latched Data
 10.1638 + */
 10.1639 +register SCSIDAT {
 10.1640 +	address			0x044
 10.1641 +	access_mode	RW
 10.1642 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1643 +	size		2
 10.1644 +}
 10.1645 +
 10.1646 +/*
 10.1647 + * SCSI Data Bus
 10.1648 + */
 10.1649 +register SCSIBUS {
 10.1650 +	address			0x046
 10.1651 +	access_mode	RW
 10.1652 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1653 +	size		2
 10.1654 +}
 10.1655 +
 10.1656 +/*
 10.1657 + * Target ID In
 10.1658 + */
 10.1659 +register TARGIDIN {
 10.1660 +	address			0x048
 10.1661 +	access_mode	RO
 10.1662 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1663 +	bit	CLKOUT		0x80
 10.1664 +	mask	TARGID		0x0F
 10.1665 +}
 10.1666 +
 10.1667 +/*
 10.1668 + * Selection/Reselection ID
 10.1669 + * Upper four bits are the device id.  The ONEBIT is set when the re/selecting
 10.1670 + * device did not set its own ID.
 10.1671 + */
 10.1672 +register SELID {
 10.1673 +	address			0x049
 10.1674 +	access_mode	RW
 10.1675 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1676 +	mask	SELID_MASK	0xf0
 10.1677 +	bit	ONEBIT		0x08
 10.1678 +}
 10.1679 +
 10.1680 +/*
 10.1681 + * SCSI Block Control
 10.1682 + * Controls Bus type and channel selection.  SELWIDE allows for the
 10.1683 + * coexistence of 8bit and 16bit devices on a wide bus.
 10.1684 + */
 10.1685 +register SBLKCTL {
 10.1686 +	address			0x04A
 10.1687 +	access_mode	RW
 10.1688 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1689 +	bit	DIAGLEDEN	0x80
 10.1690 +	bit	DIAGLEDON	0x40
 10.1691 +	bit	ENAB40		0x08	/* LVD transceiver active */
 10.1692 +	bit	ENAB20		0x04	/* SE/HVD transceiver active */
 10.1693 +	bit	SELWIDE		0x02
 10.1694 +}
 10.1695 +
 10.1696 +/*
 10.1697 + * Option Mode
 10.1698 + */
 10.1699 +register OPTIONMODE {
 10.1700 +	address			0x04A
 10.1701 +	access_mode	RW
 10.1702 +	modes		M_CFG
 10.1703 +	bit	BIOSCANCTL		0x80
 10.1704 +	bit	AUTOACKEN		0x40
 10.1705 +	bit	BIASCANCTL		0x20
 10.1706 +	bit	BUSFREEREV		0x10
 10.1707 +	bit	ENDGFORMCHK		0x04
 10.1708 +	bit	AUTO_MSGOUT_DE		0x02
 10.1709 +	mask	OPTIONMODE_DEFAULTS	AUTO_MSGOUT_DE
 10.1710 +}
 10.1711 +
 10.1712 +/*
 10.1713 + * SCSI Status 0
 10.1714 + */
 10.1715 +register SSTAT0	{
 10.1716 +	address			0x04B
 10.1717 +	access_mode	RO
 10.1718 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1719 +	bit	TARGET		0x80	/* Board acting as target */
 10.1720 +	bit	SELDO		0x40	/* Selection Done */
 10.1721 +	bit	SELDI		0x20	/* Board has been selected */
 10.1722 +	bit	SELINGO		0x10	/* Selection In Progress */
 10.1723 +	bit	IOERR		0x08	/* LVD Tranceiver mode changed */
 10.1724 +	bit	OVERRUN		0x04	/* SCSI Offset overrun detected */
 10.1725 +	bit	SPIORDY		0x02	/* SCSI PIO Ready */
 10.1726 +	bit	ARBDO		0x01	/* Arbitration Done Out */
 10.1727 +}
 10.1728 +
 10.1729 +/*
 10.1730 + * Clear SCSI Interrupt 0
 10.1731 + * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT0.
 10.1732 + */
 10.1733 +register CLRSINT0 {
 10.1734 +	address			0x04B
 10.1735 +	access_mode	WO
 10.1736 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1737 +	bit	CLRSELDO	0x40
 10.1738 +	bit	CLRSELDI	0x20
 10.1739 +	bit	CLRSELINGO	0x10
 10.1740 +	bit	CLRIOERR	0x08
 10.1741 +	bit	CLROVERRUN	0x04
 10.1742 +	bit	CLRSPIORDY	0x02
 10.1743 +	bit	CLRARBDO	0x01
 10.1744 +}
 10.1745 +
 10.1746 +/*
 10.1747 + * SCSI Interrupt Mode 0
 10.1748 + * Setting any bit will enable the corresponding function
 10.1749 + * in SIMODE0 to interrupt via the IRQ pin.
 10.1750 + */
 10.1751 +register SIMODE0 {
 10.1752 +	address			0x04B
 10.1753 +	access_mode	RW
 10.1754 +	modes		M_CFG
 10.1755 +	bit	ENSELDO		0x40
 10.1756 +	bit	ENSELDI		0x20
 10.1757 +	bit	ENSELINGO	0x10
 10.1758 +	bit	ENIOERR		0x08
 10.1759 +	bit	ENOVERRUN	0x04
 10.1760 +	bit	ENSPIORDY	0x02
 10.1761 +	bit	ENARBDO		0x01
 10.1762 +}
 10.1763 +
 10.1764 +/*
 10.1765 + * SCSI Status 1
 10.1766 + */
 10.1767 +register SSTAT1 {
 10.1768 +	address			0x04C
 10.1769 +	access_mode	RO
 10.1770 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1771 +	bit	SELTO		0x80
 10.1772 +	bit	ATNTARG 	0x40
 10.1773 +	bit	SCSIRSTI	0x20
 10.1774 +	bit	PHASEMIS	0x10
 10.1775 +	bit	BUSFREE		0x08
 10.1776 +	bit	SCSIPERR	0x04
 10.1777 +	bit	STRB2FAST	0x02
 10.1778 +	bit	REQINIT		0x01
 10.1779 +}
 10.1780 +
 10.1781 +/*
 10.1782 + * Clear SCSI Interrupt 1
 10.1783 + * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT1.
 10.1784 + */
 10.1785 +register CLRSINT1 {
 10.1786 +	address			0x04c
 10.1787 +	access_mode	WO
 10.1788 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1789 +	bit	CLRSELTIMEO	0x80
 10.1790 +	bit	CLRATNO		0x40
 10.1791 +	bit	CLRSCSIRSTI	0x20
 10.1792 +	bit	CLRBUSFREE	0x08
 10.1793 +	bit	CLRSCSIPERR	0x04
 10.1794 +	bit	CLRSTRB2FAST	0x02
 10.1795 +	bit	CLRREQINIT	0x01
 10.1796 +}
 10.1797 +
 10.1798 +/*
 10.1799 + * SCSI Status 2
 10.1800 + */
 10.1801 +register SSTAT2 {
 10.1802 +	address			0x04d
 10.1803 +	access_mode	RO
 10.1804 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1805 +	mask	BUSFREETIME	0xc0
 10.1806 +	mask	BUSFREE_LQO	0x40
 10.1807 +	mask	BUSFREE_DFF0	0x80
 10.1808 +	mask	BUSFREE_DFF1	0xC0
 10.1809 +	bit	NONPACKREQ	0x20
 10.1810 +	bit	EXP_ACTIVE	0x10	/* SCSI Expander Active */
 10.1811 +	bit	BSYX		0x08	/* Busy Expander */
 10.1812 +	bit	WIDE_RES	0x04	/* Modes 0 and 1 only */
 10.1813 +	bit	SDONE		0x02	/* Modes 0 and 1 only */
 10.1814 +	bit	DMADONE		0x01	/* Modes 0 and 1 only */
 10.1815 +}
 10.1816 +
 10.1817 +/*
 10.1818 + * Clear SCSI Interrupt 2
 10.1819 + */
 10.1820 +register CLRSINT2 {
 10.1821 +	address			0x04D
 10.1822 +	access_mode	WO
 10.1823 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1824 +	bit	CLRNONPACKREQ	0x20
 10.1825 +	bit	CLRWIDE_RES	0x04	/* Modes 0 and 1 only */
 10.1826 +	bit	CLRSDONE	0x02	/* Modes 0 and 1 only */
 10.1827 +	bit	CLRDMADONE	0x01	/* Modes 0 and 1 only */
 10.1828 +}
 10.1829 +
 10.1830 +/*
 10.1831 + * SCSI Interrupt Mode 2
 10.1832 + */
 10.1833 +register SIMODE2 {
 10.1834 +	address			0x04D
 10.1835 +	access_mode	RW
 10.1836 +	modes		M_CFG
 10.1837 +	bit	ENWIDE_RES	0x04
 10.1838 +	bit	ENSDONE		0x02
 10.1839 +	bit	ENDMADONE	0x01
 10.1840 +}
 10.1841 +
 10.1842 +/*
 10.1843 + * Physical Error Diagnosis
 10.1844 + */
 10.1845 +register PERRDIAG {
 10.1846 +	address			0x04E
 10.1847 +	access_mode	RO
 10.1848 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1849 +	bit	HIZERO		0x80
 10.1850 +	bit	HIPERR		0x40
 10.1851 +	bit	PREVPHASE	0x20
 10.1852 +	bit	PARITYERR	0x10
 10.1853 +	bit	AIPERR		0x08
 10.1854 +	bit	CRCERR		0x04
 10.1855 +	bit	DGFORMERR	0x02
 10.1856 +	bit	DTERR		0x01
 10.1857 +}
 10.1858 +
 10.1859 +/*
 10.1860 + * LQI Manager Current State
 10.1861 + */
 10.1862 +register LQISTATE {
 10.1863 +	address			0x04E
 10.1864 +	access_mode	RO
 10.1865 +	modes		M_CFG
 10.1866 +}
 10.1867 +
 10.1868 +/*
 10.1869 + * SCSI Offset Count
 10.1870 + */
 10.1871 +register SOFFCNT {
 10.1872 +	address			0x04F
 10.1873 +	access_mode	RO
 10.1874 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1875 +}
 10.1876 +
 10.1877 +/*
 10.1878 + * LQO Manager Current State
 10.1879 + */
 10.1880 +register LQOSTATE {
 10.1881 +	address			0x04F
 10.1882 +	access_mode	RO
 10.1883 +	modes		M_CFG
 10.1884 +}
 10.1885 +
 10.1886 +/*
 10.1887 + * LQI Manager Status
 10.1888 + */
 10.1889 +register LQISTAT0 {
 10.1890 +	address			0x050
 10.1891 +	access_mode	RO
 10.1892 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1893 +	bit	LQIATNQAS	0x20
 10.1894 +	bit	LQICRCT1	0x10
 10.1895 +	bit	LQICRCT2	0x08
 10.1896 +	bit	LQIBADLQT	0x04
 10.1897 +	bit	LQIATNLQ	0x02
 10.1898 +	bit	LQIATNCMD	0x01
 10.1899 +}
 10.1900 +
 10.1901 +/*
 10.1902 + * Clear LQI Interrupts 0
 10.1903 + */
 10.1904 +register CLRLQIINTO {
 10.1905 +	address			0x050
 10.1906 +	access_mode	WO
 10.1907 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1908 +	bit	CLRLQIATNQAS	0x20
 10.1909 +	bit	CLRLQICRCT1	0x10
 10.1910 +	bit	CLRLQICRCT2	0x08
 10.1911 +	bit	CLRLQIBADLQT	0x04
 10.1912 +	bit	CLRLQIATNLQ	0x02
 10.1913 +	bit	CLRLQIATNCMD	0x01
 10.1914 +}
 10.1915 +
 10.1916 +/*
 10.1917 + * LQI Manager Interrupt Mode 0
 10.1918 + */
 10.1919 +register LQIMODE0 {
 10.1920 +	address			0x050
 10.1921 +	access_mode	RW
 10.1922 +	modes		M_CFG
 10.1923 +	bit	ENLQIATNQASK	0x20
 10.1924 +	bit	ENLQICRCT1	0x10
 10.1925 +	bit	ENLQICRCT2	0x08
 10.1926 +	bit	ENLQIBADLQT	0x04
 10.1927 +	bit	ENLQIATNLQ	0x02
 10.1928 +	bit	ENLQIATNCMD	0x01
 10.1929 +}
 10.1930 +
 10.1931 +/*
 10.1932 + * LQI Manager Status 1
 10.1933 + */
 10.1934 +register LQISTAT1 {
 10.1935 +	address			0x051
 10.1936 +	access_mode	RO
 10.1937 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1938 +	mask	LQIPHASE_LQ	0x80
 10.1939 +	mask	LQIPHASE_NLQ	0x40
 10.1940 +	bit	LQIABORT	0x20
 10.1941 +	mask	LQICRCI_LQ	0x10
 10.1942 +	mask	LQICRCI_NLQ	0x08
 10.1943 +	bit	LQIBADLQI	0x04
 10.1944 +	mask	LQIOVERI_LQ	0x02
 10.1945 +	mask	LQIOVERI_NLQ	0x01
 10.1946 +}
 10.1947 +
 10.1948 +/*
 10.1949 + * Clear LQI Manager Interrupts1
 10.1950 + */
 10.1951 +register CLRLQIINT1 {
 10.1952 +	address			0x051
 10.1953 +	access_mode	WO
 10.1954 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1955 +	mask	CLRLQIPHASE_LQ	0x80
 10.1956 +	mask	CLRLQIPHASE_NLQ	0x40
 10.1957 +	bit	CLRLIQABORT	0x20
 10.1958 +	mask	CLRLQICRCI_LQ	0x10
 10.1959 +	mask	CLRLQICRCI_NLQ	0x08
 10.1960 +	bit	CLRLQIBADLQI	0x04
 10.1961 +	mask	CLRLQIOVERI_LQ	0x02
 10.1962 +	mask	CLRLQIOVERI_NLQ	0x01
 10.1963 +}
 10.1964 +
 10.1965 +/*
 10.1966 + * LQI Manager Interrupt Mode 1
 10.1967 + */
 10.1968 +register LQIMODE1 {
 10.1969 +	address			0x051
 10.1970 +	access_mode	RW
 10.1971 +	modes		M_CFG
 10.1972 +	mask	ENLQIPHASE_LQ	0x80
 10.1973 +	mask	ENLQIPHASE_NLQ	0x40
 10.1974 +	bit	ENLIQABORT	0x20
 10.1975 +	mask	ENLQICRCI_LQ	0x10
 10.1976 +	mask	ENLQICRCI_NLQ	0x08
 10.1977 +	bit	ENLQIBADLQI	0x04
 10.1978 +	mask	ENLQIOVERI_LQ	0x02
 10.1979 +	mask	ENLQIOVERI_NLQ	0x01
 10.1980 +}
 10.1981 +
 10.1982 +/*
 10.1983 + * LQI Manager Status 2
 10.1984 + */
 10.1985 +register LQISTAT2 {
 10.1986 +	address			0x052
 10.1987 +	access_mode	RO
 10.1988 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.1989 +	bit	PACKETIZED	0x80
 10.1990 +	bit	LQIPHASE_OUTPKT	0x40
 10.1991 +	bit	LQIWORKONLQ	0x20
 10.1992 +	bit	LQIWAITFIFO	0x10
 10.1993 +	bit	LQISTOPPKT	0x08
 10.1994 +	bit	LQISTOPLQ	0x04
 10.1995 +	bit	LQISTOPCMD	0x02
 10.1996 +	bit	LQIGSAVAIL	0x01
 10.1997 +}
 10.1998 +
 10.1999 +/*
 10.2000 + * SCSI Status 3
 10.2001 + */
 10.2002 +register SSTAT3 {
 10.2003 +	address			0x053
 10.2004 +	access_mode	RO
 10.2005 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.2006 +	bit	NTRAMPERR	0x02
 10.2007 +	bit	OSRAMPERR	0x01
 10.2008 +}
 10.2009 +
 10.2010 +/*
 10.2011 + * Clear SCSI Status 3
 10.2012 + */
 10.2013 +register CLRSINT3 {
 10.2014 +	address			0x053
 10.2015 +	access_mode	WO
 10.2016 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.2017 +	bit	CLRNTRAMPERR	0x02
 10.2018 +	bit	CLROSRAMPERR	0x01
 10.2019 +}
 10.2020 +
 10.2021 +/*
 10.2022 + * SCSI Interrupt Mode 3
 10.2023 + */
 10.2024 +register SIMODE3 {
 10.2025 +	address			0x053
 10.2026 +	access_mode	RW
 10.2027 +	modes		M_CFG
 10.2028 +	bit	ENNTRAMPERR	0x02
 10.2029 +	bit	ENOSRAMPERR	0x01
 10.2030 +}
 10.2031 +
 10.2032 +/*
 10.2033 + * LQO Manager Status 0
 10.2034 + */
 10.2035 +register LQOSTAT0 {
 10.2036 +	address			0x054
 10.2037 +	access_mode	RO
 10.2038 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.2039 +	bit	LQOTARGSCBPERR	0x10
 10.2040 +	bit	LQOSTOPT2	0x08
 10.2041 +	bit	LQOATNLQ	0x04
 10.2042 +	bit	LQOATNPKT	0x02
 10.2043 +	bit	LQOTCRC		0x01
 10.2044 +}
 10.2045 +
 10.2046 +/*
 10.2047 + * Clear LQO Manager interrupt 0
 10.2048 + */
 10.2049 +register CLRLQOINT0 {
 10.2050 +	address			0x054
 10.2051 +	access_mode	WO
 10.2052 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.2053 +	bit	CLRLQOTARGSCBPERR	0x10
 10.2054 +	bit	CLRLQOSTOPT2		0x08
 10.2055 +	bit	CLRLQOATNLQ		0x04
 10.2056 +	bit	CLRLQOATNPKT		0x02
 10.2057 +	bit	CLRLQOTCRC		0x01
 10.2058 +}
 10.2059 +
 10.2060 +/*
 10.2061 + * LQO Manager Interrupt Mode 0
 10.2062 + */
 10.2063 +register LQOMODE0 {
 10.2064 +	address			0x054
 10.2065 +	access_mode	RW
 10.2066 +	modes		M_CFG
 10.2067 +	bit	ENLQOTARGSCBPERR	0x10
 10.2068 +	bit	ENLQOSTOPT2		0x08
 10.2069 +	bit	ENLQOATNLQ		0x04
 10.2070 +	bit	ENLQOATNPKT		0x02
 10.2071 +	bit	ENLQOTCRC		0x01
 10.2072 +}
 10.2073 +
 10.2074 +/*
 10.2075 + * LQO Manager Status 1
 10.2076 + */
 10.2077 +register LQOSTAT1 {
 10.2078 +	address			0x055
 10.2079 +	access_mode	RO
 10.2080 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.2081 +	bit	LQOINITSCBPERR	0x10
 10.2082 +	bit	LQOSTOPI2	0x08
 10.2083 +	bit	LQOBADQAS	0x04
 10.2084 +	bit	LQOBUSFREE	0x02
 10.2085 +	bit	LQOPHACHGINPKT	0x01
 10.2086 +}
 10.2087 +
 10.2088 +/*
 10.2089 + * Clear LOQ Interrupt 1
 10.2090 + */
 10.2091 +register CLRLQOINT1 {
 10.2092 +	address			0x055
 10.2093 +	access_mode	WO
 10.2094 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.2095 +	bit	CLRLQOINITSCBPERR	0x10
 10.2096 +	bit	CLRLQOSTOPI2		0x08
 10.2097 +	bit	CLRLQOBADQAS		0x04
 10.2098 +	bit	CLRLQOBUSFREE		0x02
 10.2099 +	bit	CLRLQOPHACHGINPKT	0x01
 10.2100 +}
 10.2101 +
 10.2102 +/*
 10.2103 + * LQO Manager Interrupt Mode 1
 10.2104 + */
 10.2105 +register LQOMODE1 {
 10.2106 +	address			0x055
 10.2107 +	access_mode	RW
 10.2108 +	modes		M_CFG
 10.2109 +	bit	ENLQOINITSCBPERR	0x10
 10.2110 +	bit	ENLQOSTOPI2		0x08
 10.2111 +	bit	ENLQOBADQAS		0x04
 10.2112 +	bit	ENLQOBUSFREE		0x02
 10.2113 +	bit	ENLQOPHACHGINPKT	0x01
 10.2114 +}
 10.2115 +
 10.2116 +/*
 10.2117 + * LQO Manager Status 2
 10.2118 + */
 10.2119 +register LQOSTAT2 {
 10.2120 +	address			0x056
 10.2121 +	access_mode	RO
 10.2122 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.2123 +	mask	LQOPKT		0xE0
 10.2124 +	bit	LQOWAITFIFO	0x10
 10.2125 +	bit	LQOPHACHGOUTPKT	0x02	/* outside of packet boundaries. */
 10.2126 +	bit	LQOSTOP0	0x01	/* Stopped after sending all packets */
 10.2127 +}
 10.2128 +
 10.2129 +/*
 10.2130 + * Output Synchronizer Space Count
 10.2131 + */
 10.2132 +register OS_SPACE_CNT {
 10.2133 +	address			0x056
 10.2134 +	access_mode	RO
 10.2135 +	modes		M_CFG
 10.2136 +}
 10.2137 +
 10.2138 +/*
 10.2139 + * SCSI Interrupt Mode 1
 10.2140 + * Setting any bit will enable the corresponding function
 10.2141 + * in SIMODE1 to interrupt via the IRQ pin.
 10.2142 + */
 10.2143 +register SIMODE1 {
 10.2144 +	address			0x057
 10.2145 +	access_mode	RW
 10.2146 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.2147 +	bit	ENSELTIMO	0x80
 10.2148 +	bit	ENATNTARG	0x40
 10.2149 +	bit	ENSCSIRST	0x20
 10.2150 +	bit	ENPHASEMIS	0x10
 10.2151 +	bit	ENBUSFREE	0x08
 10.2152 +	bit	ENSCSIPERR	0x04
 10.2153 +	bit	ENSTRB2FAST	0x02
 10.2154 +	bit	ENREQINIT	0x01
 10.2155 +}
 10.2156 +
 10.2157 +/*
 10.2158 + * Good Status FIFO
 10.2159 + */
 10.2160 +register GSFIFO {
 10.2161 +	address			0x058
 10.2162 +	access_mode	RO
 10.2163 +	size		2
 10.2164 +	modes		M_DFF0, M_DFF1, M_SCSI
 10.2165 +}
 10.2166 +
 10.2167 +/*
 10.2168 + * Data FIFO SCSI Transfer Control
 10.2169 + */
 10.2170 +register DFFSXFRCTL {
 10.2171 +	address			0x05A
 10.2172 +	access_mode	RW
 10.2173 +	modes		M_DFF0, M_DFF1
 10.2174 +	bit	CLRSHCNT	0x04
 10.2175 +	bit	CLRCHN		0x02
 10.2176 +	bit	RSTCHN		0x01
 10.2177 +}
 10.2178 +
 10.2179 +/*
 10.2180 + * Next SCSI Control Block
 10.2181 + */
 10.2182 +register NEXTSCB {
 10.2183 +	address			0x05A
 10.2184 +	access_mode	RW
 10.2185 +	size		2
 10.2186 +	modes		M_SCSI
 10.2187 +}
 10.2188 +	
 10.2189 +/*
 10.2190 + * SEQ Interrupts
 10.2191 + */
 10.2192 +register SEQINTSRC {
 10.2193 +	address			0x05B
 10.2194 +	access_mode	RO
 10.2195 +	modes		M_DFF0, M_DFF1
 10.2196 +	bit	CTXTDONE	0x40
 10.2197 +	bit	SAVEPTRS	0x20
 10.2198 +	bit	CFG4DATA	0x10
 10.2199 +	bit	CFG4ISTAT	0x08
 10.2200 +	bit	CFG4TSTAT	0x04
 10.2201 +	bit	CFG4ICMD	0x02
 10.2202 +	bit	CFG4TCMD	0x01
 10.2203 +}
 10.2204 +
 10.2205 +/*
 10.2206 + * Clear Arp Interrupts
 10.2207 + */
 10.2208 +register CLRSEQINTSRC {
 10.2209 +	address			0x05B
 10.2210 +	access_mode	WO
 10.2211 +	modes		M_DFF0, M_DFF1
 10.2212 +	bit	CLRCTXTDONE	0x40
 10.2213 +	bit	CLRSAVEPTRS	0x20
 10.2214 +	bit	CLRCFG4DATA	0x10
 10.2215 +	bit	CLRCFG4ISTAT	0x08
 10.2216 +	bit	CLRCFG4TSTAT	0x04
 10.2217 +	bit	CLRCFG4ICMD	0x02
 10.2218 +	bit	CLRCFG4TCMD	0x01
 10.2219 +}
 10.2220 +
 10.2221 +/*
 10.2222 + * SEQ Interrupt Enabled (Shared)
 10.2223 + */
 10.2224 +register SEQIMODE {
 10.2225 +	address			0x05C
 10.2226 +	access_mode	RW
 10.2227 +	modes		M_DFF0, M_DFF1
 10.2228 +	bit	ENCTXTDONE	0x40
 10.2229 +	bit	ENSAVEPTRS	0x20
 10.2230 +	bit	ENCFG4DATA	0x10
 10.2231 +	bit	ENCFG4ISTAT	0x08
 10.2232 +	bit	ENCFG4TSTAT	0x04
 10.2233 +	bit	ENCFG4ICMD	0x02
 10.2234 +	bit	ENCFG4TCMD	0x01
 10.2235 +}
 10.2236 +
 10.2237 +/*
 10.2238 + * Current SCSI Control Block
 10.2239 + */
 10.2240 +register CURRSCB {
 10.2241 +	address			0x05C
 10.2242 +	access_mode	RW
 10.2243 +	size		2
 10.2244 +	modes		M_SCSI
 10.2245 +}
 10.2246 +
 10.2247 +/*
 10.2248 + * Data FIFO Status
 10.2249 + */
 10.2250 +register MDFFSTAT {
 10.2251 +	address			0x05D
 10.2252 +	access_mode	RO
 10.2253 +	modes		M_DFF0, M_DFF1
 10.2254 +	bit	LASTSDONE	0x10
 10.2255 +	bit	SHVALID		0x08
 10.2256 +	bit	DLZERO		0x04 /* FIFO data ends on packet boundary. */
 10.2257 +	bit	DATAINFIFO	0x02
 10.2258 +	bit	FIFOFREE	0x01
 10.2259 +}
 10.2260 +
 10.2261 +/*
 10.2262 + * CRC Control
 10.2263 + */
 10.2264 +register CRCCONTROL {
 10.2265 +	address			0x05d
 10.2266 +	access_mode	RW
 10.2267 +	modes		M_CFG
 10.2268 +	bit	CRCVALCHKEN		0x40
 10.2269 +}
 10.2270 +
 10.2271 +/*
 10.2272 + * SCSI Test Control
 10.2273 + */
 10.2274 +register SCSITEST {
 10.2275 +	address			0x05E
 10.2276 +	access_mode	RW
 10.2277 +	modes		M_CFG
 10.2278 +	bit	CNTRTEST	0x08
 10.2279 +	bit	SEL_TXPLL_DEBUG	0x04
 10.2280 +}
 10.2281 +
 10.2282 +/*
 10.2283 + * Data FIFO Queue Tag
 10.2284 + */
 10.2285 +register DFFTAG {
 10.2286 +	address			0x05E
 10.2287 +	access_mode	RW
 10.2288 +	size		2
 10.2289 +	modes		M_DFF0, M_DFF1
 10.2290 +}
 10.2291 +
 10.2292 +/*
 10.2293 + * Last SCSI Control Block
 10.2294 + */
 10.2295 +register LASTSCB {
 10.2296 +	address			0x05E
 10.2297 +	access_mode	RW
 10.2298 +	size		2
 10.2299 +	modes		M_SCSI
 10.2300 +}
 10.2301 +
 10.2302 +/*
 10.2303 + * SCSI I/O Cell Power-down Control
 10.2304 + */
 10.2305 +register IOPDNCTL {
 10.2306 +	address			0x05F
 10.2307 +	access_mode	RW
 10.2308 +	modes		M_CFG
 10.2309 +	bit	DISABLE_OE	0x80
 10.2310 +	bit	PDN_IDIST	0x04
 10.2311 +	bit	PDN_DIFFSENSE	0x01
 10.2312 +}
 10.2313 +
 10.2314 +/*
 10.2315 + * Shaddow Host Address.
 10.2316 + */
 10.2317 +register SHADDR {
 10.2318 +	address			0x060
 10.2319 +	access_mode	RO
 10.2320 +	size		8
 10.2321 +	modes		M_DFF0, M_DFF1
 10.2322 +}
 10.2323 +
 10.2324 +/*
 10.2325 + * Data Group CRC Interval.
 10.2326 + */
 10.2327 +register DGRPCRCI {
 10.2328 +	address			0x060
 10.2329 +	access_mode	RW
 10.2330 +	size		2
 10.2331 +	modes		M_CFG
 10.2332 +}
 10.2333 +
 10.2334 +/*
 10.2335 + * Data Transfer Negotiation Address
 10.2336 + */
 10.2337 +register NEGOADDR {
 10.2338 +	address			0x060
 10.2339 +	access_mode	RW
 10.2340 +	modes		M_SCSI
 10.2341 +}
 10.2342 +
 10.2343 +/*
 10.2344 + * Data Transfer Negotiation Data - Period Byte
 10.2345 + */
 10.2346 +register NEGPERIOD {
 10.2347 +	address			0x061
 10.2348 +	access_mode	RW
 10.2349 +	modes		M_SCSI
 10.2350 +}
 10.2351 +
 10.2352 +/*
 10.2353 + * Packetized CRC Interval
 10.2354 + */
 10.2355 +register PACKCRCI {
 10.2356 +	address			0x062
 10.2357 +	access_mode	RW
 10.2358 +	size		2
 10.2359 +	modes		M_CFG
 10.2360 +}
 10.2361 +
 10.2362 +/*
 10.2363 + * Data Transfer Negotiation Data - Offset Byte
 10.2364 + */
 10.2365 +register NEGOFFSET {
 10.2366 +	address			0x062
 10.2367 +	access_mode	RW
 10.2368 +	modes		M_SCSI
 10.2369 +}
 10.2370 +
 10.2371 +/*
 10.2372 + * Data Transfer Negotiation Data - PPR Options
 10.2373 + */
 10.2374 +register NEGPPROPTS {
 10.2375 +	address			0x063
 10.2376 +	access_mode	RW
 10.2377 +	modes		M_SCSI
 10.2378 +	bit	PPROPT_PACE	0x08
 10.2379 +	bit	PPROPT_QAS	0x04
 10.2380 +	bit	PPROPT_DT	0x02
 10.2381 +	bit	PPROPT_IUT	0x01
 10.2382 +}
 10.2383 +
 10.2384 +/*
 10.2385 + * Data Transfer Negotiation Data -  Connection Options
 10.2386 + */
 10.2387 +register NEGCONOPTS {
 10.2388 +	address			0x064
 10.2389 +	access_mode	RW
 10.2390 +	modes		M_SCSI
 10.2391 +	bit	ENAIP		0x08
 10.2392 +	bit	ENAUTOATNI	0x04
 10.2393 +	bit	ENAUTOATNO	0x02
 10.2394 +	bit	WIDEXFER	0x01
 10.2395 +}
 10.2396 +
 10.2397 +/*
 10.2398 + * Negotiation Table Annex Column Index.
 10.2399 + */
 10.2400 +register ANNEXCOL {
 10.2401 +	address			0x065
 10.2402 +	access_mode	RW
 10.2403 +	modes		M_SCSI
 10.2404 +}
 10.2405 +
 10.2406 +const AHD_ANNEXCOL_PRECOMP	4
 10.2407 +const	AHD_PRECOMP_MASK	0x07
 10.2408 +const	AHD_PRECOMP_CUTBACK_17	0x04
 10.2409 +const	AHD_PRECOMP_CUTBACK_29	0x06
 10.2410 +const	AHD_PRECOMP_CUTBACK_37	0x07
 10.2411 +const	AHD_PRECOMP_FASTSLEW	0x40
 10.2412 +const AHD_NUM_ANNEXCOLS		4
 10.2413 +
 10.2414 +/*
 10.2415 + * Negotiation Table Annex Data Port.
 10.2416 + */
 10.2417 +register ANNEXDAT {
 10.2418 +	address			0x066
 10.2419 +	access_mode	RW
 10.2420 +	modes		M_SCSI
 10.2421 +}
 10.2422 +
 10.2423 +/*
 10.2424 + * Initiator's Own Id.
 10.2425 + * The SCSI ID to use for Selection Out and seen during a reselection..
 10.2426 + */
 10.2427 +register IOWNID {
 10.2428 +	address			0x067
 10.2429 +	access_mode	RW
 10.2430 +	modes		M_SCSI
 10.2431 +}
 10.2432 +
 10.2433 +/*
 10.2434 + * 960MHz Phase-Locked Loop Control 0
 10.2435 + */
 10.2436 +register PLL960CTL0 {
 10.2437 +	address			0x068
 10.2438 +	access_mode	RW
 10.2439 +	modes		M_CFG
 10.2440 +	bit	PLL_VCOSEL	0x80
 10.2441 +	bit	PLL_PWDN	0x40
 10.2442 +	mask	PLL_NS		0x30
 10.2443 +	bit	PLL_ENLUD	0x08
 10.2444 +	bit	PLL_ENLPF	0x04
 10.2445 +	bit	PLL_DLPF	0x02
 10.2446 +	bit	PLL_ENFBM	0x01
 10.2447 +}
 10.2448 +
 10.2449 +/*
 10.2450 + * Target Own Id
 10.2451 + */
 10.2452 +register TOWNID {
 10.2453 +	address			0x069
 10.2454 +	access_mode	RW
 10.2455 +	modes		M_SCSI
 10.2456 +}
 10.2457 +
 10.2458 +/*
 10.2459 + * 960MHz Phase-Locked Loop Control 1
 10.2460 + */
 10.2461 +register PLL960CTL1 {
 10.2462 +	address			0x069
 10.2463 +	access_mode	RW
 10.2464 +	modes		M_CFG
 10.2465 +	bit	PLL_CNTEN	0x80
 10.2466 +	bit	PLL_CNTCLR	0x40
 10.2467 +	bit	PLL_RST		0x01
 10.2468 +}
 10.2469 +
 10.2470 +/*
 10.2471 + * Expander Signature
 10.2472 + */
 10.2473 +register XSIG {
 10.2474 +	address			0x06A
 10.2475 +	access_mode	RW
 10.2476 +	modes		M_SCSI
 10.2477 +}
 10.2478 +
 10.2479 +/*
 10.2480 + * Shadow Byte Count
 10.2481 + */
 10.2482 +register SHCNT {
 10.2483 +	address			0x068
 10.2484 +	access_mode	RW
 10.2485 +	size		3
 10.2486 +	modes		M_DFF0, M_DFF1
 10.2487 +}
 10.2488 +
 10.2489 +/*
 10.2490 + * Selection Out ID
 10.2491 + */
 10.2492 +register SELOID {
 10.2493 +	address			0x06B
 10.2494 +	access_mode	RW
 10.2495 +	modes		M_SCSI
 10.2496 +}
 10.2497 +
 10.2498 +/*
 10.2499 + * 960-MHz Phase-Locked Loop Test Count
 10.2500 + */
 10.2501 +register PLL960CNT0 {
 10.2502 +	address			0x06A
 10.2503 +	access_mode	RO
 10.2504 +	size		2
 10.2505 +	modes		M_CFG
 10.2506 +}
 10.2507 +
 10.2508 +/*
 10.2509 + * 400-MHz Phase-Locked Loop Control 0
 10.2510 + */
 10.2511 +register PLL400CTL0 {
 10.2512 +	address			0x06C
 10.2513 +	access_mode	RW
 10.2514 +	modes		M_CFG
 10.2515 +	bit	PLL_VCOSEL	0x80
 10.2516 +	bit	PLL_PWDN	0x40
 10.2517 +	mask	PLL_NS		0x30
 10.2518 +	bit	PLL_ENLUD	0x08
 10.2519 +	bit	PLL_ENLPF	0x04
 10.2520 +	bit	PLL_DLPF	0x02
 10.2521 +	bit	PLL_ENFBM	0x01
 10.2522 +}
 10.2523 +
 10.2524 +/*
 10.2525 + * Arbitration Fairness
 10.2526 + */
 10.2527 +register FAIRNESS {
 10.2528 +	address			0x06C
 10.2529 +	access_mode	RW
 10.2530 +	size		2
 10.2531 +	modes		M_SCSI
 10.2532 +}
 10.2533 +
 10.2534 +/*
 10.2535 + * 400-MHz Phase-Locked Loop Control 1
 10.2536 + */
 10.2537 +register PLL400CTL1 {
 10.2538 +	address			0x06D
 10.2539 +	access_mode	RW
 10.2540 +	modes		M_CFG
 10.2541 +	bit	PLL_CNTEN	0x80
 10.2542 +	bit	PLL_CNTCLR	0x40
 10.2543 +	bit	PLL_RST		0x01
 10.2544 +}
 10.2545 +
 10.2546 +/*
 10.2547 + * Arbitration Unfairness
 10.2548 + */
 10.2549 +register UNFAIRNESS {
 10.2550 +	address			0x06E
 10.2551 +	access_mode	RW
 10.2552 +	size		2
 10.2553 +	modes		M_SCSI
 10.2554 +}
 10.2555 +
 10.2556 +/*
 10.2557 + * 400-MHz Phase-Locked Loop Test Count
 10.2558 + */
 10.2559 +register PLL400CNT0 {
 10.2560 +	address			0x06E
 10.2561 +	access_mode	RO
 10.2562 +	size		2
 10.2563 +	modes		M_CFG
 10.2564 +}
 10.2565 +
 10.2566 +/*
 10.2567 + * SCB Page Pointer
 10.2568 + */
 10.2569 +register SCBPTR {
 10.2570 +	address			0x0A8
 10.2571 +	access_mode	RW
 10.2572 +	size		2
 10.2573 +	modes		M_DFF0, M_DFF1, M_CCHAN, M_SCSI
 10.2574 +}
 10.2575 +
 10.2576 +/*
 10.2577 + * CMC SCB Array Count
 10.2578 + * Number of bytes to transfer between CMC SCB memory and SCBRAM.
 10.2579 + * Transfers must be 8byte aligned and sized.
 10.2580 + */
 10.2581 +register CCSCBACNT {
 10.2582 +	address			0x0AB
 10.2583 +	access_mode	RW
 10.2584 +	modes		M_CCHAN
 10.2585 +}
 10.2586 +
 10.2587 +/*
 10.2588 + * SCB Autopointer
 10.2589 + * SCB-Next Address Snooping logic.  When an SCB is transferred to
 10.2590 + * the card, the next SCB address to be used by the CMC array can
 10.2591 + * be autoloaded from that transfer.
 10.2592 + */
 10.2593 +register SCBAUTOPTR {
 10.2594 +	address			0x0AB
 10.2595 +	access_mode	RW
 10.2596 +	modes		M_CFG
 10.2597 +	bit	AUSCBPTR_EN	0x80
 10.2598 +	mask	SCBPTR_ADDR	0x38
 10.2599 +	mask	SCBPTR_OFF	0x07
 10.2600 +}
 10.2601 +
 10.2602 +/*
 10.2603 + * CMC SG Ram Address Pointer
 10.2604 + */
 10.2605 +register CCSGADDR {
 10.2606 +	address			0x0AC
 10.2607 +	access_mode	RW
 10.2608 +	modes		M_DFF0, M_DFF1
 10.2609 +}
 10.2610 +
 10.2611 +/*
 10.2612 + * CMC SCB RAM Address Pointer
 10.2613 + */
 10.2614 +register CCSCBADDR {
 10.2615 +	address			0x0AC
 10.2616 +	access_mode	RW
 10.2617 +	modes		M_CCHAN
 10.2618 +}
 10.2619 +
 10.2620 +/*
 10.2621 + * CMC SCB Ram Back-up Address Pointer
 10.2622 + * Indicates the true stop location of transfers halted prior
 10.2623 + * to SCBHCNT going to 0.
 10.2624 + */
 10.2625 +register CCSCBADR_BK {
 10.2626 +	address			0x0AC
 10.2627 +	access_mode	RO
 10.2628 +	modes		M_CFG
 10.2629 +}
 10.2630 +
 10.2631 +/*
 10.2632 + * CMC SG Control
 10.2633 + */
 10.2634 +register CCSGCTL {
 10.2635 +	address			0x0AD
 10.2636 +	access_mode	RW
 10.2637 +	modes		M_DFF0, M_DFF1
 10.2638 +	bit	CCSGDONE	0x80
 10.2639 +	bit	SG_CACHE_AVAIL	0x10
 10.2640 +	bit	CCSGEN		0x08
 10.2641 +	bit	SG_FETCH_REQ	0x02
 10.2642 +	bit	CCSGRESET	0x01
 10.2643 +}
 10.2644 +
 10.2645 +/*
 10.2646 + * CMD SCB Control
 10.2647 + */
 10.2648 +register CCSCBCTL {
 10.2649 +	address			0x0AD
 10.2650 +	access_mode	RW
 10.2651 +	modes		M_CCHAN
 10.2652 +	bit	CCSCBDONE	0x80
 10.2653 +	bit	ARRDONE		0x40
 10.2654 +	bit	CCARREN		0x10
 10.2655 +	bit	CCSCBEN		0x08
 10.2656 +	bit	CCSCBDIR	0x04
 10.2657 +	bit	CCSCBRESET	0x01
 10.2658 +}
 10.2659 +
 10.2660 +/*
 10.2661 + * CMC Ram BIST
 10.2662 + */
 10.2663 +register CMC_RAMBIST {
 10.2664 +	address			0x0AD
 10.2665 +	access_mode	RW
 10.2666 +	modes		M_CFG
 10.2667 +	bit	SG_ELEMENT_SIZE		0x80
 10.2668 +	bit	SCBRAMBIST_FAIL		0x40
 10.2669 +	bit	SG_BIST_FAIL		0x20
 10.2670 +	bit	SG_BIST_EN		0x10
 10.2671 +	bit	CMC_BUFFER_BIST_FAIL	0x02
 10.2672 +	bit	CMC_BUFFER_BIST_EN	0x01
 10.2673 +}
 10.2674 +
 10.2675 +/*
 10.2676 + * CMC SG RAM Data Port
 10.2677 + */
 10.2678 +register CCSGRAM {
 10.2679 +	address			0x0B0
 10.2680 +	access_mode	RW
 10.2681 +	modes		M_DFF0, M_DFF1
 10.2682 +}
 10.2683 +
 10.2684 +/*
 10.2685 + * CMC SCB RAM Data Port
 10.2686 + */
 10.2687 +register CCSCBRAM {
 10.2688 +	address			0x0B0
 10.2689 +	access_mode	RW
 10.2690 +	modes		M_CCHAN
 10.2691 +}
 10.2692 +
 10.2693 +/*
 10.2694 + * Flex DMA Address.
 10.2695 + */
 10.2696 +register FLEXADR {
 10.2697 +	address			0x0B0
 10.2698 +	access_mode	RW
 10.2699 +	size		3
 10.2700 +	modes		M_SCSI
 10.2701 +}
 10.2702 +
 10.2703 +/*
 10.2704 + * Flex DMA Byte Count
 10.2705 + */
 10.2706 +register FLEXCNT {
 10.2707 +	address			0x0B3
 10.2708 +	access_mode	RW
 10.2709 +	size		2
 10.2710 +	modes		M_SCSI
 10.2711 +}
 10.2712 +
 10.2713 +/*
 10.2714 + * Flex DMA Status
 10.2715 + */
 10.2716 +register FLEXDMASTAT {
 10.2717 +	address			0x0B5
 10.2718 +	access_mode	RW
 10.2719 +	modes		M_SCSI
 10.2720 +	bit	FLEXDMAERR	0x02
 10.2721 +	bit	FLEXDMADONE	0x01
 10.2722 +}
 10.2723 +
 10.2724 +/*
 10.2725 + * Flex DMA Data Port
 10.2726 + */
 10.2727 +register FLEXDATA {
 10.2728 +	address			0x0B6
 10.2729 +	access_mode	RW
 10.2730 +	modes		M_SCSI
 10.2731 +}
 10.2732 +
 10.2733 +/*
 10.2734 + * Board Data
 10.2735 + */
 10.2736 +register BRDDAT {
 10.2737 +	address			0x0B8
 10.2738 +	access_mode	RW
 10.2739 +	modes		M_SCSI
 10.2740 +}
 10.2741 +
 10.2742 +/*
 10.2743 + * Board Control
 10.2744 + */
 10.2745 +register BRDCTL {
 10.2746 +	address			0x0B9
 10.2747 +	access_mode	RW
 10.2748 +	modes		M_SCSI
 10.2749 +	bit	FLXARBACK	0x80
 10.2750 +	bit	FLXARBREQ	0x40
 10.2751 +	mask	BRDADDR		0x38
 10.2752 +	bit	BRDEN		0x04
 10.2753 +	bit	BRDRW		0x02
 10.2754 +	bit	BRDSTB		0x01
 10.2755 +}
 10.2756 +
 10.2757 +/*
 10.2758 + * Serial EEPROM Address
 10.2759 + */
 10.2760 +register SEEADR {
 10.2761 +	address			0x0BA
 10.2762 +	access_mode	RW
 10.2763 +	modes		M_SCSI
 10.2764 +}
 10.2765 +
 10.2766 +/*
 10.2767 + * Serial EEPROM Data
 10.2768 + */
 10.2769 +register SEEDAT {
 10.2770 +	address			0x0BC
 10.2771 +	access_mode	RW
 10.2772 +	size		2
 10.2773 +	modes		M_SCSI
 10.2774 +}
 10.2775 +
 10.2776 +/*
 10.2777 + * Serial EEPROM Status
 10.2778 + */
 10.2779 +register SEESTAT {
 10.2780 +	address			0x0BE
 10.2781 +	access_mode	RO
 10.2782 +	modes		M_SCSI
 10.2783 +	bit	INIT_DONE	0x80
 10.2784 +	mask	SEEOPCODE	0x70
 10.2785 +	bit	LDALTID_L	0x08
 10.2786 +	bit	SEEARBACK	0x04
 10.2787 +	bit	SEEBUSY		0x02
 10.2788 +	bit	SEESTART	0x01
 10.2789 +}
 10.2790 +
 10.2791 +/*
 10.2792 + * Serial EEPROM Control
 10.2793 + */
 10.2794 +register SEECTL {
 10.2795 +	address			0x0BE
 10.2796 +	access_mode	RW
 10.2797 +	modes		M_SCSI
 10.2798 +	mask	SEEOPCODE	0x70
 10.2799 +	mask	SEEOP_ERASE	0x70
 10.2800 +	mask	SEEOP_READ	0x60
 10.2801 +	mask	SEEOP_WRITE	0x50
 10.2802 +	/*
 10.2803 +	 * The following four commands use special
 10.2804 +	 * addresses for differentiation.
 10.2805 +	 */
 10.2806 +	mask	SEEOP_ERAL	0x40
 10.2807 +	mask	SEEOP_EWEN	0x40
 10.2808 +	mask	SEEOP_WALL	0x40
 10.2809 +	mask	SEEOP_EWDS	0x40
 10.2810 +	bit	SEERST		0x02
 10.2811 +	bit	SEESTART	0x01
 10.2812 +}
 10.2813 +
 10.2814 +const SEEOP_ERAL_ADDR	0x80
 10.2815 +const SEEOP_EWEN_ADDR	0xC0
 10.2816 +const SEEOP_WRAL_ADDR	0x40
 10.2817 +const SEEOP_EWDS_ADDR	0x00
 10.2818 +
 10.2819 +/*
 10.2820 + * SCB Counter
 10.2821 + */
 10.2822 +register SCBCNT {
 10.2823 +	address			0x0BF
 10.2824 +	access_mode	RW
 10.2825 +	modes		M_SCSI
 10.2826 +}
 10.2827 +
 10.2828 +/*
 10.2829 + * Data FIFO Write Address
 10.2830 + * Pointer to the next QWD location to be written to the data FIFO.
 10.2831 + */
 10.2832 +register DFWADDR {
 10.2833 +	address			0x0C0
 10.2834 +	access_mode	RW
 10.2835 +	size		2
 10.2836 +	modes		M_DFF0, M_DFF1
 10.2837 +}
 10.2838 +
 10.2839 +/*
 10.2840 + * DSP Filter Control
 10.2841 + */
 10.2842 +register DSPFLTRCTL {
 10.2843 +	address			0x0C0
 10.2844 +	access_mode	RW
 10.2845 +	modes		M_CFG
 10.2846 +	bit	FLTRDISABLE	0x20
 10.2847 +	bit	EDGESENSE	0x10
 10.2848 +	mask	DSPFCNTSEL	0x0F
 10.2849 +}
 10.2850 +
 10.2851 +/*
 10.2852 + * DSP Data Channel Control
 10.2853 + */
 10.2854 +register DSPDATACTL {
 10.2855 +	address			0x0C1
 10.2856 +	access_mode	RW
 10.2857 +	modes		M_CFG
 10.2858 +	bit	BYPASSENAB	0x80
 10.2859 +	bit	DESQDIS		0x10
 10.2860 +	bit	RCVROFFSTDIS	0x04
 10.2861 +	bit	XMITOFFSTDIS	0x02
 10.2862 +}
 10.2863 +
 10.2864 +/*
 10.2865 + * Data FIFO Read Address
 10.2866 + * Pointer to the next QWD location to be read from the data FIFO.
 10.2867 + */
 10.2868 +register DFRADDR {
 10.2869 +	address			0x0C2
 10.2870 +	access_mode	RW
 10.2871 +	size		2
 10.2872 +	modes		M_DFF0, M_DFF1
 10.2873 +}
 10.2874 +
 10.2875 +/*
 10.2876 + * DSP REQ Control
 10.2877 + */
 10.2878 +register DSPREQCTL {
 10.2879 +	address			0x0C2
 10.2880 +	access_mode	RW
 10.2881 +	modes		M_CFG
 10.2882 +	mask	MANREQCTL	0xC0
 10.2883 +	mask	MANREQDLY	0x3F
 10.2884 +}
 10.2885 +
 10.2886 +/*
 10.2887 + * DSP ACK Control
 10.2888 + */
 10.2889 +register DSPACKCTL {
 10.2890 +	address			0x0C3
 10.2891 +	access_mode	RW
 10.2892 +	modes		M_CFG
 10.2893 +	mask	MANACKCTL	0xC0
 10.2894 +	mask	MANACKDLY	0x3F
 10.2895 +}
 10.2896 +
 10.2897 +/*
 10.2898 + * Data FIFO Data
 10.2899 + * Read/Write byte port into the data FIFO.  The read and write
 10.2900 + * FIFO pointers increment with each read and write respectively
 10.2901 + * to this port.
 10.2902 + */
 10.2903 +register DFDAT {
 10.2904 +	address			0x0C4
 10.2905 +	access_mode	RW
 10.2906 +	modes		M_DFF0, M_DFF1
 10.2907 +}
 10.2908 +
 10.2909 +/*
 10.2910 + * DSP Channel Select
 10.2911 + */
 10.2912 +register DSPSELECT {
 10.2913 +	address			0x0C4
 10.2914 +	access_mode	RW
 10.2915 +	modes		M_CFG
 10.2916 +	bit	AUTOINCEN	0x80
 10.2917 +	mask	DSPSEL		0x1F
 10.2918 +}
 10.2919 +
 10.2920 +const NUMDSPS 0x14
 10.2921 +
 10.2922 +/*
 10.2923 + * Write Bias Control
 10.2924 + */
 10.2925 +register WRTBIASCTL {
 10.2926 +	address			0x0C5
 10.2927 +	access_mode	WO
 10.2928 +	modes		M_CFG
 10.2929 +	bit	AUTOXBCDIS	0x80
 10.2930 +	mask	XMITMANVAL	0x3F
 10.2931 +}
 10.2932 +
 10.2933 +const WRTBIASCTL_CPQ_DEFAULT 0x97
 10.2934 +
 10.2935 +/*
 10.2936 + * Receiver Bias Control
 10.2937 + */
 10.2938 +register RCVRBIOSCTL {
 10.2939 +	address			0x0C6
 10.2940 +	access_mode	WO
 10.2941 +	modes		M_CFG
 10.2942 +	bit	AUTORBCDIS	0x80
 10.2943 +	mask	RCVRMANVAL	0x3F
 10.2944 +}
 10.2945 +
 10.2946 +/*
 10.2947 + * Write Bias Calculator
 10.2948 + */
 10.2949 +register WRTBIASCALC {
 10.2950 +	address			0x0C7
 10.2951 +	access_mode	RO
 10.2952 +	modes		M_CFG
 10.2953 +}
 10.2954 +
 10.2955 +/*
 10.2956 + * Data FIFO Pointers
 10.2957 + * Contains the byte offset from DFWADDR and DWRADDR to the current
 10.2958 + * FIFO write/read locations.
 10.2959 + */
 10.2960 +register DFPTRS {
 10.2961 +	address			0x0C8
 10.2962 +	access_mode	RW
 10.2963 +	modes		M_DFF0, M_DFF1
 10.2964 +}
 10.2965 +
 10.2966 +/*
 10.2967 + * Receiver Bias Calculator
 10.2968 + */
 10.2969 +register RCVRBIASCALC {
 10.2970 +	address			0x0C8
 10.2971 +	access_mode	RO
 10.2972 +	modes		M_CFG
 10.2973 +}
 10.2974 +
 10.2975 +/*
 10.2976 + * Data FIFO Debug Control
 10.2977 + */
 10.2978 +register DFDBCTL {
 10.2979 +	address				0x0C8
 10.2980 +	access_mode	RW
 10.2981 +	modes		M_DFF0, M_DFF1
 10.2982 +	bit	DFF_CIO_WR_RDY		0x20
 10.2983 +	bit	DFF_CIO_RD_RDY		0x10
 10.2984 +	bit	DFF_DIR_ERR		0x08
 10.2985 +	bit	DFF_RAMBIST_FAIL	0x04
 10.2986 +	bit	DFF_RAMBIST_DONE	0x02
 10.2987 +	bit	DFF_RAMBIST_EN		0x01
 10.2988 +}
 10.2989 +
 10.2990 +/*
 10.2991 + * Data FIFO Backup Read Pointer
 10.2992 + * Contains the data FIFO address to be restored if the last
 10.2993 + * data accessed from the data FIFO was not transferred successfully.
 10.2994 + */
 10.2995 +register DFBKPTR {
 10.2996 +	address			0x0C9
 10.2997 +	access_mode	RW
 10.2998 +	size		2
 10.2999 +	modes		M_DFF0, M_DFF1
 10.3000 +}
 10.3001 +
 10.3002 +/*
 10.3003 + * Skew Calculator
 10.3004 + */
 10.3005 +register SKEWCALC {
 10.3006 +	address			0x0C9
 10.3007 +	access_mode	RO
 10.3008 +	modes		M_CFG
 10.3009 +}
 10.3010 +
 10.3011 +/*
 10.3012 + * Data FIFO Space Count
 10.3013 + * Number of FIFO locations that are free.
 10.3014 + */
 10.3015 +register DFSCNT {
 10.3016 +	address			0x0CC
 10.3017 +	access_mode	RO
 10.3018 +	size		2
 10.3019 +	modes		M_DFF0, M_DFF1
 10.3020 +}
 10.3021 +
 10.3022 +/*
 10.3023 + * Data FIFO Byte Count
 10.3024 + * Number of filled FIFO locations.
 10.3025 + */
 10.3026 +register DFBCNT {
 10.3027 +	address			0x0CE
 10.3028 +	access_mode	RO
 10.3029 +	size		2
 10.3030 +	modes		M_DFF0, M_DFF1
 10.3031 +}
 10.3032 +
 10.3033 +/*
 10.3034 + * Sequencer Program Overlay Address.
 10.3035 + * Low address must be written prior to high address.
 10.3036 + */
 10.3037 +register OVLYADDR {
 10.3038 +	address			0x0D4
 10.3039 +	modes		M_SCSI
 10.3040 +	size		2
 10.3041 +	access_mode	RW
 10.3042 +}
 10.3043 +
 10.3044 +/*
 10.3045 + * Sequencer Control 0
 10.3046 + * Error detection mode, speed configuration,
 10.3047 + * single step, breakpoints and program load.
 10.3048 + */
 10.3049 +register SEQCTL0 {
 10.3050 +	address			0x0D6
 10.3051 +	access_mode RW
 10.3052 +	bit	PERRORDIS	0x80
 10.3053 +	bit	PAUSEDIS	0x40
 10.3054 +	bit	FAILDIS		0x20
 10.3055 +	bit	FASTMODE	0x10
 10.3056 +	bit	BRKADRINTEN	0x08
 10.3057 +	bit	STEP		0x04
 10.3058 +	bit	SEQRESET	0x02
 10.3059 +	bit	LOADRAM		0x01
 10.3060 +}
 10.3061 +
 10.3062 +/*
 10.3063 + * Sequencer Control 1
 10.3064 + * Instruction RAM Diagnostics
 10.3065 + */
 10.3066 +register SEQCTL1 {
 10.3067 +	address			0x0D7
 10.3068 +	access_mode RW
 10.3069 +	bit	OVRLAY_DATA_CHK	0x08
 10.3070 +	bit	RAMBIST_DONE	0x04
 10.3071 +	bit	RAMBIST_FAIL	0x02
 10.3072 +	bit	RAMBIST_EN	0x01
 10.3073 +}
 10.3074 +
 10.3075 +/*
 10.3076 + * Sequencer Flags
 10.3077 + * Zero and Carry state of the ALU.
 10.3078 + */
 10.3079 +register FLAGS {
 10.3080 +	address			0x0D8
 10.3081 +	access_mode RO
 10.3082 +	bit	ZERO		0x02
 10.3083 +	bit	CARRY		0x01
 10.3084 +}
 10.3085 +
 10.3086 +/*
 10.3087 + * Sequencer Interrupt Control
 10.3088 + */ 
 10.3089 +register SEQINTCTL {
 10.3090 +	address			0x0D9
 10.3091 +	access_mode RW
 10.3092 +	bit	INTVEC1DSL	0x80
 10.3093 +	bit	INT1_CONTEXT	0x20
 10.3094 +	bit	SCS_SEQ_INT1M1	0x10
 10.3095 +	bit	SCS_SEQ_INT1M0	0x08
 10.3096 +	mask	INTMASK		0x06
 10.3097 +	bit	IRET		0x01
 10.3098 +}
 10.3099 +
 10.3100 +/*
 10.3101 + * Sequencer RAM Data Port
 10.3102 + * Single byte window into the Sequencer Instruction Ram area starting
 10.3103 + * at the address specified by OVLYADDR.  To write a full instruction word,
 10.3104 + * simply write four bytes in succession.  OVLYADDR will increment after the
 10.3105 + * most significant instrution byte (the byte with the parity bit) is written.
 10.3106 + */
 10.3107 +register SEQRAM {
 10.3108 +	address			0x0DA
 10.3109 +	access_mode RW
 10.3110 +}
 10.3111 +
 10.3112 +/*
 10.3113 + * Sequencer Program Counter
 10.3114 + * Low byte must be written prior to high byte.
 10.3115 + */
 10.3116 +register PRGMCNT {
 10.3117 +	address			0x0DE
 10.3118 +	access_mode	RW
 10.3119 +	size		2
 10.3120 +}
 10.3121 +
 10.3122 +/*
 10.3123 + * Accumulator
 10.3124 + */
 10.3125 +register ACCUM {
 10.3126 +	address			0x0E0
 10.3127 +	access_mode RW
 10.3128 +	accumulator
 10.3129 +}
 10.3130 +
 10.3131 +/*
 10.3132 + * Source Index Register
 10.3133 + * Incrementing index for reads of SINDIR and the destination (low byte only)
 10.3134 + * for any immediate operands passed in jmp, jc, jnc, call instructions.
 10.3135 + * Example:
 10.3136 + *		mvi	0xFF	call some_routine;
 10.3137 + *
 10.3138 + *  Will set SINDEX[0] to 0xFF and call the routine "some_routine.
 10.3139 + */
 10.3140 +register SINDEX	{
 10.3141 +	address			0x0E2
 10.3142 +	access_mode	RW
 10.3143 +	size		2
 10.3144 +	sindex
 10.3145 +}
 10.3146 +
 10.3147 +/*
 10.3148 + * Destination Index Register
 10.3149 + * Incrementing index for writes to DINDIR.  Can be used as a scratch register.
 10.3150 + */
 10.3151 +register DINDEX {
 10.3152 +	address			0x0E4
 10.3153 +	access_mode	RW
 10.3154 +	size		2
 10.3155 +}
 10.3156 +
 10.3157 +/*
 10.3158 + * Break Address
 10.3159 + * Sequencer instruction breakpoint address address.
 10.3160 + */
 10.3161 +register BRKADDR0 {
 10.3162 +	address			0x0E6
 10.3163 +	access_mode	RW
 10.3164 +}
 10.3165 +
 10.3166 +register BRKADDR1 {
 10.3167 +	address			0x0E6
 10.3168 +	access_mode	RW
 10.3169 +	bit	BRKDIS		0x80	/* Disable Breakpoint */
 10.3170 +}
 10.3171 +
 10.3172 +/*
 10.3173 + * All Ones
 10.3174 + * All reads to this register return the value 0xFF.
 10.3175 + */
 10.3176 +register ALLONES {
 10.3177 +	address			0x0E8
 10.3178 +	access_mode RO
 10.3179 +	allones
 10.3180 +}
 10.3181 +
 10.3182 +/*
 10.3183 + * All Zeros
 10.3184 + * All reads to this register return the value 0.
 10.3185 + */
 10.3186 +register ALLZEROS {
 10.3187 +	address			0x0EA
 10.3188 +	access_mode RO
 10.3189 +	allzeros
 10.3190 +}
 10.3191 +
 10.3192 +/*
 10.3193 + * No Destination
 10.3194 + * Writes to this register have no effect.
 10.3195 + */
 10.3196 +register NONE {
 10.3197 +	address			0x0EA
 10.3198 +	access_mode WO
 10.3199 +	none
 10.3200 +}
 10.3201 +
 10.3202 +/*
 10.3203 + * Source Index Indirect
 10.3204 + * Reading this register is equivalent to reading (register_base + SINDEX) and
 10.3205 + * incrementing SINDEX by 1.
 10.3206 + */
 10.3207 +register SINDIR	{
 10.3208 +	address			0x0EC
 10.3209 +	access_mode RO
 10.3210 +}
 10.3211 +
 10.3212 +/*
 10.3213 + * Destination Index Indirect
 10.3214 + * Writing this register is equivalent to writing to (register_base + DINDEX)
 10.3215 + * and incrementing DINDEX by 1.
 10.3216 + */
 10.3217 +register DINDIR	 {
 10.3218 +	address			0x0ED
 10.3219 +	access_mode WO
 10.3220 +}
 10.3221 +
 10.3222 +/*
 10.3223 + * Function One
 10.3224 + * 2's complement to bit value conversion.  Write the 2's complement value
 10.3225 + * (0-7 only) to the top nibble and retrieve the bit indexed by that value
 10.3226 + * on the next read of this register. 
 10.3227 + * Example:
 10.3228 + *	Write	0x60
 10.3229 + *	Read	0x40
 10.3230 + */
 10.3231 +register FUNCTION1 {
 10.3232 +	address			0x0F0
 10.3233 +	access_mode RW
 10.3234 +}
 10.3235 +
 10.3236 +/*
 10.3237 + * Stack
 10.3238 + * Window into the stack.  Each stack location is 10 bits wide reported
 10.3239 + * low byte followed by high byte.  There are 8 stack locations.
 10.3240 + */
 10.3241 +register STACK {
 10.3242 +	address			0x0F2
 10.3243 +	access_mode RW
 10.3244 +}
 10.3245 +
 10.3246 +/*
 10.3247 + * Interrupt Vector 1 Address
 10.3248 + * Interrupt branch address for SCS SEQ_INT1 mode 0 and 1 interrupts.
 10.3249 + */
 10.3250 +register INTVEC1_ADDR {
 10.3251 +	address			0x0F4
 10.3252 +	access_mode	RW
 10.3253 +	size		2
 10.3254 +	modes		M_CFG
 10.3255 +}
 10.3256 +
 10.3257 +/*
 10.3258 + * Current Address
 10.3259 + * Address of the SEQRAM instruction currently executing instruction.
 10.3260 + */
 10.3261 +register CURADDR {
 10.3262 +	address			0x0F4
 10.3263 +	access_mode	RW
 10.3264 +	size		2
 10.3265 +	modes		M_SCSI
 10.3266 +}
 10.3267 +
 10.3268 +/*
 10.3269 + * Interrupt Vector 2 Address
 10.3270 + * Interrupt branch address for HST_SEQ_INT2 interrupts.
 10.3271 + */
 10.3272 +register INTVEC2_ADDR {
 10.3273 +	address			0x0F6
 10.3274 +	access_mode	RW
 10.3275 +	size		2
 10.3276 +	modes		M_CFG
 10.3277 +}
 10.3278 +
 10.3279 +/*
 10.3280 + * Last Address
 10.3281 + * Address of the SEQRAM instruction executed prior to the current instruction.
 10.3282 + */
 10.3283 +register LASTADDR {
 10.3284 +	address			0x0F6
 10.3285 +	access_mode	RW
 10.3286 +	size		2
 10.3287 +	modes		M_SCSI
 10.3288 +}
 10.3289 +
 10.3290 +register AHD_PCI_CONFIG_BASE {
 10.3291 +	address			0x100
 10.3292 +	access_mode	RW
 10.3293 +	size		256
 10.3294 +	modes		M_CFG
 10.3295 +}
 10.3296 +
 10.3297 +/* ---------------------- Scratch RAM Offsets ------------------------- */
 10.3298 +scratch_ram {
 10.3299 +	/* Mode Specific */
 10.3300 +	address			0x0A0
 10.3301 +	size	8
 10.3302 +	modes	0, 1, 2, 3
 10.3303 +	REG0 {
 10.3304 +		size		2
 10.3305 +	}
 10.3306 +	REG1 {
 10.3307 +		size		2
 10.3308 +	}
 10.3309 +	REG2 {
 10.3310 +		size		2
 10.3311 +	}
 10.3312 +	SG_STATE {
 10.3313 +		size		1
 10.3314 +		bit	SEGS_AVAIL	0x01
 10.3315 +		bit	LOADING_NEEDED	0x02
 10.3316 +		bit	FETCH_INPROG	0x04
 10.3317 +	}
 10.3318 +	/*
 10.3319 +	 * Track whether the transfer byte count for
 10.3320 +	 * the current data phase is odd.
 10.3321 +	 */
 10.3322 +	DATA_COUNT_ODD {
 10.3323 +		size		1
 10.3324 +	}
 10.3325 +}
 10.3326 +
 10.3327 +scratch_ram {
 10.3328 +	/* Mode Specific */
 10.3329 +	address			0x0F8
 10.3330 +	size	8
 10.3331 +	modes	0, 1, 2, 3
 10.3332 +	LONGJMP_ADDR {
 10.3333 +		size		2
 10.3334 +	}
 10.3335 +	LONGJMP_SCB {
 10.3336 +		size		2
 10.3337 +	}
 10.3338 +	ACCUM_SAVE {
 10.3339 +		size		1
 10.3340 +	}
 10.3341 +}
 10.3342 +
 10.3343 +
 10.3344 +scratch_ram {
 10.3345 +	address			0x100
 10.3346 +	size	128
 10.3347 +	modes	0, 1, 2, 3
 10.3348 +	/*
 10.3349 +	 * Per "other-id" execution queues.  We use an array of
 10.3350 +	 * tail pointers into lists of SCBs sorted by "other-id".
 10.3351 +	 * The execution head pointer threads the head SCBs for
 10.3352 +	 * each list.
 10.3353 +	 */
 10.3354 +	WAITING_SCB_TAILS {
 10.3355 +		size		32
 10.3356 +	}
 10.3357 +	WAITING_TID_HEAD {
 10.3358 +		size		2
 10.3359 +	}
 10.3360 +	WAITING_TID_TAIL {
 10.3361 +		size		2
 10.3362 +	}
 10.3363 +	/*
 10.3364 +	 * SCBID of the next SCB in the new SCB queue.
 10.3365 +	 */
 10.3366 +	NEXT_QUEUED_SCB_ADDR {
 10.3367 +		size		4
 10.3368 +	}
 10.3369 +	/*
 10.3370 +	 * head of list of SCBs that have
 10.3371 +	 * completed but have not been
 10.3372 +	 * put into the qoutfifo.
 10.3373 +	 */
 10.3374 +	COMPLETE_SCB_HEAD {
 10.3375 +		size		2
 10.3376 +	}
 10.3377 +	/*
 10.3378 +	 * The list of completed SCBs in
 10.3379 +	 * the active DMA.
 10.3380 +	 */
 10.3381 +	COMPLETE_SCB_DMAINPROG_HEAD {
 10.3382 +		size		2
 10.3383 +	}
 10.3384 +	/*
 10.3385 +	 * head of list of SCBs that have
 10.3386 +	 * completed but need to be uploaded
 10.3387 +	 * to the host prior to being completed.
 10.3388 +	 */
 10.3389 +	COMPLETE_DMA_SCB_HEAD {
 10.3390 +		size		2
 10.3391 +	}
 10.3392 +	/* Counting semaphore to prevent new select-outs */
 10.3393 +	QFREEZE_COUNT {
 10.3394 +		size		2
 10.3395 +	}
 10.3396 +	/*
 10.3397 +	 * Mode to restore on idle_loop exit.
 10.3398 +	 */
 10.3399 +	SAVED_MODE {
 10.3400 +		size		1
 10.3401 +	}
 10.3402 +	/*
 10.3403 +	 * Single byte buffer used to designate the type or message
 10.3404 +	 * to send to a target.
 10.3405 +	 */
 10.3406 +	MSG_OUT {
 10.3407 +		size		1
 10.3408 +	}
 10.3409 +	/* Parameters for DMA Logic */
 10.3410 +	DMAPARAMS {
 10.3411 +		size		1
 10.3412 +		bit	PRELOADEN	0x80
 10.3413 +		bit	WIDEODD		0x40
 10.3414 +		bit	SCSIEN		0x20
 10.3415 +		bit	SDMAEN		0x10
 10.3416 +		bit	SDMAENACK	0x10
 10.3417 +		bit	HDMAEN		0x08
 10.3418 +		bit	HDMAENACK	0x08
 10.3419 +		bit	DIRECTION	0x04	/* Set indicates PCI->SCSI */
 10.3420 +		bit	FIFOFLUSH	0x02
 10.3421 +		bit	FIFORESET	0x01
 10.3422 +	}
 10.3423 +	SEQ_FLAGS {
 10.3424 +		size		1
 10.3425 +		bit	NOT_IDENTIFIED		0x80
 10.3426 +		bit	TARGET_CMD_IS_TAGGED	0x40
 10.3427 +		bit	NO_CDB_SENT		0x40
 10.3428 +		bit	DPHASE			0x20
 10.3429 +		/* Target flags */
 10.3430 +		bit	TARG_CMD_PENDING	0x10
 10.3431 +		bit	CMDPHASE_PENDING	0x08
 10.3432 +		bit	DPHASE_PENDING		0x04
 10.3433 +		bit	SPHASE_PENDING		0x02
 10.3434 +		bit	NO_DISCONNECT		0x01
 10.3435 +	}
 10.3436 +	/*
 10.3437 +	 * Temporary storage for the
 10.3438 +	 * target/channel/lun of a
 10.3439 +	 * reconnecting target
 10.3440 +	 */
 10.3441 +	SAVED_SCSIID {
 10.3442 +		size		1
 10.3443 +	}
 10.3444 +	SAVED_LUN {
 10.3445 +		size		1
 10.3446 +	}
 10.3447 +	/*
 10.3448 +	 * The last bus phase as seen by the sequencer. 
 10.3449 +	 */
 10.3450 +	LASTPHASE {
 10.3451 +		size		1
 10.3452 +		bit	CDI		0x80
 10.3453 +		bit	IOI		0x40
 10.3454 +		bit	MSGI		0x20
 10.3455 +		mask	PHASE_MASK	CDI|IOI|MSGI
 10.3456 +		mask	P_DATAOUT	0x00
 10.3457 +		mask	P_DATAIN	IOI
 10.3458 +		mask	P_DATAOUT_DT	P_DATAOUT|MSGO
 10.3459 +		mask	P_DATAIN_DT	P_DATAIN|MSGO
 10.3460 +		mask	P_COMMAND	CDI
 10.3461 +		mask	P_MESGOUT	CDI|MSGI
 10.3462 +		mask	P_STATUS	CDI|IOI
 10.3463 +		mask	P_MESGIN	CDI|IOI|MSGI
 10.3464 +		mask	P_BUSFREE	0x01
 10.3465 +	}
 10.3466 +	/*
 10.3467 +	 * Base address of our shared data with the kernel driver in host
 10.3468 +	 * memory.  This includes the qoutfifo and target mode
 10.3469 +	 * incoming command queue.
 10.3470 +	 */
 10.3471 +	SHARED_DATA_ADDR {
 10.3472 +		size		4
 10.3473 +	}
 10.3474 +	/*
 10.3475 +	 * Pointer to location in host memory for next
 10.3476 +	 * position in the qoutfifo.
 10.3477 +	 */
 10.3478 +	QOUTFIFO_NEXT_ADDR {
 10.3479 +		size		4
 10.3480 +	}
 10.3481 +	/*
 10.3482 +	 * Kernel and sequencer offsets into the queue of
 10.3483 +	 * incoming target mode command descriptors.  The
 10.3484 +	 * queue is full when the KERNEL_TQINPOS == TQINPOS.
 10.3485 +	 */
 10.3486 +	KERNEL_TQINPOS {
 10.3487 +		size		1
 10.3488 +	}
 10.3489 +	TQINPOS {                
 10.3490 +		size		1
 10.3491 +	}
 10.3492 +	ARG_1 {
 10.3493 +		size		1
 10.3494 +		mask	SEND_MSG		0x80
 10.3495 +		mask	SEND_SENSE		0x40
 10.3496 +		mask	SEND_REJ		0x20
 10.3497 +		mask	MSGOUT_PHASEMIS		0x10
 10.3498 +		mask	EXIT_MSG_LOOP		0x08
 10.3499 +		mask	CONT_MSG_LOOP_WRITE	0x04
 10.3500 +		mask	CONT_MSG_LOOP_READ	0x03
 10.3501 +		mask	CONT_MSG_LOOP_TARG	0x02
 10.3502 +		alias	RETURN_1
 10.3503 +	}
 10.3504 +	ARG_2 {
 10.3505 +		size		1
 10.3506 +		alias	RETURN_2
 10.3507 +	}
 10.3508 +
 10.3509 +	/*
 10.3510 +	 * Snapshot of MSG_OUT taken after each message is sent.
 10.3511 +	 */
 10.3512 +	LAST_MSG {
 10.3513 +		size		1
 10.3514 +	}
 10.3515 +
 10.3516 +	/*
 10.3517 +	 * Sequences the kernel driver has okayed for us.  This allows
 10.3518 +	 * the driver to do things like prevent initiator or target
 10.3519 +	 * operations.
 10.3520 +	 */
 10.3521 +	SCSISEQ_TEMPLATE {
 10.3522 +		size		1
 10.3523 +		bit	MANUALCTL	0x40
 10.3524 +		bit	ENSELI		0x20
 10.3525 +		bit	ENRSELI		0x10
 10.3526 +		mask	MANUALP		0x0C
 10.3527 +		bit	ENAUTOATNP	0x02
 10.3528 +		bit	ALTSTIM		0x01
 10.3529 +	}
 10.3530 +
 10.3531 +	/*
 10.3532 +	 * The initiator specified tag for this target mode transaction.
 10.3533 +	 */
 10.3534 +	INITIATOR_TAG {
 10.3535 +		size		1
 10.3536 +	}
 10.3537 +
 10.3538 +	SEQ_FLAGS2 {
 10.3539 +		size		1
 10.3540 +		bit	SCB_DMA			  0x01
 10.3541 +		bit	TARGET_MSG_PENDING	  0x02
 10.3542 +		bit	SELECTOUT_QFROZEN	  0x04
 10.3543 +	}
 10.3544 +	/*
 10.3545 +	 * Target-mode CDB type to CDB length table used
 10.3546 +	 * in non-packetized operation.
 10.3547 +	 */
 10.3548 +	CMDSIZE_TABLE {
 10.3549 +		size		8
 10.3550 +	}
 10.3551 +}
 10.3552 +
 10.3553 +/************************* Hardware SCB Definition ****************************/
 10.3554 +scb {
 10.3555 +	address			0x180
 10.3556 +	size	64
 10.3557 +	modes	0, 1, 2, 3
 10.3558 +	SCB_RESIDUAL_DATACNT {
 10.3559 +		size	4
 10.3560 +		alias	SCB_CDB_STORE
 10.3561 +	}
 10.3562 +	SCB_RESIDUAL_SGPTR {
 10.3563 +		size	4
 10.3564 +		alias	SCB_CDB_PTR
 10.3565 +		mask	SG_ADDR_MASK		0xf8	/* In the last byte */
 10.3566 +		bit	SG_OVERRUN_RESID	0x02	/* In the first byte */
 10.3567 +		bit	SG_LIST_NULL		0x01	/* In the first byte */
 10.3568 +	}
 10.3569 +	SCB_SCSI_STATUS {
 10.3570 +		size	1
 10.3571 +	}
 10.3572 +	SCB_TARGET_PHASES {
 10.3573 +		size	1
 10.3574 +	}
 10.3575 +	SCB_TARGET_DATA_DIR {
 10.3576 +		size	1
 10.3577 +	}
 10.3578 +	SCB_TARGET_ITAG {
 10.3579 +		size	1
 10.3580 +	}
 10.3581 +	SCB_SENSE_BUSADDR {
 10.3582 +		/*
 10.3583 +		 * Only valid if CDB length is less than 13 bytes or
 10.3584 +		 * we are using a CDB pointer.  Otherwise contains
 10.3585 +		 * the last 4 bytes of embedded cdb information.
 10.3586 +		 */
 10.3587 +		size	4
 10.3588 +		alias	SCB_NEXT_COMPLETE
 10.3589 +	}
 10.3590 +	SCB_CDB_LEN {
 10.3591 +		size	1
 10.3592 +		bit	SCB_CDB_LEN_PTR	0x80	/* CDB in host memory */
 10.3593 +	}
 10.3594 +	SCB_TASK_MANAGEMENT {
 10.3595 +		size	1
 10.3596 +	}
 10.3597 +	SCB_TAG {
 10.3598 +		size	2
 10.3599 +	}
 10.3600 +	SCB_NEXT {
 10.3601 +		alias	SCB_NEXT_SCB_BUSADDR
 10.3602 +		size	2
 10.3603 +	}
 10.3604 +	SCB_NEXT2 {
 10.3605 +		size	2
 10.3606 +	}
 10.3607 +	SCB_DATAPTR {
 10.3608 +		size	8
 10.3609 +	}
 10.3610 +	SCB_DATACNT {
 10.3611 +		/*
 10.3612 +		 * The last byte is really the high address bits for
 10.3613 +		 * the data address.
 10.3614 +		 */
 10.3615 +		size	4
 10.3616 +		bit	SG_LAST_SEG		0x80	/* In the fourth byte */
 10.3617 +		mask	SG_HIGH_ADDR_BITS	0x7F	/* In the fourth byte */
 10.3618 +	}
 10.3619 +	SCB_SGPTR {
 10.3620 +		size	4
 10.3621 +		bit	SG_STATUS_VALID	0x04	/* In the first byte */
 10.3622 +		bit	SG_FULL_RESID	0x02	/* In the first byte */
 10.3623 +		bit	SG_LIST_NULL	0x01	/* In the first byte */
 10.3624 +	}
 10.3625 +	SCB_CONTROL {
 10.3626 +		size	1
 10.3627 +		bit	TARGET_SCB	0x80
 10.3628 +		bit	DISCENB		0x40
 10.3629 +		bit	TAG_ENB		0x20
 10.3630 +		bit	MK_MESSAGE	0x10
 10.3631 +		bit	STATUS_RCVD	0x08
 10.3632 +		bit	DISCONNECTED	0x04
 10.3633 +		mask	SCB_TAG_TYPE	0x03
 10.3634 +	}
 10.3635 +	SCB_SCSIID {
 10.3636 +		size	1
 10.3637 +		mask	TID	0xF0
 10.3638 +		mask	OID	0x0F
 10.3639 +	}
 10.3640 +	SCB_LUN {
 10.3641 +		size	1
 10.3642 +		mask	LID				0xff
 10.3643 +	}
 10.3644 +	SCB_TASK_ATTRIBUTE {
 10.3645 +		size	1
 10.3646 +		alias	SCB_NONPACKET_TAG
 10.3647 +	}
 10.3648 +	SCB_BUSADDR {
 10.3649 +		size	4
 10.3650 +	}
 10.3651 +	SCB_DISCONNECTED_LISTS {
 10.3652 +		size	16
 10.3653 +	}
 10.3654 +}
 10.3655 +
 10.3656 +/*********************************** Constants ********************************/
 10.3657 +const SEQ_STACK_SIZE	8
 10.3658 +const MK_MESSAGE_BIT_OFFSET	4
 10.3659 +const TID_SHIFT		4
 10.3660 +const TARGET_CMD_CMPLT	0xfe
 10.3661 +const INVALID_ADDR	0x80
 10.3662 +#define SCB_LIST_NULL	0xff
 10.3663 +
 10.3664 +const CCSGADDR_MAX	0x80
 10.3665 +const CCSCBADDR_MAX	0x80
 10.3666 +const CCSGRAM_MAXSEGS	16
 10.3667 +
 10.3668 +/* Selection Timeout Timer Constants */
 10.3669 +const STIMESEL_SHIFT	3
 10.3670 +const STIMESEL_MIN	0x18
 10.3671 +const STIMESEL_BUG_ADJ	0x8
 10.3672 +
 10.3673 +/* WDTR Message values */
 10.3674 +const BUS_8_BIT			0x00
 10.3675 +const BUS_16_BIT		0x01
 10.3676 +const BUS_32_BIT		0x02
 10.3677 +
 10.3678 +/* Offset maximums */
 10.3679 +const MAX_OFFSET		0xfe
 10.3680 +const MAX_OFFSET_PACED		0x7f
 10.3681 +const HOST_MSG			0xff
 10.3682 +
 10.3683 +/*
 10.3684 + * The size of our sense buffers.
 10.3685 + * Sense buffer mapping can be handled in either of two ways.
 10.3686 + * The first is to allocate a dmamap for each transaction.
 10.3687 + * Depending on the architecture, dmamaps can be costly. The
 10.3688 + * alternative is to statically map the buffers in much the same
 10.3689 + * way we handle our scatter gather lists.  The driver implements
 10.3690 + * the later.
 10.3691 + */
 10.3692 +const AHD_SENSE_BUFSIZE		256
 10.3693 +
 10.3694 +/* Target mode command processing constants */
 10.3695 +const CMD_GROUP_CODE_SHIFT	0x05
 10.3696 +
 10.3697 +const STATUS_BUSY		0x08
 10.3698 +const STATUS_QUEUE_FULL		0x28
 10.3699 +const STATUS_PKT_SENSE		0xFF
 10.3700 +const TARGET_DATA_IN		1
 10.3701 +
 10.3702 +const SCB_TRANSFER_SIZE		48
 10.3703 +/* PKT_OVERRUN_BUFSIZE must be a multiple of 256 less than 64K */
 10.3704 +const PKT_OVERRUN_BUFSIZE	512
 10.3705 +
 10.3706 +/*
 10.3707 + * Downloaded (kernel inserted) constants
 10.3708 + */
 10.3709 +const SG_PREFETCH_CNT download
 10.3710 +const SG_PREFETCH_CNT_LIMIT download
 10.3711 +const SG_PREFETCH_ALIGN_MASK download
 10.3712 +const SG_PREFETCH_ADDR_MASK download
 10.3713 +const SG_SIZEOF download
 10.3714 +const PKT_OVERRUN_BUFOFFSET download
 10.3715 +
 10.3716 +/*
 10.3717 + * BIOS SCB offsets
 10.3718 + */
 10.3719 +const NVRAM_SCB_OFFSET	0x2C
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/xen/drivers/scsi/aic7xxx/aic79xx.seq	Mon Mar 24 16:44:31 2003 +0000
    11.3 @@ -0,0 +1,1723 @@
    11.4 +/*
    11.5 + * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD.
    11.6 + *
    11.7 + * Copyright (c) 1994-2001 Justin T. Gibbs.
    11.8 + * Copyright (c) 2000-2001 Adaptec Inc.
    11.9 + * All rights reserved.
   11.10 + *
   11.11 + * Redistribution and use in source and binary forms, with or without
   11.12 + * modification, are permitted provided that the following conditions
   11.13 + * are met:
   11.14 + * 1. Redistributions of source code must retain the above copyright
   11.15 + *    notice, this list of conditions, and the following disclaimer,
   11.16 + *    without modification.
   11.17 + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   11.18 + *    substantially similar to the "NO WARRANTY" disclaimer below
   11.19 + *    ("Disclaimer") and any redistribution must be conditioned upon
   11.20 + *    including a substantially similar Disclaimer requirement for further
   11.21 + *    binary redistribution.
   11.22 + * 3. Neither the names of the above-listed copyright holders nor the names
   11.23 + *    of any contributors may be used to endorse or promote products derived
   11.24 + *    from this software without specific prior written permission.
   11.25 + *
   11.26 + * Alternatively, this software may be distributed under the terms of the
   11.27 + * GNU General Public License ("GPL") version 2 as published by the Free
   11.28 + * Software Foundation.
   11.29 + *
   11.30 + * NO WARRANTY
   11.31 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   11.32 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   11.33 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   11.34 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   11.35 + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   11.36 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   11.37 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   11.38 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   11.39 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   11.40 + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   11.41 + * POSSIBILITY OF SUCH DAMAGES.
   11.42 + *
   11.43 + * $FreeBSD$
   11.44 + */
   11.45 +
   11.46 +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#42 $"
   11.47 +PATCH_ARG_LIST = "struct ahd_softc *ahd"
   11.48 +
   11.49 +#include "aic79xx.reg"
   11.50 +#include "scsi_message.h"
   11.51 +
   11.52 +idle_loop:
   11.53 +	SET_MODE(M_SCSI, M_SCSI);
   11.54 +	test	SCSISEQ0, ENSELO|ENARBO jnz idle_loop_checkbus;
   11.55 +	test	SEQ_FLAGS2, SELECTOUT_QFROZEN jnz idle_loop_checkbus;
   11.56 +	cmp	WAITING_TID_HEAD[1], SCB_LIST_NULL je idle_loop_checkbus;
   11.57 +	/*
   11.58 +	 * ENSELO is cleared by a SELDO, so we must test for SELDO
   11.59 +	 * one last time.
   11.60 +	 */
   11.61 +BEGIN_CRITICAL;
   11.62 +	test	SSTAT0, SELDO jnz select_out;
   11.63 +END_CRITICAL;
   11.64 +	call	start_selection;
   11.65 +idle_loop_checkbus:
   11.66 +BEGIN_CRITICAL;
   11.67 +	test	SSTAT0, SELDO jnz select_out;
   11.68 +END_CRITICAL;
   11.69 +	test	SSTAT0, SELDI jnz select_in;
   11.70 +	test	SCSIPHASE, ~DATA_PHASE_MASK jz idle_loop_check_nonpackreq;
   11.71 +	test	SCSISIGO, ATNO jz idle_loop_check_nonpackreq;
   11.72 +	call	unexpected_nonpkt_phase_find_ctxt;
   11.73 +idle_loop_check_nonpackreq:
   11.74 +	test	SSTAT2, NONPACKREQ jz idle_loop_scsi;
   11.75 +	call	unexpected_nonpkt_phase_find_ctxt;
   11.76 +idle_loop_scsi:
   11.77 +BEGIN_CRITICAL;
   11.78 +	test	LQISTAT2, LQIGSAVAIL jz idle_loop_service_fifos;
   11.79 +	/*
   11.80 +	 * We have received good status for this transaction.  There may
   11.81 +	 * still be data in our FIFOs draining to the host.  Setup
   11.82 +	 * monitoring of the draining process or complete the SCB.
   11.83 +	 */
   11.84 +good_status_IU_done:
   11.85 +	bmov	SCBPTR, GSFIFO, 2;
   11.86 +	clr	SCB_SCSI_STATUS;
   11.87 +	or	SCB_CONTROL, STATUS_RCVD;
   11.88 +
   11.89 +	/*
   11.90 +	 * Since this status did not consume a FIFO, we have to
   11.91 +	 * be a bit more dilligent in how we check for FIFOs pertaining
   11.92 +	 * to this transaction.  There are three states that a FIFO still
   11.93 +	 * transferring data may be in.
   11.94 +	 *
   11.95 +	 * 1) Configured and draining to the host, with a pending CLRCHN.
   11.96 +	 * 2) Configured and draining to the host, no pending CLRCHN.
   11.97 +	 * 3) Pending cfg4data, fifo not empty.
   11.98 +	 *
   11.99 +	 * For case 1, we assume that our DMA post of the completed command
  11.100 +	 * will occur after the FIFO finishes draining due to the higher
  11.101 +	 * priority of data FIFO transfers relative to command channel
  11.102 +	 * transfers.
  11.103 +	 *
  11.104 +	 * Case 2 can be detected by noticing that a longjmp is active for the
  11.105 +	 * FIFO and LONGJMP_SCB matches our SCB.  In this case, we allow
  11.106 +	 * the routine servicing the FIFO to complete the SCB.
  11.107 +	 * 
  11.108 +	 * Case 3 implies either a pending or yet to occur save data
  11.109 +	 * pointers for this same context in the other FIFO.  So, if
  11.110 +	 * we detect case 2, we will properly defer the post of the SCB
  11.111 +	 * and achieve the desired result.  The pending cfg4data will
  11.112 +	 * notice that status has been received and complete the SCB.
  11.113 +	 */
  11.114 +	test	SCB_SGPTR, SG_LIST_NULL jz good_status_check_fifos;
  11.115 +	/*
  11.116 +	 * All segments have been loaded (or no data transfer), so
  11.117 +	 * it is safe to complete the command.  Since this was a
  11.118 +	 * cheap command to check for completion, loop to see if
  11.119 +	 * more entries can be removed from the GSFIFO.
  11.120 +	 */
  11.121 +	call	complete;
  11.122 +END_CRITICAL;
  11.123 +	jmp	idle_loop_scsi;
  11.124 +BEGIN_CRITICAL;
  11.125 +good_status_check_fifos:
  11.126 +	clc;
  11.127 +	bmov	ARG_1, SCBPTR, 2;
  11.128 +	SET_MODE(M_DFF0, M_DFF0);
  11.129 +	call	check_fifo;
  11.130 +	jc	idle_loop_service_fifos;
  11.131 +	SET_MODE(M_DFF1, M_DFF1);
  11.132 +	call	check_fifo;
  11.133 +	jc	idle_loop_service_fifos;
  11.134 +	SET_MODE(M_SCSI, M_SCSI);
  11.135 +	call	queue_scb_completion;
  11.136 +END_CRITICAL;
  11.137 +idle_loop_service_fifos:
  11.138 +	SET_MODE(M_DFF0, M_DFF0);
  11.139 +	test	LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo;
  11.140 +	call	longjmp;
  11.141 +idle_loop_next_fifo:
  11.142 +	SET_MODE(M_DFF1, M_DFF1);
  11.143 +	test	LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_last_fifo_done;
  11.144 +	call	longjmp;
  11.145 +idle_loop_last_fifo_done:
  11.146 +	call	idle_loop_cchan;
  11.147 +	jmp	idle_loop;
  11.148 +
  11.149 +idle_loop_cchan:
  11.150 +	SET_MODE(M_CCHAN, M_CCHAN);
  11.151 +	test	CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle;
  11.152 +	test	CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog;
  11.153 +	test	CCSCBCTL, CCSCBDONE jz return;
  11.154 +	/* FALLTHROUGH */
  11.155 +scbdma_tohost_done:
  11.156 +	test	CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone;
  11.157 +	/*
  11.158 +	 * A complete SCB upload requires no intervention.
  11.159 +	 * The SCB is already on the COMPLETE_SCB list
  11.160 +	 * and its completion notification will now be
  11.161 +	 * handled just like any other SCB.
  11.162 +	 */
  11.163 +	and	CCSCBCTL, ~(CCARREN|CCSCBEN) ret;
  11.164 +fill_qoutfifo_dmadone:
  11.165 +	and	CCSCBCTL, ~(CCARREN|CCSCBEN);
  11.166 +	mvi	INTSTAT, CMDCMPLT;
  11.167 +	mvi	COMPLETE_SCB_DMAINPROG_HEAD[1], SCB_LIST_NULL;
  11.168 +	bmov	QOUTFIFO_NEXT_ADDR, SCBHADDR, 4;
  11.169 +	test	QOFF_CTLSTA, SDSCB_ROLLOVR jz return;
  11.170 +	bmov	QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4 ret;
  11.171 +
  11.172 +fetch_new_scb_inprog:
  11.173 +	test	CCSCBCTL, ARRDONE jz return;
  11.174 +fetch_new_scb_done:
  11.175 +	and	CCSCBCTL, ~(CCARREN|CCSCBEN);
  11.176 +	bmov	REG0, SCBPTR, 2;
  11.177 +	/* Update the next SCB address to download. */
  11.178 +	bmov	NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4;
  11.179 +	mvi	SCB_NEXT[1], SCB_LIST_NULL;
  11.180 +	mvi	SCB_NEXT2[1], SCB_LIST_NULL;
  11.181 +	/*
  11.182 +	 * SCBs that want to send messages are always
  11.183 +	 * queued independently.  This ensures that they
  11.184 +	 * are at the head of the SCB list to select out
  11.185 +	 * to a target and we will see the MK_MESSAGE flag.
  11.186 +	 */
  11.187 +	test	SCB_CONTROL, MK_MESSAGE jnz first_new_target_scb;
  11.188 +	shr	SINDEX, 3, SCB_SCSIID;
  11.189 +	and	SINDEX, ~0x1;
  11.190 +	mvi	SINDEX[1], (WAITING_SCB_TAILS >> 8);
  11.191 +	bmov	DINDEX, SINDEX, 2;
  11.192 +	bmov	SCBPTR, SINDIR, 2;
  11.193 +	bmov	DINDIR, REG0, 2;
  11.194 +	cmp	SCBPTR[1], SCB_LIST_NULL je first_new_target_scb;
  11.195 +	bmov	SCB_NEXT, REG0, 2;
  11.196 +fetch_new_scb_fini:
  11.197 +	/* Increment our position in the QINFIFO. */
  11.198 +	mov	NONE, SNSCB_QOFF ret;
  11.199 +first_new_target_scb:
  11.200 +	cmp	WAITING_TID_HEAD[1], SCB_LIST_NULL je first_new_scb;
  11.201 +	bmov	SCBPTR, WAITING_TID_TAIL, 2;
  11.202 +	bmov	SCB_NEXT2, REG0, 2;
  11.203 +	bmov	WAITING_TID_TAIL, REG0, 2;
  11.204 +	/* Increment our position in the QINFIFO. */
  11.205 +	mov	NONE, SNSCB_QOFF ret;
  11.206 +first_new_scb:
  11.207 +	bmov	WAITING_TID_HEAD, REG0, 2;
  11.208 +	bmov	WAITING_TID_TAIL, REG0, 2;
  11.209 +	/* Increment our position in the QINFIFO. */
  11.210 +	mov	NONE, SNSCB_QOFF ret;
  11.211 +
  11.212 +scbdma_idle:
  11.213 +	/*
  11.214 +	 * Give precedence to downloading new SCBs to execute
  11.215 +	 * unless select-outs are currently frozen.
  11.216 +	 * XXX Use a timer to prevent completion starvation.
  11.217 +	 */
  11.218 +	test	SEQ_FLAGS2, SELECTOUT_QFROZEN jnz . + 2;
  11.219 +BEGIN_CRITICAL;
  11.220 +	test	QOFF_CTLSTA, NEW_SCB_AVAIL jnz fetch_new_scb;
  11.221 +	cmp	COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne dma_complete_scb;
  11.222 +	cmp	COMPLETE_SCB_HEAD[1], SCB_LIST_NULL je return;
  11.223 +	/* FALLTHROUGH */
  11.224 +fill_qoutfifo:
  11.225 +	/*
  11.226 +	 * Keep track of the SCBs we are dmaing just
  11.227 +	 * in case the DMA fails or is aborted.
  11.228 +	 */
  11.229 +	bmov	COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2;
  11.230 +	mvi	CCSCBCTL, CCSCBRESET;
  11.231 +	bmov	SCBHADDR, QOUTFIFO_NEXT_ADDR, 4;
  11.232 +	bmov	CCSCBRAM, COMPLETE_SCB_HEAD, 2;
  11.233 +	bmov	SCBPTR, COMPLETE_SCB_HEAD, 2;
  11.234 +	jmp	fill_qoutfifo_first_entry;
  11.235 +fill_qoutfifo_loop:
  11.236 +	bmov	CCSCBRAM, SCB_NEXT_COMPLETE, 2;
  11.237 +	bmov	SCBPTR, SCB_NEXT_COMPLETE, 2;
  11.238 +fill_qoutfifo_first_entry:
  11.239 +	mov	NONE, SDSCB_QOFF;
  11.240 +	cmp	SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done;
  11.241 +	cmp	CCSCBADDR, CCSCBADDR_MAX je fill_qoutfifo_done;
  11.242 +	test	QOFF_CTLSTA, SDSCB_ROLLOVR jz fill_qoutfifo_loop;
  11.243 +fill_qoutfifo_done:
  11.244 +	mov	SCBHCNT, CCSCBADDR;
  11.245 +	mvi	CCSCBCTL, CCSCBEN|CCSCBRESET;
  11.246 +	bmov	COMPLETE_SCB_HEAD, SCB_NEXT_COMPLETE, 2;
  11.247 +	mvi	SCB_NEXT_COMPLETE[1], SCB_LIST_NULL ret;
  11.248 +
  11.249 +fetch_new_scb:
  11.250 +	bmov	SCBHADDR, NEXT_QUEUED_SCB_ADDR, 4;
  11.251 +	mvi	CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET jmp dma_scb;
  11.252 +dma_complete_scb:
  11.253 +	bmov	SCBPTR, COMPLETE_DMA_SCB_HEAD, 2;
  11.254 +	bmov	SCBHADDR, SCB_BUSADDR, 4;
  11.255 +	mvi	CCARREN|CCSCBEN|CCSCBRESET call dma_scb;
  11.256 +	/*
  11.257 +	 * Now that we've started the DMA, push us onto
  11.258 +	 * the normal completion queue to have our SCBID
  11.259 +	 * posted to the kernel.
  11.260 +	 */
  11.261 +	bmov	COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;
  11.262 +	bmov	SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
  11.263 +	bmov	COMPLETE_SCB_HEAD, SCBPTR, 2 ret;
  11.264 +END_CRITICAL;
  11.265 +
  11.266 +/*
  11.267 + * Either post or fetch an SCB from host memory.  The caller
  11.268 + * is responsible for polling for transfer completion.
  11.269 + *
  11.270 + * Prerequisits: Mode == M_CCHAN
  11.271 + *		 SINDEX contains CCSCBCTL flags
  11.272 + *		 SCBHADDR set to Host SCB address
  11.273 + *		 SCBPTR set to SCB src location on "push" operations
  11.274 + */
  11.275 +SET_SRC_MODE	M_CCHAN;
  11.276 +SET_DST_MODE	M_CCHAN;
  11.277 +dma_scb:
  11.278 +	mvi	SCBHCNT, SCB_TRANSFER_SIZE;
  11.279 +	mov	CCSCBCTL, SINDEX;
  11.280 +	or	SEQ_FLAGS2, SCB_DMA ret;
  11.281 +
  11.282 +BEGIN_CRITICAL;
  11.283 +setjmp_setscb:
  11.284 +	bmov	LONGJMP_SCB, SCBPTR, 2;
  11.285 +setjmp:
  11.286 +	bmov	LONGJMP_ADDR, STACK, 2 ret;
  11.287 +setjmp_inline:
  11.288 +	bmov	LONGJMP_ADDR, STACK, 2;
  11.289 +longjmp:
  11.290 +	bmov	STACK, LONGJMP_ADDR, 2 ret;
  11.291 +END_CRITICAL;
  11.292 +
  11.293 +/************************ Packetized LongJmp Routines *************************/
  11.294 +/*
  11.295 + * Must disable interrupts when setting the mode pointer
  11.296 + * register as an interrupt occurring mid update will
  11.297 + * fail to store the new mode value for restoration on
  11.298 + * an iret.
  11.299 + */
  11.300 +set_mode_work_around:
  11.301 +	mvi	SEQINTCTL, INTVEC1DSL;
  11.302 +	mov	MODE_PTR, SINDEX;
  11.303 +	clr	SEQINTCTL ret;
  11.304 +
  11.305 +SET_SRC_MODE	M_SCSI;
  11.306 +SET_DST_MODE	M_SCSI;
  11.307 +start_selection:
  11.308 +BEGIN_CRITICAL;
  11.309 +	if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) {
  11.310 +		/*
  11.311 +		 * Razor #494
  11.312 +		 * Rev A hardware fails to update LAST/CURR/NEXTSCB
  11.313 +		 * correctly after a packetized selection in several
  11.314 +		 * situations:
  11.315 +		 *
  11.316 +		 * 1) If only one command existed in the the queue, the
  11.317 +		 *    LAST/CURR/NEXTSCB are unchanged.
  11.318 +		 *
  11.319 +		 * 2) In a non QAS, protocol allowed phase change,
  11.320 +		 *    the queue is shifted 1 too far.  LASTSCB is
  11.321 +		 *    the last SCB that was correctly processed.
  11.322 +		 * 
  11.323 +		 * 3) In the QAS case, if the full list of commands
  11.324 +		 *    was successfully sent, NEXTSCB is NULL and neither
  11.325 +		 *    CURRSCB nor LASTSCB can be trusted.  We must
  11.326 +		 *    manually walk the list counting MAXCMDCNT elements
  11.327 +		 *    to find the last SCB that was sent correctly.
  11.328 +		 *
  11.329 +		 * To simplify the workaround for this bug in SELDO
  11.330 +		 * handling, we initialize LASTSCB prior to enabling
  11.331 +		 * selection so we can rely on it even for case #1 above.
  11.332 +		 */
  11.333 +		bmov	LASTSCB, WAITING_TID_HEAD, 2;
  11.334 +	}
  11.335 +	bmov	CURRSCB, WAITING_TID_HEAD, 2;
  11.336 +	bmov	SCBPTR, WAITING_TID_HEAD, 2;
  11.337 +	shr	SELOID, 4, SCB_SCSIID;
  11.338 +	/*
  11.339 +	 * If we want to send a message to the device, ensure
  11.340 +	 * we are selecting with atn irregardless of our packetized
  11.341 +	 * agreement.  Since SPI4 only allows target reset or PPR
  11.342 +	 * messages if this is a packetized connection, the change
  11.343 +	 * to our negotiation table entry for this selection will
  11.344 +	 * be cleared when the message is acted on.
  11.345 +	 */
  11.346 +	test	SCB_CONTROL, MK_MESSAGE jz . + 3;
  11.347 +	mov	NEGOADDR, SELOID;
  11.348 +	or	NEGCONOPTS, ENAUTOATNO;
  11.349 +	or	SCSISEQ0, ENSELO ret;
  11.350 +END_CRITICAL;
  11.351 +
  11.352 +/*
  11.353 + * Allocate a FIFO for a non-packetized transaction.
  11.354 + * For some reason unkown to me, both FIFOs must be free before we
  11.355 + * can allocate a FIFO for a non-packetized transaction.  This
  11.356 + * may be fixed in Rev B.
  11.357 + */
  11.358 +allocate_fifo_loop:
  11.359 +	/*
  11.360 +	 * Do whatever work is required to free a FIFO.
  11.361 +	 */
  11.362 +	SET_MODE(M_DFF0, M_DFF0);
  11.363 +	test	LONGJMP_ADDR[1], INVALID_ADDR jnz . + 2;
  11.364 +	call	longjmp;
  11.365 +	SET_MODE(M_DFF1, M_DFF1);
  11.366 +	test	LONGJMP_ADDR[1], INVALID_ADDR jnz . + 2;
  11.367 +	call	longjmp;
  11.368 +	SET_MODE(M_SCSI, M_SCSI);
  11.369 +allocate_fifo:
  11.370 +	and	A, FIFO0FREE|FIFO1FREE, DFFSTAT;
  11.371 +	cmp	A, FIFO0FREE|FIFO1FREE jne allocate_fifo_loop;
  11.372 +take_fifo:
  11.373 +	bmov	ARG_1, SCBPTR, 2;
  11.374 +	or	DFFSTAT, CURRFIFO;
  11.375 +	SET_MODE(M_DFF1, M_DFF1);
  11.376 +	bmov	SCBPTR, ARG_1, 2 ret;
  11.377 +
  11.378 +/*
  11.379 + * We have been reselected as an initiator
  11.380 + * or selected as a target.
  11.381 + */
  11.382 +SET_SRC_MODE	M_SCSI;
  11.383 +SET_DST_MODE	M_SCSI;
  11.384 +select_in:
  11.385 +	or	SXFRCTL0, SPIOEN;
  11.386 +	and	SAVED_SCSIID, SELID_MASK, SELID;
  11.387 +	and	A, OID, IOWNID;
  11.388 +	or	SAVED_SCSIID, A;
  11.389 +	mvi	CLRSINT0, CLRSELDI;
  11.390 +	jmp	ITloop;
  11.391 +
  11.392 +/*
  11.393 + * We have successfully selected out.
  11.394 + *
  11.395 + * Clear SELDO.
  11.396 + * Dequeue all SCBs sent from the waiting queue
  11.397 + * Requeue all SCBs *not* sent to the tail of the waiting queue
  11.398 + * Take Razor #494 into account for above.
  11.399 + *
  11.400 + * In Packetized Mode:
  11.401 + *	Return to the idle loop.  Our interrupt handler will take
  11.402 + *	care of any incoming L_Qs.
  11.403 + *
  11.404 + * In Non-Packetize Mode:
  11.405 + *	Continue to our normal state machine.
  11.406 + */
  11.407 +SET_SRC_MODE	M_SCSI;
  11.408 +SET_DST_MODE	M_SCSI;
  11.409 +select_out:
  11.410 +BEGIN_CRITICAL;
  11.411 +	/* Clear out all SCBs that have been successfully sent. */
  11.412 +	if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) {
  11.413 +		/*
  11.414 +		 * For packetized, the LQO manager clears ENSELO on
  11.415 +		 * the assertion of SELDO.  If we are non-packetized,
  11.416 +		 * LASTSCB and CURRSCB are acuate.
  11.417 +		 */
  11.418 +		test	SCSISEQ0, ENSELO jnz use_lastscb;
  11.419 +
  11.420 +		/*
  11.421 +		 * The update is correct for LQOSTAT1 errors.  All
  11.422 +		 * but LQOBUSFREE are handled by kernel interrupts.
  11.423 +		 * If we see LQOBUSFREE, return to the idle loop.
  11.424 +		 * Once we are out of the select_out critical section,
  11.425 +		 * the kernel will cleanup the LQOBUSFREE and we will
  11.426 +		 * eventually restart the selection if appropriate.
  11.427 +		 */
  11.428 +		test	LQOSTAT1, LQOBUSFREE jnz idle_loop;
  11.429 +
  11.430 +		/*
  11.431 +		 * On a phase change oustside of packet boundaries,
  11.432 +		 * LASTSCB points to the currently active SCB context
  11.433 +		 * on the bus.
  11.434 +		 */
  11.435 +		test	LQOSTAT2, LQOPHACHGOUTPKT jnz use_lastscb;
  11.436 +
  11.437 +		/*
  11.438 +		 * If the hardware has traversed the whole list, NEXTSCB
  11.439 +		 * will be NULL, CURRSCB and LASTSCB cannot be trusted,
  11.440 +		 * but MAXCMDCNT is accurate.  If we stop part way through
  11.441 +		 * the list or only had one command to issue, NEXTSCB[1] is
  11.442 +		 * not NULL and LASTSCB is the last command to go out.
  11.443 +		 */
  11.444 +		cmp	NEXTSCB[1], SCB_LIST_NULL jne use_lastscb;
  11.445 +
  11.446 +		/*
  11.447 +		 * Brute force walk.
  11.448 +		 */
  11.449 +		bmov	SCBPTR, WAITING_TID_HEAD, 2;
  11.450 +		mvi	SEQINTCTL, INTVEC1DSL;
  11.451 +		mvi	MODE_PTR, MK_MODE(M_CFG, M_CFG);
  11.452 +		mov	A, MAXCMDCNT;
  11.453 +		mvi	MODE_PTR, MK_MODE(M_SCSI, M_SCSI);
  11.454 +		clr	SEQINTCTL;
  11.455 +find_lastscb_loop:
  11.456 +		dec	A;
  11.457 +		test	A, 0xFF jz found_last_sent_scb;
  11.458 +		bmov	SCBPTR, SCB_NEXT, 2;
  11.459 +		jmp	find_lastscb_loop;
  11.460 +use_lastscb:
  11.461 +		bmov	SCBPTR, LASTSCB, 2;
  11.462 +found_last_sent_scb:
  11.463 +		bmov	CURRSCB, SCBPTR, 2;
  11.464 +curscb_ww_done:
  11.465 +	} else {
  11.466 +		/*
  11.467 +		 * Untested - Verify with Rev B.
  11.468 +		 */
  11.469 +		bmov	SCBPTR, CURRSCB, 2;
  11.470 +	}
  11.471 +	/*
  11.472 +	 * Requeue any SCBs not sent, to the tail of the waiting Q.
  11.473 +	 */
  11.474 +	cmp	SCB_NEXT[1], SCB_LIST_NULL je select_out_list_done;
  11.475 +
  11.476 +	/*
  11.477 +	 * We know that neither the per-TID list nor the list of
  11.478 +	 * TIDs is empty.  Use this knowledge to our advantage.
  11.479 +	 */
  11.480 +	bmov	REG0, SCB_NEXT, 2;
  11.481 +	bmov	SCBPTR, WAITING_TID_TAIL, 2;
  11.482 +	bmov	SCB_NEXT2, REG0, 2;
  11.483 +	bmov	WAITING_TID_TAIL, REG0, 2;
  11.484 +	jmp	select_out_inc_tid_q;
  11.485 +
  11.486 +select_out_list_done:
  11.487 +	/*
  11.488 +	 * The whole list made it.  Just clear our TID's tail pointer
  11.489 +	 * unless we were queued independently due to our need to
  11.490 +	 * send a message.
  11.491 +	 */
  11.492 +	test	SCB_CONTROL, MK_MESSAGE jnz select_out_inc_tid_q;
  11.493 +	shr	DINDEX, 3, SCB_SCSIID;
  11.494 +/* XXX When we switch to SCB_SELOID, put +1 in addition below. */
  11.495 +	or	DINDEX, 1;	/* Want only the second byte */
  11.496 +	mvi	DINDEX[1], ((WAITING_SCB_TAILS) >> 8);
  11.497 +	mvi	DINDIR, SCB_LIST_NULL;
  11.498 +select_out_inc_tid_q:
  11.499 +	bmov	SCBPTR, WAITING_TID_HEAD, 2;
  11.500 +	bmov	WAITING_TID_HEAD, SCB_NEXT2, 2;
  11.501 +	cmp	WAITING_TID_HEAD[1], SCB_LIST_NULL jne . + 2;
  11.502 +	mvi	WAITING_TID_TAIL[1], SCB_LIST_NULL;
  11.503 +	bmov	SCBPTR, CURRSCB, 2;
  11.504 +END_CRITICAL;
  11.505 +
  11.506 +	mvi	CLRSINT0, CLRSELDO;
  11.507 +
  11.508 +	test	LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_phase;
  11.509 +	test	LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_phase;
  11.510 +
  11.511 +	/*
  11.512 +	 * If this is a packetized connection, return to our
  11.513 +	 * idle_loop and let our interrupt handler deal with
  11.514 +	 * any connection setup/teardown issues.  The only
  11.515 +	 * exception is the case of MK_MESSAGE SCBs.  In the
  11.516 +	 * A, the LQO manager transitions to LQOSTOP0 even if
  11.517 +	 * we have selected out with ATN asserted and the target
  11.518 +	 * REQs in a non-packet phase.
  11.519 +	 */
  11.520 +	if ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0) {
  11.521 +		test 	SCB_CONTROL, MK_MESSAGE jz select_out_no_message;
  11.522 +		test	SCSISIGO, ATNO jnz select_out_non_packetized;
  11.523 +select_out_no_message:
  11.524 +	}
  11.525 +	test	LQOSTAT2, LQOSTOP0 jnz idle_loop;
  11.526 +
  11.527 +select_out_non_packetized:
  11.528 +	/* Non packetized request. */
  11.529 +	and     SCSISEQ0, ~ENSELO;
  11.530 +	mov	SAVED_SCSIID, SCB_SCSIID;
  11.531 +	mov	SAVED_LUN, SCB_LUN;
  11.532 +	or	SXFRCTL0, SPIOEN;
  11.533 +
  11.534 +	/*
  11.535 +	 * As soon as we get a successful selection, the target
  11.536 +	 * should go into the message out phase since we have ATN
  11.537 +	 * asserted.
  11.538 +	 */
  11.539 +	mvi	MSG_OUT, MSG_IDENTIFYFLAG;
  11.540 +	mvi	SEQ_FLAGS, NO_CDB_SENT;
  11.541 +
  11.542 +	/*
  11.543 +	 * Main loop for information transfer phases.  Wait for the
  11.544 +	 * target to assert REQ before checking MSG, C/D and I/O for
  11.545 +	 * the bus phase.
  11.546 +	 */
  11.547 +mesgin_phasemis:
  11.548 +ITloop:
  11.549 +	call	phase_lock;
  11.550 +
  11.551 +	mov	A, LASTPHASE;
  11.552 +
  11.553 +	test	A, ~P_DATAIN_DT	jz p_data;
  11.554 +	cmp	A,P_COMMAND	je p_command;
  11.555 +	cmp	A,P_MESGOUT	je p_mesgout;
  11.556 +	cmp	A,P_STATUS	je p_status;
  11.557 +	cmp	A,P_MESGIN	je p_mesgin;
  11.558 +
  11.559 +	mvi	SEQINTCODE, BAD_PHASE;
  11.560 +	jmp	ITloop;			/* Try reading the bus again. */
  11.561 +
  11.562 +/*
  11.563 + * Command phase.  Set up the DMA registers and let 'er rip.
  11.564 + */
  11.565 +p_command:
  11.566 +SET_SRC_MODE	M_DFF1;
  11.567 +SET_DST_MODE	M_DFF1;
  11.568 +	test	MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))
  11.569 +		jnz p_command_allocate_fifo;
  11.570 +	/*
  11.571 +	 * Command retry.  Free our current FIFO and
  11.572 +	 * re-allocate a FIFO so transfer state is
  11.573 +	 * reset.
  11.574 +	 */
  11.575 +	mvi	DFFSXFRCTL, RSTCHN|CLRSHCNT;
  11.576 +p_command_allocate_fifo:
  11.577 +	call	allocate_fifo;
  11.578 +	add	NONE, -17, SCB_CDB_LEN;
  11.579 +	jnc	p_command_embedded;
  11.580 +p_command_from_host:
  11.581 +	bmov	HADDR[0], SCB_CDB_PTR, 11;
  11.582 +	mvi	SG_CACHE_PRE, LAST_SEG;
  11.583 +	mvi	DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN);
  11.584 +	jmp	p_command_loop;
  11.585 +p_command_embedded:
  11.586 +	bmov	SHCNT[0], SCB_CDB_LEN,  1;
  11.587 +	bmov	SHCNT[1], ALLZEROS, 2;
  11.588 +	bmov	DFDAT, SCB_CDB_STORE, 16; 
  11.589 +	mvi	DFCNTRL, SCSIEN;
  11.590 +p_command_loop:
  11.591 +	test	DFCNTRL, SCSIEN jnz p_command_loop;
  11.592 +	/*
  11.593 +	 * DMA Channel automatically disabled.
  11.594 +	 * Don't allow a data phase if the command
  11.595 +	 * was not fully transferred.  Make sure that
  11.596 +	 * we clear the IDENTIFY SEEN flag if a retry
  11.597 +	 * falls short too.
  11.598 +	 */
  11.599 +	and	SEQ_FLAGS, ~NO_CDB_SENT;
  11.600 +	test	SSTAT2, SDONE jnz ITloop;
  11.601 +	or	SEQ_FLAGS, NO_CDB_SENT;
  11.602 +	jmp	ITloop;
  11.603 +
  11.604 +
  11.605 +/*
  11.606 + * Status phase.  Wait for the data byte to appear, then read it
  11.607 + * and store it into the SCB.
  11.608 + */
  11.609 +SET_SRC_MODE	M_SCSI;
  11.610 +SET_DST_MODE	M_SCSI;
  11.611 +p_status:
  11.612 +	test	SEQ_FLAGS,NOT_IDENTIFIED jz p_status_okay;
  11.613 +	mvi	SEQINTCODE, PROTO_VIOLATION;
  11.614 +	jmp	mesgin_done;
  11.615 +p_status_okay:
  11.616 +	mov	SCB_SCSI_STATUS, SCSIDAT;
  11.617 +	or	SCB_CONTROL, STATUS_RCVD;
  11.618 +	jmp	ITloop;
  11.619 +
  11.620 +/*
  11.621 + * Message out phase.  If MSG_OUT is MSG_IDENTIFYFLAG, build a full
  11.622 + * indentify message sequence and send it to the target.  The host may
  11.623 + * override this behavior by setting the MK_MESSAGE bit in the SCB
  11.624 + * control byte.  This will cause us to interrupt the host and allow
  11.625 + * it to handle the message phase completely on its own.  If the bit
  11.626 + * associated with this target is set, we will also interrupt the host,
  11.627 + * thereby allowing it to send a message on the next selection regardless
  11.628 + * of the transaction being sent.
  11.629 + * 
  11.630 + * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message.
  11.631 + * This is done to allow the host to send messages outside of an identify
  11.632 + * sequence while protecting the seqencer from testing the MK_MESSAGE bit
  11.633 + * on an SCB that might not be for the current nexus. (For example, a
  11.634 + * BDR message in responce to a bad reselection would leave us pointed to
  11.635 + * an SCB that doesn't have anything to do with the current target).
  11.636 + *
  11.637 + * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag,
  11.638 + * bus device reset).
  11.639 + *
  11.640 + * When there are no messages to send, MSG_OUT should be set to MSG_NOOP,
  11.641 + * in case the target decides to put us in this phase for some strange
  11.642 + * reason.
  11.643 + */
  11.644 +p_mesgout_retry:
  11.645 +	/* Turn on ATN for the retry */
  11.646 +	mvi	SCSISIGO, ATNO;
  11.647 +p_mesgout:
  11.648 +	mov	SINDEX, MSG_OUT;
  11.649 +	cmp	SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host;
  11.650 +	test	SCB_CONTROL,MK_MESSAGE	jnz host_message_loop;
  11.651 +p_mesgout_identify:
  11.652 +	or	SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN;
  11.653 +	test	SCB_CONTROL, DISCENB jnz . + 2;
  11.654 +	and	SINDEX, ~DISCENB;
  11.655 +/*
  11.656 + * Send a tag message if TAG_ENB is set in the SCB control block.
  11.657 + * Use SCB_NONPACKET_TAG as the tag value.
  11.658 + */
  11.659 +p_mesgout_tag:
  11.660 +	test	SCB_CONTROL,TAG_ENB jz  p_mesgout_onebyte;
  11.661 +	mov	SCSIDAT, SINDEX;	/* Send the identify message */
  11.662 +	call	phase_lock;
  11.663 +	cmp	LASTPHASE, P_MESGOUT	jne p_mesgout_done;
  11.664 +	and	SCSIDAT,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL;
  11.665 +	call	phase_lock;
  11.666 +	cmp	LASTPHASE, P_MESGOUT	jne p_mesgout_done;
  11.667 +	mov	SCB_NONPACKET_TAG jmp p_mesgout_onebyte;
  11.668 +/*
  11.669 + * Interrupt the driver, and allow it to handle this message
  11.670 + * phase and any required retries.
  11.671 + */
  11.672 +p_mesgout_from_host:
  11.673 +	cmp	SINDEX, HOST_MSG	jne p_mesgout_onebyte;
  11.674 +	jmp	host_message_loop;
  11.675 +
  11.676 +p_mesgout_onebyte:
  11.677 +	mvi	CLRSINT1, CLRATNO;
  11.678 +	mov	SCSIDAT, SINDEX;
  11.679 +
  11.680 +/*
  11.681 + * If the next bus phase after ATN drops is message out, it means
  11.682 + * that the target is requesting that the last message(s) be resent.
  11.683 + */
  11.684 +	call	phase_lock;
  11.685 +	cmp	LASTPHASE, P_MESGOUT	je p_mesgout_retry;
  11.686 +
  11.687 +p_mesgout_done:
  11.688 +	mvi	CLRSINT1,CLRATNO;	/* Be sure to turn ATNO off */
  11.689 +	mov	LAST_MSG, MSG_OUT;
  11.690 +	mvi	MSG_OUT, MSG_NOOP;	/* No message left */
  11.691 +	jmp	ITloop;
  11.692 +
  11.693 +/*
  11.694 + * Message in phase.  Bytes are read using Automatic PIO mode.
  11.695 + */
  11.696 +p_mesgin:
  11.697 +	/* read the 1st message byte */
  11.698 +	mvi	ACCUM		call inb_first;
  11.699 +
  11.700 +	test	A,MSG_IDENTIFYFLAG	jnz mesgin_identify;
  11.701 +	cmp	A,MSG_DISCONNECT	je mesgin_disconnect;
  11.702 +	cmp	A,MSG_SAVEDATAPOINTER	je mesgin_sdptrs;
  11.703 +	cmp	ALLZEROS,A		je mesgin_complete;
  11.704 +	cmp	A,MSG_RESTOREPOINTERS	je mesgin_rdptrs;
  11.705 +	cmp	A,MSG_IGN_WIDE_RESIDUE	je mesgin_ign_wide_residue;
  11.706 +	cmp	A,MSG_NOOP		je mesgin_done;
  11.707 +
  11.708 +/*
  11.709 + * Pushed message loop to allow the kernel to
  11.710 + * run it's own message state engine.  To avoid an
  11.711 + * extra nop instruction after signaling the kernel,
  11.712 + * we perform the phase_lock before checking to see
  11.713 + * if we should exit the loop and skip the phase_lock
  11.714 + * in the ITloop.  Performing back to back phase_locks
  11.715 + * shouldn't hurt, but why do it twice...
  11.716 + */
  11.717 +host_message_loop:
  11.718 +	call	phase_lock;	/* Benign the first time through. */
  11.719 +	mvi	SEQINTCODE, HOST_MSG_LOOP;
  11.720 +	cmp	RETURN_1, EXIT_MSG_LOOP	je ITloop;
  11.721 +	cmp	RETURN_1, CONT_MSG_LOOP_WRITE	jne . + 3;
  11.722 +	mov	SCSIDAT, RETURN_2;
  11.723 +	jmp	host_message_loop;
  11.724 +	/* Must be CONT_MSG_LOOP_READ */
  11.725 +	mov	NONE, SCSIDAT;	/* ACK Byte */
  11.726 +	jmp	host_message_loop;
  11.727 +
  11.728 +mesgin_ign_wide_residue:
  11.729 +	shr	NEGOADDR, 4, SAVED_SCSIID;
  11.730 +	test	NEGCONOPTS, WIDEXFER jz mesgin_reject;
  11.731 +	/* Pull the residue byte */
  11.732 +	mvi	REG0	call inb_next;
  11.733 +	cmp	REG0, 0x01 jne mesgin_reject;
  11.734 +	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2;
  11.735 +	test	DATA_COUNT_ODD, 0x1	jz mesgin_done;
  11.736 +	mvi	SEQINTCODE, IGN_WIDE_RES;
  11.737 +	jmp	mesgin_done;
  11.738 +
  11.739 +mesgin_reject:
  11.740 +	mvi	MSG_MESSAGE_REJECT	call mk_mesg;
  11.741 +mesgin_done:
  11.742 +	mov	NONE,SCSIDAT;		/*dummy read from latch to ACK*/
  11.743 +	jmp	ITloop;
  11.744 +
  11.745 +#define INDEX_DISC_LIST_SCB(target, lun)				\
  11.746 +	mov	SCBPTR, lun;						\
  11.747 +	shr	SCBPTR[1], 3, target
  11.748 +	
  11.749 +#define INDEX_DISC_LIST(target, lun)					\
  11.750 +	INDEX_DISC_LIST_SCB(target, lun);				\
  11.751 +	and	SINDEX, 0x7, target;					\
  11.752 +	shl	SINDEX, 1;						\
  11.753 +	add	SINDEX, (SCB_DISCONNECTED_LISTS & 0xFF);		\
  11.754 +	mvi	SINDEX[1], ((SCB_DISCONNECTED_LISTS >> 8) & 0xFF)
  11.755 +
  11.756 +mesgin_identify:
  11.757 +	/*
  11.758 +	 * Determine whether a target is using tagged or non-tagged
  11.759 +	 * transactions by first looking at the transaction stored in
  11.760 +	 * the per-device, disconnected array.  If there is no untagged
  11.761 +	 * transaction for this target this must be an untagged transaction.
  11.762 +	 */
  11.763 +	shr	SINDEX, 4, SAVED_SCSIID;
  11.764 +	and	SAVED_LUN, MSG_IDENTIFY_LUNMASK, A;
  11.765 +	INDEX_DISC_LIST(SINDEX, SAVED_LUN);
  11.766 +	bmov	DINDEX, SINDEX, 2;
  11.767 +	bmov	SCBPTR, SINDIR, 2;
  11.768 +	cmp	SCBPTR[1], SCB_LIST_NULL je snoop_tag;
  11.769 +	test	SCB_CONTROL, TAG_ENB jnz snoop_tag;
  11.770 +	/* Untagged.  Setup the SCB. */
  11.771 +	bmov	REG1, SCB_TAG, 4;	/* Save SCB_TAG and SCB_NEXT */
  11.772 +	jmp dequeue_first_scb;
  11.773 +
  11.774 +/*
  11.775 + * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message.
  11.776 + * If we get one, we use the tag returned to find the proper
  11.777 + * SCB.  The disconnected list contains any outstanding tagged transactions
  11.778 + * where SCB_TAG != SCB_NONPACKET_TAG or SCB_NONPACKET_TAG + 256.
  11.779 + * After receiving the tag, look for the SCB at SCB locations tag and
  11.780 + * tag + 256.  If those SCBs do not match, traverse the disconnected
  11.781 + * list until we find the correct SCB.
  11.782 + */
  11.783 +snoop_tag:
  11.784 +	if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {
  11.785 +		or	SEQ_FLAGS, 0x80;
  11.786 +	}
  11.787 +	mov	NONE, SCSIDAT;		/* ACK Identify MSG */
  11.788 +	call	phase_lock;
  11.789 +	if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {
  11.790 +		or	SEQ_FLAGS, 0x1;
  11.791 +	}
  11.792 +	cmp	LASTPHASE, P_MESGIN	jne not_found_ITloop;
  11.793 +	if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {
  11.794 +		or	SEQ_FLAGS, 0x2;
  11.795 +	}
  11.796 +	cmp	SCSIBUS, MSG_SIMPLE_Q_TAG jne not_found;
  11.797 +get_tag:
  11.798 +	/* Save diconnected list head. */
  11.799 +	bmov	REG0, SCBPTR, 2;
  11.800 +	clr	SCBPTR[1];
  11.801 +	mvi	SCBPTR	call inb_next;	/* tag value */
  11.802 +	mov	REG1, SCBPTR;
  11.803 +verify_scb:
  11.804 +	mov	A, REG1;
  11.805 +	cmp	SCB_NONPACKET_TAG, A jne verify_other_scb;
  11.806 +	mov	A, SAVED_SCSIID;
  11.807 +	cmp	SCB_SCSIID, A jne verify_other_scb;
  11.808 +	mov	A, SAVED_LUN;
  11.809 +	cmp	SCB_LUN, A je setup_SCB;
  11.810 +verify_other_scb:
  11.811 +	xor	SCBPTR[1], 1;
  11.812 +	test	SCBPTR[1], 0xFF jnz verify_scb;
  11.813 +
  11.814 +search_disc_list:
  11.815 +	/* Restore disconnected list head. */
  11.816 +	bmov	SCBPTR, REG0, 2;
  11.817 +	mvi	REG0[1], SCB_LIST_NULL;
  11.818 +	mov	A, REG1;
  11.819 +search_disc_list_loop:
  11.820 +	cmp	SCB_NONPACKET_TAG, A je dequeue_scb;
  11.821 +	bmov	REG0, SCBPTR, 2;
  11.822 +	bmov	SCBPTR, SCB_NEXT, 2;
  11.823 +	cmp	SCBPTR[1], SCB_LIST_NULL jne search_disc_list_loop;
  11.824 +	jmp	not_found;
  11.825 +
  11.826 +dequeue_scb:
  11.827 +	bmov	REG1, SCB_TAG, 4;	/* Save SCB_TAG and SCB_NEXT */
  11.828 +	cmp	REG0[1], SCB_LIST_NULL jne dequeue_intermediate_SCB;
  11.829 +dequeue_first_scb:
  11.830 +	shr	SINDEX, 4, SAVED_SCSIID;
  11.831 +	INDEX_DISC_LIST_SCB(SINDEX, SAVED_LUN);
  11.832 +	/* Update list head. */
  11.833 +	bmov	DINDIR, REG2, 2;
  11.834 +	jmp	dequeue_restore;
  11.835 +dequeue_intermediate_SCB:
  11.836 +	bmov	SCBPTR, REG0, 2;
  11.837 +	bmov	SCB_NEXT, REG2, 2;
  11.838 +dequeue_restore:
  11.839 +	bmov	SCBPTR, REG1, 2;
  11.840 +
  11.841 +/*
  11.842 + * Ensure that the SCB the tag points to is for
  11.843 + * an SCB transaction to the reconnecting target.
  11.844 + */
  11.845 +setup_SCB:
  11.846 +	if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {
  11.847 +		or	SEQ_FLAGS, 0x10;
  11.848 +	}
  11.849 +	test	SCB_CONTROL,DISCONNECTED jz not_found;
  11.850 +	and	SCB_CONTROL,~DISCONNECTED;
  11.851 +	clr	SEQ_FLAGS;	/* make note of IDENTIFY */
  11.852 +	test	SCB_SGPTR, SG_LIST_NULL jnz . + 2;
  11.853 +	call	allocate_fifo;
  11.854 +/*	mvi	SEQINTCODE, PRINT_RESIDUALS; */
  11.855 +	/* See if the host wants to send a message upon reconnection */
  11.856 +	test	SCB_CONTROL, MK_MESSAGE jz mesgin_done;
  11.857 +	mvi	HOST_MSG	call mk_mesg;
  11.858 +	jmp	mesgin_done;
  11.859 +
  11.860 +not_found:
  11.861 +	mvi	SEQINTCODE, NO_MATCH;
  11.862 +	jmp	mesgin_done;
  11.863 +
  11.864 +not_found_ITloop:
  11.865 +	mvi	SEQINTCODE, NO_MATCH;
  11.866 +	jmp	ITloop;
  11.867 +
  11.868 +/*
  11.869 + * We received a "command complete" message.  Put the SCB on the complete
  11.870 + * queue and trigger a completion interrupt via the idle loop.  Before doing
  11.871 + * so, check to see if there
  11.872 + * is a residual or the status byte is something other than STATUS_GOOD (0).
  11.873 + * In either of these conditions, we upload the SCB back to the host so it can
  11.874 + * process this information.  In the case of a non zero status byte, we 
  11.875 + * additionally interrupt the kernel driver synchronously, allowing it to
  11.876 + * decide if sense should be retrieved.  If the kernel driver wishes to request
  11.877 + * sense, it will fill the kernel SCB with a request sense command, requeue
  11.878 + * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting 
  11.879 + * RETURN_1 to SEND_SENSE.
  11.880 + */
  11.881 +mesgin_complete:
  11.882 +
  11.883 +	/*
  11.884 +	 * If ATN is raised, we still want to give the target a message.
  11.885 +	 * Perhaps there was a parity error on this last message byte.
  11.886 +	 * Either way, the target should take us to message out phase
  11.887 +	 * and then attempt to complete the command again.  We should use a
  11.888 +	 * critical section here to guard against a timeout triggering
  11.889 +	 * for this command and setting ATN while we are still processing
  11.890 +	 * the completion.
  11.891 +	test	SCSISIGI, ATNI jnz mesgin_done;
  11.892 +	 */
  11.893 +
  11.894 +	/*
  11.895 +	 * If the target never sent an identify message but instead went
  11.896 +	 * to mesgin to give an invalid message, let the host abort us.
  11.897 +	 */
  11.898 +	test	SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT	jz . + 3;
  11.899 +	mvi	SEQINTCODE, PROTO_VIOLATION;
  11.900 +	jmp	mesgin_done;
  11.901 +
  11.902 +	/*
  11.903 +	 * If the target never gave us status information, have
  11.904 +	 * the host abort the command.
  11.905 +	 */
  11.906 +	test	SCB_CONTROL, STATUS_RCVD jz . - 2;
  11.907 +
  11.908 +	/*
  11.909 +	 * See if we attempted to deliver a message but the target ingnored us.
  11.910 +	 */
  11.911 +	test	SCB_CONTROL, MK_MESSAGE jz . + 2;
  11.912 +	mvi	SEQINTCODE, MKMSG_FAILED;
  11.913 +	call	queue_scb_completion;
  11.914 +	jmp	await_busfree;
  11.915 +
  11.916 +freeze_queue:
  11.917 +	/* Cancel any pending select-out. */
  11.918 +	test	SSTAT0, SELDO jnz . + 2;
  11.919 +	and	SCSISEQ0, ~ENSELO;
  11.920 +	mov	ACCUM_SAVE, A;
  11.921 +	clr	A;
  11.922 +	add	QFREEZE_COUNT, 1;
  11.923 +	adc	QFREEZE_COUNT[1], A;
  11.924 +	or	SEQ_FLAGS2, SELECTOUT_QFROZEN;
  11.925 +	mov	A, ACCUM_SAVE ret;
  11.926 +
  11.927 +queue_arg1_scb_completion:
  11.928 +	SET_MODE(M_SCSI, M_SCSI);
  11.929 +	bmov	SCBPTR, ARG_1, 2;
  11.930 +queue_scb_completion:
  11.931 +	test	SCB_SCSI_STATUS,0xff	jnz bad_status;
  11.932 +	/*
  11.933 +	 * Check for residuals
  11.934 +	 */
  11.935 +	test	SCB_SGPTR, SG_LIST_NULL jnz complete;	/* No xfer */
  11.936 +	test	SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */
  11.937 +	test	SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb;
  11.938 +complete:
  11.939 +	bmov	SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
  11.940 +	bmov	COMPLETE_SCB_HEAD, SCBPTR, 2 ret;
  11.941 +bad_status:
  11.942 +	cmp	SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb;
  11.943 +	call	freeze_queue;
  11.944 +upload_scb:
  11.945 +	bmov	SCB_NEXT_COMPLETE, COMPLETE_DMA_SCB_HEAD, 2;
  11.946 +	bmov	COMPLETE_DMA_SCB_HEAD, SCBPTR, 2;
  11.947 +	or	SCB_SGPTR, SG_STATUS_VALID ret;
  11.948 +
  11.949 +/*
  11.950 + * Is it a disconnect message?  Set a flag in the SCB to remind us
  11.951 + * and await the bus going free.  If this is an untagged transaction
  11.952 + * store the SCB id for it in our untagged target table for lookup on
  11.953 + * a reselction.
  11.954 + */
  11.955 +mesgin_disconnect:
  11.956 +	/*
  11.957 +	 * If ATN is raised, we still want to give the target a message.
  11.958 +	 * Perhaps there was a parity error on this last message byte
  11.959 +	 * or we want to abort this command.  Either way, the target
  11.960 +	 * should take us to message out phase and then attempt to
  11.961 +	 * disconnect again.
  11.962 +	 * XXX - Wait for more testing.
  11.963 +	test	SCSISIGI, ATNI jnz mesgin_done;
  11.964 +	 */
  11.965 +	test	SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT	jz disconnect_allowed;
  11.966 +	mvi	SEQINTCODE, PROTO_VIOLATION;
  11.967 +	jmp	mesgin_done;
  11.968 +disconnect_allowed:
  11.969 +	or	SCB_CONTROL,DISCONNECTED;
  11.970 +	test	SCB_CONTROL, TAG_ENB jz queue_disc_scb;
  11.971 +	mov	A, SCB_NONPACKET_TAG;
  11.972 +	cmp	SCBPTR, A je await_busfree;
  11.973 +queue_disc_scb:
  11.974 +	bmov	REG0, SCBPTR, 2;
  11.975 +	shr	SINDEX, 4, SCB_SCSIID;
  11.976 +	INDEX_DISC_LIST(SINDEX, SCB_LUN);
  11.977 +	bmov	DINDEX, SINDEX, 2;
  11.978 +	bmov	REG1, SINDIR, 2;
  11.979 +	bmov	DINDIR, REG0, 2;
  11.980 +	bmov	SCBPTR, REG0, 2;
  11.981 +	bmov	SCB_NEXT, REG1, 2;
  11.982 +	/* FALLTHROUGH */
  11.983 +await_busfree:
  11.984 +	and	SIMODE1, ~ENBUSFREE;
  11.985 +	mov	NONE, SCSIDAT;		/* Ack the last byte */
  11.986 +	call	clear_target_state;
  11.987 +	test	MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))
  11.988 +		jnz await_busfree_not_m_dff;
  11.989 +SET_SRC_MODE	M_DFF1;
  11.990 +SET_DST_MODE	M_DFF1;
  11.991 +await_busfree_clrchn:
  11.992 +	mvi	DFFSXFRCTL, CLRCHN;
  11.993 +await_busfree_not_m_dff:
  11.994 +	test	SSTAT1,REQINIT|BUSFREE	jz .;
  11.995 +	test	SSTAT1, BUSFREE jnz idle_loop;
  11.996 +	mvi	SEQINTCODE, MISSED_BUSFREE;
  11.997 +
  11.998 +
  11.999 +/*
 11.1000 + * Save data pointers message:
 11.1001 + * Copying RAM values back to SCB, for Save Data Pointers message, but
 11.1002 + * only if we've actually been into a data phase to change them.  This
 11.1003 + * protects against bogus data in scratch ram and the residual counts
 11.1004 + * since they are only initialized when we go into data_in or data_out.
 11.1005 + * Ack the message as soon as possible.  For chips without S/G pipelining,
 11.1006 + * we can only ack the message after SHADDR has been saved.  On these
 11.1007 + * chips, SHADDR increments with every bus transaction, even PIO.
 11.1008 + */
 11.1009 +SET_SRC_MODE	M_DFF1;
 11.1010 +SET_DST_MODE	M_DFF1;
 11.1011 +mesgin_sdptrs:
 11.1012 +	mov	NONE,SCSIDAT;		/*dummy read from latch to ACK*/
 11.1013 +	test	SEQ_FLAGS, DPHASE	jz ITloop;
 11.1014 +	call	save_pointers;
 11.1015 +	jmp	ITloop;
 11.1016 +
 11.1017 +save_pointers:
 11.1018 +	/*
 11.1019 +	 * If we are asked to save our position at the end of the
 11.1020 +	 * transfer, just mark us at the end rather than perform a
 11.1021 +	 * full save.
 11.1022 +	 */
 11.1023 +	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz save_pointers_full;
 11.1024 +	or	SCB_SGPTR, SG_LIST_NULL ret;
 11.1025 +
 11.1026 +save_pointers_full:
 11.1027 +	/*
 11.1028 +	 * The SCB_DATAPTR becomes the current SHADDR.
 11.1029 +	 * All other information comes directly from our residual
 11.1030 +	 * state.
 11.1031 +	 */
 11.1032 +	bmov	SCB_DATAPTR, SHADDR, 8;
 11.1033 +	bmov	SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8 ret;
 11.1034 +
 11.1035 +/*
 11.1036 + * Restore pointers message?  Data pointers are recopied from the
 11.1037 + * SCB anytime we enter a data phase for the first time, so all
 11.1038 + * we need to do is clear the DPHASE flag and let the data phase
 11.1039 + * code do the rest.  We also reset/reallocate the FIFO to make
 11.1040 + * sure we have a clean start for the next data phase.
 11.1041 + */
 11.1042 +mesgin_rdptrs:
 11.1043 +	and	SEQ_FLAGS, ~DPHASE;
 11.1044 +	test	MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz msgin_rdptrs_get_fifo;
 11.1045 +	mvi	DFFSXFRCTL, RSTCHN|CLRSHCNT;
 11.1046 +msgin_rdptrs_get_fifo:
 11.1047 +	call	allocate_fifo;
 11.1048 +	jmp	mesgin_done;
 11.1049 +
 11.1050 +clear_target_state:
 11.1051 +	mvi	LASTPHASE, P_BUSFREE;
 11.1052 +	/* clear target specific flags */
 11.1053 +	mvi	SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret;
 11.1054 +
 11.1055 +phase_lock:     
 11.1056 +	test	SCSIPHASE, 0xFF jz .;
 11.1057 +phase_lock_latch_phase:
 11.1058 +	and	LASTPHASE, PHASE_MASK, SCSISIGI ret;
 11.1059 +
 11.1060 +/*
 11.1061 + * Functions to read data in Automatic PIO mode.
 11.1062 + *
 11.1063 + * An ACK is not sent on input from the target until SCSIDATL is read from.
 11.1064 + * So we wait until SCSIDATL is latched (the usual way), then read the data
 11.1065 + * byte directly off the bus using SCSIBUSL.  When we have pulled the ATN
 11.1066 + * line, or we just want to acknowledge the byte, then we do a dummy read
 11.1067 + * from SCISDATL.  The SCSI spec guarantees that the target will hold the
 11.1068 + * data byte on the bus until we send our ACK.
 11.1069 + *
 11.1070 + * The assumption here is that these are called in a particular sequence,
 11.1071 + * and that REQ is already set when inb_first is called.  inb_{first,next}
 11.1072 + * use the same calling convention as inb.
 11.1073 + */
 11.1074 +inb_next:
 11.1075 +	mov	NONE,SCSIDAT;		/*dummy read from latch to ACK*/
 11.1076 +inb_next_wait:
 11.1077 +	/*
 11.1078 +	 * If there is a parity error, wait for the kernel to
 11.1079 +	 * see the interrupt and prepare our message response
 11.1080 +	 * before continuing.
 11.1081 +	 */
 11.1082 +	test	SCSIPHASE, 0xFF jz .;
 11.1083 +inb_next_check_phase:
 11.1084 +	and	LASTPHASE, PHASE_MASK, SCSISIGI;
 11.1085 +	cmp	LASTPHASE, P_MESGIN jne mesgin_phasemis;
 11.1086 +inb_first:
 11.1087 +	clr	DINDEX[1];
 11.1088 +	mov	DINDEX,SINDEX;
 11.1089 +	mov	DINDIR,SCSIBUS	ret;		/*read byte directly from bus*/
 11.1090 +inb_last:
 11.1091 +	mov	NONE,SCSIDAT ret;		/*dummy read from latch to ACK*/
 11.1092 +
 11.1093 +mk_mesg:
 11.1094 +	mvi	SCSISIGO, ATNO;
 11.1095 +	mov	MSG_OUT,SINDEX ret;
 11.1096 +
 11.1097 +SET_SRC_MODE	M_DFF1;
 11.1098 +SET_DST_MODE	M_DFF1;
 11.1099 +disable_ccsgen:
 11.1100 +	test	SG_STATE, FETCH_INPROG jz return;
 11.1101 +	clr	SG_STATE;
 11.1102 +disable_ccsgen_fetch_done:
 11.1103 +	clr	CCSGCTL ret;
 11.1104 +
 11.1105 +toggle_dff_mode:
 11.1106 +	mvi	SEQINTCTL, INTVEC1DSL;
 11.1107 +	xor	MODE_PTR, MK_MODE(M_DFF1, M_DFF1);
 11.1108 +	clr	SEQINTCTL ret;
 11.1109 +
 11.1110 +data_group_idle_loop:
 11.1111 +	mov	SAVED_MODE, MODE_PTR;
 11.1112 +	test	SG_STATE, LOADING_NEEDED jz . + 2;
 11.1113 +	call	service_fifo;
 11.1114 +	call	toggle_dff_mode;
 11.1115 +	test	SG_STATE, LOADING_NEEDED jz . + 2;
 11.1116 +	call	service_fifo;
 11.1117 +	call	idle_loop_cchan;
 11.1118 +	mov	SAVED_MODE jmp set_mode_work_around;
 11.1119 +
 11.1120 +service_fifo:
 11.1121 +	/*
 11.1122 +	 * Do we have any prefetch left???
 11.1123 +	 */
 11.1124 +	test	SG_STATE, SEGS_AVAIL jnz idle_sg_avail;
 11.1125 +
 11.1126 +	/*
 11.1127 +	 * Can this FIFO have access to the S/G cache yet?
 11.1128 +	 */
 11.1129 +	test	CCSGCTL, SG_CACHE_AVAIL jz return;
 11.1130 +
 11.1131 +	/* Did we just finish fetching segs? */
 11.1132 +	cmp	CCSGCTL, CCSGEN|SG_CACHE_AVAIL|CCSGDONE
 11.1133 +		je idle_sgfetch_complete;
 11.1134 +
 11.1135 +	/* Are we actively fetching segments? */
 11.1136 +	test	CCSGCTL, CCSGEN jnz return;
 11.1137 +
 11.1138 +	/*
 11.1139 +	 * We fetch a "cacheline aligned" and sized amount of data
 11.1140 +	 * so we don't end up referencing a non-existant page.
 11.1141 +	 * Cacheline aligned is in quotes because the kernel will
 11.1142 +	 * set the prefetch amount to a reasonable level if the
 11.1143 +	 * cacheline size is unknown.
 11.1144 +	 */
 11.1145 +	mvi	SGHCNT, SG_PREFETCH_CNT;
 11.1146 +	and	SGHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR;
 11.1147 +	bmov	SGHADDR[1], SCB_RESIDUAL_SGPTR[1], 3;
 11.1148 +	mvi	CCSGCTL, CCSGEN|SG_CACHE_AVAIL|CCSGRESET;
 11.1149 +	or	SG_STATE, FETCH_INPROG ret;
 11.1150 +idle_sgfetch_complete:
 11.1151 +	/*
 11.1152 +	 * Guard against SG_CACHE_AVAIL activating during sg fetch
 11.1153 +	 * request in the other FIFO.
 11.1154 +	 */
 11.1155 +	test	SG_STATE, FETCH_INPROG jz return;
 11.1156 +	call	disable_ccsgen_fetch_done;
 11.1157 +	and	CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR;
 11.1158 +	mvi	SG_STATE, SEGS_AVAIL|LOADING_NEEDED;
 11.1159 +idle_sg_avail:
 11.1160 +	/* Does the hardware have space for another SG entry? */
 11.1161 +	test	DFSTATUS, PRELOAD_AVAIL jz return;
 11.1162 +	if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
 11.1163 +		bmov	HADDR, CCSGRAM, 8;
 11.1164 +	} else {
 11.1165 +		bmov 	HADDR, CCSGRAM, 4;
 11.1166 +	}
 11.1167 +	bmov	HCNT, CCSGRAM, 3;
 11.1168 +	test	HCNT[0], 0x1 jz . + 2;
 11.1169 +	xor	DATA_COUNT_ODD, 0x1;
 11.1170 +	bmov	SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;
 11.1171 +	if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) {
 11.1172 +		and	HADDR[4], SG_HIGH_ADDR_BITS, SCB_RESIDUAL_DATACNT[3];
 11.1173 +	}
 11.1174 +	if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
 11.1175 +		/* Skip 4 bytes of pad. */
 11.1176 +		add	CCSGADDR, 4;
 11.1177 +	}
 11.1178 +sg_advance:
 11.1179 +	clr	A;			/* add sizeof(struct scatter) */
 11.1180 +	add	SCB_RESIDUAL_SGPTR[0],SG_SIZEOF;
 11.1181 +	adc	SCB_RESIDUAL_SGPTR[1],A;
 11.1182 +	adc	SCB_RESIDUAL_SGPTR[2],A;
 11.1183 +	adc	SCB_RESIDUAL_SGPTR[3],A;
 11.1184 +	mov	SINDEX, SCB_RESIDUAL_SGPTR[0];
 11.1185 +	test	DATA_COUNT_ODD, 0x1 jz . + 2;
 11.1186 +	or	SINDEX, ODD_SEG;
 11.1187 +	test	SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 3;
 11.1188 +	or	SINDEX, LAST_SEG;
 11.1189 +	clr	SG_STATE;
 11.1190 +	mov	SG_CACHE_PRE, SINDEX;
 11.1191 +	/*
 11.1192 +	 * Load the segment.  Or in HDMAEN here too
 11.1193 +	 * just in case HDMAENACK has not come true
 11.1194 +	 * by the time this segment is loaded.  If
 11.1195 +	 * HDMAENACK is not true, this or will disable
 11.1196 +	 * HDMAEN mid-transfer.  We do not want to simply
 11.1197 +	 * mvi our original settings as SCSIEN automatically
 11.1198 +	 * de-asserts and we don't want to accidentally
 11.1199 +	 * re-enable it.
 11.1200 +	 */
 11.1201 +	or	DFCNTRL, PRELOADEN|HDMAEN;
 11.1202 +	/*
 11.1203 +	 * Do we have another segment in the cache?
 11.1204 +	 */
 11.1205 +	add	NONE, SG_PREFETCH_CNT_LIMIT, CCSGADDR;
 11.1206 +	jnc	return;
 11.1207 +	and	SG_STATE, ~SEGS_AVAIL ret;
 11.1208 +
 11.1209 +/*
 11.1210 + * Initialize the DMA address and counter from the SCB.
 11.1211 + */
 11.1212 +load_first_seg:
 11.1213 +	bmov	HADDR, SCB_DATAPTR, 11;
 11.1214 +	and	DATA_COUNT_ODD, 0x1, SCB_DATACNT[0];
 11.1215 +	and	REG0, ~SG_FULL_RESID, SCB_SGPTR[0];
 11.1216 +	test	SCB_DATACNT[3], SG_LAST_SEG jz . + 2;
 11.1217 +	or	REG0, LAST_SEG;
 11.1218 +	test	DATA_COUNT_ODD, 0x1 jz . + 2;
 11.1219 +	or	REG0, ODD_SEG;
 11.1220 +	mov	SG_CACHE_PRE, REG0;
 11.1221 +	mvi	DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN);
 11.1222 +	/*
 11.1223 +	 * Since we've are entering a data phase, we will
 11.1224 +	 * rely on the SCB_RESID* fields.  Initialize the
 11.1225 +	 * residual and clear the full residual flag.
 11.1226 +	 */
 11.1227 +	and	SCB_SGPTR[0], ~SG_FULL_RESID;
 11.1228 +	bmov	SCB_RESIDUAL_DATACNT[3], SCB_DATACNT[3], 5;
 11.1229 +	/* If we need more S/G elements, tell the idle loop */
 11.1230 +	test	SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz . + 2;
 11.1231 +	mvi	SG_STATE, LOADING_NEEDED ret;
 11.1232 +	clr	SG_STATE ret;
 11.1233 +
 11.1234 +p_data:
 11.1235 +	test	SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT	jz p_data_allowed;
 11.1236 +	mvi	SEQINTCODE, PROTO_VIOLATION;
 11.1237 +p_data_allowed:
 11.1238 + 
 11.1239 +	test	SEQ_FLAGS, DPHASE	jz data_phase_initialize;
 11.1240 +
 11.1241 +	/*
 11.1242 +	 * If we re-enter the data phase after going through another
 11.1243 +	 * phase, our transfer location has almost certainly been
 11.1244 +	 * corrupted by the interveining, non-data, transfers.  Ask
 11.1245 +	 * the host driver to fix us up based on the transfer residual
 11.1246 +	 * unless we already know that we should be bitbucketing.
 11.1247 +	 */
 11.1248 +	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket;
 11.1249 +	mvi	SEQINTCODE, PDATA_REINIT;
 11.1250 +
 11.1251 +p_data_bitbucket:
 11.1252 +	/*
 11.1253 +	 * Turn on `Bit Bucket' mode, wait until the target takes
 11.1254 +	 * us to another phase, and then notify the host.
 11.1255 +	 */
 11.1256 +	test	MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))
 11.1257 +		jnz bitbucket_not_m_dff;
 11.1258 +	/*
 11.1259 +	 * Ensure that any FIFO contents are cleared out and the
 11.1260 +	 * FIFO free'd prior to starting the BITBUCKET.  BITBUCKET
 11.1261 +	 * doesn't discard data already in the FIFO.
 11.1262 +	 */
 11.1263 +	mvi	DFFSXFRCTL, RSTCHN|CLRSHCNT;
 11.1264 +	SET_MODE(M_SCSI, M_SCSI);
 11.1265 +bitbucket_not_m_dff:
 11.1266 +	or	SXFRCTL1,BITBUCKET;
 11.1267 +	test	SCSIPHASE, DATA_PHASE_MASK jnz .;
 11.1268 +	and	SXFRCTL1, ~BITBUCKET;
 11.1269 +	SET_MODE(M_DFF1, M_DFF1);
 11.1270 +	mvi	SEQINTCODE, DATA_OVERRUN;
 11.1271 +	jmp	ITloop;
 11.1272 +
 11.1273 +data_phase_initialize:
 11.1274 +	test	SCB_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket;
 11.1275 +	call	load_first_seg;
 11.1276 +data_phase_inbounds:
 11.1277 +	/* We have seen a data phase at least once. */
 11.1278 +	or	SEQ_FLAGS, DPHASE;
 11.1279 +data_group_dma_loop:
 11.1280 +	/*
 11.1281 +	 * The transfer is complete if either the last segment
 11.1282 +	 * completes or the target changes phase.  Both conditions
 11.1283 +	 * will clear SCSIEN.  We test SCSIEN twice during our
 11.1284 +	 * "idle loop" to avoid long delays before we notice the
 11.1285 +	 * SCSIEN transition.
 11.1286 +	 */
 11.1287 +	call	data_group_idle_loop;
 11.1288 +	test	DFCNTRL, SCSIEN jnz data_group_dma_loop;
 11.1289 +
 11.1290 +data_group_dmafinish:
 11.1291 +	/*
 11.1292 +	 * The transfer has terminated either due to a phase
 11.1293 +	 * change, and/or the completion of the last segment.
 11.1294 +	 * We have two goals here.  Do as much other work
 11.1295 +	 * as possible while the data fifo drains on a read
 11.1296 +	 * and respond as quickly as possible to the standard
 11.1297 +	 * messages (save data pointers/disconnect and command
 11.1298 +	 * complete) that usually follow a data phase.
 11.1299 +	 */
 11.1300 +	call	calc_residual;
 11.1301 +
 11.1302 +	/*
 11.1303 +	 * Go ahead and shut down the DMA engine now.
 11.1304 +	 */
 11.1305 +	test	DFCNTRL, DIRECTION jnz data_phase_finish;
 11.1306 +data_group_fifoflush:
 11.1307 +	if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {
 11.1308 +		or	DFCNTRL, FIFOFLUSH;
 11.1309 +	}
 11.1310 +	/*
 11.1311 +	 * We have enabled the auto-ack feature.  This means
 11.1312 +	 * that the controller may have already transferred
 11.1313 +	 * some overrun bytes into the data FIFO and acked them
 11.1314 +	 * on the bus.  The only way to detect this situation is
 11.1315 +	 * to wait for LAST_SEG_DONE to come true on a completed
 11.1316 +	 * transfer and then test to see if the data FIFO is
 11.1317 +	 * non-empty.  We know there is more data yet to transfer
 11.1318 +	 * if SG_LIST_NULL is not yet set, thus there cannot be
 11.1319 +	 * an overrun.
 11.1320 +	 */
 11.1321 +	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_finish;
 11.1322 +	test	SG_CACHE_SHADOW, LAST_SEG_DONE jz .;
 11.1323 +	test	DFSTATUS, FIFOEMP jnz data_phase_finish;
 11.1324 +	/* Overrun */
 11.1325 +	jmp	p_data;
 11.1326 +data_phase_finish:
 11.1327 +	/*
 11.1328 +	 * If the target has left us in data phase, loop through
 11.1329 +	 * the dma code again.  We will only loop if there is a
 11.1330 +	 * data overrun.  
 11.1331 +	 */
 11.1332 +	if ((ahd->flags & AHD_TARGETROLE) != 0) {
 11.1333 +		test	SSTAT0, TARGET jnz data_phase_done;
 11.1334 +	}
 11.1335 +	if ((ahd->flags & AHD_INITIATORROLE) != 0) {
 11.1336 +		test	SSTAT1, REQINIT jz .;
 11.1337 +		test	SCSIPHASE, DATA_PHASE_MASK jnz p_data;
 11.1338 +	}
 11.1339 +
 11.1340 +data_phase_done:
 11.1341 +	/* Kill off any pending prefetch */
 11.1342 +	call	disable_ccsgen;
 11.1343 +
 11.1344 +	if ((ahd->flags & AHD_TARGETROLE) != 0) {
 11.1345 +		test	SEQ_FLAGS, DPHASE_PENDING jz ITloop;
 11.1346 +		/*
 11.1347 +		and	SEQ_FLAGS, ~DPHASE_PENDING;
 11.1348 +		 * For data-in phases, wait for any pending acks from the
 11.1349 +		 * initiator before changing phase.  We only need to
 11.1350 +		 * send Ignore Wide Residue messages for data-in phases.
 11.1351 +		test	DFCNTRL, DIRECTION jz target_ITloop;
 11.1352 +		test	SSTAT1, REQINIT	jnz .;
 11.1353 +		test	DATA_COUNT_ODD, 0x1 jz target_ITloop;
 11.1354 +		SET_MODE(M_SCSI, M_SCSI);
 11.1355 +		test	NEGCONOPTS, WIDEXFER jz target_ITloop;
 11.1356 +		 */
 11.1357 +		/*
 11.1358 +		 * Issue an Ignore Wide Residue Message.
 11.1359 +		mvi	P_MESGIN|BSYO call change_phase;
 11.1360 +		mvi	MSG_IGN_WIDE_RESIDUE call target_outb;
 11.1361 +		mvi	1 call target_outb;
 11.1362 +		jmp	target_ITloop;
 11.1363 +		 */
 11.1364 +	} else {
 11.1365 +		jmp	ITloop;
 11.1366 +	}
 11.1367 +
 11.1368 +/*
 11.1369 + * We assume that, even though data may still be
 11.1370 + * transferring to the host, that the SCSI side of
 11.1371 + * the DMA engine is now in a static state.  This
 11.1372 + * allows us to update our notion of where we are
 11.1373 + * in this transfer.
 11.1374 + *
 11.1375 + * If, by chance, we stopped before being able
 11.1376 + * to fetch additional segments for this transfer,
 11.1377 + * yet the last S/G was completely exhausted,
 11.1378 + * call our idle loop until it is able to load
 11.1379 + * another segment.  This will allow us to immediately
 11.1380 + * pickup on the next segment on the next data phase.
 11.1381 + *
 11.1382 + * If we happened to stop on the last segment, then
 11.1383 + * our residual information is still correct from
 11.1384 + * the idle loop and there is no need to perform
 11.1385 + * any fixups.
 11.1386 + */
 11.1387 +calc_residual:
 11.1388 +	test	SG_CACHE_SHADOW, LAST_SEG jz residual_before_last_seg;
 11.1389 +	/* Record if we've consumed all S/G entries */
 11.1390 +	test	MDFFSTAT, SHVALID	jz . + 2;
 11.1391 +	bmov	SCB_RESIDUAL_DATACNT, SHCNT, 3 ret;
 11.1392 +	or	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL ret;
 11.1393 +residual_before_last_seg:
 11.1394 +	test    MDFFSTAT, SHVALID	jnz sgptr_fixup;
 11.1395 +	/*
 11.1396 +	 * Can never happen from an interrupt as the packetized
 11.1397 +	 * hardware will only interrupt us once SHVALID or
 11.1398 +	 * LAST_SEG_DONE.
 11.1399 +	 */
 11.1400 +	call	data_group_idle_loop;
 11.1401 +	jmp	calc_residual;
 11.1402 +
 11.1403 +sgptr_fixup:
 11.1404 +	/*
 11.1405 +	 * Fixup the residual next S/G pointer.  The S/G preload
 11.1406 +	 * feature of the chip allows us to load two elements
 11.1407 +	 * in addition to the currently active element.  We
 11.1408 +	 * store the bottom byte of the next S/G pointer in
 11.1409 +	 * the SG_CACHE_PTR register so we can restore the
 11.1410 +	 * correct value when the DMA completes.  If the next
 11.1411 +	 * sg ptr value has advanced to the point where higher
 11.1412 +	 * bytes in the address have been affected, fix them
 11.1413 +	 * too.
 11.1414 +	 */
 11.1415 +	test	SG_CACHE_SHADOW, 0x80 jz sgptr_fixup_done;
 11.1416 +	test	SCB_RESIDUAL_SGPTR[0], 0x80 jnz sgptr_fixup_done;
 11.1417 +	add	SCB_RESIDUAL_SGPTR[1], -1;
 11.1418 +	adc	SCB_RESIDUAL_SGPTR[2], -1; 
 11.1419 +	adc	SCB_RESIDUAL_SGPTR[3], -1;
 11.1420 +sgptr_fixup_done:
 11.1421 +	and	SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW;
 11.1422 +	clr	DATA_COUNT_ODD;
 11.1423 +	test	SG_CACHE_SHADOW, ODD_SEG jz . + 2;
 11.1424 +	or	DATA_COUNT_ODD, 0x1;
 11.1425 +	clr	SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */
 11.1426 +	bmov	SCB_RESIDUAL_DATACNT, SHCNT, 3 ret;
 11.1427 +
 11.1428 +export seq_isr:
 11.1429 +	nop;	/* Jumps in the first ISR instruction fail on Rev A. */
 11.1430 +	test	SEQINTSRC, SAVEPTRS	jnz saveptr_intr;
 11.1431 +	test	SEQINTSRC, CFG4DATA	jnz cfg4data_intr;
 11.1432 +	test	SEQINTSRC, CFG4ISTAT	jnz cfg4istat_intr;
 11.1433 +	test	SEQINTSRC, CFG4ICMD	jnz cfg4icmd_intr;
 11.1434 +	mvi	SEQINTCODE, INVALID_SEQINT;
 11.1435 +
 11.1436 +/*
 11.1437 + * There are two types of save pointers interrupts:
 11.1438 + * The first is a snapshot save pointers where the current FIFO is not
 11.1439 + * active and contains a snapshot of the current poniter information.
 11.1440 + * This happens between packets in a stream for a single L_Q.  Since we
 11.1441 + * are not performing a pointer save, we can safely clear the channel
 11.1442 + * so it can be used for other transactions.
 11.1443 + *
 11.1444 + * The second case is a save pointers on an active FIFO which occurs
 11.1445 + * if the target changes to a new L_Q or busfrees/QAS' and the transfer
 11.1446 + * has a residual.  This should occur coincident with a ctxtdone.  We
 11.1447 + * disable the interrupt and allow our active routine to handle the
 11.1448 + * save.
 11.1449 + */
 11.1450 +saveptr_intr:
 11.1451 +	test	DFCNTRL, HDMAENACK jz snapshot_saveptr;
 11.1452 +	and	SEQIMODE, ~ENSAVEPTRS;
 11.1453 +	or	SEQINTCTL, IRET ret;
 11.1454 +snapshot_saveptr:
 11.1455 +	mvi	DFFSXFRCTL, CLRCHN;
 11.1456 +	or	SEQINTCTL, IRET ret;
 11.1457 +
 11.1458 +cfg4data_intr:
 11.1459 +	test	SCB_SGPTR[0], SG_LIST_NULL jnz pkt_handle_overrun;
 11.1460 +	call	load_first_seg;
 11.1461 +	call	pkt_handle_xfer;
 11.1462 +	or	SEQINTCTL, IRET ret;
 11.1463 +
 11.1464 +cfg4istat_intr:
 11.1465 +	call	freeze_queue;
 11.1466 +	add	NONE, -13, SCB_CDB_LEN;
 11.1467 +	jnc	cfg4istat_have_sense_addr;
 11.1468 +	test	SCB_CDB_LEN, SCB_CDB_LEN_PTR jnz cfg4istat_have_sense_addr;
 11.1469 +	/*
 11.1470 +	 * Host sets up address/count and enables transfer.
 11.1471 +	 */
 11.1472 +	mvi	SEQINTCODE, CFG4ISTAT_INTR;
 11.1473 +	jmp	cfg4istat_setup_handler;
 11.1474 +cfg4istat_have_sense_addr:
 11.1475 +	bmov	HADDR, SCB_SENSE_BUSADDR, 4;
 11.1476 +	mvi	HCNT[1], (AHD_SENSE_BUFSIZE >> 8);
 11.1477 +	mvi	SG_CACHE_PRE, LAST_SEG;
 11.1478 +	mvi	DFCNTRL, PRELOADEN|SCSIEN|HDMAEN;
 11.1479 +cfg4istat_setup_handler:
 11.1480 +	/*
 11.1481 +	 * Status pkt is transferring to host.
 11.1482 +	 * Wait in idle loop for transfer to complete.
 11.1483 +	 */
 11.1484 +	call	pkt_handle_status;
 11.1485 +	or	SEQINTCTL, IRET ret;
 11.1486 +
 11.1487 +/*
 11.1488 + * See if the target has gone on in this context creating an
 11.1489 + * overrun condition.  For the write case, the hardware cannot
 11.1490 + * ack bytes until data is provided.  So, if the target begins
 11.1491 + * another  packet without changing contexts, implying we are
 11.1492 + * not sitting on a packet boundary, we are in an overrun
 11.1493 + * situation.  For the read case, the hardware will continue to
 11.1494 + * ack bytes into the FIFO, and may even ack the last overrun packet
 11.1495 + * into the FIFO.   If the FIFO should become non-empty, we are in
 11.1496 + * a read overrun case.
 11.1497 + */
 11.1498 +#define check_overrun							\
 11.1499 +	/* Not on a packet boundary. */					\
 11.1500 +	test 	MDFFSTAT, DLZERO jz pkt_handle_overrun;			\
 11.1501 +	test	DFSTATUS, FIFOEMP jz pkt_handle_overrun
 11.1502 +
 11.1503 +pkt_handle_xfer:
 11.1504 +	bmov	LONGJMP_SCB, SCBPTR, 2;
 11.1505 +	test	SG_STATE, LOADING_NEEDED jz pkt_last_seg;
 11.1506 +	call	setjmp;
 11.1507 +	test	SEQINTSRC, SAVEPTRS jnz pkt_saveptrs;
 11.1508 +	test	SCSIPHASE, ~DATA_PHASE_MASK jz . + 2;
 11.1509 +	test	SCSISIGO, ATNO jnz . + 2;
 11.1510 +	test	SSTAT2, NONPACKREQ jz pkt_service_fifo;
 11.1511 +	/*
 11.1512 +	 * Defer handling of this NONPACKREQ until we
 11.1513 +	 * can be sure it pertains to this FIFO.  SAVEPTRS
 11.1514 +	 * will not be asserted if the NONPACKREQ is for us,
 11.1515 +	 * so we must simulate it if shaddow is valid.  If
 11.1516 +	 * shaddow is not valid, keep running this FIFO until we
 11.1517 +	 * have satisfied the transfer by loading segments and
 11.1518 +	 * waiting for either shaddow valid or last_seg_done.
 11.1519 +	 */
 11.1520 +	test	MDFFSTAT, SHVALID jnz pkt_saveptrs;
 11.1521 +pkt_service_fifo:
 11.1522 +	test	SG_STATE, LOADING_NEEDED jnz service_fifo;
 11.1523 +pkt_last_seg:
 11.1524 +	call	setjmp;
 11.1525 +	test	SEQINTSRC, SAVEPTRS jnz pkt_saveptrs;
 11.1526 +	test	SG_CACHE_SHADOW, LAST_SEG_DONE jnz last_pkt_done;
 11.1527 +	test	SCSIPHASE, ~DATA_PHASE_MASK jz . + 2;
 11.1528 +	test	SCSISIGO, ATNO jnz . + 2;
 11.1529 +	test	SSTAT2, NONPACKREQ jz return;
 11.1530 +	test	MDFFSTAT, SHVALID jnz pkt_saveptrs;
 11.1531 +	jmp	return;
 11.1532 +last_pkt_done:
 11.1533 +BEGIN_CRITICAL;
 11.1534 +	if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {
 11.1535 +		or	DFCNTRL, FIFOFLUSH;
 11.1536 +	}
 11.1537 +	test	SCB_CONTROL, STATUS_RCVD jz wait_pkt_end;
 11.1538 +	check_overrun;
 11.1539 +	or	SCB_SGPTR, SG_LIST_NULL;
 11.1540 +	/*
 11.1541 +	 * I think it is safe to skip the FIFO check.
 11.1542 +	 * in this case as LAST_SEG_DONE implies
 11.1543 +	 * the other FIFO, if ever active for this transfer,
 11.1544 +	 * has completed.
 11.1545 +	 */
 11.1546 +last_pkt_queue_scb:
 11.1547 +	or	LONGJMP_ADDR[1], INVALID_ADDR;
 11.1548 +	bmov	ARG_1, SCBPTR, 2;
 11.1549 +	mvi	DFFSXFRCTL, CLRCHN;
 11.1550 +	jmp	queue_arg1_scb_completion;
 11.1551 +
 11.1552 +last_pkt_complete:
 11.1553 +	bmov	ARG_1, SCBPTR, 2;
 11.1554 +	mvi	DFFSXFRCTL, CLRCHN;
 11.1555 +check_other_fifo:
 11.1556 +	clc;
 11.1557 +	call	toggle_dff_mode;
 11.1558 +	call	check_fifo;
 11.1559 +	jnc	queue_arg1_scb_completion;
 11.1560 +return:
 11.1561 +	ret;
 11.1562 +
 11.1563 +wait_pkt_end:
 11.1564 +	call	setjmp;
 11.1565 +END_CRITICAL;
 11.1566 +wait_pkt_end_loop:
 11.1567 +	test	SEQINTSRC, CTXTDONE jnz pkt_end;
 11.1568 +	check_overrun;
 11.1569 +	test	SSTAT2, NONPACKREQ jz return;
 11.1570 +	test	SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase;
 11.1571 +pkt_end:
 11.1572 +BEGIN_CRITICAL;
 11.1573 +	check_overrun;
 11.1574 +	or	LONGJMP_ADDR[1], INVALID_ADDR;
 11.1575 +	or	SCB_SGPTR, SG_LIST_NULL;
 11.1576 +	test	SCB_CONTROL, STATUS_RCVD jnz last_pkt_complete;
 11.1577 +	mvi	DFFSXFRCTL, CLRCHN ret;
 11.1578 +END_CRITICAL;
 11.1579 +
 11.1580 +/*
 11.1581 + * Either a SAVEPTRS interrupt condition is pending for this FIFO
 11.1582 + * or we have a pending nonpackreq for this FIFO.  We differentiate
 11.1583 + * between the two by capturing the state of the SAVEPTRS interrupt
 11.1584 + * prior to clearing and handling the common code of these two cases.
 11.1585 + */
 11.1586 +pkt_saveptrs:
 11.1587 +BEGIN_CRITICAL;
 11.1588 +	if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {
 11.1589 +		or	DFCNTRL, FIFOFLUSH;
 11.1590 +	}
 11.1591 +	mov	REG0, SEQINTSRC;
 11.1592 +	mvi	CLRSEQINTSRC, CLRSAVEPTRS;
 11.1593 +	call	calc_residual;
 11.1594 +	call	save_pointers;
 11.1595 +	call	disable_ccsgen;
 11.1596 +	or	SEQIMODE, ENSAVEPTRS;
 11.1597 +	or	LONGJMP_ADDR[1], INVALID_ADDR;
 11.1598 +pkt_saveptrs_check_status:
 11.1599 +	test	REG0, SAVEPTRS jz unexpected_nonpkt_phase;
 11.1600 +	test	SCB_CONTROL, STATUS_RCVD jz pkt_saveptrs_clrchn;
 11.1601 +	jmp	last_pkt_complete;
 11.1602 +pkt_saveptrs_clrchn:
 11.1603 +	mvi	DFFSXFRCTL, CLRCHN ret;
 11.1604 +END_CRITICAL;
 11.1605 +
 11.1606 +check_status_overrun:
 11.1607 +	test	SHCNT[2], 0xFF jz status_IU_done;
 11.1608 +	mvi	SEQINTCODE, STATUS_OVERRUN;
 11.1609 +	jmp	status_IU_done;
 11.1610 +pkt_handle_status:
 11.1611 +	call	setjmp_setscb;
 11.1612 +	test	MDFFSTAT, LASTSDONE jnz check_status_overrun;
 11.1613 +	test	SEQINTSRC, CTXTDONE jz return;
 11.1614 +status_IU_done:
 11.1615 +BEGIN_CRITICAL;
 11.1616 +	if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {
 11.1617 +		or	DFCNTRL, FIFOFLUSH;
 11.1618 +	}
 11.1619 +	or	LONGJMP_ADDR[1], INVALID_ADDR;
 11.1620 +	mvi	SCB_SCSI_STATUS, STATUS_PKT_SENSE;
 11.1621 +	or	SCB_CONTROL, STATUS_RCVD;
 11.1622 +	jmp	last_pkt_complete;
 11.1623 +END_CRITICAL;
 11.1624 +
 11.1625 +SET_SRC_MODE	M_DFF0;
 11.1626 +SET_DST_MODE	M_DFF0;
 11.1627 +BEGIN_CRITICAL;
 11.1628 +check_fifo:
 11.1629 +	test	LONGJMP_ADDR[1], INVALID_ADDR jnz return;
 11.1630 +	mov	A, ARG_2;
 11.1631 +	cmp	LONGJMP_SCB[1], A	jne return;
 11.1632 +	mov	A, ARG_1;
 11.1633 +	cmp	LONGJMP_SCB[0], A	jne return;
 11.1634 +	stc	ret;
 11.1635 +END_CRITICAL;
 11.1636 +
 11.1637 +/*
 11.1638 + * Nonpackreq is a polled status.  It can come true in three situations:
 11.1639 + * we have received an L_Q, we have sent one or more L_Qs, or there is no
 11.1640 + * L_Q context associated with this REQ (REQ occurs immediately after a
 11.1641 + * (re)selection).  Routines that know that the context responsible for this
 11.1642 + * nonpackreq call directly into unexpected_nonpkt_phase.  In the case of the
 11.1643 + * top level idle loop, we exhaust all active contexts prior to determining that
 11.1644 + * we simply do not have the full I_T_L_Q for this phase.
 11.1645 + */
 11.1646 +unexpected_nonpkt_phase_find_ctxt:
 11.1647 +	/*
 11.1648 +	 * This nonpackreq is most likely associated with one of the tags
 11.1649 +	 * in a FIFO or an outgoing LQ.  Only treat it as an I_T only
 11.1650 +	 * nonpackreq if we've cleared out the FIFOs and handled any
 11.1651 +	 * pending SELDO.
 11.1652 +	 */
 11.1653 +SET_SRC_MODE	M_SCSI;
 11.1654 +SET_DST_MODE	M_SCSI;
 11.1655 +	and	A, FIFO1FREE|FIFO0FREE, DFFSTAT;
 11.1656 +	cmp	A, FIFO1FREE|FIFO0FREE jne return;
 11.1657 +	test	SSTAT0, SELDO jnz return;
 11.1658 +	mvi	SCBPTR[1], SCB_LIST_NULL;
 11.1659 +unexpected_nonpkt_phase:
 11.1660 +	test	MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz . + 3;
 11.1661 +SET_SRC_MODE	M_DFF0;
 11.1662 +SET_DST_MODE	M_DFF0;
 11.1663 +	or	LONGJMP_ADDR[1], INVALID_ADDR;
 11.1664 +	mvi	DFFSXFRCTL, CLRCHN;
 11.1665 +	mvi	CLRSINT2, CLRNONPACKREQ;
 11.1666 +	test	SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase;
 11.1667 +	mvi	SEQINTCODE, ENTERING_NONPACK;
 11.1668 +	jmp	ITloop;
 11.1669 +
 11.1670 +illegal_phase:
 11.1671 +	mvi	SEQINTCODE, ILLEGAL_PHASE;
 11.1672 +	jmp	ITloop;
 11.1673 +
 11.1674 +/*
 11.1675 + * We have entered an overrun situation.  If we have working
 11.1676 + * BITBUCKET, flip that on and let the hardware eat any overrun
 11.1677 + * data.  Otherwise use an overrun buffer in the host to simulate
 11.1678 + * BITBUCKET.
 11.1679 + */
 11.1680 +pkt_handle_overrun:
 11.1681 +	mvi	SEQINTCODE, CFG4OVERRUN;
 11.1682 +	call	freeze_queue;
 11.1683 +	if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0) {
 11.1684 +		SET_MODE(M_SCSI, M_SCSI);
 11.1685 +		or	SXFRCTL1,BITBUCKET;
 11.1686 +SET_SRC_MODE	M_DFF1;
 11.1687 +SET_DST_MODE	M_DFF1;
 11.1688 +	} else {
 11.1689 +		call	load_overrun_buf;
 11.1690 +		mvi	DFCNTRL, (HDMAEN|SCSIEN|PRELOADEN);
 11.1691 +	}
 11.1692 +	call	setjmp;
 11.1693 +	if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {
 11.1694 +		test	DFSTATUS, PKT_PRELOAD_AVAIL jz overrun_load_done;
 11.1695 +		call	load_overrun_buf;
 11.1696 +		or	DFCNTRL, PRELOADEN;
 11.1697 +overrun_load_done:
 11.1698 +	}
 11.1699 +	test	SEQINTSRC, CTXTDONE jnz pkt_overrun_end;
 11.1700 +	test	SSTAT2, NONPACKREQ jz return;
 11.1701 +pkt_overrun_end:
 11.1702 +	or	SCB_RESIDUAL_SGPTR, SG_OVERRUN_RESID;
 11.1703 +	test	SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase;
 11.1704 +	test	SCB_CONTROL, STATUS_RCVD jnz last_pkt_queue_scb;
 11.1705 +	mvi	DFFSXFRCTL, CLRCHN ret;
 11.1706 +
 11.1707 +if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {
 11.1708 +load_overrun_buf:
 11.1709 +	/*
 11.1710 +	 * Load a dummy segment if preload space is available.
 11.1711 +	 */
 11.1712 +	mov 	HADDR[0], SHARED_DATA_ADDR;
 11.1713 +	add	HADDR[1], PKT_OVERRUN_BUFOFFSET, SHARED_DATA_ADDR[1];
 11.1714 +	mov	ACCUM_SAVE, A;
 11.1715 +	clr	A;
 11.1716 +	adc	HADDR[2], A, SHARED_DATA_ADDR[2];
 11.1717 +	adc	HADDR[3], A, SHARED_DATA_ADDR[3];
 11.1718 +	mov	A, ACCUM_SAVE;
 11.1719 +	bmov	HADDR[4], ALLZEROS, 4;
 11.1720 +	/* PKT_OVERRUN_BUFSIZE is a multiple of 256 */
 11.1721 +	clr	HCNT[0];
 11.1722 +	mvi	HCNT[1], ((PKT_OVERRUN_BUFSIZE >> 8) & 0xFF);
 11.1723 +	clr	HCNT[2];
 11.1724 +}
 11.1725 +
 11.1726 +cfg4icmd_intr:
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/xen/drivers/scsi/aic7xxx/aic79xx_core.c	Mon Mar 24 16:44:31 2003 +0000
    12.3 @@ -0,0 +1,8344 @@
    12.4 +/*
    12.5 + * Core routines and tables shareable across OS platforms.
    12.6 + *
    12.7 + * Copyright (c) 1994-2001 Justin T. Gibbs.
    12.8 + * Copyright (c) 2000-2002 Adaptec Inc.
    12.9 + * All rights reserved.
   12.10 + *
   12.11 + * Redistribution and use in source and binary forms, with or without
   12.12 + * modification, are permitted provided that the following conditions
   12.13 + * are met:
   12.14 + * 1. Redistributions of source code must retain the above copyright
   12.15 + *    notice, this list of conditions, and the following disclaimer,
   12.16 + *    without modification.
   12.17 + * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   12.18 + *    substantially similar to the "NO WARRANTY" disclaimer below
   12.19 + *    ("Disclaimer") and any redistribution must be conditioned upon
   12.20 + *    including a substantially similar Disclaimer requirement for further
   12.21 + *    binary redistribution.
   12.22 + * 3. Neither the names of the above-listed copyright holders nor the names
   12.23 + *    of any contributors may be used to endorse or promote products derived
   12.24 + *    from this software without specific prior written permission.
   12.25 + *
   12.26 + * Alternatively, this software may be distributed under the terms of the
   12.27 + * GNU General Public License ("GPL") version 2 as published by the Free
   12.28 + * Software Foundation.
   12.29 + *
   12.30 + * NO WARRANTY
   12.31 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   12.32 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   12.33 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   12.34 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   12.35 + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   12.36 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   12.37 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   12.38 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   12.39 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   12.40 + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   12.41 + * POSSIBILITY OF SUCH DAMAGES.
   12.42 + *
   12.43 + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#79 $
   12.44 + *
   12.45 + * $FreeBSD$
   12.46 + */
   12.47 +
   12.48 +#ifdef __linux__
   12.49 +#include "aic79xx_osm.h"
   12.50 +#include "aic79xx_inline.h"
   12.51 +#include "aicasm/aicasm_insformat.h"
   12.52 +#else
   12.53 +#include <dev/aic7xxx/aic79xx_osm.h>
   12.54 +#include <dev/aic7xxx/aic79xx_inline.h>
   12.55 +#include <dev/aic7xxx/aicasm/aicasm_insformat.h>
   12.56 +#endif
   12.57 +
   12.58 +/****************************** Softc Data ************************************/
   12.59 +struct ahd_softc_tailq ahd_tailq = TAILQ_HEAD_INITIALIZER(ahd_tailq);
   12.60 +
   12.61 +/***************************** Lookup Tables **********************************/
   12.62 +char *ahd_chip_names[] =
   12.63 +{
   12.64 +	"NONE",
   12.65 +	"aic7901",
   12.66 +	"aic7902"
   12.67 +};
   12.68 +static const u_int num_chip_names = NUM_ELEMENTS(ahd_chip_names);
   12.69 +
   12.70 +/*
   12.71 + * Hardware error codes.
   12.72 + */
   12.73 +struct ahd_hard_error_entry {
   12.74 +        uint8_t errno;
   12.75 +	char *errmesg;
   12.76 +};
   12.77 +
   12.78 +static struct ahd_hard_error_entry ahd_hard_errors[] = {
   12.79 +	{ DSCTMOUT,	"Discard Timer has timed out" },
   12.80 +	{ ILLOPCODE,	"Illegal Opcode in sequencer program" },
   12.81 +	{ SQPARERR,	"Sequencer Parity Error" },
   12.82 +	{ DPARERR,	"Data-path Parity Error" },
   12.83 +	{ MPARERR,	"Scratch or SCB Memory Parity Error" },
   12.84 +	{ CIOPARERR,	"CIOBUS Parity Error" },
   12.85 +};
   12.86 +static const u_int num_errors = NUM_ELEMENTS(ahd_hard_errors);
   12.87 +
   12.88 +static struct ahd_phase_table_entry ahd_phase_table[] =
   12.89 +{
   12.90 +	{ P_DATAOUT,	MSG_NOOP,		"in Data-out phase"	},
   12.91 +	{ P_DATAIN,	MSG_INITIATOR_DET_ERR,	"in Data-in phase"	},
   12.92 +	{ P_DATAOUT_DT,	MSG_NOOP,		"in DT Data-out phase"	},
   12.93 +	{ P_DATAIN_DT,	MSG_INITIATOR_DET_ERR,	"in DT Data-in phase"	},
   12.94 +	{ P_COMMAND,	MSG_NOOP,		"in Command phase"	},
   12.95 +	{ P_MESGOUT,	MSG_NOOP,		"in Message-out phase"	},
   12.96 +	{ P_STATUS,	MSG_INITIATOR_DET_ERR,	"in Status phase"	},
   12.97 +	{ P_MESGIN,	MSG_PARITY_ERROR,	"in Message-in phase"	},
   12.98 +	{ P_BUSFREE,	MSG_NOOP,		"while idle"		},
   12.99 +	{ 0,		MSG_NOOP,		"in unknown phase"	}
  12.100 +};
  12.101 +
  12.102 +/*
  12.103 + * In most cases we only wish to itterate over real phases, so
  12.104 + * exclude the last element from the count.
  12.105 + */
  12.106 +static const u_int num_phases = NUM_ELEMENTS(ahd_phase_table) - 1;
  12.107 +
  12.108 +/* Our Sequencer Program */
  12.109 +#include "aic79xx_seq.h"
  12.110 +
  12.111 +/**************************** Function Declarations ***************************/
  12.112 +static void		ahd_handle_transmission_error(struct ahd_softc *ahd);
  12.113 +static void		ahd_handle_lqiphase_error(struct ahd_softc *ahd,
  12.114 +						  u_int lqistat1);
  12.115 +static int		ahd_handle_pkt_busfree(struct ahd_softc *ahd,
  12.116 +					       u_int busfreetime);
  12.117 +static int		ahd_handle_nonpkt_busfree(struct ahd_softc *ahd);
  12.118 +static void		ahd_force_renegotiation(struct ahd_softc *ahd,
  12.119 +						struct ahd_devinfo *devinfo);
  12.120 +
  12.121 +static struct ahd_tmode_tstate*
  12.122 +			ahd_alloc_tstate(struct ahd_softc *ahd,
  12.123 +					 u_int scsi_id, char channel);
  12.124 +#ifdef AHD_TARGET_MODE
  12.125 +static void		ahd_free_tstate(struct ahd_softc *ahd,
  12.126 +					u_int scsi_id, char channel, int force);
  12.127 +#endif
  12.128 +static void		ahd_devlimited_syncrate(struct ahd_softc *ahd,
  12.129 +					        struct ahd_initiator_tinfo *,
  12.130 +						u_int *period,
  12.131 +						u_int *ppr_options,
  12.132 +						role_t role);
  12.133 +static void		ahd_update_neg_table(struct ahd_softc *ahd,
  12.134 +					     struct ahd_devinfo *devinfo,
  12.135 +					     struct ahd_transinfo *tinfo);
  12.136 +static void		ahd_update_pending_scbs(struct ahd_softc *ahd);
  12.137 +static void		ahd_fetch_devinfo(struct ahd_softc *ahd,
  12.138 +					  struct ahd_devinfo *devinfo);
  12.139 +static void		ahd_scb_devinfo(struct ahd_softc *ahd,
  12.140 +					struct ahd_devinfo *devinfo,
  12.141 +					struct scb *scb);
  12.142 +static void		ahd_setup_initiator_msgout(struct ahd_softc *ahd,
  12.143 +						   struct ahd_devinfo *devinfo,
  12.144 +						   struct scb *scb);
  12.145 +static void		ahd_build_transfer_msg(struct ahd_softc *ahd,
  12.146 +					       struct ahd_devinfo *devinfo);
  12.147 +static void		ahd_construct_sdtr(struct ahd_softc *ahd,
  12.148 +					   struct ahd_devinfo *devinfo,
  12.149 +					   u_int period, u_int offset);
  12.150 +static void		ahd_construct_wdtr(struct ahd_softc *ahd,
  12.151 +					   struct ahd_devinfo *devinfo,
  12.152 +					   u_int bus_width);
  12.153 +static void		ahd_construct_ppr(struct ahd_softc *ahd,
  12.154 +					  struct ahd_devinfo *devinfo,
  12.155 +					  u_int period, u_int offset,
  12.156 +					  u_int bus_width, u_int ppr_options);
  12.157 +static void		ahd_clear_msg_state(struct ahd_softc *ahd);
  12.158 +static void		ahd_handle_message_phase(struct ahd_softc *ahd);
  12.159 +typedef enum {
  12.160 +	AHDMSG_1B,
  12.161 +	AHDMSG_2B,
  12.162 +	AHDMSG_EXT
  12.163 +} ahd_msgtype;
  12.164 +static int		ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type,
  12.165 +				     u_int msgval, int full);
  12.166 +static int		ahd_parse_msg(struct ahd_softc *ahd,
  12.167 +				      struct ahd_devinfo *devinfo);
  12.168 +static int		ahd_handle_msg_reject(struct ahd_softc *ahd,
  12.169 +					      struct ahd_devinfo *devinfo);
  12.170 +static void		ahd_handle_ign_wide_residue(struct ahd_softc *ahd,
  12.171 +						struct ahd_devinfo *devinfo);
  12.172 +static void		ahd_reinitialize_dataptrs(struct ahd_softc *ahd);
  12.173 +static void		ahd_handle_devreset(struct ahd_softc *ahd,
  12.174 +					    struct ahd_devinfo *devinfo,
  12.175 +					    cam_status status, char *message,
  12.176 +					    int verbose_level);
  12.177 +#if AHD_TARGET_MODE
  12.178 +static void		ahd_setup_target_msgin(struct ahd_softc *ahd,
  12.179 +					       struct ahd_devinfo *devinfo,
  12.180 +					       struct scb *scb);
  12.181 +#endif
  12.182 +
  12.183 +static bus_size_t	ahd_sglist_size(struct ahd_softc *ahd);
  12.184 +static bus_size_t	ahd_sglist_allocsize(struct ahd_softc *ahd);
  12.185 +static bus_dmamap_callback_t
  12.186 +			ahd_dmamap_cb; 
  12.187 +static void		ahd_initialize_hscbs(struct ahd_softc *ahd);
  12.188 +static int		ahd_init_scbdata(struct ahd_softc *ahd);
  12.189 +static void		ahd_fini_scbdata(struct ahd_softc *ahd);
  12.190 +static void		ahd_setup_iocell_workaround(struct ahd_softc *ahd);
  12.191 +static void		ahd_iocell_first_selection(struct ahd_softc *ahd);
  12.192 +static void		ahd_chip_init(struct ahd_softc *ahd);
  12.193 +static void		ahd_qinfifo_requeue(struct ahd_softc *ahd,
  12.194 +					    struct scb *prev_scb,
  12.195 +					    struct scb *scb);
  12.196 +static int		ahd_qinfifo_count(struct ahd_softc *ahd);
  12.197 +static int		ahd_search_scb_list(struct ahd_softc *ahd, int target,
  12.198 +					    char channel, int lun, u_int tag,
  12.199 +					    role_t role, uint32_t status,
  12.200 +					    ahd_search_action action,
  12.201 +					    u_int *list_head, u_int tid);
  12.202 +static void		ahd_stitch_tid_list(struct ahd_softc *ahd,
  12.203 +					    u_int tid_prev, u_int tid_cur,
  12.204 +					    u_int tid_next);
  12.205 +static void		ahd_add_scb_to_free_list(struct ahd_softc *ahd,
  12.206 +						 u_int scbid);
  12.207 +static u_int		ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
  12.208 +				     u_int prev, u_int next, u_int tid);
  12.209 +static void		ahd_reset_current_bus(struct ahd_softc *ahd);
  12.210 +static ahd_callback_t	ahd_reset_poll;
  12.211 +#ifdef AHD_DUMP_SEQ
  12.212 +static void		ahd_dumpseq(struct ahd_softc *ahd);
  12.213 +#endif
  12.214 +static void		ahd_loadseq(struct ahd_softc *ahd);
  12.215 +static int		ahd_check_patch(struct ahd_softc *ahd,
  12.216 +					struct patch **start_patch,
  12.217 +					u_int start_instr, u_int *skip_addr);
  12.218 +static u_int		ahd_resolve_seqaddr(struct ahd_softc *ahd,
  12.219 +					    u_int address);
  12.220 +static void		ahd_download_instr(struct ahd_softc *ahd,
  12.221 +					   u_int instrptr, uint8_t *dconsts);
  12.222 +#ifdef AHD_TARGET_MODE
  12.223 +static void		ahd_queue_lstate_event(struct ahd_softc *ahd,
  12.224 +					       struct ahd_tmode_lstate *lstate,
  12.225 +					       u_int initiator_id,
  12.226 +					       u_int event_type,
  12.227 +					       u_int event_arg);
  12.228 +static void		ahd_update_scsiid(struct ahd_softc *ahd,
  12.229 +					  u_int targid_mask);
  12.230 +static int		ahd_handle_target_cmd(struct ahd_softc *ahd,
  12.231 +					      struct target_cmd *cmd);
  12.232 +#endif
  12.233 +
  12.234 +/******************************** Private Inlines *****************************/
  12.235 +static __inline void	ahd_assert_atn(struct ahd_softc *ahd);
  12.236 +static __inline int	ahd_currently_packetized(struct ahd_softc *ahd);
  12.237 +static __inline int	ahd_set_active_fifo(struct ahd_softc *ahd);
  12.238 +
  12.239 +static __inline void
  12.240 +ahd_assert_atn(struct ahd_softc *ahd)
  12.241 +{
  12.242 +	ahd_outb(ahd, SCSISIGO, ATNO);
  12.243 +}
  12.244 +
  12.245 +/*
  12.246 + * Determine if the current connection has a packetized
  12.247 + * agreement.  This does not necessarily mean that we
  12.248 + * are currently in a packetized transfer.  We could
  12.249 + * just as easily be sending or receiving a message.
  12.250 + */
  12.251 +static __inline int
  12.252 +ahd_currently_packetized(struct ahd_softc *ahd)
  12.253 +{
  12.254 +	ahd_mode_state	 saved_modes;
  12.255 +	int		 packetized;
  12.256 +
  12.257 +	saved_modes = ahd_save_modes(ahd);
  12.258 +	if ((ahd->bugs & AHD_PKTIZED_STATUS_BUG) != 0) {
  12.259 +		/*
  12.260 +		 * The packetized bit refers to the last
  12.261 +		 * connection, not the current one.  Check
  12.262 +		 * for non-zero LQISTATE instead.
  12.263 +		 */
  12.264 +		ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
  12.265 +		packetized = ahd_inb(ahd, LQISTATE) != 0;
  12.266 +	} else {
  12.267 +		ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
  12.268 +		packetized = ahd_inb(ahd, LQISTAT2) & PACKETIZED;
  12.269 +	}
  12.270 +	ahd_restore_modes(ahd, saved_modes);
  12.271 +	return (packetized);
  12.272 +}
  12.273 +
  12.274 +static __inline int
  12.275 +ahd_set_active_fifo(struct ahd_softc *ahd)
  12.276 +{
  12.277 +	u_int active_fifo;
  12.278 +
  12.279 +	AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
  12.280 +	active_fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO;
  12.281 +/* XXX This is a three possition switch in the B. */
  12.282 +	switch (active_fifo) {
  12.283 +	case 0:
  12.284 +	case 1:
  12.285 +		ahd_set_modes(ahd, active_fifo, active_fifo);
  12.286 +		return (1);
  12.287 +	default:
  12.288 +		return (0);
  12.289 +	}
  12.290 +}
  12.291 +
  12.292 +/************************* Sequencer Execution Control ************************/
  12.293 +/*
  12.294 + * Restart the sequencer program from address zero
  12.295 + */
  12.296 +void
  12.297 +ahd_restart(struct ahd_softc *ahd)
  12.298 +{
  12.299 +
  12.300 +	ahd_pause(ahd);
  12.301 +
  12.302 +	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
  12.303 +
  12.304 +	/* No more pending messages */
  12.305 +	ahd_clear_msg_state(ahd);
  12.306 +	ahd_outb(ahd, SCSISIGO, 0);		/* De-assert BSY */
  12.307 +	ahd_outb(ahd, MSG_OUT, MSG_NOOP);	/* No message to send */
  12.308 +	ahd_outb(ahd, SXFRCTL1, ahd_inb(ahd, SXFRCTL1) & ~BITBUCKET);
  12.309 +	ahd_outb(ahd, SEQINTCTL, 0);
  12.310 +	ahd_outb(ahd, LASTPHASE, P_BUSFREE);
  12.311 +	ahd_outb(ahd, SEQ_FLAGS, 0);
  12.312 +	ahd_outb(ahd, SAVED_SCSIID, 0xFF);
  12.313 +	ahd_outb(ahd, SAVED_LUN, 0xFF);
  12.314 +
  12.315 +	/*
  12.316 +	 * Ensure that the sequencer's idea of TQINPOS
  12.317 +	 * matches our own.  The sequencer increments TQINPOS
  12.318 +	 * only after it sees a DMA complete and a reset could
  12.319 +	 * occur before the increment leaving the kernel to believe
  12.320 +	 * the command arrived but the sequencer to not.
  12.321 +	 */
  12.322 +	ahd_outb(ahd, TQINPOS, ahd->tqinfifonext);
  12.323 +
  12.324 +	/* Always allow reselection */
  12.325 +	ahd_outb(ahd, SCSISEQ1,
  12.326 +		 ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
  12.327 +	/* Ensure that no DMA operations are in progress */
  12.328 +	ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
  12.329 +	ahd_outb(ahd, SCBHCNT, 0);
  12.330 +	ahd_outb(ahd, CCSCBCTL, CCSCBRESET);
  12.331 +
  12.332 +	ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
  12.333 +	ahd_unpause(ahd);
  12.334 +}
  12.335 +
  12.336 +void
  12.337 +ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo)
  12.338 +{
  12.339 +	ahd_mode_state	 saved_modes;
  12.340 +
  12.341 +#if AHD_DEBUG
  12.342 +	if ((ahd_debug & AHD_SHOW_FIFOS) != 0)
  12.343 +		printf("%s: Clearing FIFO %d\n", ahd_name(ahd), fifo);
  12.344 +#endif
  12.345 +	saved_modes = ahd_save_modes(ahd);
  12.346 +	ahd_set_modes(ahd, fifo, fifo);
  12.347 +	ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT);
  12.348 +	if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
  12.349 +		ahd_outb(ahd, CCSGCTL, CCSGRESET);
  12.350 +	ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
  12.351 +	ahd_outb(ahd, SG_STATE, 0);
  12.352 +	ahd_restore_modes(ahd, saved_modes);
  12.353 +}
  12.354 +
  12.355 +/************************* Input/Output Queues ********************************/
  12.356 +void
  12.357 +ahd_run_qoutfifo(struct ahd_softc *ahd)
  12.358 +{
  12.359 +	struct scb *scb;
  12.360 +	u_int  scb_index;
  12.361 +
  12.362 +	ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD);
  12.363 +	while (ahd->qoutfifo[ahd->qoutfifonext] != SCB_LIST_NULL_LE) {
  12.364 +
  12.365 +		scb_index = ahd_le16toh(ahd->qoutfifo[ahd->qoutfifonext]);
  12.366 +		scb = ahd_lookup_scb(ahd, scb_index);
  12.367 +		if (scb == NULL) {
  12.368 +			printf("%s: WARNING no command for scb %d "
  12.369 +			       "(cmdcmplt)\nQOUTPOS = %d\n",
  12.370 +			       ahd_name(ahd), scb_index,
  12.371 +			       ahd->qoutfifonext);
  12.372 +			ahd_dump_card_state(ahd);
  12.373 +			ahd->qoutfifonext = AHD_QOUT_WRAP(ahd->qoutfifonext+1);
  12.374 +			continue;
  12.375 +		}
  12.376 +
  12.377 +		if ((ahd->qoutfifonext & 0x01) == 0x01) {
  12.378 +
  12.379 +			/*
  12.380 +			 * Clear 32bits of QOUTFIFO at a time
  12.381 +			 * so that we don't clobber an incoming
  12.382 +			 * 16bit DMA to the array on architectures
  12.383 +			 * that only support 32bit load and store
  12.384 +			 * operations.
  12.385 +			 */
  12.386 +			ahd->qoutfifo[ahd->qoutfifonext - 1] = SCB_LIST_NULL_LE;
  12.387 +			ahd->qoutfifo[ahd->qoutfifonext] = SCB_LIST_NULL_LE;
  12.388 +			ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
  12.389 +					ahd->shared_data_dmamap,
  12.390 +					/*offset*/(ahd->qoutfifonext - 1)*2,
  12.391 +					/*len*/4, BUS_DMASYNC_PREREAD);
  12.392 +		}
  12.393 +		ahd->qoutfifonext = AHD_QOUT_WRAP(ahd->qoutfifonext+1);
  12.394 +
  12.395 +		ahd_complete_scb(ahd, scb);
  12.396 +	}
  12.397 +}
  12.398 +
  12.399 +void
  12.400 +ahd_run_untagged_queues(struct ahd_softc *ahd)
  12.401 +{
  12.402 +	int i;
  12.403 +
  12.404 +	for (i = 0; i < 16; i++)
  12.405 +		ahd_run_untagged_queue(ahd, &ahd->untagged_queues[i]);
  12.406 +}
  12.407 +
  12.408 +void
  12.409 +ahd_run_untagged_queue(struct ahd_softc *ahd, struct scb_tailq *queue)
  12.410 +{
  12.411 +	struct scb *scb;
  12.412 +
  12.413 +	if (ahd->untagged_queue_lock != 0)
  12.414 +		return;
  12.415 +
  12.416 +	if ((scb = TAILQ_FIRST(queue)) != NULL
  12.417 +	 && (scb->flags & SCB_ACTIVE) == 0) {
  12.418 +		scb->flags |= SCB_ACTIVE;
  12.419 +		ahd_queue_scb(ahd, scb);
  12.420 +	}
  12.421 +}
  12.422 +
  12.423 +/************************* Interrupt Handling *********************************/
  12.424 +void
  12.425 +ahd_handle_hwerrint(struct ahd_softc *ahd)
  12.426 +{
  12.427 +	/*
  12.428 +	 * Some catastrophic hardware error has occurred.
  12.429 +	 * Print it for the user and disable the controller.
  12.430 +	 */
  12.431 +	int i;
  12.432 +	int error;
  12.433 +
  12.434 +	error = ahd_inb(ahd, ERROR);
  12.435 +	for (i = 0; i < num_errors; i++) {
  12.436 +		if ((error & ahd_hard_errors[i].errno) != 0)
  12.437 +			printf("%s: hwerrint, %s\n",
  12.438 +			       ahd_name(ahd), ahd_hard_errors[i].errmesg);
  12.439 +	}
  12.440 +
  12.441 +	ahd_dump_card_state(ahd);
  12.442 +	panic("BRKADRINT");
  12.443 +
  12.444 +	/* Tell everyone that this HBA is no longer availible */
  12.445 +	ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
  12.446 +		       CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
  12.447 +		       CAM_NO_HBA);
  12.448 +
  12.449 +	/* Tell the system that this controller has gone away. */
  12.450 +	ahd_free(ahd);
  12.451 +}
  12.452 +
  12.453 +void
  12.454 +ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
  12.455 +{
  12.456 +	u_int seqintcode;
  12.457 +
  12.458 +	/*
  12.459 +	 * Save the sequencer interrupt code and clear the SEQINT
  12.460 +	 * bit. We will unpause the sequencer, if appropriate,
  12.461 +	 * after servicing the request.
  12.462 +	 */
  12.463 +	seqintcode = ahd_inb(ahd, SEQINTCODE);
  12.464 +	ahd_outb(ahd, CLRINT, CLRSEQINT);
  12.465 +	ahd_update_modes(ahd);
  12.466 +#if AHD_DEBUG
  12.467 +	if ((ahd_debug & AHD_SHOW_MISC) != 0)
  12.468 +		printf("%s: Handle Seqint Called for code %d\n",
  12.469 +		       ahd_name(ahd), seqintcode);
  12.470 +#endif
  12.471 +	switch (seqintcode) {
  12.472 +	case ENTERING_NONPACK:
  12.473 +	{
  12.474 +		struct	scb *scb;
  12.475 +		u_int	scbid;
  12.476 +
  12.477 +		AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
  12.478 +				 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
  12.479 +		scbid = ahd_get_scbptr(ahd);
  12.480 +		scb = ahd_lookup_scb(ahd, scbid);
  12.481 +		if (scb == NULL) {
  12.482 +			/*
  12.483 +			 * Somehow need to know if this
  12.484 +			 * is from a selection or reselection.
  12.485 +			 * From that, we can termine target
  12.486 +			 * ID so we at least have an I_T nexus.
  12.487 +			 */
  12.488 +		} else {
  12.489 +			ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
  12.490 +			ahd_outb(ahd, SAVED_LUN, scb->hscb->lun);
  12.491 +			ahd_outb(ahd, SEQ_FLAGS, 0x0);
  12.492 +		}
  12.493 +		if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0
  12.494 +		 && (ahd_inb(ahd, SCSISIGO) & ATNO) != 0) {
  12.495 +			/*
  12.496 +			 * Phase change after read stream with
  12.497 +			 * CRC error with P0 asserted on last
  12.498 +			 * packet.
  12.499 +			 */
  12.500 +			printf("Assuming LQIPHASE_NLQ with P0 assertion\n");
  12.501 +		}
  12.502 +		printf("Entering NONPACK\n");
  12.503 +		break;
  12.504 +	}
  12.505 +	case INVALID_SEQINT:
  12.506 +		printf("%s: Invalid Sequencer interrupt occurred.\n",
  12.507 +		       ahd_name(ahd));
  12.508 +		ahd_dump_card_state(ahd);
  12.509 +		printf("invalid seqint");
  12.510 +		ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
  12.511 +		break;
  12.512 +	case STATUS_OVERRUN:
  12.513 +	{
  12.514 +		printf("%s: Status Overrun", ahd_name(ahd));
  12.515 +		ahd_dump_card_state(ahd);
  12.516 +		ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
  12.517 +		break;
  12.518 +	}
  12.519 +	case CFG4ISTAT_INTR:
  12.520 +	{
  12.521 +		struct	scb *scb;
  12.522 +		u_int	scbid;
  12.523 +
  12.524 +		ahd_update_modes(ahd);
  12.525 +		scbid = ahd_get_scbptr(ahd);
  12.526 +		scb = ahd_lookup_scb(ahd, scbid);
  12.527 +		if (scb == NULL) {
  12.528 +			ahd_dump_card_state(ahd);
  12.529 +			printf("CFG4ISTAT: Free SCB %d referenced", scbid);
  12.530 +			panic("For safety");
  12.531 +		}
  12.532 +		ahd_outq(ahd, HADDR, scb->sense_busaddr);
  12.533 +		ahd_outw(ahd, HCNT, AHD_SENSE_BUFSIZE);
  12.534 +		ahd_outb(ahd, HCNT + 2, 0);
  12.535 +		ahd_outb(ahd, SG_CACHE_PRE, SG_LAST_SEG);
  12.536 +		ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
  12.537 +		break;
  12.538 +	}
  12.539 +	case ILLEGAL_PHASE:
  12.540 +	{
  12.541 +		u_int bus_phase;
  12.542 +
  12.543 +		bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
  12.544 +		printf("%s: ILLEGAL_PHASE 0x%x\n",
  12.545 +		       ahd_name(ahd), bus_phase);
  12.546 +
  12.547 +		switch (bus_phase) {
  12.548 +		case P_DATAOUT:
  12.549 +		case P_DATAIN:
  12.550 +		case P_DATAOUT_DT:
  12.551 +		case P_DATAIN_DT:
  12.552 +		case P_MESGOUT:
  12.553 +		case P_STATUS:
  12.554 +		case P_MESGIN:
  12.555 +			ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
  12.556 +			printf("%s: Issued Bus Reset.\n", ahd_name(ahd));
  12.557 +			break;
  12.558 +		case P_COMMAND:
  12.559 +		{
  12.560 +			struct	ahd_devinfo devinfo;
  12.561 +			struct	scb *scb;
  12.562 +			struct	ahd_initiator_tinfo *targ_info;
  12.563 +			struct	ahd_tmode_tstate *tstate;
  12.564 +			struct	ahd_transinfo *tinfo;
  12.565 +			u_int	scbid;
  12.566 +
  12.567 +			/*
  12.568 +			 * If a target takes us into the command phase
  12.569 +			 * assume that it has been externally reset and
  12.570 +			 * has thus lost our previous packetized negotiation
  12.571 +			 * agreement.  Since we have not sent an identify
  12.572 +			 * message and may not have fully qualified the
  12.573 +			 * connection, we change our command to TUR, assert
  12.574 +			 * ATN and ABORT the task when we go to message in
  12.575 +			 * phase.  The OSM will see the REQUEUE_REQUEST
  12.576 +			 * status and retry the command.
  12.577 +			 */
  12.578 +			scbid = ahd_get_scbptr(ahd);
  12.579 +			scb = ahd_lookup_scb(ahd, scbid);
  12.580 +			if (scb == NULL) {
  12.581 +				printf("Invalid phase with no valid SCB.  "
  12.582 +				       "Resetting bus.\n");
  12.583 +				ahd_reset_channel(ahd, 'A',
  12.584 +						  /*Initiate Reset*/TRUE);
  12.585 +				break;
  12.586 +			}
  12.587 +			ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
  12.588 +					    SCB_GET_TARGET(ahd, scb),
  12.589 +					    SCB_GET_LUN(scb),
  12.590 +					    SCB_GET_CHANNEL(ahd, scb),
  12.591 +					    ROLE_INITIATOR);
  12.592 +			targ_info = ahd_fetch_transinfo(ahd,
  12.593 +							devinfo.channel,
  12.594 +							devinfo.our_scsiid,
  12.595 +							devinfo.target,
  12.596 +							&tstate);
  12.597 +			tinfo = &targ_info->curr;
  12.598 +			ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
  12.599 +				      AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
  12.600 +				      /*paused*/TRUE);
  12.601 +			ahd_set_syncrate(ahd, &devinfo, /*period*/0,
  12.602 +					 /*offset*/0, /*ppr_options*/0,
  12.603 +					 AHD_TRANS_ACTIVE, /*paused*/TRUE);
  12.604 +			ahd_outb(ahd, SCB_CDB_STORE, 0);
  12.605 +			ahd_outb(ahd, SCB_CDB_STORE+1, 0);
  12.606 +			ahd_outb(ahd, SCB_CDB_STORE+2, 0);
  12.607 +			ahd_outb(ahd, SCB_CDB_STORE+3, 0);
  12.608 +			ahd_outb(ahd, SCB_CDB_STORE+4, 0);
  12.609 +			ahd_outb(ahd, SCB_CDB_STORE+5, 0);
  12.610 +			ahd_outb(ahd, SCB_CDB_LEN, 6);
  12.611 +			scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE);
  12.612 +			scb->hscb->control |= MK_MESSAGE;
  12.613 +			ahd_outb(ahd, SCB_CONTROL, scb->hscb->control);
  12.614 +			ahd_outb(ahd, MSG_OUT, HOST_MSG);
  12.615 +			ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
  12.616 +			/*
  12.617 +			 * The lun is 0, regardless of the SCB's lun
  12.618 +			 * as we have not sent an identify message.
  12.619 +			 */
  12.620 +			ahd_outb(ahd, SAVED_LUN, 0);
  12.621 +			ahd_outb(ahd, SEQ_FLAGS, 0);
  12.622 +			ahd_assert_atn(ahd);
  12.623 +			scb->flags &= ~(SCB_PACKETIZED);
  12.624 +			scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT;
  12.625 +			ahd_freeze_devq(ahd, scb);
  12.626 +			ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
  12.627 +			ahd_freeze_scb(scb);
  12.628 +
  12.629 +			/*
  12.630 +			 * Allow the sequencer to continue with
  12.631 +			 * non-pack processing.
  12.632 +			 */
  12.633 +			ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
  12.634 +			ahd_outb(ahd, CLRLQOINT1, CLRLQOPHACHGINPKT);
  12.635 +			if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
  12.636 +				ahd_outb(ahd, CLRLQOINT1, 0);
  12.637 +			}
  12.638 +			printf("Continuing non-pack processing...\n");
  12.639 +			break;
  12.640 +		}
  12.641 +		}
  12.642 +		break;
  12.643 +	}
  12.644 +	case CFG4OVERRUN:
  12.645 +		printf("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd),
  12.646 +		       ahd_inb(ahd, MODE_PTR));
  12.647 +		break;
  12.648 +	case DUMP_CARD_STATE:
  12.649 +	{
  12.650 +		ahd_dump_card_state(ahd);
  12.651 +		break;
  12.652 +	}
  12.653 +	case PDATA_REINIT:
  12.654 +	{
  12.655 +		printf("%s: PDATA_REINIT - DFCNTRL = 0x%x "
  12.656 +		       "SG_CACHE_SHADOW = 0x%x\n",
  12.657 +		       ahd_name(ahd), ahd_inb(ahd, DFCNTRL),
  12.658 +		       ahd_inb(ahd, SG_CACHE_SHADOW));
  12.659 +		ahd_reinitialize_dataptrs(ahd);
  12.660 +		break;
  12.661 +	}
  12.662 +	case HOST_MSG_LOOP:
  12.663 +	{
  12.664 +		struct ahd_devinfo devinfo;
  12.665 +
  12.666 +		/*
  12.667 +		 * The sequencer has encountered a message phase
  12.668 +		 * that requires host assistance for completion.
  12.669 +		 * While handling the message phase(s), we will be
  12.670 +		 * notified by the sequencer after each byte is
  12.671 +		 * transfered so we can track bus phase changes.
  12.672 +		 *
  12.673 +		 * If this is the first time we've seen a HOST_MSG_LOOP
  12.674 +		 * interrupt, initialize the state of the host message
  12.675 +		 * loop.
  12.676 +		 */
  12.677 +		ahd_fetch_devinfo(ahd, &devinfo);
  12.678 +		if (ahd->msg_type == MSG_TYPE_NONE) {
  12.679 +			struct scb *scb;
  12.680 +			u_int scb_index;
  12.681 +			u_int bus_phase;
  12.682 +
  12.683 +			bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
  12.684 +			if (bus_phase != P_MESGIN
  12.685 +			 && bus_phase != P_MESGOUT) {
  12.686 +				printf("ahd_intr: HOST_MSG_LOOP bad "
  12.687 +				       "phase 0x%x\n",
  12.688 +				      bus_phase);
  12.689 +				/*
  12.690 +				 * Probably transitioned to bus free before
  12.691 +				 * we got here.  Just punt the message.
  12.692 +				 */
  12.693 +				ahd_dump_card_state(ahd);
  12.694 +				ahd_clear_intstat(ahd);
  12.695 +				ahd_restart(ahd);
  12.696 +				return;
  12.697 +			}
  12.698 +
  12.699 +			scb_index = ahd_get_scbptr(ahd);
  12.700 +			scb = ahd_lookup_scb(ahd, scb_index);
  12.701 +			if (devinfo.role == ROLE_INITIATOR) {
  12.702 +				if (bus_phase == P_MESGOUT)
  12.703 +					ahd_setup_initiator_msgout(ahd,
  12.704 +								   &devinfo,
  12.705 +								   scb);
  12.706 +				else {
  12.707 +					ahd->msg_type =
  12.708 +					    MSG_TYPE_INITIATOR_MSGIN;
  12.709 +					ahd->msgin_index = 0;
  12.710 +				}
  12.711 +			}
  12.712 +#if AHD_TARGET_MODE
  12.713 +			else {
  12.714 +				if (bus_phase == P_MESGOUT) {
  12.715 +					ahd->msg_type =
  12.716 +					    MSG_TYPE_TARGET_MSGOUT;
  12.717 +					ahd->msgin_index = 0;
  12.718 +				}
  12.719 +				else 
  12.720 +					ahd_setup_target_msgin(ahd,
  12.721 +							       &devinfo,
  12.722 +							       scb);
  12.723 +			}
  12.724 +#endif
  12.725 +		}
  12.726 +
  12.727 +		ahd_handle_message_phase(ahd);
  12.728 +		break;
  12.729 +	}
  12.730 +	case NO_MATCH:
  12.731 +	{
  12.732 +		/* Ensure we don't leave the selection hardware on */
  12.733 +		AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
  12.734 +		ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
  12.735 +
  12.736 +		printf("%s:%c:%d: no active SCB for reconnecting "
  12.737 +		       "target - issuing BUS DEVICE RESET\n",
  12.738 +		       ahd_name(ahd), 'A', ahd_inb(ahd, SELID));
  12.739 +		printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
  12.740 +		       "ARG_1 == 0x%x ACCUM = 0x%x\n",
  12.741 +		       ahd_inb(ahd, SAVED_SCSIID), ahd_inb(ahd, SAVED_LUN),
  12.742 +		       ahd_inb(ahd, ARG_1), ahd_inb(ahd, ACCUM));
  12.743 +		printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
  12.744 +		       "SINDEX == 0x%x\n",
  12.745 +		       ahd_inb(ahd, SEQ_FLAGS), ahd_get_scbptr(ahd),
  12.746 +		       ahd_find_busy_tcl(ahd,
  12.747 +			    BUILD_TCL(ahd_inb(ahd, SAVED_SCSIID),
  12.748 +				      ahd_inb(ahd, SAVED_LUN))),
  12.749 +		       ahd_inb(ahd, SINDEX));
  12.750 +		printf("SELID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
  12.751 +		       "SCB_CONTROL == 0x%x\n",
  12.752 +		       ahd_inb(ahd, SELID), ahd_inb_scbram(ahd, SCB_SCSIID),
  12.753 +		       ahd_inb_scbram(ahd, SCB_LUN),
  12.754 +		       ahd_inb_scbram(ahd, SCB_CONTROL));
  12.755 +		printf("SCSIBUS[0] == 0x%x, SCSISIGI == 0x%x\n",
  12.756 +		       ahd_inb(ahd, SCSIBUS), ahd_inb(ahd, SCSISIGI));
  12.757 +		printf("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0));
  12.758 +		printf("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0));
  12.759 +		ahd_dump_card_state(ahd);
  12.760 +		ahd->msgout_buf[0] = MSG_BUS_DEV_RESET;
  12.761 +		ahd->msgout_len = 1;
  12.762 +		ahd->msgout_index = 0;
  12.763 +		ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
  12.764 +		ahd_outb(ahd, MSG_OUT, HOST_MSG);
  12.765 +		ahd_assert_atn(ahd);
  12.766 +		break;
  12.767 +	}
  12.768 +	case PROTO_VIOLATION:
  12.769 +	{
  12.770 +		struct	scb *scb;
  12.771 +		u_int	scbid;
  12.772 +		u_int	scsiid;
  12.773 +		u_int	target;
  12.774 +		u_int	seq_flags;
  12.775 +		u_int	curphase;
  12.776 +		int	found;
  12.777 +
  12.778 +		scbid = ahd_get_scbptr(ahd);
  12.779 +		scb = ahd_lookup_scb(ahd, scbid);
  12.780 +		scsiid = ahd_inb(ahd, SAVED_SCSIID);
  12.781 +		target = SCSIID_TARGET(ahd, scsiid);
  12.782 +		seq_flags = ahd_inb(ahd, SEQ_FLAGS);
  12.783 +		curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
  12.784 +		if ((seq_flags & NOT_IDENTIFIED) != 0) {
  12.785 +
  12.786 +			/*
  12.787 +			 * The reconnecting target either did not send an
  12.788 +			 * identify message, or did, but we didn't find an SCB
  12.789 +			 * to match.
  12.790 +			 */
  12.791 +			printf("%s:%c:%d: Target did not send an "
  12.792 +			       "IDENTIFY message. LASTPHASE = 0x%x, "
  12.793 +			       "SAVED_SCSIID == 0x%x\n", ahd_name(ahd),
  12.794 +			       'A', target, ahd_inb(ahd, LASTPHASE),
  12.795 +			       scsiid);
  12.796 +		} else if (scb == NULL) {
  12.797 +			/*
  12.798 +			 * We don't seem to have an SCB active for this
  12.799 +			 * transaction.  Print an error and reset the bus.
  12.800 +			 */
  12.801 +			printf("%s:%c:%d: No SCB found during protocol "
  12.802 +			       "violation\n", ahd_name(ahd), 'A', target);
  12.803 +			goto proto_violation_reset;
  12.804 +		} else if ((seq_flags & NO_CDB_SENT) != 0) {
  12.805 +			ahd_print_path(ahd, scb);
  12.806 +			printf("No or incomplete CDB sent to device.\n");
  12.807 +		} else if ((ahd_inb(ahd, SCB_CONTROL) & STATUS_RCVD) == 0) {
  12.808 +			/*
  12.809 +			 * The target never bothered to provide status to
  12.810 +			 * us prior to completing the command.  Since we don't
  12.811 +			 * know the disposition of this command, we must attempt
  12.812 +			 * to abort it.  Assert ATN and prepare to send an abort
  12.813 +			 * message.
  12.814 +			 */
  12.815 +			ahd_print_path(ahd, scb);
  12.816 +			printf("Completed command without status.\n");
  12.817 +		} else {
  12.818 +			ahd_print_path(ahd, scb);
  12.819 +			printf("Unknown protocol violation.\n");
  12.820 +			ahd_dump_card_state(ahd);
  12.821 +		}
  12.822 +		if ((curphase & ~P_DATAIN_DT) == 0) {
  12.823 +proto_violation_reset:
  12.824 +			/*
  12.825 +			 * Target either went directly to data
  12.826 +			 * phase or didn't respond to our ATN.
  12.827 +			 * The only safe thing to do is to blow
  12.828 +			 * it away with a bus reset.
  12.829 +			 */
  12.830 +			found = ahd_reset_channel(ahd, 'A', TRUE);
  12.831 +			printf("%s: Issued Channel %c Bus Reset. "
  12.832 +			       "%d SCBs aborted\n", ahd_name(ahd), 'A', found);
  12.833 +		} else {
  12.834 +			/*
  12.835 +			 * Leave the selection hardware off in case
  12.836 +			 * this abort attempt will affect yet to
  12.837 +			 * be sent commands.
  12.838 +			 */
  12.839 +			ahd_outb(ahd, SCSISEQ0,
  12.840 +				 ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
  12.841 +			ahd_print_path(ahd, scb);
  12.842 +			printf("Protocol violation %s.  Attempting to abort.\n",
  12.843 +			       ahd_lookup_phase_entry(curphase)->phasemsg);
  12.844 +			scb->flags |= SCB_ABORT;
  12.845 +			ahd_assert_atn(ahd);
  12.846 +			ahd_outb(ahd, MSG_OUT, HOST_MSG);
  12.847 +		}
  12.848 +		return;
  12.849 +	}
  12.850 +	case IGN_WIDE_RES:
  12.851 +	{
  12.852 +		struct ahd_devinfo devinfo;
  12.853 +
  12.854 +		ahd_fetch_devinfo(ahd, &devinfo);
  12.855 +		ahd_handle_ign_wide_residue(ahd, &devinfo);
  12.856 +		break;
  12.857 +	}
  12.858 +	case BAD_PHASE:
  12.859 +	{
  12.860 +		u_int lastphase;
  12.861 +
  12.862 +		lastphase = ahd_inb(ahd, LASTPHASE);
  12.863 +		printf("%s:%c:%d: unknown scsi bus phase %x, "
  12.864 +		       "lastphase = 0x%x.  Attempting to continue\n",
  12.865 +		       ahd_name(ahd), 'A',
  12.866 +		       SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
  12.867 +		       lastphase, ahd_inb(ahd, SCSISIGI));
  12.868 +		break;
  12.869 +	}
  12.870 +	case MISSED_BUSFREE:
  12.871 +	{
  12.872 +		u_int lastphase;
  12.873 +
  12.874 +		lastphase = ahd_inb(ahd, LASTPHASE);
  12.875 +		printf("%s:%c:%d: Missed busfree. "
  12.876 +		       "Lastphase = 0x%x, Curphase = 0x%x\n",
  12.877 +		       ahd_name(ahd), 'A',
  12.878 +		       SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
  12.879 +		       lastphase, ahd_inb(ahd, SCSISIGI));
  12.880 +		ahd_restart(ahd);
  12.881 +		return;
  12.882 +	}
  12.883 +	case DATA_OVERRUN:
  12.884 +	{
  12.885 +		/*
  12.886 +		 * When the sequencer detects an overrun, it
  12.887 +		 * places the controller in "BITBUCKET" mode
  12.888 +		 * and allows the target to complete its transfer.
  12.889 +		 * Unfortunately, none of the counters get updated
  12.890 +		 * when the controller is in this mode, so we have
  12.891 +		 * no way of knowing how large the overrun was.
  12.892 +		 */
  12.893 +		struct	scb *scb;
  12.894 +		u_int	scbindex = ahd_get_scbptr(ahd);
  12.895 +		u_int	lastphase = ahd_inb(ahd, LASTPHASE);
  12.896 +
  12.897 +		scb = ahd_lookup_scb(ahd, scbindex);
  12.898 +		ahd_print_path(ahd, scb);
  12.899 +		printf("data overrun detected %s."
  12.900 +		       "  Tag == 0x%x.\n",
  12.901 +		       ahd_lookup_phase_entry(lastphase)->phasemsg,
  12.902 +  		       SCB_GET_TAG(scb));
  12.903 +		ahd_print_path(ahd, scb);
  12.904 +		printf("%s seen Data Phase.  Length = %ld.  NumSGs = %d.\n",
  12.905 +		       ahd_inb(ahd, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
  12.906 +		       ahd_get_transfer_length(scb), scb->sg_count);
  12.907 +		ahd_dump_sglist(scb);
  12.908 +
  12.909 +		/*
  12.910 +		 * Set this and it will take effect when the
  12.911 +		 * target does a command complete.
  12.912 +		 */
  12.913 +		ahd_freeze_devq(ahd, scb);
  12.914 +		ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
  12.915 +		ahd_freeze_scb(scb);
  12.916 +		break;
  12.917 +	}
  12.918 +	case MKMSG_FAILED:
  12.919 +	{
  12.920 +		struct ahd_devinfo devinfo;
  12.921 +		struct scb *scb;
  12.922 +		u_int scbid;
  12.923 +
  12.924 +		ahd_fetch_devinfo(ahd, &devinfo);
  12.925 +		printf("%s:%c:%d:%d: Attempt to issue message failed\n",
  12.926 +		       ahd_name(ahd), devinfo.channel, devinfo.target,
  12.927 +		       devinfo.lun);
  12.928 +		scbid = ahd_get_scbptr(ahd);
  12.929 +		scb = ahd_lookup_scb(ahd, scbid);
  12.930 +		if (scb != NULL
  12.931 +		 && (scb->flags & SCB_RECOVERY_SCB) != 0)
  12.932 +			/*
  12.933 +			 * Ensure that we didn't put a second instance of this
  12.934 +			 * SCB into the QINFIFO.
  12.935 +			 */
  12.936 +			ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
  12.937 +					   SCB_GET_CHANNEL(ahd, scb),
  12.938 +					   SCB_GET_LUN(scb), SCB_GET_TAG(scb),
  12.939 +					   ROLE_INITIATOR, /*status*/0,
  12.940 +					   SEARCH_REMOVE);
  12.941 +		ahd_outb(ahd, SCB_CONTROL,
  12.942 +			 ahd_inb(ahd, SCB_CONTROL) & ~MK_MESSAGE);
  12.943 +		break;
  12.944 +	}
  12.945 +	}
  12.946 +	/*
  12.947 +	 *  The sequencer is paused immediately on
  12.948 +	 *  a SEQINT, so we should restart it when
  12.949 +	 *  we're done.
  12.950 +	 */
  12.951 +	ahd_unpause(ahd);
  12.952 +}
  12.953 +
  12.954 +void
  12.955 +ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
  12.956 +{
  12.957 +	struct scb	*scb;
  12.958 +	u_int		 status0;
  12.959 +	u_int		 status3;
  12.960 +	u_int		 status;
  12.961 +	u_int		 lqistat1;
  12.962 +	u_int		 lqostat0;
  12.963 +	u_int		 scbid;
  12.964 +
  12.965 +	ahd_update_modes(ahd);
  12.966 +	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
  12.967 +
  12.968 +	status3 = ahd_inb(ahd, SSTAT3) & (NTRAMPERR|OSRAMPERR);
  12.969 +	status0 = ahd_inb(ahd, SSTAT0) & (IOERR|OVERRUN|SELDI|SELDO);
  12.970 +	status = ahd_inb(ahd, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
  12.971 +	lqistat1 = ahd_inb(ahd, LQISTAT1);
  12.972 +	lqostat0 = ahd_inb(ahd, LQOSTAT0);
  12.973 +	if ((status0 & (SELDI|SELDO)) != 0) {
  12.974 +		u_int simode0;
  12.975 +
  12.976 +		ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
  12.977 +		simode0 = ahd_inb(ahd, SIMODE0);
  12.978 +		status0 &= simode0 & (ENSELDO|ENSELDI|IOERR);
  12.979 +		ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
  12.980 +	}
  12.981 +	scbid = ahd_get_scbptr(ahd);
  12.982 +	scb = ahd_lookup_scb(ahd, scbid);
  12.983 +	if (scb != NULL
  12.984 +	 && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
  12.985 +		scb = NULL;
  12.986 +
  12.987 +	/* Make sure the sequencer is in a safe location. */
  12.988 +	ahd_clear_critical_section(ahd);
  12.989 +
  12.990 +	if ((status0 & IOERR) != 0) {
  12.991 +		int now_lvd;
  12.992 +
  12.993 +		now_lvd = ahd_inb(ahd, SBLKCTL) & ENAB40;
  12.994 +		printf("%s: Transceiver State Has Changed to %s mode\n",
  12.995 +		       ahd_name(ahd), now_lvd ? "LVD" : "SE");
  12.996 +		ahd_outb(ahd, CLRSINT0, CLRIOERR);
  12.997 +/* XXX Still True?? */
  12.998 +		/*
  12.999 +		 * When transitioning to SE mode, the reset line
 12.1000 +		 * glitches, triggering an arbitration bug in some
 12.1001 +		 * Ultra2 controllers.  This bug is cleared when we
 12.1002 +		 * assert the reset line.  Since a reset glitch has
 12.1003 +		 * already occurred with this transition and a
 12.1004 +		 * transceiver state change is handled just like
 12.1005 +		 * a bus reset anyway, asserting the reset line
 12.1006 +		 * ourselves is safe.
 12.1007 +		 */
 12.1008 +		ahd_reset_channel(ahd, 'A', /*Initiate Reset*/now_lvd == 0);
 12.1009 +
 12.1010 +		ahd_pause(ahd);
 12.1011 +		ahd_setup_iocell_workaround(ahd);
 12.1012 +		ahd_unpause(ahd);
 12.1013 +	} else if ((status0 & OVERRUN) != 0) {
 12.1014 +		printf("%s: SCSI offset overrun detected.  Resetting bus.\n",
 12.1015 +		       ahd_name(ahd));
 12.1016 +		ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
 12.1017 +	} else if ((status & SCSIRSTI) != 0) {
 12.1018 +		printf("%s: Someone reset channel A\n", ahd_name(ahd));
 12.1019 +		ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE);
 12.1020 +	} else if ((status & SCSIPERR) != 0) {
 12.1021 +		ahd_handle_transmission_error(ahd);
 12.1022 +	} else if (lqostat0 != 0) {
 12.1023 +		printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0);
 12.1024 +		ahd_outb(ahd, CLRLQOINT0, lqostat0);
 12.1025 +		if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
 12.1026 +			ahd_outb(ahd, CLRLQOINT1, 0);
 12.1027 +		}
 12.1028 +	} else if ((status & SELTO) != 0) {
 12.1029 +		u_int scbid;
 12.1030 +
 12.1031 +		/* Stop the selection */
 12.1032 +		ahd_outb(ahd, SCSISEQ0, 0);
 12.1033 +
 12.1034 +		/* No more pending messages */
 12.1035 +		ahd_clear_msg_state(ahd);
 12.1036 +
 12.1037 +		/* Clear interrupt state */
 12.1038 +		ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENBUSFREE);
 12.1039 +		ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
 12.1040 +
 12.1041 +		/*
 12.1042 +		 * Although the driver does not care about the
 12.1043 +		 * 'Selection in Progress' status bit, the busy
 12.1044 +		 * LED does.  SELINGO is only cleared by a sucessfull
 12.1045 +		 * selection, so we must manually clear it to insure
 12.1046 +		 * the LED turns off just incase no future successful
 12.1047 +		 * selections occur (e.g. no devices on the bus).
 12.1048 +		 */
 12.1049 +		ahd_outb(ahd, CLRSINT0, CLRSELINGO);
 12.1050 +
 12.1051 +		scbid = ahd_inw(ahd, WAITING_TID_HEAD);
 12.1052 +#if AHD_DEBUG
 12.1053 +		if ((ahd_debug & AHD_SHOW_SELTO) != 0)
 12.1054 +			printf("%s: Saw Selection Timeout for SCB 0x%x\n",
 12.1055 +			       ahd_name(ahd), scbid);
 12.1056 +#endif
 12.1057 +		scb = ahd_lookup_scb(ahd, scbid);
 12.1058 +		if (scb == NULL) {
 12.1059 +			printf("%s: ahd_intr - referenced scb not "
 12.1060 +			       "valid during SELTO scb(0x%x)\n",
 12.1061 +			       ahd_name(ahd), scbid);
 12.1062 +			ahd_dump_card_state(ahd);
 12.1063 +			panic("For diagnostics");
 12.1064 +		} else {
 12.1065 +			ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT);
 12.1066 +			ahd_freeze_devq(ahd, scb);
 12.1067 +		}
 12.1068 +		ahd_outb(ahd, CLRINT, CLRSCSIINT);
 12.1069 +		ahd_iocell_first_selection(ahd);
 12.1070 +		ahd_restart(ahd);
 12.1071 +	} else if ((status0 & (SELDI|SELDO)) != 0) {
 12.1072 +		ahd_iocell_first_selection(ahd);
 12.1073 +		ahd_unpause(ahd);
 12.1074 +	} else if (status3 != 0) {
 12.1075 +		printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n",
 12.1076 +		       ahd_name(ahd), status3);
 12.1077 +		ahd_outb(ahd, CLRSINT3, status3);
 12.1078 +	} else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) {
 12.1079 +		ahd_handle_lqiphase_error(ahd, lqistat1);
 12.1080 +	} else if ((status & BUSFREE) != 0) {
 12.1081 +		u_int busfreetime;
 12.1082 +		u_int lqostat1;
 12.1083 +		int   restart;
 12.1084 +		int   clear_fifo;
 12.1085 +		int   packetized;
 12.1086 +		u_int mode;
 12.1087 +
 12.1088 +		/*
 12.1089 +		 * Clear our selection hardware as soon as possible.
 12.1090 +		 * We may have an entry in the waiting Q for this target,
 12.1091 +		 * that is affected by this busfree and we don't want to
 12.1092 +		 * go about selecting the target while we handle the event.
 12.1093 +		 */
 12.1094 +		ahd_outb(ahd, SCSISEQ0, 0);
 12.1095 +
 12.1096 +		/*
 12.1097 +		 * Determine what we were up to at the time of
 12.1098 +		 * the busfree.
 12.1099 +		 */
 12.1100 +		mode = AHD_MODE_SCSI;
 12.1101 +		ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
 12.1102 +		busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME;
 12.1103 +		lqostat1 = ahd_inb(ahd, LQOSTAT1);
 12.1104 +		switch (busfreetime) {
 12.1105 +		case BUSFREE_DFF0:
 12.1106 +		case BUSFREE_DFF1:
 12.1107 +		{
 12.1108 +			u_int	scbid;
 12.1109 +			struct	scb *scb;
 12.1110 +
 12.1111 +			mode = busfreetime == BUSFREE_DFF0
 12.1112 +			     ? AHD_MODE_DFF0 : AHD_MODE_DFF1;
 12.1113 +			ahd_set_modes(ahd, mode, mode);
 12.1114 +			scbid = ahd_get_scbptr(ahd);
 12.1115 +			scb = ahd_lookup_scb(ahd, scbid);
 12.1116 +			if (scb == NULL) {
 12.1117 +				printf("%s: Invalid SCB in DFF%d "
 12.1118 +				       "during unexpected busfree\n",
 12.1119 +				       ahd_name(ahd), mode);
 12.1120 +				packetized = 0;
 12.1121 +			} else
 12.1122 +				packetized = (scb->flags & SCB_PACKETIZED) != 0;
 12.1123 +			clear_fifo = 1;
 12.1124 +			break;
 12.1125 +		}
 12.1126 +		case BUSFREE_LQO:
 12.1127 +			clear_fifo = 0;
 12.1128 +			packetized = 1;
 12.1129 +			break;
 12.1130 +		default:
 12.1131 +			clear_fifo = 0;
 12.1132 +			packetized =  (lqostat1 & LQOBUSFREE) != 0;
 12.1133 +			if (!packetized
 12.1134 +			 && ahd_inb(ahd, LASTPHASE) == P_BUSFREE)
 12.1135 +				packetized = 1;
 12.1136 +			break;
 12.1137 +		}
 12.1138 +
 12.1139 +#if AHD_DEBUG
 12.1140 +		if ((ahd_debug & AHD_SHOW_MISC) != 0)
 12.1141 +			printf("Saw Busfree.  Busfreetime = 0x%x.\n",
 12.1142 +			       busfreetime);
 12.1143 +#endif
 12.1144 +		/*
 12.1145 +		 * Busfrees that occur in non-packetized phases are
 12.1146 +		 * handled by the nonpkt_busfree handler.
 12.1147 +		 */
 12.1148 +		if (packetized && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) {
 12.1149 +			restart = ahd_handle_pkt_busfree(ahd, busfreetime);
 12.1150 +		} else {
 12.1151 +			restart = ahd_handle_nonpkt_busfree(ahd);
 12.1152 +		}
 12.1153 +		/*
 12.1154 +		 * Clear the busfree interrupt status.  The setting of
 12.1155 +		 * the interrupt is a pulse, so we do not need to muck
 12.1156 +		 * with the ENBUSFREE logic.  This also ensures that if
 12.1157 +		 * the bus has moved on to another connection, busfree
 12.1158 +		 * protection is still in force.
 12.1159 +		 */
 12.1160 +		ahd_outb(ahd, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);
 12.1161 +
 12.1162 +		if (clear_fifo)
 12.1163 +			ahd_clear_fifo(ahd, mode);
 12.1164 +
 12.1165 +		ahd_clear_msg_state(ahd);
 12.1166 +		ahd_outb(ahd, CLRINT, CLRSCSIINT);
 12.1167 +		if (restart)
 12.1168 +			ahd_restart(ahd);
 12.1169 +		else {
 12.1170 +			ahd_unpause(ahd);
 12.1171 +		}
 12.1172 +	} else {
 12.1173 +		printf("%s: Missing case in ahd_handle_scsiint. status = %x\n",
 12.1174 +		       ahd_name(ahd), status);
 12.1175 +		printf("%s: lqostat1 == 0x%x, SIMODE1 == 0x%x\n",
 12.1176 +		       ahd_name(ahd), ahd_inb(ahd, LQOSTAT1),
 12.1177 +		       ahd_inb(ahd, SIMODE1));
 12.1178 +		ahd_outb(ahd, CLRINT, CLRSCSIINT);
 12.1179 +		ahd_dump_card_state(ahd);
 12.1180 +		panic("Missing SCSIINT case");
 12.1181 +		ahd_unpause(ahd);
 12.1182 +	}
 12.1183 +}
 12.1184 +
 12.1185 +static void
 12.1186 +ahd_handle_transmission_error(struct ahd_softc *ahd)
 12.1187 +{
 12.1188 +	u_int		 lqistat1;
 12.1189 +	u_int		 lqistat2;
 12.1190 +	u_int		 msg_out;
 12.1191 +	u_int		 curphase;
 12.1192 +	u_int		 lastphase;
 12.1193 +	u_int		 perrdiag;
 12.1194 +
 12.1195 +	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
 12.1196 +	lqistat1 = ahd_inb(ahd, LQISTAT1) & ~(LQIPHASE_LQ|LQIPHASE_NLQ);
 12.1197 +	lqistat2 = ahd_inb(ahd, LQISTAT2);
 12.1198 +	if ((lqistat1 & (LQICRCI_NLQ|LQICRCI_LQ)) == 0
 12.1199 +	 && (ahd->bugs & AHD_NLQICRC_DELAYED_BUG) != 0) {
 12.1200 +		u_int lqistate;
 12.1201 +
 12.1202 +		ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
 12.1203 +		lqistate = ahd_inb(ahd, LQISTATE);
 12.1204 +		if ((lqistate >= 0x1E && lqistate <= 0x24)
 12.1205 +		 || (lqistate == 0x29)) {
 12.1206 +			printf("%s: NLQCRC found via LQISTATE\n",
 12.1207 +			       ahd_name(ahd));
 12.1208 +			lqistat1 |= LQICRCI_NLQ;
 12.1209 +		}
 12.1210 +		ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
 12.1211 +	}
 12.1212 +
 12.1213 +	ahd_outb(ahd, CLRLQIINT1, lqistat1);
 12.1214 +	lastphase = ahd_inb(ahd, LASTPHASE);
 12.1215 +	curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
 12.1216 +	perrdiag = ahd_inb(ahd, PERRDIAG);
 12.1217 +	msg_out = MSG_INITIATOR_DET_ERR;
 12.1218 +	ahd_outb(ahd, CLRSINT1, CLRSCSIPERR);
 12.1219 +	printf("%s: Transmission error detected\n", ahd_name(ahd));
 12.1220 +	printf("%s: lqistat1 == 0x%x, LASTPHASE == 0x0%x, "
 12.1221 +	       "curphase = 0x%x, perrdiag == 0x%x\n",
 12.1222 +	       ahd_name(ahd), lqistat1, lastphase, curphase, perrdiag);
 12.1223 +	ahd_dump_card_state(ahd);
 12.1224 +	if ((lqistat1 & (LQIOVERI_LQ|LQIOVERI_NLQ)) != 0) {
 12.1225 +		printf("%s: Gross protocol error during incoming "
 12.1226 +		       "packet.  lqistat1 == 0x%x.  Resetting bus.\n",
 12.1227 +		       ahd_name(ahd), lqistat1);
 12.1228 +		ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
 12.1229 +		return;
 12.1230 +	} else if ((lqistat1 & LQICRCI_LQ) != 0) {
 12.1231 +		/*
 12.1232 +		 * A CRC error has been detected on an incoming LQ.
 12.1233 +		 * The bus is currently hung on the last ACK.
 12.1234 +		 * Hit LQIRETRY to release the last ack, and
 12.1235 +		 * wait for the sequencer to determine that ATNO
 12.1236 +		 * is asserted while in message out to take us
 12.1237 +		 * to our host message loop.  No NONPACKREQ or
 12.1238 +		 * LQIPHASE type errors will occur in this
 12.1239 +		 * scenario.  After this first LQIRETRY, the LQI
 12.1240 +		 * manager will be in ISELO where it will
 12.1241 +		 * happily sit until another packet phase begins.
 12.1242 +		 * Unexpected bus free detection is enabled
 12.1243 +		 * through any phases that occur after we release
 12.1244 +		 * this last ack until the LQI manager sees a
 12.1245 +		 * packet phase.  This implies we may have to
 12.1246 +		 * ignore a perfectly valid "unexected busfree"
 12.1247 +		 * after our "initiator detected error" message is
 12.1248 +		 * sent.  A busfree is the expected response after
 12.1249 +		 * we tell the target that it's L_Q was corrupted.
 12.1250 +		 * (SPI4R09 10.7.3.3.3)
 12.1251 +		 */
 12.1252 +		ahd_outb(ahd, LQCTL2, LQIRETRY);
 12.1253 +		printf("LQIRetry for LQICRCI_LQ to release ACK\n");
 12.1254 +	} else if ((lqistat1 & LQICRCI_NLQ) != 0) {
 12.1255 +		u_int scbid;
 12.1256 +		struct scb *scb;
 12.1257 +
 12.1258 +		/*
 12.1259 +		 * We detected a CRC error in a NON-LQ packet.
 12.1260 +		 * The hardware has varying behavior in this situation
 12.1261 +		 * depending on whether this packet was part of a
 12.1262 +		 * stream or not.
 12.1263 +		 *
 12.1264 +		 * PKT by PKT mode:
 12.1265 +		 * The hardware has already acked the complete packet.
 12.1266 +		 * If the target honors our outstanding ATN condition,
 12.1267 +		 * we should be (or soon will be) in MSGOUT phase.
 12.1268 +		 * This will trigger the LQIPHASE_LQ status bit as the
 12.1269 +		 * hardware was expecting another LQ.  Unexpected
 12.1270 +		 * busfree detection is enabled.  Once LQIPHASE_LQ is
 12.1271 +		 * true (first entry into host message loop is much
 12.1272 +		 * the same), we must clear LQIPHASE_LQ and hit
 12.1273 +		 * LQIRETRY so the hardware is ready to handle
 12.1274 +		 * a future LQ.  NONPACKREQ will not be asserted again
 12.1275 +		 * once we hit LQIRETRY until another packet is
 12.1276 +		 * processed.  The target may either go busfree
 12.1277 +		 * or start another packet in response to our message.
 12.1278 +		 *
 12.1279 +		 * Read Streaming P0 asserted:
 12.1280 +		 * If we raise ATN and the target completes the entire
 12.1281 +		 * stream (P0 asserted during the last packet), the
 12.1282 +		 * hardware will ack all data and return to the ISTART
 12.1283 +		 * state.  When the target reponds to our ATN condition,
 12.1284 +		 * LQIPHASE_LQ will be asserted.  We should respond to
 12.1285 +		 * this with an LQIRETRY to prepare for any future
 12.1286 +		 * packets.  NONPACKREQ will not be asserted again
 12.1287 +		 * once we hit LQIRETRY until another packet is
 12.1288 +		 * processed.  The target may either go busfree or
 12.1289 +		 * start another packet in response to our message.
 12.1290 +		 * Busfree detection is enabled.
 12.1291 +		 *
 12.1292 +		 * Read Streaming P0 not asserted:
 12.1293 +		 * If we raise ATN and the target transitions to
 12.1294 +		 * MSGOUT in or after a packet where P0 is not
 12.1295 +		 * asserted, the hardware will assert LQIPHASE_NLQ.
 12.1296 +		 * We should respond to the LQIPHASE_NLQ with an
 12.1297 +		 * LQICONTINUE.  Should the target stay in a non-pkt
 12.1298 +		 * phase after we send our message, the hardware
 12.1299 +		 * will assert LQIPHASE_LQ.  Recovery is then just as
 12.1300 +		 * listed above for the read streaming with P0 asserted.
 12.1301 +		 * Busfree detection is enabled.
 12.1302 +		 */
 12.1303 +		printf("LQICRC_NLQ\n");
 12.1304 +		ahd_set_active_fifo(ahd);
 12.1305 +		scbid = ahd_get_scbptr(ahd);
 12.1306 +		scb = ahd_lookup_scb(ahd, scbid);
 12.1307 +		if (scb == NULL) {
 12.1308 +			printf("%s: No SCB valid for LQICRC_NLQ.  "
 12.1309 +			       "Resetting bus\n", ahd_name(ahd));
 12.1310 +			ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
 12.1311 +			return;
 12.1312 +		}
 12.1313 +		scb->flags |= SCB_TRANSMISSION_ERROR;
 12.1314 +	} else if ((lqistat1 & LQIBADLQI) != 0) {
 12.1315 +		printf("Need to handle BADLQI!\n");
 12.1316 +		ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
 12.1317 +		return;
 12.1318 +	} else if ((perrdiag & (PARITYERR|LASTPHASE)) == PARITYERR) {
 12.1319 +		if ((curphase & ~P_DATAIN_DT) != 0) {
 12.1320 +			/* Ack the byte.  So we can continue. */
 12.1321 +			printf("Acking %s to clear perror\n",
 12.1322 +			       ahd_lookup_phase_entry(curphase)->phasemsg);
 12.1323 +			ahd_inb(ahd, SCSIDAT);
 12.1324 +		}
 12.1325 +	
 12.1326 +		if (curphase == P_MESGIN)
 12.1327 +			msg_out = MSG_PARITY_ERROR;
 12.1328 +	}
 12.1329 +
 12.1330 +	/*
 12.1331 +	 * We've set the hardware to assert ATN if we 
 12.1332 +	 * get a parity error on "in" phases, so all we
 12.1333 +	 * need to do is stuff the message buffer with
 12.1334 +	 * the appropriate message.  "In" phases have set
 12.1335 +	 * mesg_out to something other than MSG_NOP.
 12.1336 +	 */
 12.1337 +	ahd->send_msg_perror = msg_out;
 12.1338 +	ahd_outb(ahd, MSG_OUT, HOST_MSG);
 12.1339 +	ahd_outb(ahd, CLRINT, CLRSCSIINT);
 12.1340 +	ahd_unpause(ahd);
 12.1341 +}
 12.1342 +
 12.1343 +static void
 12.1344 +ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1)
 12.1345 +{
 12.1346 +	/*
 12.1347 +	 * Clear the sources of the interrupts.
 12.1348 +	 */
 12.1349 +	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
 12.1350 +	ahd_outb(ahd, CLRLQIINT1, lqistat1);
 12.1351 +
 12.1352 +	/*
 12.1353 +	 * If the "illegal" phase changes were in response
 12.1354 +	 * to our ATN to flag a CRC error, AND we ended up
 12.1355 +	 * on packet boundaries, clear the error, restart the
 12.1356 +	 * LQI manager as appropriate, and go on our merry
 12.1357 +	 * way toward sending the message.  Otherwise, reset
 12.1358 +	 * the bus to clear the error.
 12.1359 +	 */
 12.1360 +	ahd_set_active_fifo(ahd);
 12.1361 +	if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0
 12.1362 +	 && (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) {
 12.1363 +		if ((lqistat1 & LQIPHASE_LQ) != 0) {
 12.1364 +			printf("LQIRETRY for LQIPHASE_LQ\n");
 12.1365 +			ahd_outb(ahd, LQCTL2, LQIRETRY);
 12.1366 +		} else if ((lqistat1 & LQIPHASE_NLQ) != 0) {
 12.1367 +			printf("LQICONTINUE for LQIPHASE_NLQ\n");
 12.1368 +			ahd_outb(ahd, LQCTL2, LQIRETRY);
 12.1369 +		} else
 12.1370 +			panic("ahd_handle_lqiphase_error: No phase errors\n");
 12.1371 +		ahd_dump_card_state(ahd);
 12.1372 +		ahd_outb(ahd, CLRINT, CLRSCSIINT);
 12.1373 +		ahd_unpause(ahd);
 12.1374 +	} else {
 12.1375 +		printf("Reseting Channel for LQI Phase error\n");
 12.1376 +		ahd_dump_card_state(ahd);
 12.1377 +		ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
 12.1378 +	}
 12.1379 +}
 12.1380 +
 12.1381 +/*
 12.1382 + * Packetized unexpected or expected busfree.
 12.1383 + * Entered in MODE_SCSI.
 12.1384 + */
 12.1385 +static int
 12.1386 +ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
 12.1387 +{
 12.1388 +	u_int lqostat1;
 12.1389 +
 12.1390 +	AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
 12.1391 +			 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
 12.1392 +	lqostat1 = ahd_inb(ahd, LQOSTAT1);
 12.1393 +	if ((lqostat1 & LQOBUSFREE) != 0) {
 12.1394 +		struct scb *scb;
 12.1395 +		u_int scbid;
 12.1396 +		u_int waiting_h;
 12.1397 +		u_int waiting_t;
 12.1398 +		u_int next;
 12.1399 +
 12.1400 +		if ((busfreetime & BUSFREE_LQO) == 0)
 12.1401 +			printf("%s: Warning, BUSFREE time is 0x%x.  "
 12.1402 +			       "Expected BUSFREE_LQO.\n",
 12.1403 +			       ahd_name(ahd), busfreetime);
 12.1404 +
 12.1405 +		scbid = ahd_get_scbptr(ahd);
 12.1406 +		scb = ahd_lookup_scb(ahd, scbid);
 12.1407 +		if (scb == NULL)
 12.1408 +		       panic("SCB not valid during LQOBUSFREE");
 12.1409 +		ahd_print_path(ahd, scb);
 12.1410 +		printf("Probable outgoing LQ CRC error.  Retrying command\n");
 12.1411 +
 12.1412 +		/*
 12.1413 +		 * Return the LQO manager to its idle loop.  It will
 12.1414 +		 * not do this automatically if the busfree occurs
 12.1415 +		 * after the first REQ of either the LQ or command
 12.1416 +		 * packet or between the LQ and command packet.
 12.1417 +		 */
 12.1418 +		ahd_outb(ahd, LQCTL2, ahd_inb(ahd, LQCTL2) | LQOTOIDLE);
 12.1419 +
 12.1420 +		/*
 12.1421 +		 * Clear the status.
 12.1422 +		 */
 12.1423 +		ahd_outb(ahd, CLRLQOINT1, CLRLQOBUSFREE);
 12.1424 +		if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
 12.1425 +			ahd_outb(ahd, CLRLQOINT1, 0);
 12.1426 +		}
 12.1427 +		/*
 12.1428 +		 * The LQO manager detected an unexpected busfree
 12.1429 +		 * either:
 12.1430 +		 *
 12.1431 +		 * 1) During an outgoing LQ.
 12.1432 +		 * 2) After an outgoing LQ but before the first
 12.1433 +		 *    REQ of the command packet.
 12.1434 +		 * 3) During an outgoing command packet.
 12.1435 +		 *
 12.1436 +		 * In all cases, CURRSCB is pointing to the
 12.1437 +		 * SCB that encountered the failure.  Clean
 12.1438 +		 * up the queue, clear SELDO and LQOBUSFREE,
 12.1439 +		 * and allow the sequencer to restart the select
 12.1440 +		 * out at its lesure.
 12.1441 +		 */
 12.1442 +		ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
 12.1443 +		ahd_outb(ahd, CLRSINT0, CLRSELDO);
 12.1444 +		waiting_h = ahd_inw(ahd, WAITING_TID_HEAD);
 12.1445 +		if (waiting_h != scbid) {
 12.1446 +
 12.1447 +			ahd_outw(ahd, WAITING_TID_HEAD, scbid);
 12.1448 +			waiting_t = ahd_inw(ahd, WAITING_TID_TAIL);
 12.1449 +			next = SCB_LIST_NULL;
 12.1450 +			if (waiting_t == waiting_h) {
 12.1451 +				ahd_outw(ahd, WAITING_TID_TAIL, scbid);
 12.1452 +			} else {
 12.1453 +				ahd_set_scbptr(ahd, waiting_h);
 12.1454 +				next = ahd_inw(ahd, SCB_NEXT2);
 12.1455 +			}
 12.1456 +			ahd_set_scbptr(ahd, scbid);
 12.1457 +			ahd_outw(ahd, SCB_NEXT2, next);
 12.1458 +		}
 12.1459 +
 12.1460 +		/* Return unpausing the sequencer. */
 12.1461 +		return (0);
 12.1462 +	}
 12.1463 +	if (ahd->src_mode != AHD_MODE_SCSI) {
 12.1464 +		u_int	scbid;
 12.1465 +		struct	scb *scb;
 12.1466 +
 12.1467 +		scbid = ahd_get_scbptr(ahd);
 12.1468 +		scb = ahd_lookup_scb(ahd, scbid);
 12.1469 +		ahd_print_path(ahd, scb);
 12.1470 +		printf("Unexpected PKT busfree condition\n");
 12.1471 +		ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A',
 12.1472 +			       SCB_GET_LUN(scb), SCB_GET_TAG(scb),
 12.1473 +			       ROLE_INITIATOR, CAM_UNEXP_BUSFREE);
 12.1474 +
 12.1475 +		/* Return restarting the sequencer. */
 12.1476 +		return (1);
 12.1477 +	}
 12.1478 +	printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd));
 12.1479 +	ahd_dump_card_state(ahd);
 12.1480 +	/* Restart the sequencer. */
 12.1481 +	return (1);
 12.1482 +}
 12.1483 +
 12.1484 +/*
 12.1485 + * Non-packetized unexpected or expected busfree.
 12.1486 + */
 12.1487 +static int
 12.1488 +ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
 12.1489 +{
 12.1490 +	struct	ahd_devinfo devinfo;
 12.1491 +	struct	scb *scb;
 12.1492 +	u_int	lastphase;
 12.1493 +	u_int	saved_scsiid;
 12.1494 +	u_int	saved_lun;
 12.1495 +	u_int	target;
 12.1496 +	u_int	initiator_role_id;
 12.1497 +	u_int	scbid;
 12.1498 +	int	printerror;
 12.1499 +
 12.1500 +	/*
 12.1501 +	 * Look at what phase we were last in.  If its message out,
 12.1502 +	 * chances are pretty good that the busfree was in response
 12.1503 +	 * to one of our abort requests.
 12.1504 +	 */
 12.1505 +	lastphase = ahd_inb(ahd, LASTPHASE);
 12.1506 +	saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
 12.1507 +	saved_lun = ahd_inb(ahd, SAVED_LUN);
 12.1508 +	target = SCSIID_TARGET(ahd, saved_scsiid);
 12.1509 +	initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
 12.1510 +	ahd_compile_devinfo(&devinfo, initiator_role_id,
 12.1511 +			    target, saved_lun, 'A', ROLE_INITIATOR);
 12.1512 +	printerror = 1;
 12.1513 +
 12.1514 +	scbid = ahd_get_scbptr(ahd);
 12.1515 +	scb = ahd_lookup_scb(ahd, scbid);
 12.1516 +	if (scb != NULL
 12.1517 +	 && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
 12.1518 +		scb = NULL;
 12.1519 +
 12.1520 +	if (lastphase == P_MESGOUT) {
 12.1521 +		u_int tag;
 12.1522 +
 12.1523 +		tag = SCB_LIST_NULL;
 12.1524 +		if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE)
 12.1525 +		 || ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) {
 12.1526 +			int found;
 12.1527 +			int sent_msg;
 12.1528 +
 12.1529 +			sent_msg = ahd->msgout_buf[ahd->msgout_index - 1];
 12.1530 +			ahd_print_path(ahd, scb);
 12.1531 +			printf("SCB %d - Abort%s Completed.\n",
 12.1532 +			       SCB_GET_TAG(scb),
 12.1533 +			       sent_msg == MSG_ABORT_TAG ? "" : " Tag");
 12.1534 +
 12.1535 +			if (sent_msg == MSG_ABORT_TAG)
 12.1536 +				tag = SCB_GET_TAG(scb);
 12.1537 +
 12.1538 +			if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) {
 12.1539 +				/*
 12.1540 +				 * This abort is in response to an
 12.1541 +				 * unexpected switch to command phase
 12.1542 +				 * for a packetized connection.  Since
 12.1543 +				 * the identify message was never sent,
 12.1544 +				 * "saved lun" is 0.  We really want to
 12.1545 +				 * abort only the SCB that encountered
 12.1546 +				 * this error, which could have a different
 12.1547 +				 * lun.  The SCB will be retried so the OS
 12.1548 +				 * will see the UA after renegotiating to
 12.1549 +				 * packetized.
 12.1550 +				 */
 12.1551 +				tag = SCB_GET_TAG(scb);
 12.1552 +				saved_lun = scb->hscb->lun;
 12.1553 +			}
 12.1554 +			found = ahd_abort_scbs(ahd, target, 'A', saved_lun,
 12.1555 +					       tag, ROLE_INITIATOR,
 12.1556 +					       CAM_REQ_ABORTED);
 12.1557 +			printf("found == 0x%x\n", found);
 12.1558 +			printerror = 0;
 12.1559 +		} else if (ahd_sent_msg(ahd, AHDMSG_1B,
 12.1560 +					MSG_BUS_DEV_RESET, TRUE)) {
 12.1561 +#ifdef __FreeBSD__
 12.1562 +			/*
 12.1563 +			 * Don't mark the user's request for this BDR
 12.1564 +			 * as completing with CAM_BDR_SENT.  CAM3
 12.1565 +			 * specifies CAM_REQ_CMP.
 12.1566 +			 */
 12.1567 +			if (scb != NULL
 12.1568 +			 && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
 12.1569 +			 && ahd_match_scb(ahd, scb, target, 'A',
 12.1570 +					  CAM_LUN_WILDCARD, SCB_LIST_NULL,
 12.1571 +					  ROLE_INITIATOR))
 12.1572 +				ahd_set_transaction_status(scb, CAM_REQ_CMP);
 12.1573 +#endif
 12.1574 +			ahd_handle_devreset(ahd, &devinfo, CAM_BDR_SENT,
 12.1575 +					    "Bus Device Reset",
 12.1576 +					    /*verbose_level*/0);
 12.1577 +			printerror = 0;
 12.1578 +		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)) {
 12.1579 +			struct ahd_initiator_tinfo *tinfo;
 12.1580 +			struct ahd_tmode_tstate *tstate;
 12.1581 +
 12.1582 +			/*
 12.1583 +			 * PPR Rejected.  Try non-ppr negotiation
 12.1584 +			 * and retry command.
 12.1585 +			 */
 12.1586 +			tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
 12.1587 +						    devinfo.our_scsiid,
 12.1588 +						    devinfo.target, &tstate);
 12.1589 +			tinfo->curr.transport_version = 2;
 12.1590 +			tinfo->goal.transport_version = 2;
 12.1591 +			tinfo->goal.ppr_options = 0;
 12.1592 +			ahd_qinfifo_requeue_tail(ahd, scb);
 12.1593 +			printerror = 0;
 12.1594 +		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
 12.1595 +			|| ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)) {
 12.1596 +			/*
 12.1597 +			 * Negotiation Rejected.  Go-async and
 12.1598 +			 * retry command.
 12.1599 +			 */
 12.1600 +			ahd_set_width(ahd, &devinfo,
 12.1601 +				      MSG_EXT_WDTR_BUS_8_BIT,
 12.1602 +				      AHD_TRANS_CUR|AHD_TRANS_GOAL,
 12.1603 +				      /*paused*/TRUE);
 12.1604 +			ahd_set_syncrate(ahd, &devinfo,
 12.1605 +					/*period*/0, /*offset*/0,
 12.1606 +					/*ppr_options*/0,
 12.1607 +					AHD_TRANS_CUR|AHD_TRANS_GOAL,
 12.1608 +					/*paused*/TRUE);
 12.1609 +			ahd_qinfifo_requeue_tail(ahd, scb);
 12.1610 +			printerror = 0;
 12.1611 +		} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
 12.1612 +			&& ahd_sent_msg(ahd, AHDMSG_1B,
 12.1613 +					 MSG_INITIATOR_DET_ERR, TRUE)) {
 12.1614 +
 12.1615 +#if AHD_DEBUG
 12.1616 +			if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
 12.1617 +				printf("Expected IDE Busfree\n");
 12.1618 +#endif
 12.1619 +			printerror = 0;
 12.1620 +		}
 12.1621 +	} else if (lastphase == P_MESGIN) {
 12.1622 +
 12.1623 +		if ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0) {
 12.1624 +
 12.1625 +			ahd_freeze_devq(ahd, scb);
 12.1626 +			ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
 12.1627 +			ahd_freeze_scb(scb);
 12.1628 +			if ((ahd->msg_flags & MSG_FLAG_IU_REQ_CHANGED) != 0) {
 12.1629 +				ahd_print_path(ahd, scb);
 12.1630 +				printf("Now %spacketized.\n",
 12.1631 +				       (scb->flags & SCB_PACKETIZED) == 0
 12.1632 +				     ? "" : "non-");
 12.1633 +				ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
 12.1634 +					       SCB_GET_CHANNEL(ahd, scb),
 12.1635 +					       SCB_GET_LUN(scb), SCB_LIST_NULL,
 12.1636 +					       ROLE_INITIATOR, CAM_REQ_ABORTED);
 12.1637 +			} else {
 12.1638 +#if AHD_DEBUG
 12.1639 +				if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
 12.1640 +					printf("PPR Negotiation Busfree.\n");
 12.1641 +#endif
 12.1642 +				ahd_done(ahd, scb);
 12.1643 +			}
 12.1644 +			printerror = 0;
 12.1645 +		}
 12.1646 +	}
 12.1647 +	if (printerror != 0) {
 12.1648 +		int aborted;
 12.1649 +
 12.1650 +		aborted = 0;
 12.1651 +		if (scb != NULL) {
 12.1652 +			u_int tag;
 12.1653 +
 12.1654 +			if ((scb->hscb->control & TAG_ENB) != 0)
 12.1655 +				tag = SCB_GET_TAG(scb);
 12.1656 +			else
 12.1657 +				tag = SCB_LIST_NULL;
 12.1658 +			ahd_print_path(ahd, scb);
 12.1659 +			aborted = ahd_abort_scbs(ahd, target, 'A',
 12.1660 +				       SCB_GET_LUN(scb), tag,
 12.1661 +				       ROLE_INITIATOR,
 12.1662 +				       CAM_UNEXP_BUSFREE);
 12.1663 +		} else {
 12.1664 +			/*
 12.1665 +			 * We had not fully identified this connection,
 12.1666 +			 * so we cannot abort anything.
 12.1667 +			 */
 12.1668 +			printf("%s: ", ahd_name(ahd));
 12.1669 +		}
 12.1670 +		if (lastphase != P_BUSFREE)
 12.1671 +			ahd_force_renegotiation(ahd, &devinfo);
 12.1672 +		printf("Unexpected busfree %s, %d SCBs aborted, "
 12.1673 +		       "PRGMCNT == 0x%x\n",
 12.1674 +		       ahd_lookup_phase_entry(lastphase)->phasemsg,
 12.1675 +		       aborted,
 12.1676 +		       ahd_inb(ahd, PRGMCNT)
 12.1677 +			| (ahd_inb(ahd, PRGMCNT+1) << 8));
 12.1678 +		ahd_dump_card_state(ahd);
 12.1679 +	}
 12.1680 +	/* Always restart the sequencer. */
 12.1681 +	return (1);
 12.1682 +}
 12.1683 +
 12.1684 +/*
 12.1685 + * Force renegotiation to occur the next time we initiate
 12.1686 + * a command to the current device.
 12.1687 + */
 12.1688 +static void
 12.1689 +ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
 12.1690 +{
 12.1691 +	struct	ahd_initiator_tinfo *targ_info;
 12.1692 +	struct	ahd_tmode_tstate *tstate;
 12.1693 +
 12.1694 +	printf("Forcing renegotiation (%d:%c:%d)\n",
 12.1695 +	       devinfo->our_scsiid, devinfo->channel, 
 12.1696 +	       devinfo->target);
 12.1697 +	targ_info = ahd_fetch_transinfo(ahd,
 12.1698 +					devinfo->channel,
 12.1699 +					devinfo->our_scsiid,
 12.1700 +					devinfo->target,
 12.1701 +					&tstate);
 12.1702 +	ahd_update_neg_request(ahd, devinfo, tstate,
 12.1703 +			       targ_info, /*force*/TRUE);
 12.1704 +}
 12.1705 +
 12.1706 +#define AHD_MAX_STEPS 2000
 12.1707 +void
 12.1708 +ahd_clear_critical_section(struct ahd_softc *ahd)
 12.1709 +{
 12.1710 +	ahd_mode_state	saved_modes;
 12.1711 +	int		stepping;
 12.1712 +	int		steps;
 12.1713 +	u_int		simode0;
 12.1714 +	u_int		simode1;
 12.1715 +	u_int		simode3;
 12.1716 +	u_int		lqimode0;
 12.1717 +	u_int		lqimode1;
 12.1718 +	u_int		lqomode0;
 12.1719 +	u_int		lqomode1;
 12.1720 +
 12.1721 +	if (ahd->num_critical_sections == 0)
 12.1722 +		return;
 12.1723 +
 12.1724 +	stepping = FALSE;
 12.1725 +	steps = 0;
 12.1726 +	simode0 = 0;
 12.1727 +	simode1 = 0;
 12.1728 +	simode3 = 0;
 12.1729 +	lqimode0 = 0;
 12.1730 +	lqimode1 = 0;
 12.1731 +	lqomode0 = 0;
 12.1732 +	lqomode1 = 0;
 12.1733 +	saved_modes = ahd_save_modes(ahd);
 12.1734 +	for (;;) {
 12.1735 +		struct	cs *cs;
 12.1736 +		u_int	seqaddr;
 12.1737 +		u_int	i;
 12.1738 +
 12.1739 +		ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
 12.1740 +		seqaddr = ahd_inb(ahd, CURADDR)
 12.1741 +			| (ahd_inb(ahd, CURADDR+1) << 8);
 12.1742 +
 12.1743 +		cs = ahd->critical_sections;
 12.1744 +		for (i = 0; i < ahd->num_critical_sections; i++, cs++) {
 12.1745 +			
 12.1746 +			if (cs->begin < seqaddr && cs->end >= seqaddr)
 12.1747 +				break;
 12.1748 +		}
 12.1749 +
 12.1750 +		if (i == ahd->num_critical_sections)
 12.1751 +			break;
 12.1752 +
 12.1753 +		if (steps > AHD_MAX_STEPS) {
 12.1754 +			printf("%s: Infinite loop in critical section\n",
 12.1755 +			       ahd_name(ahd));
 12.1756 +			ahd_dump_card_state(ahd);
 12.1757 +			panic("critical section loop");
 12.1758 +		}
 12.1759 +
 12.1760 +		steps++;
 12.1761 +		if (stepping == FALSE) {
 12.1762 +
 12.1763 +			/*
 12.1764 +			 * Disable all interrupt sources so that the
 12.1765 +			 * sequencer will not be stuck by a pausing
 12.1766 +			 * interrupt condition while we attempt to
 12.1767 +			 * leave a critical section.
 12.1768 +			 */
 12.1769 +			ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
 12.1770 +			simode0 = ahd_inb(ahd, SIMODE0);
 12.1771 +			simode3 = ahd_inb(ahd, SIMODE3);
 12.1772 +			lqimode0 = ahd_inb(ahd, LQIMODE0);
 12.1773 +			lqimode1 = ahd_inb(ahd, LQIMODE1);
 12.1774 +			lqomode0 = ahd_inb(ahd, LQOMODE0);
 12.1775 +			lqomode1 = ahd_inb(ahd, LQOMODE1);
 12.1776 +			ahd_outb(ahd, SIMODE0, 0);
 12.1777 +			ahd_outb(ahd, SIMODE3, 0);
 12.1778 +			ahd_outb(ahd, LQIMODE0, 0);
 12.1779 +			ahd_outb(ahd, LQIMODE1, 0);
 12.1780 +			ahd_outb(ahd, LQOMODE0, 0);
 12.1781 +			ahd_outb(ahd, LQOMODE1, 0);
 12.1782 +			ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
 12.1783 +			simode1 = ahd_inb(ahd, SIMODE1);
 12.1784 +			ahd_outb(ahd, SIMODE1, 0);
 12.1785 +			ahd_outb(ahd, CLRINT, CLRSCSIINT);
 12.1786 +			ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP);
 12.1787 +			stepping = TRUE;
 12.1788 +		}
 12.1789 +		ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
 12.1790 +		ahd_outb(ahd, HCNTRL, ahd->unpause);
 12.1791 +		do {
 12.1792 +			ahd_delay(200);
 12.1793 +		} while (!ahd_is_paused(ahd));
 12.1794 +		ahd_update_modes(ahd);
 12.1795 +	}
 12.1796 +	if (stepping) {
 12.1797 +		ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
 12.1798 +		ahd_outb(ahd, SIMODE0, simode0);
 12.1799 +		ahd_outb(ahd, SIMODE3, simode3);
 12.1800 +		ahd_outb(ahd, LQIMODE0, lqimode0);
 12.1801 +		ahd_outb(ahd, LQIMODE1, lqimode1);
 12.1802 +		ahd_outb(ahd, LQOMODE0, lqomode0);
 12.1803 +		ahd_outb(ahd, LQOMODE1, lqomode1);
 12.1804 +		ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
 12.1805 +		ahd_outb(ahd, SIMODE1, simode1);
 12.1806 +		ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP);
 12.1807 +	}
 12.1808 +	ahd_restore_modes(ahd, saved_modes);
 12.1809 +}
 12.1810 +
 12.1811 +/*
 12.1812 + * Clear any pending interrupt status.
 12.1813 + */
 12.1814 +void
 12.1815 +ahd_clear_intstat(struct ahd_softc *ahd)
 12.1816 +{
 12.1817 +	/* Clear any interrupt conditions this may have caused */
 12.1818 +	ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
 12.1819 +				|CLRBUSFREE|CLRSCSIPERR|CLRREQINIT);
 12.1820 +	ahd_outb(ahd, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO|CLRIOERR);
 12.1821 +	ahd_outb(ahd, CLRINT, CLRSCSIINT);
 12.1822 +}
 12.1823 +
 12.1824 +/**************************** Debugging Routines ******************************/
 12.1825 +#ifdef AHD_DEBUG
 12.1826 +uint32_t ahd_debug = AHD_DEBUG;
 12.1827 +#endif
 12.1828 +void
 12.1829 +ahd_print_scb(struct scb *scb)
 12.1830 +{
 12.1831 +	struct hardware_scb *hscb;
 12.1832 +	int i;
 12.1833 +
 12.1834 +	hscb = scb->hscb;
 12.1835 +	printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
 12.1836 +	       (void *)scb,
 12.1837 +	       hscb->control,
 12.1838 +	       hscb->scsiid,
 12.1839 +	       hscb->lun,
 12.1840 +	       hscb->cdb_len);
 12.1841 +	printf("Shared Data: ");
 12.1842 +	for (i = 0; i < sizeof(hscb->shared_data.idata.cdb); i++)
 12.1843 +		printf("%#02x", hscb->shared_data.idata.cdb[i]);
 12.1844 +	printf("        dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n",
 12.1845 +	       (uint32_t)((ahd_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF),
 12.1846 +	       (uint32_t)(ahd_le64toh(hscb->dataptr) & 0xFFFFFFFF),
 12.1847 +	       ahd_le32toh(hscb->datacnt),
 12.1848 +	       ahd_le32toh(hscb->sgptr),
 12.1849 +	       SCB_GET_TAG(scb));
 12.1850 +	ahd_dump_sglist(scb);
 12.1851 +}
 12.1852 +
 12.1853 +void
 12.1854 +ahd_dump_sglist(struct scb *scb)
 12.1855 +{
 12.1856 +	int i;
 12.1857 +
 12.1858 +	if (scb->sg_count > 0) {
 12.1859 +		if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) {
 12.1860 +			struct ahd_dma64_seg *sg_list;
 12.1861 +
 12.1862 +			sg_list = (struct ahd_dma64_seg*)scb->sg_list;
 12.1863 +			for (i = 0; i < scb->sg_count; i++) {
 12.1864 +				uint64_t addr;
 12.1865 +
 12.1866 +				addr = ahd_le64toh(sg_list[i].addr);
 12.1867 +				printf("sg[%d] - Addr 0x%x%x : Length %d\n",
 12.1868 +				       i,
 12.1869 +				       (uint32_t)((addr >> 32) & 0xFFFFFFFF),
 12.1870 +				       (uint32_t)(addr & 0xFFFFFFFF),
 12.1871 +				       ahd_le32toh(sg_list[i].len));
 12.1872 +			}
 12.1873 +		} else {
 12.1874 +			struct ahd_dma_seg *sg_list;
 12.1875 +
 12.1876 +			sg_list = (struct ahd_dma_seg*)scb->sg_list;
 12.1877 +			for (i = 0; i < scb->sg_count; i++) {
 12.1878 +				printf("sg[%d] - Addr 0x%x%x : Length %d\n",
 12.1879 +				       i,
 12.1880 +				       (ahd_le32toh(sg_list[i].len) >> 24
 12.1881 +				        & SG_HIGH_ADDR_BITS),
 12.1882 +				       ahd_le32toh(sg_list[i].addr),
 12.1883 +				       ahd_le32toh(sg_list[i].len)
 12.1884 +				       & AHD_SG_LEN_MASK);
 12.1885 +			}
 12.1886 +		}
 12.1887 +	}
 12.1888 +}
 12.1889 +
 12.1890 +/************************* Transfer Negotiation *******************************/
 12.1891 +/*
 12.1892 + * Allocate per target mode instance (ID we respond to as a target)
 12.1893 + * transfer negotiation data structures.
 12.1894 + */
 12.1895 +static struct ahd_tmode_tstate *
 12.1896 +ahd_alloc_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel)
 12.1897 +{
 12.1898 +	struct ahd_tmode_tstate *master_tstate;
 12.1899 +	struct ahd_tmode_tstate *tstate;
 12.1900 +	int i;
 12.1901 +
 12.1902 +	master_tstate = ahd->enabled_targets[ahd->our_id];
 12.1903 +	if (ahd->enabled_targets[scsi_id] != NULL
 12.1904 +	 && ahd->enabled_targets[scsi_id] != master_tstate)
 12.1905 +		panic("%s: ahd_alloc_tstate - Target already allocated",
 12.1906 +		      ahd_name(ahd));
 12.1907 +	tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT);
 12.1908 +	if (tstate == NULL)
 12.1909 +		return (NULL);
 12.1910 +
 12.1911 +	/*
 12.1912 +	 * If we have allocated a master tstate, copy user settings from
 12.1913 +	 * the master tstate (taken from SRAM or the EEPROM) for this
 12.1914 +	 * channel, but reset our current and goal settings to async/narrow
 12.1915 +	 * until an initiator talks to us.
 12.1916 +	 */
 12.1917 +	if (master_tstate != NULL) {
 12.1918 +		memcpy(tstate, master_tstate, sizeof(*tstate));
 12.1919 +		memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
 12.1920 +		for (i = 0; i < 16; i++) {
 12.1921 +			memset(&tstate->transinfo[i].curr, 0,
 12.1922 +			      sizeof(tstate->transinfo[i].curr));
 12.1923 +			memset(&tstate->transinfo[i].goal, 0,
 12.1924 +			      sizeof(tstate->transinfo[i].goal));
 12.1925 +		}
 12.1926 +	} else
 12.1927 +		memset(tstate, 0, sizeof(*tstate));
 12.1928 +	ahd->enabled_targets[scsi_id] = tstate;
 12.1929 +	return (tstate);
 12.1930 +}
 12.1931 +
 12.1932 +#ifdef AHD_TARGET_MODE
 12.1933 +/*
 12.1934 + * Free per target mode instance (ID we respond to as a target)
 12.1935 + * transfer negotiation data structures.
 12.1936 + */
 12.1937 +static void
 12.1938 +ahd_free_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel, int force)
 12.1939 +{
 12.1940 +	struct ahd_tmode_tstate *tstate;
 12.1941 +
 12.1942 +	/*
 12.1943 +	 * Don't clean up our "master" tstate.
 12.1944 +	 * It has our default user settings.
 12.1945 +	 */
 12.1946 +	if (scsi_id == ahd->our_id
 12.1947 +	 && force == FALSE)
 12.1948 +		return;
 12.1949 +
 12.1950 +	tstate = ahd->enabled_targets[scsi_id];
 12.1951 +	if (tstate != NULL)
 12.1952 +		free(tstate, M_DEVBUF);
 12.1953 +	ahd->enabled_targets[scsi_id] = NULL;
 12.1954 +}
 12.1955 +#endif
 12.1956 +
 12.1957 +/*
 12.1958 + * Called when we have an active connection to a target on the bus,
 12.1959 + * this function finds the nearest period to the input period limited
 12.1960 + * by the capabilities of the bus connectivity of and sync settings for
 12.1961 + * the target.
 12.1962 + */
 12.1963 +void
 12.1964 +ahd_devlimited_syncrate(struct ahd_softc *ahd,
 12.1965 +			struct ahd_initiator_tinfo *tinfo,
 12.1966 +			u_int *period, u_int *ppr_options, role_t role)
 12.1967 +{
 12.1968 +	struct	ahd_transinfo *transinfo;
 12.1969 +	u_int	maxsync;
 12.1970 +
 12.1971 +	if ((ahd_inb(ahd, SBLKCTL) & ENAB40) != 0
 12.1972 +	 && (ahd_inb(ahd, SSTAT2) & EXP_ACTIVE) == 0) {
 12.1973 +		maxsync = AHD_SYNCRATE_PACED;
 12.1974 +	} else {
 12.1975 +		maxsync = AHD_SYNCRATE_ULTRA;
 12.1976 +		/* Can't do DT related options on an SE bus */
 12.1977 +		*ppr_options &= MSG_EXT_PPR_QAS_REQ;
 12.1978 +	}
 12.1979 +	/*
 12.1980 +	 * Never allow a value higher than our current goal
 12.1981 +	 * period otherwise we may allow a target initiated
 12.1982 +	 * negotiation to go above the limit as set by the
 12.1983 +	 * user.  In the case of an initiator initiated
 12.1984 +	 * sync negotiation, we limit based on the user
 12.1985 +	 * setting.  This allows the system to still accept
 12.1986 +	 * incoming negotiations even if target initiated
 12.1987 +	 * negotiation is not performed.
 12.1988 +	 */
 12.1989 +	if (role == ROLE_TARGET)
 12.1990 +		transinfo = &tinfo->user;
 12.1991 +	else 
 12.1992 +		transinfo = &tinfo->goal;
 12.1993 +	*ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN);
 12.1994 +	if (transinfo->period == 0) {
 12.1995 +		*period = 0;
 12.1996 +		*ppr_options = 0;
 12.1997 +	} else {
 12.1998 +		*period = MAX(*period, transinfo->period);
 12.1999 +		ahd_find_syncrate(ahd, period, ppr_options, maxsync);
 12.2000 +	}
 12.2001 +}
 12.2002 +
 12.2003 +/*
 12.2004 + * Look up the valid period to SCSIRATE conversion in our table.
 12.2005 + * Return the period and offset that should be sent to the target
 12.2006 + * if this was the beginning of an SDTR.
 12.2007 + */
 12.2008 +void
 12.2009 +ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
 12.2010 +		  u_int *ppr_options, u_int maxsync)
 12.2011 +{
 12.2012 +	/* Skip all PACED only entries if IU is not available */
 12.2013 +	if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0
 12.2014 +	 && maxsync < AHD_SYNCRATE_DT)
 12.2015 +		maxsync = AHD_SYNCRATE_DT;
 12.2016 +
 12.2017 +	/* Skip all DT only entries if DT is not available */
 12.2018 +	if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
 12.2019 +	 && maxsync < AHD_SYNCRATE_ULTRA2)
 12.2020 +		maxsync = AHD_SYNCRATE_ULTRA2;
 12.2021 +	
 12.2022 +	if (*period < maxsync)
 12.2023 +		*period = maxsync;
 12.2024 +
 12.2025 +	if ((*ppr_options & MSG_EXT_PPR_DT_REQ) != 0
 12.2026 +	 && *period > AHD_SYNCRATE_MIN_DT)
 12.2027 +		*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
 12.2028 +		
 12.2029 +	if (*period > AHD_SYNCRATE_MIN)
 12.2030 +		*period = 0;
 12.2031 +
 12.2032 +	/* Honor PPR option conformance rules. */
 12.2033 +	if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0)
 12.2034 +		*ppr_options &= (MSG_EXT_PPR_DT_REQ|MSG_EXT_PPR_QAS_REQ);
 12.2035 +
 12.2036 +	if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0)
 12.2037 +		*ppr_options &= MSG_EXT_PPR_QAS_REQ;
 12.2038 +}
 12.2039 +
 12.2040 +/*
 12.2041 + * Truncate the given synchronous offset to a value the
 12.2042 + * current adapter type and syncrate are capable of.
 12.2043 + */
 12.2044 +void
 12.2045 +ahd_validate_offset(struct ahd_softc *ahd,
 12.2046 +		    struct ahd_initiator_tinfo *tinfo,
 12.2047 +		    u_int period, u_int *offset, int wide,
 12.2048 +		    role_t role)
 12.2049 +{
 12.2050 +	u_int maxoffset;
 12.2051 +
 12.2052 +	/* Limit offset to what we can do */
 12.2053 +	if (period == 0)
 12.2054 +		maxoffset = 0;
 12.2055 +	else if (period <= AHD_SYNCRATE_PACED)
 12.2056 +		maxoffset = MAX_OFFSET_PACED;
 12.2057 +	else
 12.2058 +		maxoffset = MAX_OFFSET;
 12.2059 +	*offset = MIN(*offset, maxoffset);
 12.2060 +	if (tinfo != NULL) {
 12.2061 +		if (role == ROLE_TARGET)
 12.2062 +			*offset = MIN(*offset, tinfo->user.offset);
 12.2063 +		else
 12.2064 +			*offset = MIN(*offset, tinfo->goal.offset);
 12.2065 +	}
 12.2066 +}
 12.2067 +
 12.2068 +/*
 12.2069 + * Truncate the given transfer width parameter to a value the
 12.2070 + * current adapter type is capable of.
 12.2071 + */
 12.2072 +void
 12.2073 +ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo,
 12.2074 +		   u_int *bus_width, role_t role)
 12.2075 +{
 12.2076 +	switch (*bus_width) {
 12.2077 +	default:
 12.2078 +		if (ahd->features & AHD_WIDE) {
 12.2079 +			/* Respond Wide */
 12.2080 +			*bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 12.2081 +			break;
 12.2082 +		}
 12.2083 +		/* FALLTHROUGH */
 12.2084 +	case MSG_EXT_WDTR_BUS_8_BIT:
 12.2085 +		*bus_width = MSG_EXT_WDTR_BUS_8_BIT;
 12.2086 +		break;
 12.2087 +	}
 12.2088 +	if (tinfo != NULL) {
 12.2089 +		if (role == ROLE_TARGET)
 12.2090 +			*bus_width = MIN(tinfo->user.width, *bus_width);
 12.2091 +		else
 12.2092 +			*bus_width = MIN(tinfo->goal.width, *bus_width);
 12.2093 +	}
 12.2094 +}
 12.2095 +
 12.2096 +/*
 12.2097 + * Update the bitmask of targets for which the controller should
 12.2098 + * negotiate with at the next convenient oportunity.  This currently
 12.2099 + * means the next time we send the initial identify messages for
 12.2100 + * a new transaction.
 12.2101 + */
 12.2102 +int
 12.2103 +ahd_update_neg_request(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
 12.2104 +		       struct ahd_tmode_tstate *tstate,
 12.2105 +		       struct ahd_initiator_tinfo *tinfo, int force)
 12.2106 +{
 12.2107 +	u_int auto_negotiate_orig;
 12.2108 +
 12.2109 +	auto_negotiate_orig = tstate->auto_negotiate;
 12.2110 +	if (tinfo->curr.period != tinfo->goal.period
 12.2111 +	 || tinfo->curr.width != tinfo->goal.width
 12.2112 +	 || tinfo->curr.offset != tinfo->goal.offset
 12.2113 +	 || tinfo->curr.ppr_options != tinfo->goal.ppr_options
 12.2114 +	 || (force
 12.2115 +	  && (tinfo->goal.period != 0
 12.2116 +	   || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
 12.2117 +	   || tinfo->goal.ppr_options != 0)))
 12.2118 +		tstate->auto_negotiate |= devinfo->target_mask;
 12.2119 +	else
 12.2120 +		tstate->auto_negotiate &= ~devinfo->target_mask;
 12.2121 +
 12.2122 +	return (auto_negotiate_orig != tstate->auto_negotiate);
 12.2123 +}
 12.2124 +
 12.2125 +/*
 12.2126 + * Update the user/goal/curr tables of synchronous negotiation
 12.2127 + * parameters as well as, in the case of a current or active update,
 12.2128 + * any data structures on the host controller.  In the case of an
 12.2129 + * active update, the specified target is currently talking to us on
 12.2130 + * the bus, so the transfer parameter update must take effect
 12.2131 + * immediately.
 12.2132 + */
 12.2133 +void
 12.2134 +ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
 12.2135 +		 u_int period, u_int offset, u_int ppr_options,
 12.2136 +		 u_int type, int paused)
 12.2137 +{
 12.2138 +	struct	ahd_initiator_tinfo *tinfo;
 12.2139 +	struct	ahd_tmode_tstate *tstate;
 12.2140 +	u_int	old_period;
 12.2141 +	u_int	old_offset;
 12.2142 +	u_int	old_ppr;
 12.2143 +	int	active;
 12.2144 +	int	update_needed;
 12.2145 +
 12.2146 +	active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE;
 12.2147 +	update_needed = 0;
 12.2148 +
 12.2149 +	if (period == 0 || offset == 0) {
 12.2150 +		period = 0;
 12.2151 +		offset = 0;
 12.2152 +	}
 12.2153 +
 12.2154 +	tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
 12.2155 +				    devinfo->target, &tstate);
 12.2156 +
 12.2157 +	if ((type & AHD_TRANS_USER) != 0) {
 12.2158 +		tinfo->user.period = period;
 12.2159 +		tinfo->user.offset = offset;
 12.2160 +		tinfo->user.ppr_options = ppr_options;
 12.2161 +	}
 12.2162 +
 12.2163 +	if ((type & AHD_TRANS_GOAL) != 0) {
 12.2164 +		tinfo->goal.period = period;
 12.2165 +		tinfo->goal.offset = offset;
 12.2166 +		tinfo->goal.ppr_options = ppr_options;
 12.2167 +	}
 12.2168 +
 12.2169 +	old_period = tinfo->curr.period;
 12.2170 +	old_offset = tinfo->curr.offset;
 12.2171 +	old_ppr	   = tinfo->curr.ppr_options;
 12.2172 +
 12.2173 +	if ((type & AHD_TRANS_CUR) != 0
 12.2174 +	 && (old_period != period
 12.2175 +	  || old_offset != offset
 12.2176 +	  || old_ppr != ppr_options)) {
 12.2177 +
 12.2178 +		update_needed++;
 12.2179 +
 12.2180 +		tinfo->curr.period = period;
 12.2181 +		tinfo->curr.offset = offset;
 12.2182 +		tinfo->curr.ppr_options = ppr_options;
 12.2183 +
 12.2184 +		ahd_send_async(ahd, devinfo->channel, devinfo->target,
 12.2185 +			       CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
 12.2186 +		if (bootverbose) {
 12.2187 +			if (offset != 0) {
 12.2188 +				printf("%s: target %d synchronous with "
 12.2189 +				       "period = 0x%x, offset = 0x%x%s\n",
 12.2190 +				       ahd_name(ahd), devinfo->target,
 12.2191 +				       period, offset,
 12.2192 +				       (ppr_options & MSG_EXT_PPR_DT_REQ)
 12.2193 +				       ? " (DT)" : "");
 12.2194 +			} else {
 12.2195 +				printf("%s: target %d using "
 12.2196 +				       "asynchronous transfers\n",
 12.2197 +				       ahd_name(ahd), devinfo->target);
 12.2198 +			}
 12.2199 +		}
 12.2200 +	}
 12.2201 +	/*
 12.2202 +	 * Always refresh the neg-table to handle the case of the
 12.2203 +	 * sequencer setting the ENATNO bit for a MK_MESSAGE request.
 12.2204 +	 * We will always renegotiate in that case if this is a
 12.2205 +	 * packetized request.
 12.2206 +	 */
 12.2207 +	if ((type & AHD_TRANS_CUR) != 0)
 12.2208 +		ahd_update_neg_table(ahd, devinfo, &tinfo->curr);
 12.2209 +
 12.2210 +	update_needed += ahd_update_neg_request(ahd, devinfo, tstate,
 12.2211 +						tinfo, /*force*/FALSE);
 12.2212 +
 12.2213 +	if (update_needed)
 12.2214 +		ahd_update_pending_scbs(ahd);
 12.2215 +}
 12.2216 +
 12.2217 +/*
 12.2218 + * Update the user/goal/curr tables of wide negotiation
 12.2219