File:  [DragonFly] / src / sys / dev / disk / trm / trm.c
Revision 1.3: download - view: text, annotated - select for diffs
Thu Aug 7 21:16:54 2003 UTC (11 years ago) by dillon
Branches: MAIN
CVS tags: HEAD
kernel tree reorganization stage 1: Major cvs repository work (not logged as
commits) plus a major reworking of the #include's to accomodate the
relocations.

    * CVS repository files manually moved.  Old directories left intact
      and empty (temporary).

    * Reorganize all filesystems into vfs/, most devices into dev/,
      sub-divide devices by function.

    * Begin to move device-specific architecture files to the device
      subdirs rather then throwing them all into, e.g. i386/include

    * Reorganize files related to system busses, placing the related code
      in a new bus/ directory.  Also move cam to bus/cam though this may
      not have been the best idea in retrospect.

    * Reorganize emulation code and place it in a new emulation/ directory.

    * Remove the -I- compiler option in order to allow #include file
      localization, rename all config generated X.h files to use_X.h to
      clean up the conflicts.

    * Remove /usr/src/include (or /usr/include) dependancies during the
      kernel build, beyond what is normally needed to compile helper
      programs.

    * Make config create 'machine' softlinks for architecture specific
      directories outside of the standard <arch>/include.

    * Bump the config rev.

    WARNING! after this commit /usr/include and /usr/src/sys/compile/*
    should be regenerated from scratch.

    1: /*
    2:  *       O.S   : FreeBSD CAM
    3:  *	FILE NAME  : trm.c					      
    4:  *	     BY    : C.L. Huang 	(ching@tekram.com.tw)
    5:  *               Erich Chen     (erich@tekram.com.tw)
    6:  *	Description: Device Driver for Tekram DC395U/UW/F ,DC315/U 
    7:  *		         PCI SCSI Bus Master Host Adapter	
    8:  *               (SCSI chip set used Tekram ASIC TRM-S1040)
    9:  * (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
   10:  */
   11: 
   12: /*
   13:  *	HISTORY:					
   14:  *						
   15:  *	REV#	DATE	NAME    	DESCRIPTION	
   16:  *  1.05   05/01/1999  ERICH CHEN  First released for 3.x.x (CAM)
   17:  *  1.06   07/29/1999  ERICH CHEN  Modify for NEW PCI
   18:  *  1.07   12/12/1999  ERICH CHEN  Modify for 3.3.x ,DCB no free
   19:  *  1.08   06/12/2000  ERICH CHEN  Modify for 4.x.x 
   20:  */
   21: 
   22: /*
   23:  *
   24:  *
   25:  * Redistribution and use in source and binary forms, with or without
   26:  * modification, are permitted provided that the following conditions
   27:  * are met:
   28:  * 1. Redistributions of source code must retain the above copyright
   29:  *    notice, this list of conditions and the following disclaimer.
   30:  * 2. Redistributions in binary form must reproduce the above copyright
   31:  *    notice, this list of conditions and the following disclaimer in the
   32:  *    documentation and/or other materials provided with the distribution.
   33:  * 3. The name of the author may not be used to endorse or promote products
   34:  *    derived from this software without specific prior written permission.
   35:  *
   36:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   37:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   38:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   39:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   40:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   41:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   42:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   43:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   44:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   45:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   46:  *
   47:  * $FreeBSD: src/sys/dev/trm/trm.c,v 1.2.2.2 2002/12/19 20:34:45 cognet Exp $
   48:  * $DragonFly: src/sys/dev/disk/trm/trm.c,v 1.3 2003/08/07 21:16:54 dillon Exp $
   49:  */
   50: 
   51: /*
   52:  * Imported into FreeBSD source repository, and updated to compile under  
   53:  * FreeBSD-3.0-DEVELOPMENT, by Stefan Esser <se@FreeBSD.Org>, 1996-12-17  
   54:  */
   55: 
   56: /*
   57:  * Updated to compile under FreeBSD 5.0-CURRENT by Olivier Houchard
   58:  * <doginou@ci0.org>, 2002-03-04
   59:  */
   60: 
   61: #include <sys/param.h>
   62: 
   63: #include <sys/systm.h>
   64: #include <sys/malloc.h>
   65: #include <sys/queue.h>
   66: #if __FreeBSD_version >= 500000
   67: #include <sys/bio.h>
   68: #endif
   69: #include <sys/buf.h>
   70: #include <sys/bus.h>
   71: #include <sys/kernel.h>
   72: 
   73: #include <vm/vm.h>
   74: #include <vm/pmap.h>
   75: 
   76: #include <bus/pci/pcivar.h>
   77: #include <bus/pci/pcireg.h>
   78: #include <machine/resource.h>
   79: #include <machine/bus_pio.h>
   80: #include <machine/bus.h>
   81: #include <machine/clock.h>
   82: #include <sys/rman.h>
   83: 
   84: #include <bus/cam/cam.h>
   85: #include <bus/cam/cam_ccb.h>
   86: #include <bus/cam/cam_sim.h>
   87: #include <bus/cam/cam_xpt_sim.h>
   88: #include <bus/cam/cam_debug.h>
   89: 
   90: #include <bus/cam/scsi/scsi_all.h>
   91: 
   92: #include "trm.h"
   93: 
   94: #define trm_reg_read8(reg)	bus_space_read_1(pACB->tag, pACB->bsh, reg)
   95: #define trm_reg_read16(reg)	bus_space_read_2(pACB->tag, pACB->bsh, reg)
   96: #define trm_reg_read32(reg)	bus_space_read_4(pACB->tag, pACB->bsh, reg)
   97: #define trm_reg_write8(value,reg)	bus_space_write_1(pACB->tag, pACB->bsh,\
   98: 		reg, value)
   99: #define trm_reg_write16(value,reg)	bus_space_write_2(pACB->tag, pACB->bsh,\
  100: 		reg, value)
  101: #define trm_reg_write32(value,reg)	bus_space_write_4(pACB->tag, pACB->bsh,\
  102: 		reg, value)
  103: 
  104: #define PCI_Vendor_ID_TEKRAM	0x1DE1
  105: #define PCI_Device_ID_TRM_S1040	0x0391
  106: #define PCI_DEVICEID_TRMS1040	0x03911DE1
  107: 
  108: #ifdef trm_DEBUG1
  109: #define TRM_DPRINTF(fmt, arg...) printf("trm: " fmt, ##arg)
  110: #else
  111: #define TRM_DPRINTF(fmt, arg...) {}
  112: #endif /* TRM_DEBUG */
  113: 
  114: static void	trm_check_eeprom(PNVRAMTYPE pEEpromBuf,PACB pACB);
  115: static void	TRM_read_all(PNVRAMTYPE pEEpromBuf,PACB pACB);
  116: static u_int8_t	TRM_get_data(PACB pACB, u_int8_t bAddr);
  117: static void	TRM_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB);
  118: static void	TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData);
  119: static void	TRM_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr);
  120: static void	TRM_wait_30us(PACB pACB);
  121: 
  122: static void	trm_Interrupt(void *vpACB);
  123: static void	trm_DataOutPhase0(PACB pACB, PSRB pSRB, 
  124: 					 u_int8_t * pscsi_status);
  125: static void	trm_DataInPhase0(PACB pACB, PSRB pSRB, 
  126: 					u_int8_t * pscsi_status);
  127: static void	trm_CommandPhase0(PACB pACB, PSRB pSRB, 
  128: 					 u_int8_t * pscsi_status);
  129: static void	trm_StatusPhase0(PACB pACB, PSRB pSRB, 
  130: 					u_int8_t * pscsi_status);
  131: static void	trm_MsgOutPhase0(PACB pACB, PSRB pSRB, 
  132: 					u_int8_t * pscsi_status);
  133: static void	trm_MsgInPhase0(PACB pACB, PSRB pSRB, 
  134: 					u_int8_t * pscsi_status);
  135: static void	trm_DataOutPhase1(PACB pACB, PSRB pSRB, 
  136: 					 u_int8_t * pscsi_status);
  137: static void	trm_DataInPhase1(PACB pACB, PSRB pSRB, 
  138: 					u_int8_t * pscsi_status);
  139: static void	trm_CommandPhase1(PACB pACB, PSRB pSRB, 
  140: 					 u_int8_t * pscsi_status);
  141: static void	trm_StatusPhase1(PACB pACB, PSRB pSRB, 
  142: 					u_int8_t * pscsi_status);
  143: static void	trm_MsgOutPhase1(PACB pACB, PSRB pSRB, 
  144: 					u_int8_t * pscsi_status);
  145: static void	trm_MsgInPhase1(PACB pACB, PSRB pSRB, 
  146: 					u_int8_t * pscsi_status);
  147: static void	trm_Nop0(PACB pACB, PSRB pSRB, u_int8_t * pscsi_status);
  148: static void	trm_Nop1(PACB pACB, PSRB pSRB, u_int8_t * pscsi_status);
  149: static void	trm_SetXferRate(PACB pACB, PSRB pSRB,PDCB pDCB);
  150: static void	trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir);
  151: static void	trm_Disconnect(PACB pACB);
  152: static void	trm_Reselect(PACB pACB);
  153: static void	trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB);
  154: static void	trm_DoingSRB_Done(PACB pACB);
  155: static void	trm_ScsiRstDetect(PACB pACB);
  156: static void	trm_ResetSCSIBus(PACB pACB);
  157: static void	trm_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB);
  158: static void	trm_EnableMsgOutAbort2(PACB pACB, PSRB pSRB);
  159: static void	trm_EnableMsgOutAbort1(PACB pACB, PSRB pSRB);
  160: static void	trm_SendSRB(PACB pACB, PSRB pSRB);
  161: static int	trm_probe(device_t tag);
  162: static int	trm_attach(device_t tag);
  163: static void	trm_reset(PACB pACB);
  164: 
  165: static u_int16_t	trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB);
  166: 
  167: static int	trm_initAdapter(PACB pACB, u_int16_t unit, 
  168:     					device_t pci_config_id);
  169: static void	trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit, 
  170:     					u_int32_t i, u_int32_t j);
  171: static void	trm_initSRB(PSRB psrb);
  172: static void	trm_linkSRB(PACB pACB);
  173: static void	trm_initACB(PACB pACB, u_int16_t unit);
  174: /* CAM SIM entry points */
  175: #define ccb_trmsrb_ptr spriv_ptr0
  176: #define ccb_trmacb_ptr spriv_ptr1
  177: static void	trm_action(struct cam_sim *psim, union ccb *pccb);
  178: static void	trm_poll(struct cam_sim *psim);
  179: 
  180: 
  181: static void * trm_SCSI_phase0[] = {
  182: 	trm_DataOutPhase0,    /* phase:0 */
  183: 	trm_DataInPhase0,     /* phase:1 */
  184: 	trm_CommandPhase0,    /* phase:2 */
  185: 	trm_StatusPhase0,     /* phase:3 */
  186: 	trm_Nop0,             /* phase:4 */
  187: 	trm_Nop1,             /* phase:5 */
  188: 	trm_MsgOutPhase0,     /* phase:6 */
  189: 	trm_MsgInPhase0,      /* phase:7 */
  190: };
  191: 
  192: /*
  193:  *
  194:  *          stateV = (void *) trm_SCSI_phase1[phase]
  195:  *
  196:  */
  197: static void * trm_SCSI_phase1[] = {
  198: 	trm_DataOutPhase1,    /* phase:0 */
  199: 	trm_DataInPhase1,     /* phase:1 */
  200: 	trm_CommandPhase1,    /* phase:2 */
  201: 	trm_StatusPhase1,     /* phase:3 */
  202: 	trm_Nop0,             /* phase:4 */
  203: 	trm_Nop1,             /* phase:5 */
  204: 	trm_MsgOutPhase1,     /* phase:6 */
  205: 	trm_MsgInPhase1,      /* phase:7 */
  206: };
  207: 
  208: 
  209: NVRAMTYPE trm_eepromBuf[MAX_ADAPTER_NUM];
  210: /*
  211:  *Fast20:  000	 50ns, 20.0 Mbytes/s
  212:  *	       001	 75ns, 13.3 Mbytes/s
  213:  *	       010	100ns, 10.0 Mbytes/s
  214:  *	       011	125ns,  8.0 Mbytes/s
  215:  *	       100	150ns,  6.6 Mbytes/s
  216:  *	       101	175ns,  5.7 Mbytes/s
  217:  *	       110	200ns,  5.0 Mbytes/s
  218:  *	       111	250ns,  4.0 Mbytes/s
  219:  *
  220:  *Fast40:  000	 25ns, 40.0 Mbytes/s
  221:  *	       001	 50ns, 20.0 Mbytes/s
  222:  *	       010	 75ns, 13.3 Mbytes/s
  223:  *	       011	100ns, 10.0 Mbytes/s
  224:  *	       100	125ns,  8.0 Mbytes/s
  225:  *	       101	150ns,  6.6 Mbytes/s
  226:  *	       110	175ns,  5.7 Mbytes/s
  227:  *	       111	200ns,  5.0 Mbytes/s
  228:  */
  229:                                              /* real period: */
  230: u_int8_t dc395x_trm_clock_period[] = {
  231: 	12,/*  48  ns 20   MB/sec */
  232: 	18,/*  72  ns 13.3 MB/sec */
  233: 	25,/* 100  ns 10.0 MB/sec */
  234: 	31,/* 124  ns  8.0 MB/sec */
  235: 	37,/* 148  ns  6.6 MB/sec */
  236: 	43,/* 172  ns  5.7 MB/sec */
  237: 	50,/* 200  ns  5.0 MB/sec */
  238: 	62 /* 248  ns  4.0 MB/sec */
  239: };
  240: 
  241: u_int8_t dc395x_trm_tinfo_sync_period[] = { 
  242: 	12,/* 20.0 MB/sec */
  243: 	18,/* 13.3 MB/sec */
  244: 	25,/* 10.0 MB/sec */
  245: 	31,/*  8.0 MB/sec */
  246: 	37,/*  6.6 MB/sec */
  247: 	43,/*  5.7 MB/sec */
  248: 	50,/*  5.0 MB/sec */
  249: 	62,/*  4.0 MB/sec */
  250: };
  251: 
  252: static PSRB
  253: trm_GetSRB(PACB pACB)
  254: {
  255: 	int	intflag;
  256: 	PSRB	pSRB;
  257: 
  258: 	intflag = splcam();
  259:     	pSRB = pACB->pFreeSRB;
  260: 	if (pSRB) {
  261: 		pACB->pFreeSRB = pSRB->pNextSRB;
  262: 		pSRB->pNextSRB = NULL;
  263: 	}
  264: 	splx(intflag);
  265:     	return (pSRB);
  266: }
  267: 
  268: static void
  269: trm_RewaitSRB0(PDCB pDCB, PSRB pSRB)
  270: {
  271: 	PSRB	psrb1;
  272: 	int	intflag;
  273: 
  274: 	intflag = splcam();
  275:     	if ((psrb1 = pDCB->pWaitingSRB)) {
  276: 		pSRB->pNextSRB = psrb1;
  277: 		pDCB->pWaitingSRB = pSRB;
  278: 	} else {
  279: 	  	pSRB->pNextSRB = NULL;
  280: 		pDCB->pWaitingSRB = pSRB;
  281: 		pDCB->pWaitLastSRB = pSRB;
  282: 	}
  283: 	splx(intflag);
  284: }
  285: 
  286: static void
  287: trm_RewaitSRB(PDCB pDCB, PSRB pSRB)
  288: {
  289: 	PSRB	psrb1;
  290: 	int	intflag;
  291: 	u_int8_t	bval;
  292: 
  293: 	intflag = splcam();
  294:     	pDCB->GoingSRBCnt--;
  295: 	psrb1 = pDCB->pGoingSRB;
  296: 	if (pSRB == psrb1)
  297: 		pDCB->pGoingSRB = psrb1->pNextSRB;
  298: 	else {
  299: 		while (pSRB != psrb1->pNextSRB)
  300: 			psrb1 = psrb1->pNextSRB;
  301: 		psrb1->pNextSRB = pSRB->pNextSRB;
  302: 		if (pSRB == pDCB->pGoingLastSRB)
  303: 			pDCB->pGoingLastSRB = psrb1;
  304: 	}
  305: 	if ((psrb1 = pDCB->pWaitingSRB)) {
  306: 		pSRB->pNextSRB = psrb1;
  307: 		pDCB->pWaitingSRB = pSRB;
  308: 	} else {
  309: 		pSRB->pNextSRB = NULL;
  310: 		pDCB->pWaitingSRB = pSRB;
  311: 		pDCB->pWaitLastSRB = pSRB;
  312: 	}
  313: 	bval = pSRB->TagNumber;
  314: 	pDCB->TagMask &= (~(1 << bval));	  /* Free TAG number */
  315: 	splx(intflag);
  316: }
  317: 
  318: static void
  319: trm_DoWaitingSRB(PACB pACB)
  320: {
  321: 	int	intflag;
  322: 	PDCB	ptr, ptr1;
  323: 	PSRB	pSRB;
  324: 
  325: 	intflag = splcam();
  326:     	if (!(pACB->pActiveDCB) && 
  327: 	    !(pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV))) {
  328: 		ptr = pACB->pDCBRunRobin;
  329: 		if (!ptr) {
  330: 			ptr = pACB->pLinkDCB;
  331: 			pACB->pDCBRunRobin = ptr;
  332: 		}
  333: 		ptr1 = ptr;
  334: 		for (;ptr1 ;) {
  335: 			pACB->pDCBRunRobin = ptr1->pNextDCB;
  336: 			if (!(ptr1->MaxCommand > ptr1->GoingSRBCnt) 
  337: 			    || !(pSRB = ptr1->pWaitingSRB)) {
  338: 				if (pACB->pDCBRunRobin == ptr)
  339: 					break;
  340: 				ptr1 = ptr1->pNextDCB;
  341: 			} else {
  342: 				if (!trm_StartSCSI(pACB, ptr1, pSRB)) {
  343: 				/* 
  344: 				 * If trm_StartSCSI return 0 :
  345: 				 * current interrupt status is interrupt enable 
  346: 				 * It's said that SCSI processor is unoccupied 
  347: 				 */
  348: 					ptr1->GoingSRBCnt++;
  349: 					if (ptr1->pWaitLastSRB == pSRB) {
  350: 						ptr1->pWaitingSRB = NULL;
  351: 						ptr1->pWaitLastSRB = NULL;
  352: 					} else
  353: 						ptr1->pWaitingSRB = pSRB->pNextSRB;
  354: 					pSRB->pNextSRB = NULL;
  355: 					if (ptr1->pGoingSRB) 
  356: 						ptr1->pGoingLastSRB->pNextSRB = pSRB;
  357: 					else
  358: 						ptr1->pGoingSRB = pSRB;
  359: 					ptr1->pGoingLastSRB = pSRB;
  360: 				}
  361: 				break;
  362: 			}
  363: 		}
  364: 	}
  365: 	splx(intflag);
  366: 	return;
  367: }
  368: 
  369: static void
  370: trm_SRBwaiting(PDCB pDCB, PSRB pSRB)
  371: {
  372:   
  373: 	if (pDCB->pWaitingSRB) {
  374: 		pDCB->pWaitLastSRB->pNextSRB = pSRB;
  375: 		pDCB->pWaitLastSRB = pSRB;
  376: 		pSRB->pNextSRB = NULL;
  377: 	} else {
  378: 		pDCB->pWaitingSRB = pSRB;
  379: 		pDCB->pWaitLastSRB = pSRB;
  380: 	}
  381: }
  382: 
  383: static void
  384: trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int vp)
  385: {
  386: 	int		flags;
  387: 	PACB		pACB;
  388: 	PSRB		pSRB;
  389: 	union ccb	*ccb;
  390: 	u_long		totalxferlen=0;
  391: 
  392: 	pSRB = (PSRB)arg;
  393: 	ccb = pSRB->pccb;
  394: 	pACB = (PACB)ccb->ccb_h.ccb_trmacb_ptr;
  395: 	TRM_DPRINTF("trm_ExecuteSRB..........\n");        
  396: 	if (nseg != 0) {
  397: 		PSEG			psg;
  398: 		bus_dma_segment_t	*end_seg;
  399: 		bus_dmasync_op_t	op;
  400: 
  401: 		/* Copy the segments into our SG list */
  402: 		end_seg = dm_segs + nseg;
  403: 		psg = (PSEG) &pSRB->SegmentX[0];
  404: 		pSRB->SRBSGListPointer= psg;
  405: 		while (dm_segs < end_seg) {
  406: 			psg->address = vp?(u_long)vtophys(dm_segs->ds_addr)
  407: 			  :(u_long)dm_segs->ds_addr;
  408: 			psg->length = (u_long)dm_segs->ds_len;
  409: 			totalxferlen += dm_segs->ds_len;
  410: 			psg++;
  411: 			dm_segs++;
  412: 		}
  413: 		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
  414: 			op = BUS_DMASYNC_PREREAD;
  415: 		} else {
  416: 			op = BUS_DMASYNC_PREWRITE;
  417: 		}
  418: 		bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op);
  419: 	}
  420: 	pSRB->RetryCnt = 0;
  421: 	pSRB->SRBTotalXferLength=totalxferlen;
  422: 	pSRB->SRBSGCount = nseg;
  423: 	pSRB->SRBSGIndex = 0;
  424: 	pSRB->AdaptStatus = 0;
  425: 	pSRB->TargetStatus = 0;
  426: 	pSRB->MsgCnt = 0;
  427: 	pSRB->SRBStatus = 0;
  428: 	pSRB->SRBFlag = 0;
  429: 	pSRB->SRBState = 0;
  430: 	pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
  431: 
  432: 	flags = splcam();
  433: 	if (ccb->ccb_h.status != CAM_REQ_INPROG) {
  434: 		if (nseg != 0)
  435: 			bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap);
  436: 		pSRB->pNextSRB = pACB->pFreeSRB;
  437: 		pACB->pFreeSRB = pSRB;
  438: 		xpt_done(ccb);
  439: 		splx(flags);
  440: 		return;
  441: 	}
  442: 	ccb->ccb_h.status |= CAM_SIM_QUEUED;
  443: #if 0
  444: 	/* XXX Need a timeout handler */
  445: 	ccb->ccb_h.timeout_ch = timeout(trmtimeout, (caddr_t)srb, (ccb->ccb_h.timeout * hz) / 1000);
  446: #endif
  447: 	trm_SendSRB(pACB, pSRB);
  448: 	splx(flags);
  449: 	return;
  450: }
  451: 
  452: static void
  453: trm_SendSRB(PACB pACB, PSRB pSRB)
  454: {
  455: 	int	intflag;
  456: 	PDCB	pDCB;
  457: 
  458: 	intflag = splcam();
  459: 	pDCB = pSRB->pSRBDCB;
  460: 	if (!(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB)
  461: 	    || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV))) {
  462: 		TRM_DPRINTF("pDCB->MaxCommand=%d \n",pDCB->MaxCommand);        
  463: 		TRM_DPRINTF("pDCB->GoingSRBCnt=%d \n",pDCB->GoingSRBCnt);
  464: 		TRM_DPRINTF("pACB->pActiveDCB=%8x \n",(u_int)pACB->pActiveDCB);
  465: 		TRM_DPRINTF("pACB->ACBFlag=%x \n",pACB->ACBFlag);
  466: 	    	trm_SRBwaiting(pDCB, pSRB);
  467: 		goto SND_EXIT;
  468: 	}
  469: 
  470: 	if (pDCB->pWaitingSRB) {
  471: 		trm_SRBwaiting(pDCB, pSRB);
  472: 		pSRB = pDCB->pWaitingSRB;
  473: 		pDCB->pWaitingSRB = pSRB->pNextSRB;
  474: 		pSRB->pNextSRB = NULL;
  475: 	}
  476: 
  477: 	if (!trm_StartSCSI(pACB, pDCB, pSRB)) { 
  478: 	/* 
  479: 	 * If trm_StartSCSI return 0 :
  480: 	 * current interrupt status is interrupt enable 
  481: 	 * It's said that SCSI processor is unoccupied 
  482: 	 */
  483: 		pDCB->GoingSRBCnt++; /* stack waiting SRB*/
  484: 		if (pDCB->pGoingSRB) {
  485: 			pDCB->pGoingLastSRB->pNextSRB = pSRB;
  486: 			pDCB->pGoingLastSRB = pSRB;
  487: 		} else {
  488: 			pDCB->pGoingSRB = pSRB;
  489: 			pDCB->pGoingLastSRB = pSRB;
  490: 		}
  491: 	} else {
  492: 	/* 
  493: 	 * If trm_StartSCSI return 1 :
  494: 	 * current interrupt status is interrupt disreenable 
  495: 	 * It's said that SCSI processor has more one SRB need to do
  496: 	 */
  497: 		trm_RewaitSRB0(pDCB, pSRB);
  498: 	}
  499: SND_EXIT:
  500: 	splx(intflag);
  501: 	/*
  502: 	 *	enable interrupt
  503: 	 */
  504: 	return;
  505: }
  506: 
  507: 
  508: static void
  509: trm_action(struct cam_sim *psim, union ccb *pccb) 
  510: {
  511: 	PACB	pACB;
  512: 	u_int	target_id,target_lun;
  513: 
  514: 	CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE, ("trm_action\n"));
  515: 
  516: 	pACB = (PACB) cam_sim_softc(psim);
  517:     	target_id  = pccb->ccb_h.target_id;
  518: 	target_lun = pccb->ccb_h.target_lun;
  519: 
  520: 	switch (pccb->ccb_h.func_code) {
  521: 		case XPT_NOOP:	        	
  522: 			TRM_DPRINTF(" XPT_NOOP \n");
  523: 			pccb->ccb_h.status = CAM_REQ_INVALID;
  524: 			xpt_done(pccb);
  525: 			break;
  526: 		/*
  527: 		 * Execute the requested I/O operation 
  528: 	 	 */
  529: 		case XPT_SCSI_IO: {
  530: 			PDCB			pDCB = NULL;
  531: 			PSRB			pSRB;
  532: 			struct ccb_scsiio	*pcsio;
  533:      
  534: 			pcsio = &pccb->csio;
  535: 			TRM_DPRINTF(" XPT_SCSI_IO \n");
  536: 			TRM_DPRINTF("trm: target_id= %d target_lun= %d \n"
  537: 			     ,target_id, target_lun);
  538: 			TRM_DPRINTF(
  539: 			    "pACB->scan_devices[target_id][target_lun]= %d \n"
  540: 			    ,pACB->scan_devices[target_id][target_lun]);
  541: 			pDCB = pACB->pDCB[target_id][target_lun];
  542: 			/*
  543: 			 * Assign an SRB and connect it with this ccb.
  544: 			 */
  545: 			pSRB = trm_GetSRB(pACB);
  546: 			if (!pSRB) {
  547: 				/* Freeze SIMQ */
  548: 				pccb->ccb_h.status = CAM_RESRC_UNAVAIL;
  549: 				xpt_done(pccb);
  550: 				return;
  551: 			}
  552: 	    		pSRB->pSRBDCB = pDCB;
  553: 	    		pccb->ccb_h.ccb_trmsrb_ptr = pSRB;
  554: 	    		pccb->ccb_h.ccb_trmacb_ptr = pACB;
  555: 		    	pSRB->pccb = pccb;
  556: 			pSRB->ScsiCmdLen = pcsio->cdb_len;
  557: 			/* 
  558: 			 * move layer of CAM command block to layer of SCSI
  559: 			 * Request Block for SCSI processor command doing
  560: 			 */
  561: 			bcopy(pcsio->cdb_io.cdb_bytes,pSRB->CmdBlock
  562: 			    ,pcsio->cdb_len);
  563: 			if ((pccb->ccb_h.flags & CAM_DIR_MASK)
  564: 			    != CAM_DIR_NONE) {
  565: 				if ((pccb->ccb_h.flags &
  566: 				      CAM_SCATTER_VALID) == 0) {
  567: 					if ((pccb->ccb_h.flags 
  568: 					      & CAM_DATA_PHYS) == 0) {
  569: 						int flags;
  570: 						int error;
  571: 
  572: 						flags = splsoftvm();
  573: 						error = bus_dmamap_load(
  574: 						    pACB->buffer_dmat,
  575: 						    pSRB->dmamap,
  576: 						    pcsio->data_ptr,
  577: 						    pcsio->dxfer_len,
  578: 						    trm_ExecuteSRB,
  579: 						    pSRB,
  580: 						    0);
  581: 						if (error == EINPROGRESS) {
  582: 							xpt_freeze_simq(
  583: 							    pACB->psim,
  584: 							    1);
  585: 							pccb->ccb_h.status |=
  586: 							  CAM_RELEASE_SIMQ;
  587: 						}
  588: 						splx(flags);
  589: 					} else {   
  590: 						struct bus_dma_segment seg;
  591: 
  592: 						/* Pointer to physical buffer */
  593: 						seg.ds_addr = 
  594: 						  (bus_addr_t)pcsio->data_ptr;
  595: 						seg.ds_len = pcsio->dxfer_len;
  596: 						trm_ExecuteSRB(pSRB, &seg, 1,
  597: 						    0);
  598: 					}
  599: 				} else { 
  600: 					/*  CAM_SCATTER_VALID */
  601: 					struct bus_dma_segment *segs;
  602: 
  603: 					if ((pccb->ccb_h.flags &
  604: 					     CAM_SG_LIST_PHYS) == 0 ||
  605: 					     (pccb->ccb_h.flags 
  606: 					     & CAM_DATA_PHYS) != 0) {
  607: 						pSRB->pNextSRB = pACB->pFreeSRB;
  608: 						pACB->pFreeSRB = pSRB;
  609: 						pccb->ccb_h.status = 
  610: 						  CAM_PROVIDE_FAIL;
  611: 						xpt_done(pccb);
  612: 						return;
  613: 					}
  614: 
  615: 					/* cam SG list is physical,
  616: 					 *  cam data is virtual 
  617: 					 */
  618: 					segs = (struct bus_dma_segment *)
  619: 					    pcsio->data_ptr;
  620: 					trm_ExecuteSRB(pSRB, segs,
  621: 					    pcsio->sglist_cnt, 1);
  622: 				}   /*  CAM_SCATTER_VALID */
  623: 			} else
  624: 				trm_ExecuteSRB(pSRB, NULL, 0, 0);
  625: 				  }
  626: 			break;
  627: 		case XPT_GDEV_TYPE:		    
  628: 			TRM_DPRINTF(" XPT_GDEV_TYPE \n");
  629: 	    		pccb->ccb_h.status = CAM_REQ_INVALID;
  630: 			xpt_done(pccb);
  631: 			break;
  632: 		case XPT_GDEVLIST:		    
  633: 			TRM_DPRINTF(" XPT_GDEVLIST \n");
  634: 			pccb->ccb_h.status = CAM_REQ_INVALID;
  635: 			xpt_done(pccb);
  636: 			break;
  637: 		/*
  638: 		 * Path routing inquiry 
  639: 	       	 * Path Inquiry CCB 
  640: 		 */
  641: 		case XPT_PATH_INQ: {
  642: 			struct ccb_pathinq *cpi = &pccb->cpi;
  643: 
  644: 			TRM_DPRINTF(" XPT_PATH_INQ \n");
  645: 			cpi->version_num = 1; 
  646: 			cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
  647: 			cpi->target_sprt = 0;
  648: 			cpi->hba_misc = 0;
  649: 			cpi->hba_eng_cnt = 0;
  650: 			cpi->max_target = 15 ; 
  651: 			cpi->max_lun = pACB->max_lun;        /* 7 or 0 */
  652: 			cpi->initiator_id = pACB->AdaptSCSIID;
  653: 			cpi->bus_id = cam_sim_bus(psim);
  654: 			strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
  655: 			strncpy(cpi->hba_vid, "Tekram_TRM", HBA_IDLEN);
  656: 			strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
  657: 			cpi->unit_number = cam_sim_unit(psim);
  658: 			cpi->ccb_h.status = CAM_REQ_CMP;
  659: 			xpt_done(pccb);
  660: 				   }
  661: 			break;
  662: 		/*
  663: 		 * Release a frozen SIM queue 
  664: 		 * Release SIM Queue 
  665: 		 */
  666: 		case XPT_REL_SIMQ:		    
  667: 			TRM_DPRINTF(" XPT_REL_SIMQ \n");
  668: 			pccb->ccb_h.status = CAM_REQ_INVALID;
  669: 			xpt_done(pccb);
  670: 			break;
  671: 		/*
  672: 		 * Set Asynchronous Callback Parameters 
  673: 		 * Set Asynchronous Callback CCB
  674:  		 */
  675: 		case XPT_SASYNC_CB:		    
  676: 			TRM_DPRINTF(" XPT_SASYNC_CB \n");
  677: 			pccb->ccb_h.status = CAM_REQ_INVALID;
  678: 			xpt_done(pccb);
  679: 			break;
  680: 		/*
  681: 		 * Set device type information 
  682: 		 * Set Device Type CCB 
  683:  		 */
  684: 		case XPT_SDEV_TYPE:		    
  685: 			TRM_DPRINTF(" XPT_SDEV_TYPE \n");
  686: 			pccb->ccb_h.status = CAM_REQ_INVALID;
  687: 			xpt_done(pccb);
  688: 			break;
  689: 		/*
  690: 		 * (Re)Scan the SCSI Bus 
  691: 	 	 * Rescan the given bus, or bus/target/lun
  692:  		 */
  693: 		case XPT_SCAN_BUS:		    
  694: 			TRM_DPRINTF(" XPT_SCAN_BUS \n");
  695: 	    		pccb->ccb_h.status = CAM_REQ_INVALID;
  696: 			xpt_done(pccb);
  697: 			break;
  698: 		/*
  699: 		 * Get EDT entries matching the given pattern 
  700:  		 */
  701: 		case XPT_DEV_MATCH:	    	
  702: 			TRM_DPRINTF(" XPT_DEV_MATCH \n");
  703: 	    		pccb->ccb_h.status = CAM_REQ_INVALID;
  704: 			xpt_done(pccb);
  705: 			break;
  706: 		/*
  707: 		 * Turn on debugging for a bus, target or lun 
  708:       		 */
  709: 		case XPT_DEBUG:	    	    
  710: 			TRM_DPRINTF(" XPT_DEBUG \n");
  711: 			pccb->ccb_h.status = CAM_REQ_INVALID;
  712: 			xpt_done(pccb);
  713: 			break;
  714: 			/*
  715: 			 * XPT_ABORT = 0x10, Abort the specified CCB 
  716: 			 * Abort XPT request CCB 
  717: 			 */
  718: 		case XPT_ABORT:             
  719: 			TRM_DPRINTF(" XPT_ABORT \n");
  720: 			pccb->ccb_h.status = CAM_REQ_INVALID;
  721: 			xpt_done(pccb);
  722: 			break;
  723: 		/*
  724: 		 * Reset the specified SCSI bus 
  725: 		 * Reset SCSI Bus CCB 
  726:  		 */
  727: 		case XPT_RESET_BUS: {		
  728: 			int i;
  729: 
  730: 			TRM_DPRINTF(" XPT_RESET_BUS \n");
  731: 	    		trm_reset(pACB);
  732: 			pACB->ACBFlag=0;
  733: 			for (i=0; i<500; i++)
  734: 				DELAY(1000);
  735: 			pccb->ccb_h.status = CAM_REQ_CMP;
  736: 			xpt_done(pccb);
  737: 				    }
  738: 			break;
  739: 		/*
  740: 		 * Bus Device Reset the specified SCSI device 
  741: 		 * Reset SCSI Device CCB 
  742:  		 */
  743: 		case XPT_RESET_DEV:	    	
  744: 		/*
  745: 		 * Don't (yet?) support vendor
  746: 		 * specific commands.
  747: 		 */
  748: 			TRM_DPRINTF(" XPT_RESET_DEV \n");
  749: 	    		pccb->ccb_h.status = CAM_REQ_INVALID;
  750: 			xpt_done(pccb);
  751: 			break;
  752: 		/*
  753: 		 * Terminate the I/O process 
  754: 		 * Terminate I/O Process Request CCB 
  755:  		 */
  756: 		case XPT_TERM_IO:	    	
  757: 			TRM_DPRINTF(" XPT_TERM_IO \n");
  758: 	    		pccb->ccb_h.status = CAM_REQ_INVALID;
  759: 			xpt_done(pccb);
  760: 			break;
  761: 		/*
  762: 		 * Scan Logical Unit 
  763: 		 */
  764: 		case XPT_SCAN_LUN:		   
  765: 			TRM_DPRINTF(" XPT_SCAN_LUN \n");
  766: 			pccb->ccb_h.status = CAM_REQ_INVALID;
  767: 			xpt_done(pccb);
  768: 			break;
  769: 
  770: 		/*
  771: 		 * Get/Set transfer rate/width/disconnection/tag queueing 
  772: 		 * settings 
  773: 		 * (GET) default/user transfer settings for the target 
  774: 	 	 */
  775: 		case XPT_GET_TRAN_SETTINGS: {
  776: 			struct	ccb_trans_settings *cts;        
  777: 			int	intflag;
  778: 			struct	trm_transinfo *tinfo;
  779: 			PDCB	pDCB;	
  780: 			
  781: 			TRM_DPRINTF(" XPT_GET_TRAN_SETTINGS \n");
  782: 	    		cts = &pccb->cts;
  783: 			pDCB = pACB->pDCB[target_id][target_lun];
  784: 			intflag = splcam();
  785: 			/*
  786: 			 * disable interrupt
  787: 			 */
  788: 			if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
  789: 				/* current transfer settings */
  790: 				if (pDCB->tinfo.disc_tag & TRM_CUR_DISCENB)
  791: 					cts->flags = CCB_TRANS_DISC_ENB;
  792: 				else
  793: 					cts->flags = 0;/* no tag & disconnect */
  794: 				if (pDCB->tinfo.disc_tag & TRM_CUR_TAGENB)
  795: 					cts->flags |= CCB_TRANS_TAG_ENB;
  796: 				tinfo = &pDCB->tinfo.current;
  797: 				TRM_DPRINTF("CURRENT:  cts->flags= %2x \n",
  798: 				    cts->flags);
  799: 			} else {
  800: 		  	  /* default(user) transfer settings */
  801: 				if (pDCB->tinfo.disc_tag & TRM_USR_DISCENB)
  802: 					cts->flags = CCB_TRANS_DISC_ENB;
  803: 				else
  804: 					cts->flags = 0;
  805: 				if (pDCB->tinfo.disc_tag & TRM_USR_TAGENB)
  806: 					cts->flags |= CCB_TRANS_TAG_ENB;
  807: 				tinfo = &pDCB->tinfo.user;
  808: 				TRM_DPRINTF("USER: cts->flags= %2x \n",
  809: 					cts->flags);
  810: 			}
  811: 			cts->sync_period = tinfo->period;
  812: 			cts->sync_offset = tinfo->offset;
  813: 			cts->bus_width   = tinfo->width;
  814: 			TRM_DPRINTF("pDCB->SyncPeriod: %d  \n", 
  815: 				pDCB->SyncPeriod);
  816: 			TRM_DPRINTF("period: %d  \n", tinfo->period);
  817: 			TRM_DPRINTF("offset: %d  \n", tinfo->offset);
  818: 			TRM_DPRINTF("width: %d  \n", tinfo->width);
  819: 
  820: 	    		splx(intflag);
  821: 			cts->valid = CCB_TRANS_SYNC_RATE_VALID | 
  822: 			    CCB_TRANS_SYNC_OFFSET_VALID | 
  823: 			    CCB_TRANS_BUS_WIDTH_VALID | 
  824: 			    CCB_TRANS_DISC_VALID | 
  825: 			    CCB_TRANS_TQ_VALID;
  826: 			pccb->ccb_h.status = CAM_REQ_CMP;
  827: 			xpt_done(pccb);
  828: 					    }
  829: 			break;
  830: 		/* 
  831: 		 * Get/Set transfer rate/width/disconnection/tag queueing 
  832: 		 * settings
  833: 		 * (Set) transfer rate/width negotiation settings 
  834: 		 */
  835: 		case XPT_SET_TRAN_SETTINGS: {
  836: 			struct	ccb_trans_settings *cts;
  837: 			u_int	update_type;
  838: 			int	intflag;
  839: 			PDCB	pDCB;
  840: 
  841: 			TRM_DPRINTF(" XPT_SET_TRAN_SETTINGS \n");
  842: 	    		cts = &pccb->cts;
  843: 			update_type = 0;
  844: 			if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
  845: 				update_type |= TRM_TRANS_GOAL;
  846: 			if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
  847: 				update_type |= TRM_TRANS_USER;
  848: 			intflag = splcam();
  849: 	    		pDCB = pACB->pDCB[target_id][target_lun];
  850: 
  851: 			if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
  852: 			  /*ccb disc enables */
  853: 				if (update_type & TRM_TRANS_GOAL) {
  854: 					if ((cts->flags & CCB_TRANS_DISC_ENB)
  855: 					    != 0) 
  856: 				    		pDCB->tinfo.disc_tag 
  857: 						    |= TRM_CUR_DISCENB;
  858: 					else
  859: 						pDCB->tinfo.disc_tag &=
  860: 						    ~TRM_CUR_DISCENB;
  861: 				}
  862: 				if (update_type & TRM_TRANS_USER) {
  863: 					if ((cts->flags & CCB_TRANS_DISC_ENB)
  864: 					    != 0)
  865: 						pDCB->tinfo.disc_tag 
  866: 						    |= TRM_USR_DISCENB;
  867: 					else
  868: 						pDCB->tinfo.disc_tag &=
  869: 						    ~TRM_USR_DISCENB;
  870: 				}
  871: 			}
  872: 			if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
  873: 			  /* if ccb tag q active */
  874: 				if (update_type & TRM_TRANS_GOAL) {
  875: 					if ((cts->flags & CCB_TRANS_TAG_ENB)
  876: 					    != 0)
  877: 						pDCB->tinfo.disc_tag |= 
  878: 						    TRM_CUR_TAGENB;
  879: 					else
  880: 						pDCB->tinfo.disc_tag &= 
  881: 						    ~TRM_CUR_TAGENB;
  882: 				}
  883: 				if (update_type & TRM_TRANS_USER) {
  884: 					if ((cts->flags & CCB_TRANS_TAG_ENB)
  885: 					    != 0)
  886: 				  		pDCB->tinfo.disc_tag |= 
  887: 						    TRM_USR_TAGENB;
  888: 					else
  889: 						pDCB->tinfo.disc_tag &= 
  890: 						    ~TRM_USR_TAGENB;
  891: 				}	
  892: 			}
  893: 			/* Minimum sync period factor	*/
  894: 
  895: 			if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
  896: 				/* if ccb sync active */
  897: 				/* TRM-S1040 MinSyncPeriod = 4 clocks/byte */
  898: 				if ((cts->sync_period != 0) &&
  899: 				    (cts->sync_period < 125))
  900: 					cts->sync_period = 125;
  901: 				/* 1/(125*4) minsync 2 MByte/sec */
  902: 				if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID)
  903: 				    != 0) {
  904: 					if (cts->sync_offset == 0)
  905: 				 		cts->sync_period = 0;
  906: 					/* TRM-S1040 MaxSyncOffset = 15 bytes*/
  907: 					if (cts->sync_offset > 15) 
  908: 						cts->sync_offset = 15;
  909: 				}
  910: 			}
  911: 			if ((update_type & TRM_TRANS_USER) != 0) {
  912: 				pDCB->tinfo.user.period = cts->sync_period;
  913: 				pDCB->tinfo.user.offset = cts->sync_offset;
  914: 				pDCB->tinfo.user.width  = cts->bus_width;
  915: 			}
  916: 			if ((update_type & TRM_TRANS_GOAL) != 0) {
  917: 				pDCB->tinfo.goal.period = cts->sync_period;
  918: 				pDCB->tinfo.goal.offset = cts->sync_offset;
  919: 				pDCB->tinfo.goal.width  = cts->bus_width;
  920: 			}
  921: 			splx(intflag);
  922: 			pccb->ccb_h.status = CAM_REQ_CMP;
  923: 			xpt_done(pccb);
  924: 			break;
  925: 					    }
  926: 		/*
  927: 		 * Calculate the geometry parameters for a device give
  928: 		 * the sector size and volume size. 
  929:    		 */
  930: 		case XPT_CALC_GEOMETRY:	{
  931: 			struct		ccb_calc_geometry *ccg;
  932: 			u_int32_t	size_mb;
  933: 			u_int32_t	secs_per_cylinder;
  934: 			int		extended;
  935: 
  936: 			TRM_DPRINTF(" XPT_CALC_GEOMETRY \n");
  937: 			ccg = &pccb->ccg;
  938: 			size_mb = ccg->volume_size / 
  939: 			    ((1024L * 1024L) / ccg->block_size);
  940: 			extended =  1;		
  941: 			if (size_mb > 1024 && extended) {
  942: 				ccg->heads = 255;
  943: 				ccg->secs_per_track = 63;
  944: 			} else {
  945: 				ccg->heads = 64;
  946: 				ccg->secs_per_track = 32;
  947: 			}
  948: 			secs_per_cylinder = ccg->heads * ccg->secs_per_track;
  949: 			ccg->cylinders = ccg->volume_size / secs_per_cylinder;
  950: 			pccb->ccb_h.status = CAM_REQ_CMP;
  951: 			xpt_done(pccb);
  952: 					}
  953: 			break;
  954: 		case XPT_ENG_INQ:           
  955: 			TRM_DPRINTF(" XPT_ENG_INQ \n");
  956: 	    		pccb->ccb_h.status = CAM_REQ_INVALID;
  957: 			xpt_done(pccb);
  958: 			break;
  959: 		/*
  960: 		 * HBA execute engine request 
  961: 		 * This structure must match SCSIIO size 
  962: 		 */
  963: 		case XPT_ENG_EXEC:		    
  964: 			TRM_DPRINTF(" XPT_ENG_EXEC \n");
  965: 	    		pccb->ccb_h.status = CAM_REQ_INVALID;
  966: 			xpt_done(pccb);
  967: 			break;
  968: 		/*
  969: 		 * XPT_EN_LUN = 0x30, Enable LUN as a target 
  970: 		 * Target mode structures. 
  971: 	 	 */
  972: 		case XPT_EN_LUN:            
  973: 		/*
  974: 		 * Don't (yet?) support vendor
  975: 		 * specific commands.
  976: 		 */
  977: 			TRM_DPRINTF(" XPT_EN_LUN \n");
  978: 			pccb->ccb_h.status = CAM_REQ_INVALID;
  979: 			xpt_done(pccb);
  980: 			break;
  981: 		/*
  982: 		* Execute target I/O request 
  983: 		*/
  984: 		case XPT_TARGET_IO:		    
  985: 		/*
  986: 		 * Don't (yet?) support vendor
  987: 		 * specific commands.
  988: 		 */
  989: 			TRM_DPRINTF(" XPT_TARGET_IO \n");
  990: 			pccb->ccb_h.status = CAM_REQ_INVALID;
  991: 			xpt_done(pccb);
  992: 			break;
  993: 		/*
  994: 		 * Accept Host Target Mode CDB 
  995:        		 */
  996: 		case XPT_ACCEPT_TARGET_IO:	
  997: 		/*
  998: 		 * Don't (yet?) support vendor
  999: 		 * specific commands.
 1000: 		 */
 1001: 			TRM_DPRINTF(" XPT_ACCEPT_TARGET_IO \n");
 1002: 			pccb->ccb_h.status = CAM_REQ_INVALID;
 1003: 			xpt_done(pccb);
 1004: 			break;
 1005: 		/*
 1006: 		 * Continue Host Target I/O Connection 
 1007:  		 */
 1008: 		case XPT_CONT_TARGET_IO:  	
 1009: 		/*
 1010: 		 * Don't (yet?) support vendor
 1011: 		 * specific commands.
 1012: 		 */
 1013: 			TRM_DPRINTF(" XPT_CONT_TARGET_IO \n");
 1014: 			pccb->ccb_h.status = CAM_REQ_INVALID;
 1015: 			xpt_done(pccb);
 1016: 			break;
 1017: 		/*
 1018: 		 * Notify Host Target driver of event 
 1019:  		 */
 1020: 		case XPT_IMMED_NOTIFY:	    
 1021: 			TRM_DPRINTF(" XPT_IMMED_NOTIFY \n");
 1022: 	    		pccb->ccb_h.status = CAM_REQ_INVALID;
 1023: 			xpt_done(pccb);
 1024: 			break;
 1025: 		/*
 1026: 		 * Acknowledgement of event
 1027:        		 */
 1028: 		case XPT_NOTIFY_ACK:	    
 1029: 			TRM_DPRINTF(" XPT_NOTIFY_ACK \n");
 1030: 	    		pccb->ccb_h.status = CAM_REQ_INVALID;
 1031: 			xpt_done(pccb);
 1032: 			break;
 1033: 		/*
 1034: 		 * XPT_VUNIQUE = 0x80
 1035: 		 */
 1036: 		case XPT_VUNIQUE:   
 1037: 			pccb->ccb_h.status = CAM_REQ_INVALID;
 1038: 			xpt_done(pccb);
 1039: 			break;
 1040: 		default:
 1041: 			pccb->ccb_h.status = CAM_REQ_INVALID;
 1042: 			xpt_done(pccb);
 1043: 			break;
 1044: 	}
 1045: }
 1046: 
 1047: static void 
 1048: trm_poll(struct cam_sim *psim)
 1049: {       
 1050:   
 1051: }
 1052: 
 1053: static void
 1054: trm_ResetDevParam(PACB pACB)
 1055: {
 1056: 	PDCB		pDCB, pdcb;
 1057: 	PNVRAMTYPE 	pEEpromBuf;
 1058: 	u_int8_t	PeriodIndex;
 1059: 
 1060: 	pDCB = pACB->pLinkDCB;
 1061: 	if (pDCB == NULL)
 1062: 		return;
 1063: 	pdcb = pDCB;
 1064: 	do {
 1065: 		pDCB->SyncMode  &= ~(SYNC_NEGO_DONE+ WIDE_NEGO_DONE);
 1066: 		pDCB->SyncPeriod = 0;
 1067: 		pDCB->SyncOffset = 0;
 1068: 		pEEpromBuf = &trm_eepromBuf[pACB->AdapterUnit];
 1069: 		pDCB->DevMode = 
 1070: 		  pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarCfg0;
 1071: 		pDCB->AdpMode = pEEpromBuf->NvramChannelCfg;
 1072: 		PeriodIndex =
 1073: 		   pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarPeriod & 0x07;
 1074: 		pDCB->MaxNegoPeriod = dc395x_trm_clock_period[PeriodIndex];
 1075: 		if ((pDCB->DevMode & NTC_DO_WIDE_NEGO) && 
 1076: 		    (pACB->Config & HCC_WIDE_CARD))
 1077: 			pDCB->SyncMode |= WIDE_NEGO_ENABLE;
 1078: 		pDCB = pDCB->pNextDCB;
 1079: 	}
 1080: 	while (pdcb != pDCB);
 1081: }
 1082: 
 1083: static void
 1084: trm_RecoverSRB(PACB pACB)
 1085: {
 1086: 	PDCB		pDCB, pdcb;
 1087: 	PSRB		psrb, psrb2;
 1088:        	u_int16_t	cnt, i;
 1089: 
 1090: 	pDCB = pACB->pLinkDCB;
 1091: 	if (pDCB == NULL)
 1092: 		return;
 1093: 	pdcb = pDCB;
 1094: 	do {
 1095: 		cnt = pdcb->GoingSRBCnt;
 1096: 		psrb = pdcb->pGoingSRB;
 1097: 		for (i = 0; i < cnt; i++) {
 1098: 			psrb2 = psrb;
 1099: 			psrb = psrb->pNextSRB;
 1100: 			if (pdcb->pWaitingSRB) {
 1101: 				psrb2->pNextSRB = pdcb->pWaitingSRB;
 1102: 				pdcb->pWaitingSRB = psrb2;
 1103: 			} else {
 1104: 				pdcb->pWaitingSRB = psrb2;
 1105: 				pdcb->pWaitLastSRB = psrb2;
 1106: 				psrb2->pNextSRB = NULL;
 1107: 			}
 1108: 		}
 1109: 		pdcb->GoingSRBCnt = 0;
 1110: 		pdcb->pGoingSRB = NULL;
 1111: 		pdcb->TagMask = 0;
 1112: 		pdcb = pdcb->pNextDCB;
 1113: 	}
 1114: 	while (pdcb != pDCB);
 1115: }
 1116: 
 1117: static void
 1118: trm_reset(PACB pACB)
 1119: {
 1120: 	int		intflag;
 1121: 	u_int16_t	i;
 1122: 
 1123:     	TRM_DPRINTF("trm: RESET");
 1124:     	intflag = splcam();
 1125: 	trm_reg_write8(0x00, TRMREG_DMA_INTEN);
 1126: 	trm_reg_write8(0x00, TRMREG_SCSI_INTEN);
 1127: 
 1128: 	trm_ResetSCSIBus(pACB);
 1129: 	for (i = 0; i < 500; i++)
 1130: 		DELAY(1000);
 1131:     	trm_reg_write8(0x7F, TRMREG_SCSI_INTEN); 
 1132: 	/* Enable DMA interrupt	*/
 1133: 	trm_reg_write8(EN_SCSIINTR, TRMREG_DMA_INTEN);
 1134: 	/* Clear DMA FIFO */
 1135: 	trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL);
 1136: 	/* Clear SCSI FIFO */
 1137: 	trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL);
 1138: 	trm_ResetDevParam(pACB);
 1139: 	trm_DoingSRB_Done(pACB);
 1140: 	pACB->pActiveDCB = NULL;
 1141: 	pACB->ACBFlag = 0;/* RESET_DETECT, RESET_DONE ,RESET_DEV */
 1142: 	trm_DoWaitingSRB(pACB);
 1143: 	/* Tell the XPT layer that a bus reset occured    */
 1144: 	if (pACB->ppath != NULL)
 1145: 		xpt_async(AC_BUS_RESET, pACB->ppath, NULL);
 1146: 	splx(intflag);
 1147:     	return;
 1148: }
 1149: 
 1150: static u_int16_t
 1151: trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB)
 1152: {
 1153: 	u_int16_t	return_code;
 1154: 	u_int8_t	tag_number, scsicommand, i,command,identify_message;
 1155: 	u_int8_t *	ptr;
 1156: 	u_long		tag_mask;
 1157: 	union  ccb	*pccb;
 1158: 	struct ccb_scsiio *pcsio;
 1159: 
 1160: 	pccb  = pSRB->pccb;
 1161: 	pcsio = &pccb->csio;
 1162: 	pSRB->TagNumber = 31;
 1163: 
 1164: 	trm_reg_write8(pACB->AdaptSCSIID, TRMREG_SCSI_HOSTID);
 1165: 	trm_reg_write8(pDCB->TargetID, TRMREG_SCSI_TARGETID);
 1166: 	trm_reg_write8(pDCB->SyncPeriod, TRMREG_SCSI_SYNC);
 1167: 	trm_reg_write8(pDCB->SyncOffset, TRMREG_SCSI_OFFSET);
 1168: 	pSRB->ScsiPhase = PH_BUS_FREE;/* initial phase */
 1169: 	/* Flush FIFO */
 1170: 	trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
 1171: 
 1172: 	identify_message = pDCB->IdentifyMsg;
 1173: 
 1174:    	if ((pSRB->CmdBlock[0] == INQUIRY) ||
 1175: 	    (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
 1176: 	    (pSRB->SRBFlag & AUTO_REQSENSE)) {
 1177: 		if (((pDCB->SyncMode & WIDE_NEGO_ENABLE) &&
 1178: 		      !(pDCB->SyncMode & WIDE_NEGO_DONE)) \
 1179: 		|| ((pDCB->SyncMode & SYNC_NEGO_ENABLE) &&
 1180: 		  !(pDCB->SyncMode & SYNC_NEGO_DONE))) {
 1181: 			if (!(pDCB->IdentifyMsg & 7) ||
 1182: 			    (pSRB->CmdBlock[0] != INQUIRY)) {
 1183: 				scsicommand = SCMD_SEL_ATNSTOP;
 1184: 				pSRB->SRBState = SRB_MSGOUT;
 1185: 				goto polling;
 1186: 			}
 1187: 		}
 1188:        	/* 
 1189:        	* Send identify message	
 1190:        	*/
 1191: 		trm_reg_write8((identify_message & 0xBF) ,TRMREG_SCSI_FIFO); 
 1192: 		scsicommand = SCMD_SEL_ATN;
 1193: 		pSRB->SRBState = SRB_START_;
 1194: 	} else {
 1195: 		/* not inquiry,request sense,auto request sense */
 1196: 		/* 
 1197: 		 * Send identify message	
 1198: 		 */
 1199: 		trm_reg_write8(identify_message,TRMREG_SCSI_FIFO);
 1200: 		scsicommand = SCMD_SEL_ATN;
 1201: 		pSRB->SRBState = SRB_START_;
 1202: 		if (pDCB->SyncMode & EN_TAG_QUEUING) {
 1203: 		  /* Send Tag message */
 1204: 	      	  /* 
 1205: 	       	   * Get tag id
 1206:    		   */
 1207: 			tag_mask = 1;
 1208: 			tag_number = 0;
 1209: 			while (tag_mask & pDCB->TagMask) {
 1210: 				tag_mask = tag_mask << 1;
 1211: 				tag_number++;
 1212: 			}
 1213: 			/* 
 1214: 			 * Send Tag id
 1215: 			 */
 1216: 			trm_reg_write8(MSG_SIMPLE_QTAG, TRMREG_SCSI_FIFO);
 1217: 			trm_reg_write8(tag_number, TRMREG_SCSI_FIFO);
 1218: 			pDCB->TagMask |= tag_mask;
 1219: 			pSRB->TagNumber = tag_number;
 1220: 			scsicommand = SCMD_SEL_ATN3;
 1221: 			pSRB->SRBState = SRB_START_;
 1222: 		}
 1223: 	}
 1224: polling:
 1225: 	/*
 1226: 	 * 	 Send CDB ..command block .........			
 1227: 	 */
 1228:    	if (pSRB->SRBFlag & AUTO_REQSENSE) {
 1229: 		trm_reg_write8(REQUEST_SENSE, TRMREG_SCSI_FIFO);
 1230: 		trm_reg_write8((pDCB->IdentifyMsg << 5), TRMREG_SCSI_FIFO);
 1231: 		trm_reg_write8(0, TRMREG_SCSI_FIFO);
 1232: 		trm_reg_write8(0, TRMREG_SCSI_FIFO);
 1233: 		trm_reg_write8(pcsio->sense_len, TRMREG_SCSI_FIFO);
 1234: 		trm_reg_write8(0, TRMREG_SCSI_FIFO);
 1235: 	} else {
 1236: 		ptr = (u_int8_t *) pSRB->CmdBlock;
 1237: 		for (i = 0; i < pSRB->ScsiCmdLen ; i++) {
 1238: 			command = *ptr++;
 1239: 			trm_reg_write8(command,TRMREG_SCSI_FIFO);
 1240: 		}
 1241: 	}
 1242: 	if (trm_reg_read16(TRMREG_SCSI_STATUS) & SCSIINTERRUPT) { 
 1243: 	    /* 
 1244: 	     * If trm_StartSCSI return 1 :
 1245: 	     * current interrupt status is interrupt disreenable 
 1246: 	     * It's said that SCSI processor has more one SRB need to do,
 1247:      	     * SCSI processor has been occupied by one SRB.
 1248: 	     */
 1249: 		pSRB->SRBState = SRB_READY;
 1250: 		pDCB->TagMask &= ~(1 << pSRB->TagNumber);
 1251: 		return_code = 1;
 1252: 	} else { 
 1253: 	  /* 
 1254: 	   * If trm_StartSCSI return 0 :
 1255: 	   * current interrupt status is interrupt enable 
 1256: 	   * It's said that SCSI processor is unoccupied 
 1257: 	   */
 1258: 		pSRB->ScsiPhase  = SCSI_NOP1; /* SCSI bus free Phase */
 1259: 		pACB->pActiveDCB = pDCB;
 1260: 		pDCB->pActiveSRB = pSRB;
 1261: 		return_code = 0;
 1262: 		trm_reg_write16(DO_DATALATCH | DO_HWRESELECT, 
 1263: 		    TRMREG_SCSI_CONTROL);/* it's important for atn stop*/
 1264: 		/*
 1265: 		 * SCSI cammand 
 1266: 		 */
 1267: 		trm_reg_write8(scsicommand,TRMREG_SCSI_COMMAND);
 1268: 	}
 1269: 	return (return_code);	
 1270: }
 1271: 
 1272: static void 
 1273: trm_Interrupt(vpACB)
 1274: void *vpACB;
 1275: {
 1276: 	PACB		pACB;
 1277: 	PDCB		pDCB;
 1278: 	PSRB		pSRB;
 1279: 	u_int16_t	phase;
 1280: 	void		(*stateV)(PACB, PSRB, u_int8_t *);
 1281: 	u_int8_t	scsi_status=0, scsi_intstatus;
 1282: 
 1283: 	pACB = vpACB;
 1284: 
 1285: 	if (pACB == NULL) {
 1286: 		TRM_DPRINTF("trm_Interrupt: pACB NULL return......");
 1287: 	    	return;
 1288: 	}
 1289: 
 1290: 	scsi_status = trm_reg_read16(TRMREG_SCSI_STATUS);
 1291: 	if (!(scsi_status & SCSIINTERRUPT)) {
 1292: 		TRM_DPRINTF("trm_Interrupt: TRMREG_SCSI_STATUS scsi_status = NULL ,return......");
 1293: 	    	return;
 1294: 	}
 1295: 	TRM_DPRINTF("scsi_status=%2x,",scsi_status);
 1296: 
 1297:     	scsi_intstatus = trm_reg_read8(TRMREG_SCSI_INTSTATUS);
 1298: 
 1299: 	TRM_DPRINTF("scsi_intstatus=%2x,",scsi_intstatus);
 1300: 
 1301:     	if (scsi_intstatus & (INT_SELTIMEOUT | INT_DISCONNECT)) {
 1302: 		trm_Disconnect(pACB);
 1303: 		return;
 1304: 	}
 1305: 
 1306: 	if (scsi_intstatus & INT_RESELECTED) {
 1307: 		trm_Reselect(pACB);
 1308: 		return;
 1309: 	}
 1310: 	if (scsi_intstatus & INT_SCSIRESET) {
 1311: 		trm_ScsiRstDetect(pACB);
 1312: 		return;
 1313: 	}
 1314: 
 1315: 	if (scsi_intstatus & (INT_BUSSERVICE | INT_CMDDONE)) {
 1316: 		pDCB = pACB->pActiveDCB;
 1317: 		pSRB = pDCB->pActiveSRB;
 1318: 		if (pDCB) {
 1319: 			if (pDCB->DCBFlag & ABORT_DEV_)
 1320: 				trm_EnableMsgOutAbort1(pACB, pSRB);
 1321: 		}
 1322: 		phase = (u_int16_t) pSRB->ScsiPhase;  /* phase: */
 1323: 		stateV = (void *) trm_SCSI_phase0[phase];
 1324: 		stateV(pACB, pSRB, &scsi_status);
 1325: 		pSRB->ScsiPhase = scsi_status & PHASEMASK; 
 1326: 		/* phase:0,1,2,3,4,5,6,7 */
 1327: 		phase = (u_int16_t) scsi_status & PHASEMASK;       
 1328: 		stateV = (void *) trm_SCSI_phase1[phase];
 1329: 		stateV(pACB, pSRB, &scsi_status);  
 1330: 	}
 1331: }
 1332: 
 1333: static void
 1334: trm_MsgOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1335: {
 1336: 
 1337: 	if (pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT))
 1338: 		*pscsi_status = PH_BUS_FREE;
 1339: 	/*.. initial phase*/
 1340: }
 1341: 
 1342: static void
 1343: trm_MsgOutPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1344: {
 1345: 	u_int8_t	bval;
 1346: 	u_int16_t	i, cnt;
 1347: 	u_int8_t *	ptr;
 1348: 	PDCB		pDCB;
 1349: 
 1350: 	trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
 1351: 	pDCB = pACB->pActiveDCB;
 1352: 	if (!(pSRB->SRBState & SRB_MSGOUT)) {
 1353: 		cnt = pSRB->MsgCnt;
 1354: 		if (cnt) {
 1355: 			ptr = (u_int8_t *) pSRB->MsgOutBuf;
 1356: 			for (i = 0; i < cnt; i++) {
 1357: 				trm_reg_write8(*ptr, TRMREG_SCSI_FIFO);
 1358: 				ptr++;
 1359: 			}
 1360: 			pSRB->MsgCnt = 0;
 1361: 			if ((pDCB->DCBFlag & ABORT_DEV_) &&
 1362: 			    (pSRB->MsgOutBuf[0] == MSG_ABORT)) {
 1363: 				pSRB->SRBState = SRB_ABORT_SENT;
 1364: 			}
 1365: 		} else {
 1366: 			bval = MSG_ABORT;	
 1367: 			if ((pSRB->CmdBlock[0] == INQUIRY) ||
 1368: 					(pSRB->CmdBlock[0] == REQUEST_SENSE) ||
 1369: 					(pSRB->SRBFlag & AUTO_REQSENSE)) {
 1370: 				if (pDCB->SyncMode & SYNC_NEGO_ENABLE) {
 1371: 					goto  mop1;
 1372: 				}
 1373: 			}
 1374: 			trm_reg_write8(bval, TRMREG_SCSI_FIFO);
 1375: 		}
 1376: 	} else {
 1377: mop1:   /* message out phase */
 1378: 		if (!(pSRB->SRBState & SRB_DO_WIDE_NEGO)
 1379: 		    && (pDCB->SyncMode & WIDE_NEGO_ENABLE)) {
 1380: 		  /*
 1381: 	   	   * WIDE DATA TRANSFER REQUEST code (03h)
 1382: 		   */
 1383: 			pDCB->SyncMode &= ~(SYNC_NEGO_DONE | EN_ATN_STOP);
 1384: 			trm_reg_write8((pDCB->IdentifyMsg & 0xBF),
 1385: 			    TRMREG_SCSI_FIFO); 
 1386: 			trm_reg_write8(MSG_EXTENDED,TRMREG_SCSI_FIFO);
 1387: 			/* (01h) */
 1388: 			trm_reg_write8(2,TRMREG_SCSI_FIFO);	
 1389: 			/* Message length (02h) */
 1390: 			trm_reg_write8(3,TRMREG_SCSI_FIFO);
 1391: 			/* wide data xfer (03h) */
 1392: 			trm_reg_write8(1,TRMREG_SCSI_FIFO);
 1393: 			/* width:0(8bit),1(16bit),2(32bit) */
 1394: 			pSRB->SRBState |= SRB_DO_WIDE_NEGO; 
 1395: 		} else if (!(pSRB->SRBState & SRB_DO_SYNC_NEGO) 
 1396: 		    && (pDCB->SyncMode & SYNC_NEGO_ENABLE)) {
 1397: 		  /*
 1398: 	   	   * SYNCHRONOUS DATA TRANSFER REQUEST code (01h)
 1399: 		   */
 1400: 			if (!(pDCB->SyncMode & WIDE_NEGO_DONE))
 1401: 				trm_reg_write8((pDCB->IdentifyMsg & 0xBF),
 1402: 						TRMREG_SCSI_FIFO);
 1403: 			trm_reg_write8(MSG_EXTENDED,TRMREG_SCSI_FIFO);
 1404: 		  /* (01h) */
 1405: 			trm_reg_write8(3,TRMREG_SCSI_FIFO); 
 1406: 		  /* Message length (03h) */
 1407: 			trm_reg_write8(1,TRMREG_SCSI_FIFO);
 1408: 		  /* SYNCHRONOUS DATA TRANSFER REQUEST code (01h) */
 1409: 			trm_reg_write8(pDCB->MaxNegoPeriod,TRMREG_SCSI_FIFO);
 1410: 		  /* Transfer peeriod factor */
 1411: 			trm_reg_write8(SYNC_NEGO_OFFSET,TRMREG_SCSI_FIFO); 
 1412: 		  /* REQ/ACK offset */
 1413: 			pSRB->SRBState |= SRB_DO_SYNC_NEGO;
 1414: 		}
 1415: 	}
 1416: 	trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
 1417: 	/* it's important for atn stop */
 1418: 	/*
 1419: 	 * SCSI cammand 
 1420: 	 */
 1421: 	trm_reg_write8(SCMD_FIFO_OUT, TRMREG_SCSI_COMMAND);
 1422: }
 1423: 
 1424: static void 
 1425: trm_CommandPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1426: {
 1427: 
 1428: }
 1429: 
 1430: static void 
 1431: trm_CommandPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1432: {
 1433: 	PDCB			pDCB;
 1434: 	u_int8_t *		ptr;
 1435: 	u_int16_t		i, cnt;
 1436: 	union  ccb		*pccb;
 1437: 	struct ccb_scsiio	*pcsio;
 1438: 
 1439: 	pccb  = pSRB->pccb;
 1440: 	pcsio = &pccb->csio;
 1441: 
 1442: 	trm_reg_write16(DO_CLRATN | DO_CLRFIFO , TRMREG_SCSI_CONTROL);
 1443: 	if (!(pSRB->SRBFlag & AUTO_REQSENSE)) {
 1444: 		cnt = (u_int16_t) pSRB->ScsiCmdLen;
 1445: 		ptr = (u_int8_t *) pSRB->CmdBlock;
 1446: 		for (i = 0; i < cnt; i++) {
 1447: 			trm_reg_write8(*ptr, TRMREG_SCSI_FIFO);
 1448: 			ptr++;
 1449: 		}
 1450: 	} else {
 1451: 		trm_reg_write8(REQUEST_SENSE, TRMREG_SCSI_FIFO);
 1452: 		pDCB = pACB->pActiveDCB;
 1453: 		/* target id */
 1454: 		trm_reg_write8((pDCB->IdentifyMsg << 5), TRMREG_SCSI_FIFO);
 1455: 		trm_reg_write8(0, TRMREG_SCSI_FIFO);
 1456: 		trm_reg_write8(0, TRMREG_SCSI_FIFO);
 1457: 		/* sizeof(struct scsi_sense_data) */
 1458: 		trm_reg_write8(pcsio->sense_len, TRMREG_SCSI_FIFO);
 1459: 		trm_reg_write8(0, TRMREG_SCSI_FIFO);
 1460: 	}
 1461: 	pSRB->SRBState = SRB_COMMAND;
 1462: 	trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
 1463: 	/* it's important for atn stop*/
 1464: 	/*
 1465: 	 * SCSI cammand 
 1466: 	 */
 1467: 	trm_reg_write8(SCMD_FIFO_OUT, TRMREG_SCSI_COMMAND);
 1468: }
 1469: 
 1470: static void
 1471: trm_DataOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1472: {
 1473: 	PDCB		pDCB;
 1474: 	u_int8_t	TempDMAstatus,SGIndexTemp;
 1475: 	u_int16_t	scsi_status;
 1476: 	PSEG		pseg;
 1477: 	u_long		TempSRBXferredLength,dLeftCounter=0;
 1478: 
 1479: 	pDCB = pSRB->pSRBDCB;
 1480: 	scsi_status = *pscsi_status;
 1481: 
 1482: 	if (!(pSRB->SRBState & SRB_XFERPAD)) {
 1483: 		if (scsi_status & PARITYERROR)
 1484: 			pSRB->SRBStatus |= PARITY_ERROR;
 1485: 		if (!(scsi_status & SCSIXFERDONE)) {
 1486:       		  /*
 1487: 		   * when data transfer from DMA FIFO to SCSI FIFO
 1488: 		   * if there was some data left in SCSI FIFO
 1489: 		   */
 1490:   			dLeftCounter = (u_long) 
 1491: 			  (trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x1F);
 1492: 			if (pDCB->SyncPeriod & WIDE_SYNC) {
 1493: 			  /*
 1494: 		   	   * if WIDE scsi SCSI FIFOCNT unit is word
 1495: 	   		   * so need to * 2
 1496:    			   */
 1497: 				dLeftCounter <<= 1;
 1498: 			}
 1499: 		}
 1500: 		/*
 1501: 		 * caculate all the residue data that not yet tranfered
 1502: 		 * SCSI transfer counter + left in SCSI FIFO data
 1503: 		 *
 1504: 		 * .....TRM_SCSI_COUNTER (24bits)
 1505: 		 * The counter always decrement by one for every SCSI byte 
 1506: 		 *transfer.
 1507: 		 * .....TRM_SCSI_FIFOCNT (5bits)
 1508: 		 * The counter is SCSI FIFO offset counter
 1509: 		 */
 1510: 		dLeftCounter += trm_reg_read32(TRMREG_SCSI_COUNTER);
 1511: 		if (dLeftCounter == 1) {
 1512: 			dLeftCounter = 0;
 1513: 			trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL);
 1514: 		}
 1515: 		if ((dLeftCounter == 0) || 
 1516: 		    (scsi_status & SCSIXFERCNT_2_ZERO)) {   
 1517: 			TempDMAstatus = trm_reg_read8(TRMREG_DMA_STATUS);
 1518: 			while (!(TempDMAstatus & DMAXFERCOMP)) {
 1519: 				TempDMAstatus = 
 1520: 				  trm_reg_read8(TRMREG_DMA_STATUS);
 1521: 			}
 1522: 			pSRB->SRBTotalXferLength = 0;
 1523: 		} else {
 1524: 		  /* Update SG list		*/
 1525: 		  /*
 1526: 	   	   * if transfer not yet complete
 1527:    		   * there were some data residue in SCSI FIFO or
 1528: 		   * SCSI transfer counter not empty
 1529: 		   */
 1530: 			if (pSRB->SRBTotalXferLength != dLeftCounter) {
 1531: 			  /*
 1532: 		  	   * data that had transferred length
 1533: 	   		   */
 1534: 				TempSRBXferredLength = 
 1535: 				  pSRB->SRBTotalXferLength - dLeftCounter;
 1536: 				/*
 1537: 				 * next time to be transferred length
 1538: 				 */
 1539: 				pSRB->SRBTotalXferLength = dLeftCounter;
 1540: 				/*
 1541: 				 * parsing from last time disconnect SRBSGIndex
 1542: 				 */
 1543: 				pseg = 
 1544: 				  pSRB->SRBSGListPointer + pSRB->SRBSGIndex;
 1545: 				for (SGIndexTemp = pSRB->SRBSGIndex;
 1546: 				    SGIndexTemp < pSRB->SRBSGCount; 
 1547: 				    SGIndexTemp++) {
 1548: 					/* 
 1549: 					 * find last time which SG transfer be 
 1550: 					 * disconnect 
 1551: 					 */
 1552: 					if (TempSRBXferredLength >= 
 1553: 					    pseg->length) 
 1554: 						TempSRBXferredLength -= 
 1555: 						  pseg->length;
 1556: 					else {
 1557: 				  	  /*
 1558: 			   		   * update last time disconnected SG 
 1559: 					   * list
 1560: 				   	   */
 1561: 						pseg->length -= 
 1562: 						  TempSRBXferredLength; 
 1563: 						/* residue data length  */
 1564: 						pseg->address += 
 1565: 						  TempSRBXferredLength;
 1566: 						/* residue data pointer */
 1567: 						pSRB->SRBSGIndex = SGIndexTemp;
 1568: 						break;
 1569: 					}
 1570: 					pseg++;
 1571: 				}
 1572: 			}
 1573: 		}
 1574: 	}
 1575: 	trm_reg_write8(STOPDMAXFER ,TRMREG_DMA_CONTROL);
 1576: }
 1577: 
 1578: 
 1579: static void
 1580: trm_DataOutPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1581: {
 1582: 	u_int16_t	ioDir;
 1583: 	/*
 1584: 	 * do prepare befor transfer when data out phase
 1585: 	 */
 1586: 
 1587: 	ioDir = XFERDATAOUT;
 1588: 	trm_DataIO_transfer(pACB, pSRB, ioDir);
 1589: }
 1590: 
 1591: static void 
 1592: trm_DataInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1593: {
 1594: 	u_int8_t	bval,SGIndexTemp;
 1595: 	u_int16_t	scsi_status;
 1596: 	PSEG		pseg;
 1597: 	u_long		TempSRBXferredLength,dLeftCounter = 0;
 1598: 
 1599:     	scsi_status = *pscsi_status;
 1600: 	if (!(pSRB->SRBState & SRB_XFERPAD)) {
 1601: 		if (scsi_status & PARITYERROR)
 1602: 			pSRB->SRBStatus |= PARITY_ERROR;
 1603: 		dLeftCounter += trm_reg_read32(TRMREG_SCSI_COUNTER);
 1604: 		if ((dLeftCounter == 0) || (scsi_status & SCSIXFERCNT_2_ZERO)) {
 1605: 			bval = trm_reg_read8(TRMREG_DMA_STATUS);
 1606: 			while (!(bval & DMAXFERCOMP))
 1607: 				bval = trm_reg_read8(TRMREG_DMA_STATUS);
 1608: 			pSRB->SRBTotalXferLength = 0;
 1609: 		} else {  
 1610: 	  	  /*
 1611:    		   * parsing the case:
 1612: 	   	   * when a transfer not yet complete 
 1613: 	   	   * but be disconnected by uper layer
 1614: 	   	   * if transfer not yet complete
 1615: 	   	   * there were some data residue in SCSI FIFO or
 1616: 	   	   * SCSI transfer counter not empty
 1617: 	   	   */
 1618: 		  if (pSRB->SRBTotalXferLength != dLeftCounter) {
 1619: 				/*
 1620: 				 * data that had transferred length
 1621: 				 */
 1622: 		  	TempSRBXferredLength = 
 1623: 			  pSRB->SRBTotalXferLength - dLeftCounter;
 1624: 				/*
 1625: 			 	 * next time to be transferred length
 1626: 				 */
 1627: 			pSRB->SRBTotalXferLength = dLeftCounter;
 1628: 				/*
 1629: 				 * parsing from last time disconnect SRBSGIndex
 1630: 				 */
 1631: 			pseg = pSRB->SRBSGListPointer + pSRB->SRBSGIndex;
 1632: 			for (SGIndexTemp = pSRB->SRBSGIndex; 
 1633: 			    SGIndexTemp < pSRB->SRBSGCount;
 1634: 			    SGIndexTemp++) {
 1635: 			  /* 
 1636: 	   		   * find last time which SG transfer be disconnect 
 1637: 	   		   */
 1638: 	 			if (TempSRBXferredLength >= pseg->length)
 1639: 					TempSRBXferredLength -= pseg->length;
 1640: 				else {
 1641: 		  		  /*
 1642:    				   * update last time disconnected SG list
 1643: 				   */
 1644: 					pseg->length -= TempSRBXferredLength;
 1645: 					/* residue data length  */
 1646: 					pseg->address += TempSRBXferredLength;
 1647: 					/* residue data pointer */
 1648: 					pSRB->SRBSGIndex = SGIndexTemp;
 1649: 					break;
 1650: 				} 
 1651: 				pseg++;
 1652: 			}
 1653: 	  	  }
 1654: 		}
 1655: 	}
 1656: }
 1657: 
 1658: static void
 1659: trm_DataInPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1660: {
 1661: 	u_int16_t	ioDir;
 1662: 	/*
 1663: 	 * do prepare befor transfer when data in phase
 1664: 	 */
 1665: 	
 1666: 	ioDir = XFERDATAIN;
 1667: 	trm_DataIO_transfer(pACB, pSRB, ioDir);
 1668: }
 1669: 
 1670: static void
 1671: trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir)
 1672: {
 1673: 	u_int8_t	bval;
 1674: 	PDCB		pDCB;
 1675: 
 1676: 	pDCB = pSRB->pSRBDCB;
 1677: 	if (pSRB->SRBSGIndex < pSRB->SRBSGCount) {
 1678: 		if (pSRB->SRBTotalXferLength != 0) {
 1679: 			pSRB->SRBSGPhyAddr = vtophys(pSRB->SRBSGListPointer);
 1680: 			/* 
 1681: 			 * load what physical address of Scatter/Gather list 
 1682: 			 table want to be transfer
 1683: 			 */
 1684: 			pSRB->SRBState = SRB_DATA_XFER;
 1685: 			trm_reg_write32(0, TRMREG_DMA_XHIGHADDR);
 1686: 			trm_reg_write32(
 1687: 			    (pSRB->SRBSGPhyAddr + 
 1688: 			     ((u_long)pSRB->SRBSGIndex << 3)),
 1689: 			    TRMREG_DMA_XLOWADDR);
 1690: 			/*
 1691: 			 * load how many bytes in the Scatter/Gather 
 1692: 			 * list table 
 1693: 			 */
 1694: 			trm_reg_write32(
 1695: 			    ((u_long)(pSRB->SRBSGCount - pSRB->SRBSGIndex) << 3),
 1696: 			    TRMREG_DMA_XCNT);			
 1697: 			/*
 1698: 			 * load total transfer length (24bits) max value
 1699: 			 * 16Mbyte 
 1700: 			 */
 1701: 			trm_reg_write32(pSRB->SRBTotalXferLength,
 1702: 			    TRMREG_SCSI_COUNTER);
 1703: 			/* Start DMA transfer */
 1704: 			trm_reg_write16(ioDir, TRMREG_DMA_COMMAND);
 1705: 			/* Start SCSI transfer */
 1706: 			trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
 1707: 			/* it's important for atn stop */
 1708: 			/*
 1709: 			 * SCSI cammand 
 1710: 			 */
 1711: 			bval = (ioDir == XFERDATAOUT) ?
 1712: 			  SCMD_DMA_OUT : SCMD_DMA_IN;
 1713: 			trm_reg_write8(bval, TRMREG_SCSI_COMMAND);
 1714: 		} else {
 1715: 		  /* xfer pad */
 1716: 			if (pSRB->SRBSGCount) {
 1717: 				pSRB->AdaptStatus = H_OVER_UNDER_RUN;
 1718: 				pSRB->SRBStatus |= OVER_RUN;
 1719: 			}
 1720: 			if (pDCB->SyncPeriod & WIDE_SYNC)
 1721: 				trm_reg_write32(2,TRMREG_SCSI_COUNTER);
 1722: 			else
 1723: 				trm_reg_write32(1,TRMREG_SCSI_COUNTER);
 1724: 			if (ioDir == XFERDATAOUT)
 1725: 				trm_reg_write16(0, TRMREG_SCSI_FIFO);
 1726: 			else
 1727: 				trm_reg_read16(TRMREG_SCSI_FIFO);
 1728: 			pSRB->SRBState |= SRB_XFERPAD;
 1729: 			trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
 1730: 			/* it's important for atn stop */
 1731: 			/*
 1732: 			 * SCSI cammand 
 1733: 			 */
 1734: 			bval = (ioDir == XFERDATAOUT) ? 
 1735: 			  SCMD_FIFO_OUT : SCMD_FIFO_IN;
 1736: 			trm_reg_write8(bval, TRMREG_SCSI_COMMAND);
 1737: 		}
 1738: 	}
 1739: }
 1740: 
 1741: static void
 1742: trm_StatusPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1743: {
 1744: 
 1745: 	pSRB->TargetStatus = trm_reg_read8(TRMREG_SCSI_FIFO);
 1746: 	pSRB->SRBState = SRB_COMPLETED;
 1747: 	*pscsi_status = PH_BUS_FREE;  
 1748: 	/*.. initial phase*/
 1749: 	trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
 1750: 	/* it's important for atn stop */
 1751: 	/*
 1752: 	 * SCSI cammand 
 1753: 	 */
 1754: 	trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
 1755: }
 1756: 
 1757: 
 1758: 
 1759: static void
 1760: trm_StatusPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1761: {
 1762: 
 1763: 	if (trm_reg_read16(TRMREG_DMA_COMMAND) & 0x0001) {
 1764: 		if (!(trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x40))
 1765: 	       		trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
 1766: 		if (!(trm_reg_read16(TRMREG_DMA_FIFOCNT) & 0x8000))
 1767: 			trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL);
 1768: 	} else {
 1769: 		if (!(trm_reg_read16(TRMREG_DMA_FIFOCNT) & 0x8000))
 1770: 			trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL);
 1771: 		if (!(trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x40))
 1772: 			trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
 1773: 	}
 1774: 	pSRB->SRBState = SRB_STATUS;
 1775: 	trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
 1776: 	/* it's important for atn stop */
 1777: 	/*
 1778: 	 * SCSI cammand 
 1779: 	 */
 1780: 	trm_reg_write8(SCMD_COMP, TRMREG_SCSI_COMMAND);
 1781: }
 1782: 
 1783: /*
 1784:  *scsiiom		 
 1785:  *       trm_MsgInPhase0: one of trm_SCSI_phase0[] vectors
 1786:  *            stateV = (void *) trm_SCSI_phase0[phase]
 1787:  *		           if phase =7    
 1788:  * extended message codes:
 1789:  *
 1790:  *   code        description
 1791:  *
 1792:  *    02h        Reserved
 1793:  *    00h        MODIFY DATA  POINTER
 1794:  *    01h        SYNCHRONOUS DATA TRANSFER REQUEST
 1795:  *    03h        WIDE DATA TRANSFER REQUEST
 1796:  * 04h - 7Fh     Reserved
 1797:  * 80h - FFh     Vendor specific  
 1798:  *		        
 1799:  */
 1800: 
 1801: static void
 1802: trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 1803: {
 1804: 	u_int8_t	message_in_code,bIndex,message_in_tag_id;
 1805: 	PDCB		pDCB;
 1806: 	PSRB		pSRBTemp;
 1807: 
 1808: 	pDCB = pACB->pActiveDCB;
 1809: 
 1810: 	message_in_code = trm_reg_read8(TRMREG_SCSI_FIFO);
 1811: 	if (!(pSRB->SRBState & SRB_EXTEND_MSGIN)) {
 1812: 		if (message_in_code == MSG_DISCONNECT) {
 1813: 			pSRB->SRBState = SRB_DISCONNECT;
 1814: 			goto  min6;
 1815: 		} else if (message_in_code == MSG_SAVE_PTR) {
 1816: 			goto  min6;
 1817: 		} else if ((message_in_code == MSG_EXTENDED) ||
 1818: 		    ((message_in_code >= MSG_SIMPLE_QTAG) &&
 1819: 		     (message_in_code <= MSG_ORDER_QTAG))) {
 1820: 			pSRB->SRBState |= SRB_EXTEND_MSGIN;
 1821: 		    	pSRB->MsgInBuf[0] = message_in_code;
 1822: 			/* extended message      (01h) */
 1823: 			pSRB->MsgCnt = 1;
 1824: 			pSRB->pMsgPtr = &pSRB->MsgInBuf[1];
 1825: 			/* extended message length (n) */
 1826: 			goto  min6;
 1827: 		} else if (message_in_code == MSG_REJECT_) {
 1828: 			/* Reject message */
 1829: 			if (pDCB->SyncMode & WIDE_NEGO_ENABLE) {
 1830: 			  /* do wide nego reject */
 1831: 				pDCB = pSRB->pSRBDCB;
 1832: 				pDCB->SyncMode |= WIDE_NEGO_DONE;
 1833: 				pDCB->SyncMode &= ~(SYNC_NEGO_DONE | 
 1834: 				    EN_ATN_STOP | WIDE_NEGO_ENABLE);
 1835: 				pSRB->SRBState &= ~(SRB_DO_WIDE_NEGO+SRB_MSGIN);
 1836: 				if ((pDCB->SyncMode & SYNC_NEGO_ENABLE) 
 1837: 				    && !(pDCB->SyncMode & SYNC_NEGO_DONE)) {   
 1838: 				  /* Set ATN, in case ATN was clear */
 1839: 					pSRB->SRBState |= SRB_MSGOUT;
 1840: 					trm_reg_write16(
 1841: 					    DO_SETATN,
 1842: 					    TRMREG_SCSI_CONTROL);
 1843: 				} else {   
 1844: 			  	  /* Clear ATN */
 1845: 					trm_reg_write16(
 1846: 					    DO_CLRATN,
 1847: 					    TRMREG_SCSI_CONTROL);
 1848: 				}
 1849: 			} else if (pDCB->SyncMode & SYNC_NEGO_ENABLE) { 
 1850: 			  /* do sync nego reject */
 1851: 				trm_reg_write16(DO_CLRATN,TRMREG_SCSI_CONTROL);
 1852: 				if (pSRB->SRBState & SRB_DO_SYNC_NEGO) {
 1853: 					pDCB = pSRB->pSRBDCB;
 1854: 					pDCB->SyncMode &= 
 1855: 					  ~(SYNC_NEGO_ENABLE+SYNC_NEGO_DONE); 
 1856: 					pDCB->SyncPeriod = 0;
 1857: 					pDCB->SyncOffset = 0;
 1858: 					goto  re_prog;
 1859: 				}
 1860: 			}
 1861: 			goto  min6;
 1862: 		} else if (message_in_code == MSG_IGNOREWIDE) {
 1863: 			trm_reg_write32(1, TRMREG_SCSI_COUNTER);
 1864: 			trm_reg_read8(TRMREG_SCSI_FIFO);
 1865: 			goto  min6;
 1866: 		} else {
 1867: 	  	  /* Restore data pointer message */
 1868:   		  /* Save data pointer message	  */
 1869: 		  /* Completion message		  */
 1870: 		  /* NOP message       	          */
 1871: 			goto  min6;
 1872: 		}
 1873: 	} else {	
 1874: 	  /* 
 1875:    	   * Parsing incomming extented messages 
 1876: 	   */
 1877: 		*pSRB->pMsgPtr = message_in_code;
 1878: 		pSRB->MsgCnt++;
 1879: 		pSRB->pMsgPtr++;
 1880: 		TRM_DPRINTF("pSRB->MsgInBuf[0]=%2x \n ",pSRB->MsgInBuf[0]);
 1881: 		TRM_DPRINTF("pSRB->MsgInBuf[1]=%2x \n ",pSRB->MsgInBuf[1]);
 1882: 		TRM_DPRINTF("pSRB->MsgInBuf[2]=%2x \n ",pSRB->MsgInBuf[2]);
 1883: 		TRM_DPRINTF("pSRB->MsgInBuf[3]=%2x \n ",pSRB->MsgInBuf[3]);
 1884: 		TRM_DPRINTF("pSRB->MsgInBuf[4]=%2x \n ",pSRB->MsgInBuf[4]);
 1885: 	    	if ((pSRB->MsgInBuf[0] >= MSG_SIMPLE_QTAG)
 1886: 		    && (pSRB->MsgInBuf[0] <= MSG_ORDER_QTAG)) {
 1887: 		  /*
 1888: 	   	   * is QUEUE tag message :
 1889:    		   *
 1890: 	   	   * byte 0:
 1891: 	   	   * HEAD    QUEUE TAG (20h)
 1892: 	   	   * ORDERED QUEUE TAG (21h)
 1893: 	   	   * SIMPLE  QUEUE TAG (22h)
 1894: 	   	   * byte 1:
 1895: 	   	   * Queue tag (00h - FFh)
 1896: 	   	   */
 1897: 			if (pSRB->MsgCnt == 2) {
 1898: 				pSRB->SRBState = 0;
 1899: 				message_in_tag_id = pSRB->MsgInBuf[1];
 1900: 				pSRB = pDCB->pGoingSRB;
 1901: 				pSRBTemp = pDCB->pGoingLastSRB;
 1902: 				if (pSRB) {
 1903: 					for (;;) {
 1904: 						if (pSRB->TagNumber != 
 1905: 						    message_in_tag_id) {
 1906: 							if (pSRB == pSRBTemp) {
 1907: 								goto  mingx0;
 1908: 							}
 1909: 							pSRB = pSRB->pNextSRB;
 1910: 						} else
 1911: 							break;
 1912: 					}
 1913: 					if (pDCB->DCBFlag & ABORT_DEV_) {
 1914: 						pSRB->SRBState = SRB_ABORT_SENT;
 1915: 						trm_EnableMsgOutAbort1(
 1916: 						    pACB, pSRB);
 1917: 					}
 1918: 					if (!(pSRB->SRBState & SRB_DISCONNECT))
 1919: 						goto  mingx0;
 1920: 					pDCB->pActiveSRB = pSRB;
 1921: 					pSRB->SRBState = SRB_DATA_XFER;
 1922: 				} else {
 1923: mingx0:
 1924: 	     				pSRB = pACB->pTmpSRB;
 1925: 					pSRB->SRBState = SRB_UNEXPECT_RESEL;
 1926: 					pDCB->pActiveSRB = pSRB;
 1927: 					pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
 1928: 					trm_EnableMsgOutAbort2(
 1929: 					    pACB,
 1930: 					    pSRB);
 1931: 				}
 1932: 			}
 1933: 		} else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) &&
 1934: 		    (pSRB->MsgInBuf[2] == 3) && (pSRB->MsgCnt == 4)) {
 1935: 		  /*
 1936: 	   	   * is Wide data xfer Extended message :
 1937: 	   	   * ======================================
 1938: 	   	   * WIDE DATA TRANSFER REQUEST
 1939:    		   * ======================================
 1940: 		   * byte 0 :  Extended message (01h)
 1941: 		   * byte 1 :  Extended message length (02h)
 1942: 		   * byte 2 :  WIDE DATA TRANSFER code (03h)
 1943: 		   * byte 3 :  Transfer width exponent 
 1944: 		   */
 1945: 			pDCB = pSRB->pSRBDCB;
 1946: 			pSRB->SRBState &= ~(SRB_EXTEND_MSGIN+SRB_DO_WIDE_NEGO);
 1947: 			if ((pSRB->MsgInBuf[1] != 2)) {
 1948: 			  /* Length is wrong, reject it  */
 1949: 				pDCB->SyncMode &=
 1950: 				  ~(WIDE_NEGO_ENABLE+WIDE_NEGO_DONE); 
 1951: 				pSRB->MsgCnt = 1;
 1952: 				pSRB->MsgInBuf[0] = MSG_REJECT_;
 1953: 				trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
 1954: 				goto  min6;
 1955: 			}
 1956: 			if (pDCB->SyncMode & WIDE_NEGO_ENABLE) {		
 1957: 			  /* Do wide negoniation */
 1958: 				if (pSRB->MsgInBuf[3] > 2) {
 1959: 				  /* > 32 bit	*/
 1960: 				  /* reject_msg: */
 1961: 					pDCB->SyncMode &= 
 1962: 					  ~(WIDE_NEGO_ENABLE+WIDE_NEGO_DONE); 
 1963: 					pSRB->MsgCnt = 1;
 1964: 					pSRB->MsgInBuf[0] = MSG_REJECT_;
 1965: 					trm_reg_write16(DO_SETATN,
 1966: 					    TRMREG_SCSI_CONTROL);
 1967: 					goto  min6;
 1968: 				}
 1969: 				if (pSRB->MsgInBuf[3] == 2) {
 1970: 					pSRB->MsgInBuf[3] = 1;
 1971: 					/* do 16 bits	*/
 1972: 				} else {
 1973: 					if (!(pDCB->SyncMode 
 1974: 					      & WIDE_NEGO_DONE)) {
 1975: 						pSRB->SRBState &=
 1976: 						  ~(SRB_DO_WIDE_NEGO+SRB_MSGIN);
 1977: 						pDCB->SyncMode |= 
 1978: 						  WIDE_NEGO_DONE;
 1979: 						pDCB->SyncMode &=
 1980: 						  ~(SYNC_NEGO_DONE |
 1981: 						      EN_ATN_STOP |
 1982: 						      WIDE_NEGO_ENABLE);
 1983: 						if (pSRB->MsgInBuf[3] != 0) {
 1984: 						  /* is Wide data xfer */
 1985: 							pDCB->SyncPeriod |=
 1986: 							  WIDE_SYNC;
 1987: 							pDCB->tinfo.current.width 
 1988: 							  = MSG_EXT_WDTR_BUS_16_BIT;
 1989: 							pDCB->tinfo.goal.width
 1990: 							  = MSG_EXT_WDTR_BUS_16_BIT;
 1991: 						}
 1992: 					}
 1993: 				}
 1994: 			} else
 1995: 				pSRB->MsgInBuf[3] = 0;
 1996: 			pSRB->SRBState |= SRB_MSGOUT;
 1997: 			trm_reg_write16(DO_SETATN,TRMREG_SCSI_CONTROL);
 1998: 			goto  min6;
 1999: 		} else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) &&
 2000: 		    (pSRB->MsgInBuf[2] == 1) && (pSRB->MsgCnt == 5)) {
 2001: 			/*
 2002: 			 * is 8bit transfer Extended message :
 2003: 			 * =================================
 2004: 			 * SYNCHRONOUS DATA TRANSFER REQUEST
 2005: 			 * =================================
 2006: 			 * byte 0 :  Extended message (01h)
 2007: 			 * byte 1 :  Extended message length (03)
 2008: 			 * byte 2 :  SYNCHRONOUS DATA TRANSFER code (01h)
 2009: 			 * byte 3 :  Transfer period factor 
 2010: 			 * byte 4 :  REQ/ACK offset  
 2011: 			 */
 2012: 			pSRB->SRBState &= ~(SRB_EXTEND_MSGIN+SRB_DO_SYNC_NEGO);
 2013: 			if ((pSRB->MsgInBuf[1] != 3) ||
 2014: 			    (pSRB->MsgInBuf[2] != 1)) {
 2015: 			  /* reject_msg: */
 2016: 				pSRB->MsgCnt = 1;
 2017: 				pSRB->MsgInBuf[0] = MSG_REJECT_;
 2018: 				trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
 2019: 			} else if (!(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4])) {
 2020: 				/* set async */
 2021: 				pDCB = pSRB->pSRBDCB;
 2022: 				/* disable sync & sync nego */
 2023: 				pDCB->SyncMode &= 
 2024: 				  ~(SYNC_NEGO_ENABLE+SYNC_NEGO_DONE);
 2025: 				pDCB->SyncPeriod = 0;
 2026: 				pDCB->SyncOffset = 0;
 2027: 				pDCB->tinfo.goal.period = 0;
 2028: 				pDCB->tinfo.goal.offset = 0;
 2029: 				pDCB->tinfo.current.period = 0;
 2030: 				pDCB->tinfo.current.offset = 0;
 2031: 				pDCB->tinfo.current.width = 
 2032: 				  MSG_EXT_WDTR_BUS_8_BIT;
 2033: 				goto  re_prog;
 2034: 			} else {
 2035: 				/* set sync */
 2036: 				pDCB = pSRB->pSRBDCB;
 2037: 				pDCB->SyncMode |= 
 2038: 				  SYNC_NEGO_ENABLE+SYNC_NEGO_DONE;
 2039: 				pDCB->MaxNegoPeriod = pSRB->MsgInBuf[3];
 2040: 				/* Transfer period factor */
 2041: 				pDCB->SyncOffset = pSRB->MsgInBuf[4]; 
 2042: 				/* REQ/ACK offset */
 2043: 				for (bIndex = 0; bIndex < 7; bIndex++) {
 2044: 				  if (pSRB->MsgInBuf[3] <=
 2045: 				      dc395x_trm_clock_period[bIndex]) {
 2046: 				  	break;
 2047: 				  }
 2048: 				}
 2049: 				pDCB->tinfo.goal.period =
 2050: 				  dc395x_trm_tinfo_sync_period[bIndex];
 2051: 				pDCB->tinfo.current.period = 
 2052: 				  dc395x_trm_tinfo_sync_period[bIndex];
 2053: 				pDCB->tinfo.goal.offset = pDCB->SyncOffset;
 2054: 				pDCB->tinfo.current.offset = pDCB->SyncOffset;
 2055: 				pDCB->SyncPeriod |= (bIndex | ALT_SYNC);
 2056: re_prog:
 2057: 				/*               
 2058: 				 *
 2059: 	 			 *   program SCSI control register
 2060: 	 			 *
 2061: 	 			 */
 2062: 				trm_reg_write8(pDCB->SyncPeriod,
 2063: 				    TRMREG_SCSI_SYNC);
 2064: 				trm_reg_write8(pDCB->SyncOffset,
 2065: 				    TRMREG_SCSI_OFFSET);
 2066: 				trm_SetXferRate(pACB,pSRB,pDCB);
 2067: 			}
 2068: 		}
 2069: 	}
 2070: min6:
 2071: 	*pscsi_status = PH_BUS_FREE;
 2072: 	/* .. initial phase */
 2073: 	trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
 2074: 	/* it's important for atn stop */
 2075: 	/*
 2076: 	 * SCSI cammand 
 2077: 	 */
 2078: 	trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
 2079: }
 2080: 
 2081: static void
 2082: trm_MsgInPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 2083: {
 2084: 
 2085: 	trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
 2086: 	trm_reg_write32(1,TRMREG_SCSI_COUNTER);
 2087: 	if (!(pSRB->SRBState & SRB_MSGIN)) {
 2088: 		pSRB->SRBState &= SRB_DISCONNECT;
 2089: 		pSRB->SRBState |= SRB_MSGIN;
 2090: 	}
 2091: 	trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
 2092: 	/* it's important for atn stop*/
 2093: 	/*
 2094: 	 * SCSI cammand 
 2095: 	 */
 2096: 	trm_reg_write8(SCMD_FIFO_IN, TRMREG_SCSI_COMMAND);
 2097: }
 2098: 
 2099: static void
 2100: trm_Nop0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 2101: {
 2102: 
 2103: }
 2104: 
 2105: static void
 2106: trm_Nop1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
 2107: {
 2108: 
 2109: }
 2110: 
 2111: static void
 2112: trm_SetXferRate(PACB pACB,PSRB pSRB, PDCB pDCB)
 2113: {
 2114: 	u_int16_t	cnt, i;
 2115: 	u_int8_t	bval;
 2116: 	PDCB		pDCBTemp;
 2117: 	u_int		target_id,target_lun;
 2118: 
 2119: 	/*
 2120: 	 * set all lun device's  period , offset
 2121: 	 */
 2122: 	target_id  = pSRB->pccb->ccb_h.target_id;
 2123: 	target_lun = pSRB->pccb->ccb_h.target_lun;
 2124: 	TRM_DPRINTF("trm_SetXferRate:target_id= %d ,target_lun= %d \n"
 2125: 	    ,target_id,target_lun);
 2126: 	if (!(pDCB->IdentifyMsg & 0x07)) {
 2127: 		if (!pACB->scan_devices[target_id][target_lun]) {
 2128: 			pDCBTemp = pACB->pLinkDCB;
 2129: 			cnt = pACB->DeviceCnt;
 2130: 			bval = pDCB->TargetID;
 2131: 			for (i = 0; i < cnt; i++) {
 2132: 				if (pDCBTemp->TargetID == bval) {
 2133: 					pDCBTemp->SyncPeriod = pDCB->SyncPeriod;
 2134: 					pDCBTemp->SyncOffset = pDCB->SyncOffset;
 2135: 					pDCBTemp->SyncMode = pDCB->SyncMode;
 2136: 				}
 2137: 				pDCBTemp = pDCBTemp->pNextDCB;
 2138: 			}
 2139: 		}
 2140: 	}
 2141: 	return;
 2142: }
 2143: 
 2144: /*
 2145:  * scsiiom		
 2146:  *            trm_Interrupt       
 2147:  *		        
 2148:  *
 2149:  *    ---SCSI bus phase
 2150:  *
 2151:  * 	PH_DATA_OUT	        0x00	 Data out phase	              
 2152:  * 	PH_DATA_IN	        0x01	 Data in phase	            
 2153:  * 	PH_COMMAND	        0x02	 Command phase	 
 2154:  * 	PH_STATUS	        0x03	 Status phase
 2155:  *	PH_BUS_FREE	        0x04	 Invalid phase used as bus free	
 2156:  * 	PH_BUS_FREE	        0x05	 Invalid phase used as bus free	
 2157:  * 	PH_MSG_OUT	        0x06	 Message out phase
 2158:  * 	PH_MSG_IN	        0x07	 Message in phase
 2159:  *
 2160:  */
 2161: static void 
 2162: trm_Disconnect(PACB pACB)
 2163: {
 2164: 	PDCB		pDCB;
 2165: 	PSRB		pSRB, psrb;
 2166: 	int		intflag;
 2167: 	u_int16_t	i,j, cnt;
 2168: 	u_int8_t	bval;
 2169: 	u_int		target_id,target_lun;
 2170: 	
 2171: 	TRM_DPRINTF("trm_Disconnect...............\n ");
 2172: 	
 2173: 	intflag = splcam();
 2174:        	pDCB = pACB->pActiveDCB;
 2175: 	if (!pDCB) {
 2176: 		TRM_DPRINTF(" Exception Disconnect DCB=NULL..............\n ");
 2177: 		j = 400;
 2178:     		while (--j) 
 2179: 			DELAY(1);
 2180: 		/* 1 msec */
 2181: 		trm_reg_write16((DO_CLRFIFO | DO_HWRESELECT),
 2182: 		    TRMREG_SCSI_CONTROL);
 2183: 		return;
 2184: 	}
 2185: 	pSRB = pDCB->pActiveSRB; 
 2186: 	/* bug pSRB=0 */
 2187: 	target_id  = pSRB->pccb->ccb_h.target_id;
 2188: 	target_lun = pSRB->pccb->ccb_h.target_lun;
 2189: 	TRM_DPRINTF(":pDCB->pActiveSRB= %8x \n ",(u_int) pDCB->pActiveSRB);
 2190: 	pACB->pActiveDCB = 0;
 2191: 	pSRB->ScsiPhase = PH_BUS_FREE; 
 2192: 	/* SCSI bus free Phase */
 2193: 	trm_reg_write16((DO_CLRFIFO | DO_HWRESELECT), TRMREG_SCSI_CONTROL);
 2194: 	if (pSRB->SRBState & SRB_UNEXPECT_RESEL) {
 2195: 		pSRB->SRBState = 0;
 2196: 		trm_DoWaitingSRB(pACB);
 2197: 	} else if (pSRB->SRBState & SRB_ABORT_SENT) {
 2198: 		pDCB->TagMask = 0;
 2199: 		pDCB->DCBFlag = 0;
 2200: 		cnt = pDCB->GoingSRBCnt;
 2201: 		pDCB->GoingSRBCnt = 0;
 2202: 		pSRB = pDCB->pGoingSRB;
 2203: 		for (i = 0; i < cnt; i++) {
 2204: 			psrb = pSRB->pNextSRB;
 2205: 			pSRB->pNextSRB = pACB->pFreeSRB;
 2206: 			pACB->pFreeSRB = pSRB;
 2207: 			pSRB = psrb;
 2208: 		}
 2209: 		pDCB->pGoingSRB = 0;
 2210: 		trm_DoWaitingSRB(pACB);
 2211: 	} else {
 2212: 		if ((pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) || 
 2213: 		    !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED))) {
 2214: 		  /* Selection time out */
 2215: 			if (!(pACB->scan_devices[target_id][target_lun])) {
 2216: 				pSRB->SRBState = SRB_READY;
 2217: 				trm_RewaitSRB(pDCB, pSRB);
 2218: 			} else {
 2219: 				pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
 2220: 				goto  disc1;
 2221: 			}
 2222: 		} else if (pSRB->SRBState & SRB_DISCONNECT) {
 2223: 			/*
 2224: 			 * SRB_DISCONNECT
 2225: 			 */
 2226: 			trm_DoWaitingSRB(pACB);
 2227: 		} else if (pSRB->SRBState & SRB_COMPLETED) {
 2228: disc1:
 2229: 		  /*
 2230: 		   * SRB_COMPLETED
 2231: 		   */
 2232: 			if (pDCB->MaxCommand > 1) {
 2233: 				bval = pSRB->TagNumber;
 2234: 				pDCB->TagMask &= (~(1 << bval));
 2235: 				/* free tag mask */
 2236: 			}
 2237: 			pDCB->pActiveSRB = 0;
 2238: 			pSRB->SRBState = SRB_FREE;
 2239: 			trm_SRBdone(pACB, pDCB, pSRB);
 2240: 		}
 2241: 	}
 2242: 	splx(intflag);
 2243: 	return;
 2244: }
 2245: 
 2246: static void
 2247: trm_Reselect(PACB pACB)
 2248: {
 2249: 	PDCB		pDCB;
 2250: 	PSRB		pSRB;
 2251: 	u_int16_t	RselTarLunId;
 2252: 
 2253: 	TRM_DPRINTF("trm_Reselect................. \n");
 2254: 	pDCB = pACB->pActiveDCB;
 2255: 	if (pDCB) {
 2256: 	  /* Arbitration lost but Reselection win */
 2257: 		pSRB = pDCB->pActiveSRB;
 2258: 		pSRB->SRBState = SRB_READY;
 2259: 		trm_RewaitSRB(pDCB, pSRB);
 2260: 	}
 2261: 	/* Read Reselected Target Id and LUN */
 2262: 	RselTarLunId = trm_reg_read16(TRMREG_SCSI_TARGETID) & 0x1FFF;
 2263: 	pDCB = pACB->pLinkDCB;
 2264: 	while (RselTarLunId != *((u_int16_t *) &pDCB->TargetID)) {
 2265: 	  /* get pDCB of the reselect id */
 2266: 		pDCB = pDCB->pNextDCB;
 2267: 	}
 2268: 
 2269: 	pACB->pActiveDCB = pDCB;
 2270: 	if (pDCB->SyncMode & EN_TAG_QUEUING) {
 2271: 		pSRB = pACB->pTmpSRB;
 2272: 		pDCB->pActiveSRB = pSRB;
 2273: 	} else {
 2274: 		pSRB = pDCB->pActiveSRB;
 2275: 		if (!pSRB || !(pSRB->SRBState & SRB_DISCONNECT)) {
 2276: 		  /*
 2277: 	   	   * abort command
 2278:    		   */
 2279: 			pSRB = pACB->pTmpSRB;
 2280: 			pSRB->SRBState = SRB_UNEXPECT_RESEL;
 2281: 			pDCB->pActiveSRB = pSRB;
 2282: 			trm_EnableMsgOutAbort1(pACB, pSRB);
 2283: 		} else {
 2284: 			if (pDCB->DCBFlag & ABORT_DEV_) {
 2285: 				pSRB->SRBState = SRB_ABORT_SENT;
 2286: 				trm_EnableMsgOutAbort1(pACB, pSRB);
 2287: 			} else 
 2288: 				pSRB->SRBState = SRB_DATA_XFER;
 2289: 		}
 2290: 	}
 2291: 	pSRB->ScsiPhase = PH_BUS_FREE;
 2292: 	/* SCSI bus free Phase */
 2293: 	/* 
 2294: 	 * Program HA ID, target ID, period and offset
 2295: 	 */
 2296: 	trm_reg_write8((u_int8_t) RselTarLunId,TRMREG_SCSI_TARGETID);
 2297: 	/* target ID */
 2298: 	trm_reg_write8(pACB->AdaptSCSIID,TRMREG_SCSI_HOSTID);
 2299: 	/* host   ID */
 2300: 	trm_reg_write8(pDCB->SyncPeriod,TRMREG_SCSI_SYNC);
 2301: 	/* period    */
 2302: 	trm_reg_write8(pDCB->SyncOffset,TRMREG_SCSI_OFFSET); 
 2303: 	/* offset    */
 2304: 	trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
 2305: 	/* it's important for atn stop*/
 2306: 	/*
 2307: 	 * SCSI cammand 
 2308: 	 */
 2309: 	trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
 2310: 	/* to rls the /ACK signal */
 2311: }
 2312: 
 2313: static void
 2314: trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB)
 2315: {
 2316: 	PSRB			psrb;
 2317: 	u_int8_t		bval, bval1,status;
 2318: 	union ccb		*pccb;
 2319: 	struct ccb_scsiio	*pcsio;
 2320: 	PSCSI_INQDATA		ptr;
 2321: 	int			intflag;
 2322: 	u_int			target_id,target_lun;
 2323: 	PDCB			pTempDCB;
 2324: 
 2325: 	pccb  = pSRB->pccb;
 2326: 	if (pccb == NULL)
 2327: 		return;
 2328: 	pcsio = &pccb->csio;
 2329: 	target_id  = pSRB->pccb->ccb_h.target_id;
 2330: 	target_lun = pSRB->pccb->ccb_h.target_lun;
 2331: 	if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
 2332: 		bus_dmasync_op_t op;
 2333: 		if ((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
 2334: 			op = BUS_DMASYNC_POSTREAD;
 2335: 		else
 2336: 			op = BUS_DMASYNC_POSTWRITE;
 2337: 		bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op);
 2338: 		bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap);
 2339: 	}
 2340:     	/*
 2341: 	 *
 2342: 	 * target status
 2343: 	 *
 2344: 	 */
 2345: 	status = pSRB->TargetStatus;
 2346: 	pcsio->scsi_status=SCSI_STAT_GOOD;
 2347: 	pccb->ccb_h.status = CAM_REQ_CMP;
 2348: 	if (pSRB->SRBFlag & AUTO_REQSENSE) {
 2349: 	  /* 
 2350:    	   * status of auto request sense 
 2351: 	   */
 2352: 		pSRB->SRBFlag &= ~AUTO_REQSENSE;
 2353: 		pSRB->AdaptStatus = 0;
 2354: 		pSRB->TargetStatus = SCSI_STATUS_CHECK_COND;
 2355: 		
 2356: 		if (status == SCSI_STATUS_CHECK_COND) {
 2357: 			pccb->ccb_h.status = CAM_SEL_TIMEOUT;
 2358: 			goto ckc_e;
 2359: 		}
 2360: 		*((u_long *) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
 2361: 		*((u_long *) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];
 2362: 		pSRB->SRBTotalXferLength = pSRB->Segment1[1];
 2363: 		pSRB->SegmentX[0].address = pSRB->SgSenseTemp.address;
 2364: 		pSRB->SegmentX[0].length = pSRB->SgSenseTemp.length;
 2365: 		pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
 2366: 		pccb->ccb_h.status = CAM_AUTOSNS_VALID;
 2367: 		goto ckc_e;
 2368: 	}
 2369: 	/*
 2370: 	 * target status
 2371: 	 */
 2372: 	if (status) {
 2373: 		if (status == SCSI_STATUS_CHECK_COND) {
 2374: 			if ((pcsio->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) {
 2375: 			  TRM_DPRINTF("trm_RequestSense..................\n");
 2376: 			  trm_RequestSense(pACB, pDCB, pSRB);
 2377: 			  return;
 2378: 			}
 2379: 			pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
 2380: 			pccb->ccb_h.status = CAM_AUTOSNS_VALID |
 2381: 			  CAM_SCSI_STATUS_ERROR;
 2382: 			goto ckc_e;
 2383: 		} else if (status == SCSI_STAT_QUEUEFULL) {
 2384: 			bval = (u_int8_t) pDCB->GoingSRBCnt;
 2385: 			bval--;
 2386: 			pDCB->MaxCommand = bval;
 2387: 			trm_RewaitSRB(pDCB, pSRB);
 2388: 			pSRB->AdaptStatus = 0;
 2389: 			pSRB->TargetStatus = 0;
 2390: 			pcsio->scsi_status = SCSI_STAT_QUEUEFULL;
 2391: 			pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
 2392: 			goto ckc_e;
 2393: 		} else if (status == SCSI_STAT_SEL_TIMEOUT) {
 2394: 			pSRB->AdaptStatus  = H_SEL_TIMEOUT;
 2395: 			pSRB->TargetStatus = 0;
 2396: 			pcsio->scsi_status = SCSI_STAT_SEL_TIMEOUT;
 2397: 			pccb->ccb_h.status = CAM_SEL_TIMEOUT;
 2398: 		} else if (status == SCSI_STAT_BUSY) {
 2399: 			TRM_DPRINTF("trm: target busy at %s %d\n",
 2400: 				__FILE__, __LINE__);
 2401: 			pcsio->scsi_status = SCSI_STAT_BUSY;
 2402: 			pccb->ccb_h.status = CAM_SCSI_BUSY;
 2403: 		  /* The device busy, try again later?	  */
 2404: 		} else if (status == SCSI_STAT_RESCONFLICT) {
 2405: 			TRM_DPRINTF("trm: target reserved at %s %d\n",
 2406: 				__FILE__, __LINE__);
 2407: 			pcsio->scsi_status = SCSI_STAT_RESCONFLICT;
 2408: 			pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;	/*XXX*/
 2409: 		} else {
 2410: 			pSRB->AdaptStatus = 0;
 2411: 			if (pSRB->RetryCnt) {
 2412: 				pSRB->RetryCnt--;
 2413: 				pSRB->TargetStatus = 0;
 2414: 				pSRB->SRBSGIndex = 0;
 2415: 				pSRB->SRBSGListPointer = (PSEG)
 2416: 				  &pSRB->SegmentX[0];
 2417: 				if (trm_StartSCSI(pACB, pDCB, pSRB)) {
 2418: 				  /* 
 2419: 				   * If trm_StartSCSI return 1 :
 2420: 				   * current interrupt status is interrupt 
 2421: 				   * disreenable 
 2422: 				   * It's said that SCSI processor has more 
 2423: 				   * one SRB need to do
 2424: 				   */
 2425: 					trm_RewaitSRB(pDCB, pSRB);
 2426: 				}
 2427: 				return;
 2428: 			} else {
 2429:         			TRM_DPRINTF("trm: driver stuffup at %s %d\n",
 2430: 					__FILE__, __LINE__);
 2431: 		      		pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
 2432: 			}
 2433: 		}
 2434: 	} else {
 2435:         /* 
 2436:  	 * process initiator status..........................
 2437: 	 * Adapter (initiator) status
 2438: 	 */
 2439: 		status = pSRB->AdaptStatus;
 2440: 		if (status & H_OVER_UNDER_RUN) {
 2441: 			pSRB->TargetStatus = 0;
 2442: 			pccb->ccb_h.status = CAM_DATA_RUN_ERR;
 2443: 			/* Illegal length (over/under run) */
 2444: 		} else if (pSRB->SRBStatus & PARITY_ERROR) {
 2445: 			TRM_DPRINTF("trm: driver stuffup %s %d\n",
 2446: 				__FILE__, __LINE__);
 2447: 			pDCB->tinfo.goal.period = 0;
 2448: 			pDCB->tinfo.goal.offset = 0;
 2449: 			/* Driver failed to perform operation */
 2450: 			pccb->ccb_h.status = CAM_UNCOR_PARITY;
 2451: 		} else {
 2452: 		  /* no error */
 2453: 			pSRB->AdaptStatus = 0;
 2454: 			pSRB->TargetStatus = 0;
 2455: 			pccb->ccb_h.status = CAM_REQ_CMP;
 2456: 			/* there is no error, (sense is invalid) */
 2457: 		}
 2458: 	}
 2459: ckc_e:
 2460: 	if (pACB->scan_devices[target_id][target_lun]) {
 2461: 	  /*
 2462: 	   *   if SCSI command in "scan devices" duty
 2463: 	   */
 2464: 		if (pSRB->CmdBlock[0] == TEST_UNIT_READY) 
 2465: 			pACB->scan_devices[target_id][target_lun] = 0;
 2466: 		/* SCSI command phase :test unit ready */
 2467: 		else if (pSRB->CmdBlock[0] == INQUIRY) {
 2468: 		  /* 
 2469: 		   * SCSI command phase :inquiry scsi device data 
 2470: 		   * (type,capacity,manufacture.... 
 2471: 		   */
 2472: 			if (pccb->ccb_h.status == CAM_SEL_TIMEOUT)
 2473: 				goto NO_DEV;
 2474: 			ptr = (PSCSI_INQDATA) pcsio->data_ptr;
 2475: 			/* page fault */
 2476: 			TRM_DPRINTF("trm_SRBdone..PSCSI_INQDATA:%2x \n",
 2477: 			    ptr->DevType);
 2478: 		  	bval1 = ptr->DevType & SCSI_DEVTYPE; 
 2479: 			if (bval1 == SCSI_NODEV) {
 2480: NO_DEV:
 2481: 	  			TRM_DPRINTF("trm_SRBdone NO Device:target_id= %d ,target_lun= %d \n",
 2482: 				    target_id,
 2483: 				    target_lun);
 2484: 		      		intflag = splcam();
 2485: 				pACB->scan_devices[target_id][target_lun] = 0;
 2486: 				/* no device set scan device flag =0*/
 2487: 				/* pDCB Q link */
 2488: 				/* move the head of DCB to tempDCB*/
 2489: 				pTempDCB=pACB->pLinkDCB;  
 2490: 				/* search current DCB for pass link */
 2491: 				while (pTempDCB->pNextDCB != pDCB) {
 2492: 					pTempDCB = pTempDCB->pNextDCB;
 2493: 				}
 2494: 				/*
 2495: 				 * when the current DCB found than connect 
 2496: 				 * current DCB tail 
 2497: 				 */
 2498: 				/* to the DCB tail that before current DCB */
 2499: 				pTempDCB->pNextDCB = pDCB->pNextDCB;
 2500: 				/*
 2501: 				 * if there was only one DCB ,connect his tail
 2502: 				 * to his head 
 2503: 				 */
 2504: 				if (pACB->pLinkDCB == pDCB)
 2505: 					pACB->pLinkDCB = pTempDCB->pNextDCB;
 2506: 				if (pACB->pDCBRunRobin == pDCB)
 2507: 					pACB->pDCBRunRobin = pTempDCB->pNextDCB;
 2508: 				pACB->DeviceCnt--;
 2509: 				if (pACB->DeviceCnt == 0) {
 2510: 					pACB->pLinkDCB = NULL;
 2511: 					pACB->pDCBRunRobin = NULL;
 2512: 				}
 2513: 				splx(intflag);
 2514: 			} else { 
 2515: #ifdef trm_DEBUG1
 2516: 				int j;
 2517: 				for (j = 0; j < 28; j++) {
 2518: 					TRM_DPRINTF("ptr=%2x ", 
 2519: 						((u_int8_t *)ptr)[j]);
 2520: 				}
 2521: #endif
 2522: 	      			pDCB->DevType = bval1;
 2523: 				if (bval1 == SCSI_DASD ||
 2524: 				    bval1 == SCSI_OPTICAL) {
 2525: 					if ((((ptr->Vers & 0x07) >= 2) ||
 2526: 					      ((ptr->RDF & 0x0F) == 2)) && 
 2527: 					    (ptr->Flags & SCSI_INQ_CMDQUEUE) &&
 2528: 					    (pDCB->DevMode & TAG_QUEUING_) &&
 2529: 					    (pDCB->DevMode & EN_DISCONNECT_)) {
 2530: 						if (pDCB->DevMode &
 2531: 						    TAG_QUEUING_) {
 2532: 							pDCB->MaxCommand = 
 2533: 							  pACB->TagMaxNum;
 2534: 							pDCB->SyncMode |= 
 2535: 							  EN_TAG_QUEUING;
 2536: 							pDCB->TagMask = 0;
 2537: 							pDCB->tinfo.disc_tag |=
 2538: 							  TRM_CUR_TAGENB;
 2539: 						} else {
 2540: 							pDCB->SyncMode |= 
 2541: 							  EN_ATN_STOP;
 2542: 							pDCB->tinfo.disc_tag &=
 2543: 							  ~TRM_CUR_TAGENB;
 2544: 						}
 2545: 					}
 2546: 				}
 2547: 			}
 2548: 			/* pSRB->CmdBlock[0] == INQUIRY */
 2549: 		}
 2550: 		/* pACB->scan_devices[target_id][target_lun] */
 2551: 	}
 2552:     	intflag = splcam();
 2553: 	/*  ReleaseSRB(pDCB, pSRB); */
 2554: 	if (pSRB == pDCB->pGoingSRB)
 2555: 		pDCB->pGoingSRB = pSRB->pNextSRB;
 2556: 	else {
 2557: 		psrb = pDCB->pGoingSRB;
 2558: 		while (psrb->pNextSRB != pSRB) {
 2559: 			psrb = psrb->pNextSRB;
 2560: 		}
 2561: 		psrb->pNextSRB = pSRB->pNextSRB;
 2562: 		if (pSRB == pDCB->pGoingLastSRB) {
 2563: 			pDCB->pGoingLastSRB = psrb;
 2564: 		}
 2565: 	}
 2566: 	pSRB->pNextSRB = pACB->pFreeSRB;
 2567: 	pACB->pFreeSRB = pSRB;
 2568: 	pDCB->GoingSRBCnt--;
 2569: 	trm_DoWaitingSRB(pACB);
 2570: 
 2571: 	splx(intflag);
 2572: 	/*  Notify cmd done */
 2573: 	xpt_done (pccb);
 2574: }
 2575: 
 2576: static void
 2577: trm_DoingSRB_Done(PACB pACB)
 2578: {
 2579: 	PDCB		pDCB, pdcb;
 2580: 	PSRB		psrb, psrb2;
 2581: 	u_int16_t	cnt, i;
 2582: 	union ccb 	*pccb;
 2583: 
 2584: 	pDCB = pACB->pLinkDCB;
 2585: 	if (pDCB == NULL) 
 2586:   		return;
 2587: 	pdcb = pDCB;
 2588:     	do {
 2589: 		cnt = pdcb->GoingSRBCnt;
 2590: 		psrb = pdcb->pGoingSRB;
 2591: 		for (i = 0; i < cnt; i++) {
 2592: 			psrb2 = psrb->pNextSRB;
 2593: 		    	pccb = psrb->pccb;
 2594: 			pccb->ccb_h.status = CAM_SEL_TIMEOUT;
 2595: 			/*  ReleaseSRB(pDCB, pSRB); */
 2596: 			psrb->pNextSRB = pACB->pFreeSRB;
 2597: 			pACB->pFreeSRB = psrb;
 2598: 			xpt_done(pccb);
 2599: 			psrb  = psrb2;
 2600: 		}
 2601: 		pdcb->GoingSRBCnt = 0;;
 2602: 		pdcb->pGoingSRB = NULL;
 2603: 		pdcb->TagMask = 0;
 2604: 		pdcb = pdcb->pNextDCB;
 2605: 	}
 2606: 	while (pdcb != pDCB);
 2607: }
 2608: 
 2609: static void 
 2610: trm_ResetSCSIBus(PACB pACB)
 2611: {
 2612: 	int	intflag;
 2613: 
 2614: 	intflag = splcam();
 2615:     	pACB->ACBFlag |= RESET_DEV;
 2616: 
 2617: 	trm_reg_write16(DO_RSTSCSI,TRMREG_SCSI_CONTROL);
 2618: 	while (!(trm_reg_read16(TRMREG_SCSI_INTSTATUS) & INT_SCSIRESET));
 2619: 	splx(intflag);
 2620: 	return;
 2621: }
 2622: 
 2623: static void 
 2624: trm_ScsiRstDetect(PACB pACB)
 2625: {
 2626: 	int	intflag;
 2627: 	u_long	wlval;
 2628: 
 2629: 	TRM_DPRINTF("trm_ScsiRstDetect \n");
 2630: 	wlval = 1000;
 2631: 	while (--wlval)
 2632: 		DELAY(1000);
 2633: 	intflag = splcam();
 2634:     	trm_reg_write8(STOPDMAXFER,TRMREG_DMA_CONTROL);
 2635: 
 2636: 	trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL);
 2637: 
 2638: 	if (pACB->ACBFlag & RESET_DEV)
 2639: 		pACB->ACBFlag |= RESET_DONE;
 2640: 	else {
 2641: 		pACB->ACBFlag |= RESET_DETECT;
 2642: 		trm_ResetDevParam(pACB);
 2643: 		/*	trm_DoingSRB_Done(pACB); ???? */
 2644: 		trm_RecoverSRB(pACB);
 2645: 		pACB->pActiveDCB = NULL;
 2646: 		pACB->ACBFlag = 0;
 2647: 		trm_DoWaitingSRB(pACB);
 2648: 	}
 2649: 	splx(intflag);
 2650:     	return;
 2651: }
 2652: 
 2653: static void
 2654: trm_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB)	
 2655: {
 2656: 	union ccb		*pccb;
 2657: 	struct ccb_scsiio	*pcsio;
 2658: 
 2659: 	pccb  = pSRB->pccb;
 2660: 	pcsio = &pccb->csio;
 2661: 
 2662: 	pSRB->SRBFlag |= AUTO_REQSENSE;
 2663: 	pSRB->Segment0[0] = *((u_long *) &(pSRB->CmdBlock[0]));
 2664: 	pSRB->Segment0[1] = *((u_long *) &(pSRB->CmdBlock[4]));
 2665: 	pSRB->Segment1[0] = (u_long) ((pSRB->ScsiCmdLen << 8) + 
 2666: 	    pSRB->SRBSGCount);
 2667: 	pSRB->Segment1[1] = pSRB->SRBTotalXferLength; /* ?????????? */
 2668: 
 2669: 	/* $$$$$$ Status of initiator/target $$$$$$$$ */
 2670: 	pSRB->AdaptStatus = 0;
 2671: 	pSRB->TargetStatus = 0;
 2672: 	/* $$$$$$ Status of initiator/target $$$$$$$$ */
 2673: 	
 2674: 	pSRB->SRBTotalXferLength = sizeof(pcsio->sense_data);
 2675: 	pSRB->SgSenseTemp.address = pSRB->SegmentX[0].address;
 2676: 	pSRB->SgSenseTemp.length  = pSRB->SegmentX[0].length;
 2677: 	pSRB->SegmentX[0].address = (u_long) vtophys(&pcsio->sense_data);
 2678: 	pSRB->SegmentX[0].length = (u_long) pcsio->sense_len;
 2679: 	pSRB->SRBSGListPointer = &pSRB->SegmentX[0];
 2680: 	pSRB->SRBSGCount = 1;
 2681: 	pSRB->SRBSGIndex = 0;
 2682: 	
 2683: 	*((u_long *) &(pSRB->CmdBlock[0])) = 0x00000003;
 2684: 	pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5;
 2685: 	*((u_int16_t *) &(pSRB->CmdBlock[4])) = pcsio->sense_len;
 2686: 	pSRB->ScsiCmdLen = 6;
 2687: 	
 2688: 	if (trm_StartSCSI(pACB, pDCB, pSRB))
 2689: 	   /* 
 2690: 	    * If trm_StartSCSI return 1 :
 2691: 	    * current interrupt status is interrupt disreenable 
 2692: 	    * It's said that SCSI processor has more one SRB need to do
 2693: 	    */
 2694: 		trm_RewaitSRB(pDCB, pSRB);
 2695: }
 2696: 
 2697: static void 
 2698: trm_EnableMsgOutAbort2(PACB pACB, PSRB pSRB)
 2699: {
 2700: 
 2701: 	pSRB->MsgCnt = 1;
 2702: 	trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
 2703: }
 2704: 
 2705: static void
 2706: trm_EnableMsgOutAbort1(PACB pACB, PSRB pSRB)
 2707: {
 2708:   
 2709: 	pSRB->MsgOutBuf[0] = MSG_ABORT;
 2710: 	trm_EnableMsgOutAbort2(pACB, pSRB);
 2711: }
 2712: 
 2713: static void
 2714: trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,u_int32_t i,u_int32_t j)
 2715: {
 2716: 	PNVRAMTYPE 	pEEpromBuf;
 2717: 	u_int8_t	bval,PeriodIndex;
 2718: 	u_int		target_id,target_lun;
 2719: 	PDCB		pTempDCB;
 2720: 	int		intflag;
 2721:     
 2722:     	target_id  = i;
 2723: 	target_lun = j;
 2724: 
 2725: 	intflag = splcam();
 2726: 	if (pACB->pLinkDCB == 0) {
 2727: 		pACB->pLinkDCB = pDCB;
 2728: 		/* 
 2729: 		 * RunRobin impersonate the role 
 2730: 		 * that let each device had good proportion 
 2731: 		 * about SCSI command proceeding 
 2732: 		 */
 2733: 		pACB->pDCBRunRobin = pDCB;
 2734: 		pDCB->pNextDCB = pDCB;
 2735: 	} else {
 2736: 		pTempDCB=pACB->pLinkDCB;
 2737: 		/* search the last nod of DCB link */
 2738: 		while (pTempDCB->pNextDCB != pACB->pLinkDCB)
 2739: 			pTempDCB = pTempDCB->pNextDCB;
 2740: 		/* connect current DCB with last DCB tail */
 2741: 		pTempDCB->pNextDCB = pDCB;
 2742: 		/* connect current DCB tail to this DCB Q head */
 2743: 		pDCB->pNextDCB=pACB->pLinkDCB;
 2744: 	}
 2745: 	splx(intflag);
 2746: 
 2747: 	pACB->DeviceCnt++;
 2748: 	pDCB->pDCBACB = pACB;
 2749: 	pDCB->TargetID = target_id;
 2750: 	pDCB->TargetLUN =  target_lun;
 2751: 	pDCB->pWaitingSRB = NULL;
 2752: 	pDCB->pGoingSRB = NULL;
 2753: 	pDCB->GoingSRBCnt = 0;
 2754: 	pDCB->pActiveSRB = NULL;
 2755: 	pDCB->TagMask = 0;
 2756: 	pDCB->MaxCommand = 1;
 2757: 	pDCB->DCBFlag = 0;
 2758: 	/* $$$$$$$ */
 2759: 	pEEpromBuf = &trm_eepromBuf[unit];
 2760: 	pDCB->DevMode = pEEpromBuf->NvramTarget[target_id].NvmTarCfg0;
 2761: 	pDCB->AdpMode = pEEpromBuf->NvramChannelCfg;
 2762: 	/* $$$$$$$ */
 2763: 	/* 
 2764: 	 * disconnect enable ?
 2765: 	 */
 2766: 	if (pDCB->DevMode & NTC_DO_DISCONNECT) {
 2767: 		bval = 0xC0;
 2768: 		pDCB->tinfo.disc_tag |= TRM_USR_DISCENB ;
 2769: 	} else {
 2770: 		bval = 0x80;
 2771: 		pDCB->tinfo.disc_tag &= ~(TRM_USR_DISCENB);
 2772: 	}
 2773: 	bval |= target_lun;
 2774: 	pDCB->IdentifyMsg = bval;
 2775: 	/* $$$$$$$ */
 2776: 	/*
 2777: 	 * tag Qing enable ?
 2778: 	 */
 2779: 	if (pDCB->DevMode & TAG_QUEUING_) {
 2780: 		pDCB->tinfo.disc_tag |= TRM_USR_TAGENB ;
 2781: 	} else
 2782: 		pDCB->tinfo.disc_tag &= ~(TRM_USR_TAGENB);
 2783: 	/* $$$$$$$ */
 2784: 	/*
 2785: 	 * wide nego ,sync nego enable ?
 2786: 	 */
 2787: 	pDCB->SyncPeriod = 0;
 2788: 	pDCB->SyncOffset = 0;
 2789: 	PeriodIndex = pEEpromBuf->NvramTarget[target_id].NvmTarPeriod & 0x07;
 2790: 	pDCB->MaxNegoPeriod = dc395x_trm_clock_period[ PeriodIndex ] ;
 2791: 	pDCB->SyncMode = 0;
 2792: 	if ((pDCB->DevMode & NTC_DO_WIDE_NEGO) && 
 2793: 	    (pACB->Config & HCC_WIDE_CARD))
 2794: 		pDCB->SyncMode |= WIDE_NEGO_ENABLE;
 2795: 	/* enable wide nego */
 2796:    	if (pDCB->DevMode & NTC_DO_SYNC_NEGO)
 2797: 		pDCB->SyncMode |= SYNC_NEGO_ENABLE;
 2798: 	/* enable sync nego */
 2799: 	/* $$$$$$$ */
 2800: 	/*
 2801: 	 *	Fill in tinfo structure.
 2802: 	 */
 2803: 	pDCB->tinfo.user.period = pDCB->MaxNegoPeriod;
 2804: 	pDCB->tinfo.user.offset = (pDCB->SyncMode & SYNC_NEGO_ENABLE) ? 15 : 0;
 2805: 	pDCB->tinfo.user.width  = (pDCB->SyncMode & WIDE_NEGO_ENABLE) ? 
 2806: 	  MSG_EXT_WDTR_BUS_16_BIT : MSG_EXT_WDTR_BUS_8_BIT;
 2807: 
 2808: 	pDCB->tinfo.current.period = 0;
 2809: 	pDCB->tinfo.current.offset = 0;
 2810: 	pDCB->tinfo.current.width = MSG_EXT_WDTR_BUS_8_BIT;
 2811: }
 2812: 
 2813: static void 
 2814: trm_initSRB(PSRB psrb)
 2815: {
 2816:   
 2817: 	psrb->PhysSRB = vtophys(psrb);
 2818: }
 2819: 
 2820: static void
 2821: trm_linkSRB(PACB pACB)
 2822: {
 2823: 	u_int16_t	i;
 2824: 
 2825: 	for (i = 0; i < MAX_SRB_CNT; i++) {
 2826: 		if (i != MAX_SRB_CNT - 1)
 2827: 			/*
 2828: 			 * link all SRB 
 2829: 			 */
 2830: 			pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
 2831:     	else
 2832: 			/*
 2833: 			 * load NULL to NextSRB of the last SRB
 2834: 			 */
 2835: 		pACB->SRB_array[i].pNextSRB = NULL;
 2836: 	/*
 2837:  	 * convert and save physical address of SRB to pSRB->PhysSRB
 2838: 	 */
 2839: 	trm_initSRB((PSRB) &pACB->SRB_array[i]);
 2840: 	}
 2841: }
 2842: 
 2843: 
 2844: static void
 2845: trm_initACB(PACB pACB, u_int16_t unit)
 2846: {
 2847: 	PNVRAMTYPE	pEEpromBuf;
 2848: 	u_int16_t		i,j;
 2849:     
 2850: 	pEEpromBuf = &trm_eepromBuf[unit];
 2851: 	pACB->max_id = 15;
 2852: 	
 2853: 	if (pEEpromBuf->NvramChannelCfg & NAC_SCANLUN)
 2854:   		pACB->max_lun = 7;
 2855: 	else
 2856: 		pACB->max_lun = 0;
 2857: 
 2858: 	TRM_DPRINTF("trm: pACB->max_id= %d pACB->max_lun= %d \n",
 2859: 	    pACB->max_id, pACB->max_lun);
 2860: 
 2861: 	pACB->pLinkDCB = NULL;
 2862: 	pACB->pDCBRunRobin = NULL;
 2863: 	pACB->pActiveDCB = NULL;
 2864: 	pACB->pFreeSRB = pACB->SRB_array;
 2865: 	pACB->AdapterUnit = unit;
 2866: 	pACB->AdaptSCSIID = pEEpromBuf->NvramScsiId;
 2867: 	pACB->AdaptSCSILUN = 0;
 2868: 	pACB->DeviceCnt = 0;
 2869: 	pACB->TagMaxNum = 2 << pEEpromBuf->NvramMaxTag ;
 2870: 	pACB->ACBFlag = 0;
 2871: 	/* 
 2872: 	 * link all device's SRB Q of this adapter 
 2873: 	 */
 2874: 	trm_linkSRB(pACB);
 2875: 	/* 
 2876: 	 * temp SRB for Q tag used or abord command used 
 2877: 	 */
 2878: 	pACB->pTmpSRB = &pACB->TmpSRB;
 2879: 	/*
 2880: 	 * convert and save physical address of SRB to pSRB->PhysSRB
 2881: 	 */
 2882: 	trm_initSRB(pACB->pTmpSRB);
 2883: 	/* allocate DCB array for scan device */
 2884: 	for (i = 0; i < (pACB->max_id +1); i++) {   
 2885: 		if (pACB->AdaptSCSIID != i) {
 2886: 			for (j = 0; j < (pACB->max_lun +1); j++) {
 2887: 				pACB->scan_devices[i][j] = 1;
 2888: 				pACB->pDCB[i][j]= (PDCB) malloc (
 2889: 				    sizeof (struct _DCB), M_DEVBUF, M_WAITOK);
 2890: 				trm_initDCB(pACB,
 2891: 				    pACB->pDCB[i][j], unit, i, j);
 2892: 				TRM_DPRINTF("pDCB= %8x \n",
 2893: 					(u_int)pACB->pDCB[i][j]);
 2894: 			}
 2895: 		}
 2896: 	}
 2897:     	TRM_DPRINTF("sizeof(struct _DCB)= %8x \n",sizeof(struct _DCB));
 2898: 	TRM_DPRINTF("sizeof(struct _ACB)= %8x \n",sizeof(struct _ACB));
 2899: 	TRM_DPRINTF("sizeof(struct _SRB)= %8x \n",sizeof(struct _SRB));
 2900: }
 2901: 
 2902: static void
 2903: TRM_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB)
 2904: {
 2905: 	u_int8_t	*bpEeprom = (u_int8_t *) pEEpromBuf;
 2906: 	u_int8_t	bAddr;
 2907: 
 2908: 	/* Enable SEEPROM */
 2909: 	trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) | EN_EEPROM),
 2910: 	    TRMREG_GEN_CONTROL);
 2911: 	/*
 2912: 	 * Write enable
 2913: 	 */
 2914: 	TRM_write_cmd(pACB, 0x04, 0xFF);
 2915: 	trm_reg_write8(0, TRMREG_GEN_NVRAM);
 2916: 	TRM_wait_30us(pACB);
 2917: 	for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++) { 
 2918: 		TRM_set_data(pACB, bAddr, *bpEeprom);
 2919: 	}
 2920: 	/* 
 2921: 	 * Write disable
 2922: 	 */
 2923: 	TRM_write_cmd(pACB, 0x04, 0x00);
 2924: 	trm_reg_write8(0 , TRMREG_GEN_NVRAM);
 2925: 	TRM_wait_30us(pACB);
 2926: 	/* Disable SEEPROM */
 2927: 	trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) & ~EN_EEPROM),
 2928: 	    TRMREG_GEN_CONTROL);
 2929: 	return;
 2930: }
 2931: 
 2932: static void
 2933: TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData)
 2934: {
 2935: 	int		i;
 2936: 	u_int8_t	bSendData;
 2937: 	/* 
 2938: 	 * Send write command & address	
 2939: 	 */
 2940: 	
 2941: 	TRM_write_cmd(pACB, 0x05, bAddr);
 2942: 	/* 
 2943: 	 * Write data 
 2944: 	 */
 2945: 	for (i = 0; i < 8; i++, bData <<= 1) {
 2946: 		bSendData = NVR_SELECT;
 2947: 		if (bData & 0x80)
 2948: 		  /* Start from bit 7	*/
 2949: 			bSendData |= NVR_BITOUT;
 2950: 		trm_reg_write8(bSendData , TRMREG_GEN_NVRAM);
 2951: 		TRM_wait_30us(pACB);
 2952: 		trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
 2953: 		TRM_wait_30us(pACB);
 2954: 	}
 2955: 	trm_reg_write8(NVR_SELECT , TRMREG_GEN_NVRAM);
 2956: 	TRM_wait_30us(pACB);
 2957: 	/*
 2958: 	 * Disable chip select 
 2959: 	 */
 2960: 	trm_reg_write8(0 , TRMREG_GEN_NVRAM);
 2961: 	TRM_wait_30us(pACB);
 2962: 	trm_reg_write8(NVR_SELECT ,TRMREG_GEN_NVRAM);
 2963: 	TRM_wait_30us(pACB);
 2964: 	/* 
 2965: 	 * Wait for write ready	
 2966: 	 */
 2967: 	while (1) {
 2968: 		trm_reg_write8((NVR_SELECT | NVR_CLOCK), TRMREG_GEN_NVRAM);
 2969: 		TRM_wait_30us(pACB);
 2970: 		trm_reg_write8(NVR_SELECT, TRMREG_GEN_NVRAM);
 2971: 		TRM_wait_30us(pACB);
 2972: 		if (trm_reg_read8(TRMREG_GEN_NVRAM) & NVR_BITIN) {
 2973: 			break;
 2974: 		}
 2975: 	}
 2976: 	/* 
 2977: 	 * Disable chip select 
 2978: 	 */
 2979: 	trm_reg_write8(0, TRMREG_GEN_NVRAM);
 2980: 	return;
 2981: }
 2982: 
 2983: static void 
 2984: TRM_read_all(PNVRAMTYPE pEEpromBuf, PACB pACB)
 2985: {
 2986: 	u_int8_t	*bpEeprom = (u_int8_t*) pEEpromBuf;
 2987: 	u_int8_t	bAddr;
 2988:     
 2989: 	/*
 2990: 	 * Enable SEEPROM 
 2991: 	 */
 2992: 	trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) | EN_EEPROM),
 2993: 	    TRMREG_GEN_CONTROL);
 2994: 	for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++)
 2995: 		*bpEeprom = TRM_get_data(pACB, bAddr);
 2996: 	/* 
 2997: 	 * Disable SEEPROM 
 2998: 	 */
 2999: 	trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) & ~EN_EEPROM),
 3000: 	    TRMREG_GEN_CONTROL);
 3001: 	return;
 3002: }
 3003: 
 3004: static u_int8_t
 3005: TRM_get_data(PACB pACB, u_int8_t bAddr)
 3006: {
 3007: 	int		i;
 3008: 	u_int8_t	bReadData, bData = 0;
 3009: 	/* 
 3010: 	* Send read command & address
 3011: 	*/
 3012: 	
 3013: 	TRM_write_cmd(pACB, 0x06, bAddr);
 3014: 				
 3015: 	for (i = 0; i < 8; i++) {
 3016: 	  /* 
 3017: 	   * Read data
 3018: 	   */
 3019: 		trm_reg_write8((NVR_SELECT | NVR_CLOCK) , TRMREG_GEN_NVRAM);
 3020: 		TRM_wait_30us(pACB);
 3021: 		trm_reg_write8(NVR_SELECT , TRMREG_GEN_NVRAM);
 3022: 		/* 
 3023: 		 * Get data bit while falling edge 
 3024: 		 */
 3025: 		bReadData = trm_reg_read8(TRMREG_GEN_NVRAM);
 3026: 		bData <<= 1;
 3027: 		if (bReadData & NVR_BITIN) {
 3028: 			bData |= 1;
 3029: 		}
 3030: 		TRM_wait_30us(pACB);
 3031: 	}
 3032: 	/* 
 3033: 	 * Disable chip select 
 3034: 	 */
 3035: 	trm_reg_write8(0, TRMREG_GEN_NVRAM);
 3036: 	return (bData);
 3037: }
 3038: 
 3039: static void
 3040: TRM_wait_30us(PACB pACB)
 3041: {
 3042:   
 3043: 	/*    ScsiPortStallExecution(30);	 wait 30 us	*/
 3044: 	trm_reg_write8(5, TRMREG_GEN_TIMER);
 3045: 	while (!(trm_reg_read8(TRMREG_GEN_STATUS) & GTIMEOUT));
 3046: 	return;
 3047: }
 3048: 
 3049: static void
 3050: TRM_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr)
 3051: {
 3052: 	int		i;
 3053: 	u_int8_t	bSendData;
 3054: 					
 3055:     	for (i = 0; i < 3; i++, bCmd <<= 1) {
 3056: 	  /* 
 3057:    	   * Program SB+OP code		
 3058:    	   */
 3059:      		bSendData = NVR_SELECT;
 3060: 		if (bCmd & 0x04)	
 3061: 			bSendData |= NVR_BITOUT;
 3062: 		/* start from bit 2 */
 3063: 		trm_reg_write8(bSendData, TRMREG_GEN_NVRAM);
 3064: 		TRM_wait_30us(pACB);
 3065: 		trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
 3066: 		TRM_wait_30us(pACB);
 3067: 	}	
 3068: 	for (i = 0; i < 7; i++, bAddr <<= 1) {
 3069: 	  /* 
 3070: 	   * Program address		
 3071: 	   */
 3072: 		bSendData = NVR_SELECT;
 3073: 		if (bAddr & 0x40)	
 3074: 		  /* Start from bit 6	*/
 3075: 			bSendData |= NVR_BITOUT;
 3076: 		trm_reg_write8(bSendData , TRMREG_GEN_NVRAM);
 3077: 		TRM_wait_30us(pACB);
 3078: 		trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
 3079: 		TRM_wait_30us(pACB);
 3080: 	}
 3081: 	trm_reg_write8(NVR_SELECT, TRMREG_GEN_NVRAM);
 3082: 	TRM_wait_30us(pACB);
 3083: }
 3084: 
 3085: static void
 3086: trm_check_eeprom(PNVRAMTYPE pEEpromBuf, PACB pACB)
 3087: {
 3088: 	u_int16_t	*wpEeprom = (u_int16_t *) pEEpromBuf;
 3089: 	u_int16_t	wAddr, wCheckSum;
 3090: 	u_long	dAddr, *dpEeprom;
 3091: 
 3092: 	TRM_read_all(pEEpromBuf,pACB);
 3093: 	wCheckSum = 0;
 3094: 	for (wAddr = 0, wpEeprom = (u_int16_t *) pEEpromBuf;
 3095: 	    wAddr < 64; wAddr++, wpEeprom++) {
 3096: 		wCheckSum += *wpEeprom;
 3097: 	}
 3098: 	if (wCheckSum != 0x1234) {
 3099: 	  /* 
 3100:    	   * Checksum error, load default	
 3101: 	   */
 3102: 		pEEpromBuf->NvramSubVendorID[0]	= (u_int8_t) PCI_Vendor_ID_TEKRAM;
 3103: 		pEEpromBuf->NvramSubVendorID[1]	=
 3104: 		  (u_int8_t) (PCI_Vendor_ID_TEKRAM >> 8);
 3105: 		pEEpromBuf->NvramSubSysID[0] = (u_int8_t) PCI_Device_ID_TRM_S1040;
 3106: 		pEEpromBuf->NvramSubSysID[1] = 
 3107: 		  (u_int8_t) (PCI_Device_ID_TRM_S1040 >> 8);
 3108: 		pEEpromBuf->NvramSubClass = 0x00;
 3109: 		pEEpromBuf->NvramVendorID[0] = (u_int8_t) PCI_Vendor_ID_TEKRAM;
 3110: 		pEEpromBuf->NvramVendorID[1] =
 3111: 		  (u_int8_t) (PCI_Vendor_ID_TEKRAM >> 8);
 3112: 		pEEpromBuf->NvramDeviceID[0] = (u_int8_t) PCI_Device_ID_TRM_S1040;
 3113: 		pEEpromBuf->NvramDeviceID[1] = 
 3114: 		  (u_int8_t) (PCI_Device_ID_TRM_S1040 >> 8);
 3115: 		pEEpromBuf->NvramReserved = 0x00;
 3116: 
 3117: 		for (dAddr = 0, dpEeprom = (u_long *) pEEpromBuf->NvramTarget;
 3118: 		    dAddr < 16; dAddr++, dpEeprom++) {
 3119: 			*dpEeprom = 0x00000077;
 3120: 			/* NvmTarCfg3,NvmTarCfg2,NvmTarPeriod,NvmTarCfg0 */
 3121: 		}
 3122: 
 3123: 		*dpEeprom++ = 0x04000F07;
 3124: 		/* NvramMaxTag,NvramDelayTime,NvramChannelCfg,NvramScsiId */
 3125: 		*dpEeprom++ = 0x00000015;
 3126: 		/* NvramReserved1,NvramBootLun,NvramBootTarget,NvramReserved0 */
 3127: 		for (dAddr = 0; dAddr < 12; dAddr++, dpEeprom++)
 3128: 			*dpEeprom = 0x00;
 3129: 		pEEpromBuf->NvramCheckSum = 0x00;
 3130: 		for (wAddr = 0, wCheckSum = 0, wpEeprom = (u_int16_t *) pEEpromBuf;
 3131: 		    wAddr < 63; wAddr++, wpEeprom++)
 3132: 	      		wCheckSum += *wpEeprom;
 3133: 		*wpEeprom = 0x1234 - wCheckSum;
 3134: 		TRM_write_all(pEEpromBuf,pACB);
 3135: 	}
 3136: 	return;
 3137: }
 3138: static int
 3139: trm_initAdapter(PACB pACB, u_int16_t unit, device_t pci_config_id)
 3140: {
 3141: 	PNVRAMTYPE	pEEpromBuf;
 3142: 	u_int16_t	wval;
 3143: 	u_int8_t	bval;
 3144: 
 3145: 	pEEpromBuf = &trm_eepromBuf[unit];
 3146: 
 3147: 	/* 250ms selection timeout */
 3148: 	trm_reg_write8(SEL_TIMEOUT, TRMREG_SCSI_TIMEOUT);
 3149: 	/* Mask all the interrupt */
 3150: 	trm_reg_write8(0x00, TRMREG_DMA_INTEN);    
 3151: 	trm_reg_write8(0x00, TRMREG_SCSI_INTEN);     
 3152: 	/* Reset SCSI module */
 3153: 	trm_reg_write16(DO_RSTMODULE, TRMREG_SCSI_CONTROL); 
 3154: 	/* program configuration 0 */
 3155: 	pACB->Config = HCC_AUTOTERM | HCC_PARITY;
 3156: 	if (trm_reg_read8(TRMREG_GEN_STATUS) & WIDESCSI)
 3157: 		pACB->Config |= HCC_WIDE_CARD;
 3158: 	if (pEEpromBuf->NvramChannelCfg & NAC_POWERON_SCSI_RESET)
 3159: 		pACB->Config |= HCC_SCSI_RESET;
 3160: 	if (pACB->Config & HCC_PARITY)
 3161: 		bval = PHASELATCH | INITIATOR | BLOCKRST | PARITYCHECK;
 3162: 	else
 3163: 		bval = PHASELATCH | INITIATOR | BLOCKRST ;
 3164: 	trm_reg_write8(bval,TRMREG_SCSI_CONFIG0); 
 3165: 	/* program configuration 1 */
 3166: 	trm_reg_write8(0x13, TRMREG_SCSI_CONFIG1); 
 3167: 	/* program Host ID */
 3168: 	bval = pEEpromBuf->NvramScsiId;
 3169: 	trm_reg_write8(bval, TRMREG_SCSI_HOSTID); 
 3170: 	/* set ansynchronous transfer */
 3171: 	trm_reg_write8(0x00, TRMREG_SCSI_OFFSET); 
 3172: 	/* Trun LED control off*/
 3173: 	wval = trm_reg_read16(TRMREG_GEN_CONTROL) & 0x7F;
 3174: 	trm_reg_write16(wval, TRMREG_GEN_CONTROL); 
 3175: 	/* DMA config */
 3176: 	wval = trm_reg_read16(TRMREG_DMA_CONFIG) | DMA_ENHANCE;
 3177: 	trm_reg_write16(wval, TRMREG_DMA_CONFIG); 
 3178: 	/* Clear pending interrupt status */
 3179: 	trm_reg_read8(TRMREG_SCSI_INTSTATUS);
 3180: 	/* Enable SCSI interrupt */
 3181: 	trm_reg_write8(0x7F, TRMREG_SCSI_INTEN); 
 3182: 	trm_reg_write8(EN_SCSIINTR, TRMREG_DMA_INTEN); 
 3183: 	return (0);
 3184: }
 3185: 
 3186: static PACB
 3187: trm_init(u_int16_t unit, device_t pci_config_id)
 3188: {
 3189: 	PACB		pACB;
 3190: 	int		rid = PCIR_MAPS;
 3191:     
 3192:  	pACB = (PACB) device_get_softc(pci_config_id);
 3193:    	if (!pACB) {
 3194: 		printf("trm%d: cannot allocate ACB !\n", unit);
 3195: 		return (NULL);
 3196: 	}
 3197: 	bzero (pACB, sizeof (struct _ACB));
 3198: 	pACB->iores = bus_alloc_resource(pci_config_id, SYS_RES_IOPORT, 
 3199: 	    &rid, 0, ~0, 1, RF_ACTIVE);
 3200:     	if (pACB->iores == NULL) {
 3201: 		printf("trm_init: bus_alloc_resource failed!\n");
 3202: 		return (NULL);
 3203: 	}
 3204: 	pACB->tag = rman_get_bustag(pACB->iores);
 3205: 	pACB->bsh = rman_get_bushandle(pACB->iores);
 3206: 	if (bus_dma_tag_create(/*parent_dmat*/                 NULL, 
 3207: 	      /*alignment*/                      1,
 3208: 	      /*boundary*/                       0,
 3209: 	      /*lowaddr*/  BUS_SPACE_MAXADDR_32BIT,
 3210: 	      /*highaddr*/       BUS_SPACE_MAXADDR,
 3211: 	      /*filter*/                      NULL, 
 3212: 	      /*filterarg*/                   NULL,
 3213: 	      /*maxsize*/                 MAXBSIZE,
 3214: 	      /*nsegments*/               TRM_NSEG,
 3215: 	      /*maxsegsz*/    TRM_MAXTRANSFER_SIZE,
 3216: 	      /*flags*/           BUS_DMA_ALLOCNOW,
 3217: 	      &pACB->buffer_dmat) != 0) 
 3218: 		goto bad;
 3219: 	trm_check_eeprom(&trm_eepromBuf[unit],pACB);
 3220: 	trm_initACB(pACB, unit);
 3221:    	if (trm_initAdapter(pACB, unit, pci_config_id)) {
 3222: 		printf("trm_initAdapter: initial ERROR\n");
 3223: 		goto bad;
 3224: 	}
 3225: 	return (pACB);
 3226: bad:
 3227: 	if (pACB->iores)
 3228: 		bus_release_resource(pci_config_id, SYS_RES_IOPORT, PCIR_MAPS,
 3229: 		    pACB->iores);
 3230: 	if (pACB->buffer_dmat)
 3231: 		bus_dma_tag_destroy(pACB->buffer_dmat);
 3232: 	return (NULL);
 3233: }
 3234: 
 3235: static int
 3236: trm_attach(device_t pci_config_id)
 3237: {
 3238: 	struct	cam_devq *device_Q;
 3239: 	u_long	device_id;
 3240: 	PACB	pACB = 0;
 3241: 	int	rid = 0;
 3242: 	int unit = device_get_unit(pci_config_id);
 3243: 	
 3244: 	device_id = pci_get_devid(pci_config_id);
 3245: 	/*
 3246: 	 * These cards do not allow memory mapped accesses
 3247: 	 */
 3248: 	if (device_id == PCI_DEVICEID_TRMS1040) {
 3249: 		if ((pACB=trm_init((u_int16_t) unit,
 3250: 			pci_config_id)) == NULL) {
 3251: 			printf("trm%d: trm_init error!\n",unit);
 3252: 			return (ENXIO);
 3253: 		}
 3254: 	} else
 3255: 		return (ENXIO);
 3256: 	/* After setting up the adapter, map our interrupt */
 3257: 	/*  
 3258: 	 * Now let the CAM generic SCSI layer find the SCSI devices on the bus
 3259: 	 * start queue to reset to the idle loop.
 3260: 	 * Create device queue of SIM(s)
 3261: 	 * (MAX_START_JOB - 1) : max_sim_transactions
 3262: 	 */
 3263: 	pACB->irq = bus_alloc_resource(pci_config_id, SYS_RES_IRQ, &rid, 0,
 3264: 	    ~0, 1, RF_SHAREABLE | RF_ACTIVE);
 3265:     	if (pACB->irq == NULL ||
 3266: 	    bus_setup_intr(pci_config_id, pACB->irq, 
 3267: 	    INTR_TYPE_CAM, trm_Interrupt, pACB, &pACB->ih)) {
 3268: 		printf("trm%d: register Interrupt handler error!\n", unit);
 3269: 		goto bad;
 3270: 	}
 3271: 	device_Q = cam_simq_alloc(MAX_START_JOB);
 3272: 	if (device_Q == NULL){ 
 3273: 		printf("trm%d: device_Q == NULL !\n",unit);
 3274: 		goto bad;
 3275: 	}
 3276: 	/*
 3277: 	 * Now tell the generic SCSI layer
 3278: 	 * about our bus.
 3279: 	 * If this is the xpt layer creating a sim, then it's OK
 3280: 	 * to wait for an allocation.
 3281: 	 * XXX Should we pass in a flag to indicate that wait is OK?
 3282: 	 *
 3283: 	 *                    SIM allocation
 3284: 	 *
 3285: 	 *                 SCSI Interface Modules
 3286: 	 * The sim driver creates a sim for each controller.  The sim device
 3287: 	 * queue is separately created in order to allow resource sharing betwee
 3288: 	 * sims.  For instance, a driver may create one sim for each channel of
 3289: 	 * a multi-channel controller and use the same queue for each channel.
 3290: 	 * In this way, the queue resources are shared across all the channels
 3291: 	 * of the multi-channel controller.
 3292: 	 * trm_action     : sim_action_func
 3293: 	 * trm_poll       : sim_poll_func
 3294: 	 * "trm"        : sim_name ,if sim_name =  "xpt" ..M_DEVBUF,M_WAITOK
 3295: 	 * pACB         : *softc    if sim_name <> "xpt" ..M_DEVBUF,M_NOWAIT
 3296: 	 * pACB->unit   : unit
 3297: 	 * 1            : max_dev_transactions
 3298: 	 * MAX_TAGS     : max_tagged_dev_transactions
 3299: 	 *
 3300: 	 *  *******Construct our first channel SIM entry
 3301: 	 */
 3302: 	pACB->psim = cam_sim_alloc(trm_action,
 3303: 	    trm_poll,
 3304: 	    "trm",
 3305: 	    pACB,
 3306: 	    unit,
 3307: 	    1,
 3308: 	    MAX_TAGS_CMD_QUEUE,
 3309: 	    device_Q);
 3310: 	if (pACB->psim == NULL) {
 3311: 		printf("trm%d: SIM allocate fault !\n",unit);
 3312: 		cam_simq_free(device_Q);  /* SIM allocate fault*/
 3313: 		goto bad;
 3314: 	}
 3315: 	if (xpt_bus_register(pACB->psim, 0) != CAM_SUCCESS)  {
 3316: 		printf("trm%d: xpt_bus_register fault !\n",unit);
 3317: 		goto bad;
 3318: 	}
 3319: 	if (xpt_create_path(&pACB->ppath,
 3320: 	      NULL,
 3321: 	      cam_sim_path(pACB->psim),
 3322: 	      CAM_TARGET_WILDCARD,
 3323: 	      CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
 3324: 		printf("trm%d: xpt_create_path fault !\n",unit);
 3325: 		xpt_bus_deregister(cam_sim_path(pACB->psim));
 3326: 		goto bad;
 3327: 		/* 
 3328: 		 * cam_sim_free(pACB->psim, TRUE);  free_devq 
 3329: 		 * pACB->psim = NULL;
 3330: 		 */
 3331: 		return (ENXIO);
 3332: 	}
 3333: 	return (0);
 3334: bad:
 3335: 	if (pACB->iores)
 3336: 		bus_release_resource(pci_config_id, SYS_RES_IOPORT, PCIR_MAPS,
 3337: 		    pACB->iores);
 3338: 	if (pACB->buffer_dmat)
 3339: 		bus_dma_tag_destroy(pACB->buffer_dmat);
 3340: 	if (pACB->ih)
 3341: 		bus_teardown_intr(pci_config_id, pACB->irq, pACB->ih);
 3342: 	if (pACB->irq)
 3343: 		bus_release_resource(pci_config_id, SYS_RES_IRQ, 0, pACB->irq);
 3344: 	if (pACB->psim)
 3345: 		cam_sim_free(pACB->psim, TRUE);
 3346: 	
 3347: 	return (ENXIO);
 3348: 	
 3349: }
 3350: 
 3351: /*
 3352: *                  pci_device
 3353: *         trm_probe (device_t tag, pcidi_t type)
 3354: *
 3355: */
 3356: static int
 3357: trm_probe(device_t tag)
 3358: {
 3359:   
 3360: 	if (pci_get_devid(tag) == PCI_DEVICEID_TRMS1040) { 
 3361: 		device_set_desc(tag,
 3362: 		    "Tekram DC395U/UW/F DC315/U Fast20 Wide SCSI Adapter");
 3363: 		return (0);
 3364: 	} else
 3365: 		return (ENXIO);
 3366: }
 3367: 
 3368: static int
 3369: trm_detach(device_t dev)
 3370: {
 3371: 	PACB pACB = device_get_softc(dev);
 3372: 
 3373: 	bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, pACB->iores);
 3374: 	bus_dma_tag_destroy(pACB->buffer_dmat);	
 3375: 	bus_teardown_intr(dev, pACB->irq, pACB->ih);
 3376: 	bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irq);
 3377: 	xpt_async(AC_LOST_DEVICE, pACB->ppath, NULL);
 3378: 	xpt_free_path(pACB->ppath);
 3379: 	xpt_bus_deregister(cam_sim_path(pACB->psim));
 3380: 	cam_sim_free(pACB->psim, TRUE);
 3381: 	return (0);
 3382: }
 3383: static device_method_t trm_methods[] = {
 3384: 	/* Device interface */
 3385: 	DEVMETHOD(device_probe,		trm_probe),
 3386: 	DEVMETHOD(device_attach,	trm_attach),
 3387: 	DEVMETHOD(device_detach,	trm_detach),
 3388: 	{ 0, 0 }
 3389: };
 3390: 
 3391: static driver_t trm_driver = {
 3392: 	"trm", trm_methods, sizeof(struct _ACB)
 3393: };
 3394: 
 3395: static devclass_t trm_devclass;
 3396: DRIVER_MODULE(trm, pci, trm_driver, trm_devclass, 0, 0);