Index: ObsoleteFiles.inc =================================================================== --- ObsoleteFiles.inc +++ ObsoleteFiles.inc @@ -38,6 +38,8 @@ # xargs -n1 | sort | uniq -d; # done +# 20191128: Removal of trm(4) +OLD_FILES+=usr/share/man/man4/trm.4.gz # 20191121: Removal of sio(4) OLD_FILES+=usr/share/man/man4/sio.4.gz # 20191105: picobsd(8), et al, removed. Index: share/man/man4/Makefile =================================================================== --- share/man/man4/Makefile +++ share/man/man4/Makefile @@ -522,7 +522,6 @@ ti.4 \ timecounters.4 \ ${_tpm.4} \ - trm.4 \ tty.4 \ tun.4 \ twa.4 \ Index: share/man/man4/trm.4 =================================================================== --- share/man/man4/trm.4 +++ /dev/null @@ -1,110 +0,0 @@ -.\" $NetBSD: trm.4,v 1.3 2001/11/11 05:24:45 tsutsui Exp $ -.\" -.\" Copyright (c) 2002, David E O'Brien. All rights reserved. -.\" Copyright (c) 2001, Izumi Tsutsui. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd December 8, 2002 -.Dt TRM 4 -.Os -.Sh NAME -.Nm trm -.Nd Tekram TRM-S1040 ASIC based PCI SCSI host adapter driver -.Sh SYNOPSIS -To compile this driver into the kernel, -place the following lines in your -kernel configuration file: -.Bd -ragged -offset indent -.Cd "device scbus" -.Cd "device trm" -.Ed -.Pp -Alternatively, to load the driver as a -module at boot time, place the following line in -.Xr loader.conf 5 : -.Bd -literal -offset indent -trm_load="YES" -.Ed -.Sh DEPRECATION NOTICE -This driver is scheduled for removal prior to the release of -.Fx 13.0 -.Sh DESCRIPTION -The -.Nm -driver supports PCI SCSI host adapters based on the Tekram TRM-S1040 SCSI ASIC. -.Sh HARDWARE -SCSI controllers supported by the -.Nm -driver include: -.Pp -.Bl -bullet -compact -.It -.Tn Tekram DC-315 -PCI Ultra SCSI adapter without BIOS and internal SCSI connector -.It -.Tn Tekram DC-315U -PCI Ultra SCSI adapter without BIOS -.It -.Tn Tekram DC-395F -PCI Ultra-Wide SCSI adapter with flash BIOS and 68-pin external SCSI connector -.It -.Tn Tekram DC-395U -PCI Ultra SCSI adapter with flash BIOS -.It -.Tn Tekram DC-395UW -PCI Ultra-Wide SCSI adapter with flash BIOS -.It -.Tn Tekram DC-395U2W -PCI Ultra2-Wide SCSI adapter with flash BIOS -.El -.Pp -For the Tekram DC-310/U and DC-390F/U/UW/U2B/U2W/U3W PCI SCSI host adapters, -use the -.Xr sym 4 -driver. -.Sh SEE ALSO -.Xr cd 4 , -.Xr ch 4 , -.Xr da 4 , -.Xr intro 4 , -.Xr sa 4 , -.Xr scsi 4 , -.Xr sym 4 -.Pp -.Pa http://www.tekram.com/ -.Sh AUTHORS -.An -nosplit -The -.Nm -driver was originally written for -.Fx 3.0 Ns /i386 -by -.An Erich Chen -of Tekram Technology, -and ported to -.Fx 5.0 -by -.An Olivier Houchard Aq Mt cognet@FreeBSD.org . Index: sys/amd64/conf/GENERIC =================================================================== --- sys/amd64/conf/GENERIC +++ sys/amd64/conf/GENERIC @@ -150,7 +150,6 @@ device mps # LSI-Logic MPT-Fusion 2 device mpr # LSI-Logic MPT-Fusion 3 device sym # NCR/Symbios Logic -device trm # Tekram DC395U/UW/F DC315U adapters device isci # Intel C600 SAS controller device ocs_fc # Emulex FC adapters device pvscsi # VMware PVSCSI Index: sys/conf/NOTES =================================================================== --- sys/conf/NOTES +++ sys/conf/NOTES @@ -1511,7 +1511,6 @@ # 53C810, 53C810A, 53C815, 53C825, 53C825A, 53C860, 53C875, # 53C876, 53C885, 53C895, 53C895A, 53C896, 53C897, 53C1510D, # 53C1010-33, 53C1010-66. -# trm: Tekram DC395U/UW/F DC315U adapters. device ahc device ahd @@ -1538,7 +1537,6 @@ device mps # LSI-Logic MPT-Fusion 2 device mpt # LSI-Logic MPT-Fusion device sym -device trm # The aic7xxx driver will attempt to use memory mapped I/O for all PCI # controllers that have it configured only if this option is set. Unfortunately, Index: sys/conf/files =================================================================== --- sys/conf/files +++ sys/conf/files @@ -3144,7 +3144,6 @@ dev/tdfx/tdfx_linux.c optional tdfx_linux tdfx compat_linux dev/tdfx/tdfx_pci.c optional tdfx pci dev/ti/if_ti.c optional ti pci -dev/trm/trm.c optional trm dev/twa/tw_cl_init.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_cl_intr.c optional twa \ Index: sys/dev/trm/trm.h =================================================================== --- sys/dev/trm/trm.h +++ sys/dev/trm/trm.h @@ -1,979 +0,0 @@ -/*- - * File Name : trm.h - * - * Tekram DC395U/UW/F ,DC315/U - * PCI SCSI Bus Master Host Adapter Device Driver - * (SCSI chip set used Tekram ASIC TRM-S1040) - * - * SPDX-License-Identifier: BSD-3-Clause - * - * (C)Copyright 1995-2001 Tekram Technology Co.,Ltd. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef trm_H -#define trm_H - -/* SCSI CAM */ - -#define TRM_TRANS_CUR 0x01 /* Modify current neogtiation status */ -#define TRM_TRANS_ACTIVE 0x03 /* Assume this is the active target */ -#define TRM_TRANS_GOAL 0x04 /* Modify negotiation goal */ -#define TRM_TRANS_USER 0x08 /* Modify user negotiation settings */ - -struct trm_transinfo { - u_int8_t width; - u_int8_t period; - u_int8_t offset; -}; - -struct trm_target_info { - u_int8_t disc_tag; /* bits define..... */ -#define TRM_CUR_DISCENB 0x01 /* current setting disconnect enable */ -#define TRM_CUR_TAGENB 0x02 /* current setting tag command Q enable */ -#define TRM_USR_DISCENB 0x04 /* user adapter device setting disconnect enable */ -#define TRM_USR_TAGENB 0x08 /* user adapter device setting tag command Q enable*/ - struct trm_transinfo current; /* info of current */ - struct trm_transinfo goal; /* info of after negotiating */ - struct trm_transinfo user; /* info of user adapter device setting */ -}; -/* - * SCSI CAM ** - */ - -/* - * bus_dma_segment_t - * - * Describes a single contiguous DMA transaction. Values - * are suitable for programming into DMA registers. - * - *typedef struct bus_dma_segment - *{ - * bus_addr_t ds_addr; // DMA address - * bus_size_t ds_len; // length of transfer - *} bus_dma_segment_t; - */ - -/*;----------------------Segment Entry------------------------------------*/ -typedef struct _SGentry { - u_int32_t address; - u_int32_t length; -} SGentry, *PSEG; -/* - *----------------------------------------------------------------------- - * feature of chip set MAX value - *----------------------------------------------------------------------- - */ - -#define TRM_MAX_ADAPTER_NUM 4 -#define TRM_MAX_DEVICES 16 -#define TRM_MAX_SG_LISTENTRY 32 -#define TRM_MAX_TARGETS 16 -#define TRM_MAX_TAGS_CMD_QUEUE 256 /* MAX_CMD_QUEUE 20*/ -#define TRM_MAX_CMD_PER_LUN 32 -#define TRM_MAX_SRB_CNT 256 -#define TRM_MAX_START_JOB 256 -#define TRM_MAXPHYS (128 * 1024) -#define TRM_NSEG (btoc(TRM_MAXPHYS) + 1) -#define TRM_MAXTRANSFER_SIZE 0xFFFFFF /* restricted by 24 bit counter */ -#define PAGELEN 4096 - -#define SEL_TIMEOUT 153 /* 250 ms selection timeout (@ 40MHz) */ - -/* - * CAM ccb - * Union of all CCB types for kernel space allocation. This union should - * never be used for manipulating CCBs - its only use is for the allocation - * and deallocation of raw CCB space and is the return type of xpt_ccb_alloc - * and the argument to xpt_ccb_free. - * - *union ccb { - * struct ccb_hdr ccb_h; // For convenience - * struct ccb_scsiio csio; - * struct ccb_getdev cgd; - * struct ccb_getdevlist cgdl; - * struct ccb_pathinq cpi; - * struct ccb_relsim crs; - * struct ccb_setasync csa; - * struct ccb_setdev csd; - * struct ccb_dev_match cdm; - * struct ccb_trans_settings cts; - * struct ccb_calc_geometry ccg; - * struct ccb_abort cab; - * struct ccb_resetbus crb; - * struct ccb_resetdev crd; - * struct ccb_termio tio; - * struct ccb_accept_tio atio; - * struct ccb_scsiio ctio; - * struct ccb_en_lun cel; - * struct ccb_immed_notify cin; - * struct ccb_notify_ack cna; - * struct ccb_eng_inq cei; - * struct ccb_eng_exec cee; - * struct ccb_rescan crcn; - * struct ccb_debug cdbg; - * }; - */ - -/* - *----------------------------------------------------------------------- - * SCSI Request Block - *----------------------------------------------------------------------- - */ -struct _SRB { - u_int8_t CmdBlock[12]; - u_long Segment0[2]; - u_long Segment1[2]; - struct _SRB *pNextSRB; - struct _DCB *pSRBDCB; - SGentry SgSenseTemp; - - PSEG pSRBSGL; /* scatter gather list */ - - u_int32_t SRBSGPhyAddr; /* a segment starting address */ - u_int32_t SRBTotalXferLength; - - /* - * CAM ccb - */ - union ccb *pccb; - bus_dmamap_t sg_dmamap; - bus_dmamap_t dmamap; - u_int16_t SRBState; - u_int8_t * pMsgPtr; - - u_int8_t SRBSGCount; - u_int8_t SRBSGIndex; - u_int8_t MsgInBuf[6]; - u_int8_t MsgOutBuf[6]; - - u_int8_t AdaptStatus; - u_int8_t TargetStatus; - u_int8_t MsgCnt; - u_int8_t TagNumber; - - u_int8_t SRBStatus; - u_int8_t RetryCnt; - u_int8_t SRBFlag; - u_int8_t ScsiCmdLen; - u_int8_t ScsiPhase; - u_int8_t Reserved[3]; /*;for dword alignment */ -}; -typedef struct _SRB TRM_SRB, *PSRB; - -/* - *----------------------------------------------------------------------- - * Device Control Block - *----------------------------------------------------------------------- - */ -struct _DCB -{ - PSRB pWaitingSRB; - PSRB pWaitingLastSRB; - - PSRB pGoingSRB; - PSRB pGoingLastSRB; - - PSRB pActiveSRB; - - u_int16_t GoingSRBCnt; - u_int16_t MaxActiveCommandCnt; - - u_int8_t TargetID; /*; SCSI Target ID (SCSI Only) */ - u_int8_t TargetLUN; /*; SCSI Log. Unit (SCSI Only) */ - u_int8_t DCBFlag; - u_int8_t DevType; - - u_int8_t SyncMode; /* mode ? (1 sync):(0 async) */ - u_int8_t MaxNegoPeriod; /* for nego. */ - u_int8_t SyncPeriod; /* for reg. */ - u_int8_t SyncOffset; /* for reg. and nego.(low nibble) */ - - u_int8_t DevMode; - u_int8_t AdpMode; - - u_int8_t IdentifyMsg; - u_int8_t DCBstatus; /* DCB status */ - /*u_int8_t Reserved[3]; for dword alignment */ - struct trm_target_info tinfo; /* 10 bytes */ - struct _DCB *pNextDCB; -}; -typedef struct _DCB TRM_DCB, *PDCB; - -/* - *----------------------------------------------------------------------- - * Adapter Control Block - *----------------------------------------------------------------------- - */ -struct _ACB -{ - device_t dev; - - bus_space_tag_t tag; - bus_space_handle_t bsh; - bus_dma_tag_t parent_dmat; - bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */ - bus_dma_tag_t srb_dmat; - bus_dma_tag_t sense_dmat; /* dmat for sense buffer */ - bus_dma_tag_t sg_dmat; - bus_dmamap_t sense_dmamap; - bus_dmamap_t srb_dmamap; - bus_addr_t sense_busaddr; - struct scsi_sense_data *sense_buffers; - struct resource *iores, *irq; - void *ih; - /* - * CAM SIM/XPT - */ - struct cam_sim *psim; - struct cam_path *ppath; - - TRM_SRB TmpSRB; - TRM_DCB DCBarray[16][8]; - - u_int32_t srb_physbase; - - PSRB pFreeSRB; - PDCB pActiveDCB; - - PDCB pLinkDCB; - PDCB pDCBRunRobin; - - u_int16_t max_id; - u_int16_t max_lun; - - u_int8_t msgin123[4]; - - u_int8_t scan_devices[16][8]; - - u_int8_t AdaptSCSIID; /*; Adapter SCSI Target ID */ - u_int8_t AdaptSCSILUN; /*; Adapter SCSI LUN */ - u_int8_t DeviceCnt; - u_int8_t ACBFlag; - - u_int8_t TagMaxNum; - u_int8_t Config; - u_int8_t AdaptType; - u_int8_t AdapterUnit; /* nth Adapter this driver */ -}; -typedef struct _ACB TRM_ACB, *PACB; -/* - * ----SRB State machine definition - */ -#define SRB_FREE 0x0000 -#define SRB_WAIT 0x0001 -#define SRB_READY 0x0002 -#define SRB_MSGOUT 0x0004 /*arbitration+msg_out 1st byte*/ -#define SRB_MSGIN 0x0008 -#define SRB_EXTEND_MSGIN 0x0010 -#define SRB_COMMAND 0x0020 -#define SRB_START_ 0x0040 /*arbitration+msg_out+command_out*/ -#define SRB_DISCONNECT 0x0080 -#define SRB_DATA_XFER 0x0100 -#define SRB_XFERPAD 0x0200 -#define SRB_STATUS 0x0400 -#define SRB_COMPLETED 0x0800 -#define SRB_ABORT_SENT 0x1000 -#define SRB_DO_SYNC_NEGO 0x2000 -#define SRB_DO_WIDE_NEGO 0x4000 -#define SRB_UNEXPECT_RESEL 0x8000 -/* - * - * ACB Config - * - */ -#define HCC_WIDE_CARD 0x20 -#define HCC_SCSI_RESET 0x10 -#define HCC_PARITY 0x08 -#define HCC_AUTOTERM 0x04 -#define HCC_LOW8TERM 0x02 -#define HCC_UP8TERM 0x01 -/* - * ---ACB Flag - */ -#define RESET_DEV 0x00000001 -#define RESET_DETECT 0x00000002 -#define RESET_DONE 0x00000004 - -/* - * ---DCB Flag - */ -#define ABORT_DEV_ 0x00000001 - -/* - * ---DCB status - */ -#define DS_IN_QUEUE 0x00000001 - -/* - * ---SRB status - */ -#define SRB_OK 0x00000001 -#define ABORTION 0x00000002 -#define OVER_RUN 0x00000004 -#define UNDER_RUN 0x00000008 -#define PARITY_ERROR 0x00000010 -#define SRB_ERROR 0x00000020 - -/* - * ---SRB Flag - */ -#define DATAOUT 0x00000080 -#define DATAIN 0x00000040 -#define RESIDUAL_VALID 0x00000020 -#define ENABLE_TIMER 0x00000010 -#define RESET_DEV0 0x00000004 -#define ABORT_DEV 0x00000002 -#define AUTO_REQSENSE 0x00000001 - -/* - * ---Adapter status - */ -#define H_STATUS_GOOD 0x00 -#define H_SEL_TIMEOUT 0x11 -#define H_OVER_UNDER_RUN 0x12 -#define H_UNEXP_BUS_FREE 0x13 -#define H_TARGET_PHASE_F 0x14 -#define H_INVALID_CCB_OP 0x16 -#define H_LINK_CCB_BAD 0x17 -#define H_BAD_TARGET_DIR 0x18 -#define H_DUPLICATE_CCB 0x19 -#define H_BAD_CCB_OR_SG 0x1A -#define H_ABORT 0x0FF - -/* - * ---SCSI Status byte codes - */ -#define SCSI_STAT_GOOD 0x00 /*; Good status */ -#define SCSI_STAT_CHECKCOND 0x02 /*; SCSI Check Condition */ -#define SCSI_STAT_CONDMET 0x04 /*; Condition Met */ -#define SCSI_STAT_BUSY 0x08 /*; Target busy status */ -#define SCSI_STAT_INTER 0x10 /*; Intermediate status */ -#define SCSI_STAT_INTERCONDMET 0x14 /*; Intermediate condition met */ -#define SCSI_STAT_RESCONFLICT 0x18 /*; Reservation conflict */ -#define SCSI_STAT_CMDTERM 0x22 /*; Command Terminated */ -#define SCSI_STAT_QUEUEFULL 0x28 /*; Queue Full */ -#define SCSI_STAT_UNEXP_BUS_F 0xFD /*; Unexpect Bus Free */ -#define SCSI_STAT_BUS_RST_DETECT 0xFE /*; Scsi Bus Reset detected */ -#define SCSI_STAT_SEL_TIMEOUT 0xFF /*; Selection Time out */ - -/* - * ---Sync_Mode - */ -#define SYNC_WIDE_TAG_ATNT_DISABLE 0x00000000 -#define SYNC_NEGO_ENABLE 0x00000001 -#define SYNC_NEGO_DONE 0x00000002 -#define WIDE_NEGO_ENABLE 0x00000004 -#define WIDE_NEGO_DONE 0x00000008 -#define EN_TAG_QUEUING 0x00000010 -#define EN_ATN_STOP 0x00000020 - -#define SYNC_NEGO_OFFSET 15 -/* - * ---SCSI bus phase - */ -#define SCSI_DATA_OUT_ 0 -#define SCSI_DATA_IN_ 1 -#define SCSI_COMMAND 2 -#define SCSI_STATUS_ 3 -#define SCSI_NOP0 4 -#define SCSI_NOP1 5 -#define SCSI_MSG_OUT 6 -#define SCSI_MSG_IN 7 - -/* - * ----SCSI MSG u_int8_t - */ -#define MSG_COMPLETE 0x00 -#define MSG_EXTENDED 0x01 -#define MSG_SAVE_PTR 0x02 -#define MSG_RESTORE_PTR 0x03 -#define MSG_DISCONNECT 0x04 -#define MSG_INITIATOR_ERROR 0x05 -#define MSG_ABORT 0x06 -#define MSG_REJECT_ 0x07 -#define MSG_NOP 0x08 -#define MSG_PARITY_ERROR 0x09 -#define MSG_LINK_CMD_COMPL 0x0A -#define MSG_LINK_CMD_COMPL_FLG 0x0B -#define MSG_BUS_RESET 0x0C -/* #define MSG_ABORT_TAG 0x0D */ -#define MSG_SIMPLE_QTAG 0x20 -#define MSG_HEAD_QTAG 0x21 -#define MSG_ORDER_QTAG 0x22 -#define MSG_IGNOREWIDE 0x23 -/* #define MSG_IDENTIFY 0x80 */ -#define MSG_HOST_ID 0xC0 -/* bus wide length */ -#define MSG_EXT_WDTR_BUS_8_BIT 0x00 -#define MSG_EXT_WDTR_BUS_16_BIT 0x01 -#define MSG_EXT_WDTR_BUS_32_BIT 0x02 -/* - * ----SCSI STATUS u_int8_t - */ -#define STATUS_GOOD 0x00 -#define CHECK_CONDITION_ 0x02 -#define STATUS_BUSY 0x08 -#define STATUS_INTERMEDIATE 0x10 -#define RESERVE_CONFLICT 0x18 - -/* - * ---- cmd->result - */ -#define STATUS_MASK_ 0xFF -#define MSG_MASK 0xFF00 -#define RETURN_MASK 0xFF0000 - -/* - * Inquiry Data format - */ - -typedef struct _SCSIInqData { /* INQ */ - - u_int8_t DevType; /* Periph Qualifier & Periph Dev Type */ - u_int8_t RMB_TypeMod; /* rem media bit & Dev Type Modifier */ - u_int8_t Vers; /* ISO, ECMA, & ANSI versions */ - u_int8_t RDF; /* AEN, TRMIOP, & response data format*/ - u_int8_t AddLen; /* length of additional data */ - u_int8_t Res1; /* reserved */ - u_int8_t Res2; /* reserved */ - u_int8_t Flags; /* RelADr,Wbus32,Wbus16,Sync,etc. */ - u_int8_t VendorID[8]; /* Vendor Identification */ - u_int8_t ProductID[16]; /* Product Identification */ - u_int8_t ProductRev[4]; /* Product Revision */ -} SCSI_INQDATA, *PSCSI_INQDATA; - - -/* - * Inquiry byte 0 masks - */ -#define SCSI_DEVTYPE 0x1F /* Peripheral Device Type */ -#define SCSI_PERIPHQUAL 0xE0 /* Peripheral Qualifier */ -/* - * Inquiry byte 1 mask - */ -#define SCSI_REMOVABLE_MEDIA 0x80 /* Removable Media bit (1=removable) */ -/* - * Peripheral Device Type definitions - */ -#define SCSI_DASD 0x00 /* Direct-access Device */ -#define SCSI_SEQACESS 0x01 /* Sequential-access device */ -#define SCSI_PRINTER 0x02 /* Printer device */ -#define SCSI_PROCESSOR 0x03 /* Processor device */ -#define SCSI_WRITEONCE 0x04 /* Write-once device */ -#define SCSI_CDROM 0x05 /* CD-ROM device */ -#define SCSI_SCANNER 0x06 /* Scanner device */ -#define SCSI_OPTICAL 0x07 /* Optical memory device */ -#define SCSI_MEDCHGR 0x08 /* Medium changer device */ -#define SCSI_COMM 0x09 /* Communications device */ -#define SCSI_NODEV 0x1F /* Unknown or no device type */ -/* - * Inquiry flag definitions (Inq data byte 7) - */ -#define SCSI_INQ_RELADR 0x80 /* device supports relative addressing*/ -#define SCSI_INQ_WBUS32 0x40 /* device supports 32 bit data xfers */ -#define SCSI_INQ_WBUS16 0x20 /* device supports 16 bit data xfers */ -#define SCSI_INQ_SYNC 0x10 /* device supports synchronous xfer */ -#define SCSI_INQ_LINKED 0x08 /* device supports linked commands */ -#define SCSI_INQ_CMDQUEUE 0x02 /* device supports command queueing */ -#define SCSI_INQ_SFTRE 0x01 /* device supports soft resets */ -/* - *========================================================== - * EEPROM byte offset - *========================================================== - */ -typedef struct _EEprom { - u_int8_t EE_MODE1; - u_int8_t EE_SPEED; - u_int8_t xx1; - u_int8_t xx2; -} EEprom, *PEEprom; - -#define EE_ADAPT_SCSI_ID 64 -#define EE_MODE2 65 -#define EE_DELAY 66 -#define EE_TAG_CMD_NUM 67 - -/* - * EE_MODE1 bits definition - */ -#define PARITY_CHK_ 0x00000001 -#define SYNC_NEGO_ 0x00000002 -#define EN_DISCONNECT_ 0x00000004 -#define SEND_START_ 0x00000008 -#define TAG_QUEUING_ 0x00000010 - -/* - * EE_MODE2 bits definition - */ -#define MORE2_DRV 0x00000001 -#define GREATER_1G 0x00000002 -#define RST_SCSI_BUS 0x00000004 -#define ACTIVE_NEGATION 0x00000008 -#define NO_SEEK 0x00000010 -#define LUN_CHECK 0x00000020 - -#define ENABLE_CE 0x01 -#define DISABLE_CE 0x00 -#define EEPROM_READ 0x80 - -/* - * The PCI configuration register offset for TRM_S1040 - * Registers bit Definition - */ -#define TRMREG_ID 0x00 /* Vendor and Device ID */ -#define TRMREG_COMMAND 0x04 /* PCI command register */ -#define TRMREG_IOBASE 0x10 /* I/O Space base address */ -#define TRMREG_ROMBASE 0x30 /* Expansion ROM Base Address */ -#define TRMREG_INTLINE 0x3C /* Interrupt line */ - -/* - * - * The SCSI register offset for TRM_S1040 - * - */ -#define TRMREG_SCSI_STATUS 0x80 /* SCSI Status (R) */ -/* ######### */ -#define COMMANDPHASEDONE 0x2000 /* SCSI command phase done */ -#define SCSIXFERDONE 0x0800 /* SCSI SCSI transfer done */ -#define SCSIXFERCNT_2_ZERO 0x0100 /* SCSI SCSI transfer count to zero*/ -#define SCSIINTERRUPT 0x0080 /* SCSI interrupt pending */ -#define COMMANDABORT 0x0040 /* SCSI command abort */ -#define SEQUENCERACTIVE 0x0020 /* SCSI sequencer active */ -#define PHASEMISMATCH 0x0010 /* SCSI phase mismatch */ -#define PARITYERROR 0x0008 /* SCSI parity error */ - -#define PHASEMASK 0x0007 /* Phase MSG/CD/IO */ -#define PH_DATA_OUT 0x00 /* Data out phase */ -#define PH_DATA_IN 0x01 /* Data in phase */ -#define PH_COMMAND 0x02 /* Command phase */ -#define PH_STATUS 0x03 /* Status phase */ -#define PH_BUS_FREE 0x05 /* Invalid phase used as bus free */ -#define PH_MSG_OUT 0x06 /* Message out phase */ -#define PH_MSG_IN 0x07 /* Message in phase */ - -#define TRMREG_SCSI_CONTROL 0x80 /* SCSI Control (W) */ -/* ######### */ -#define DO_CLRATN 0x0400 /* Clear ATN */ -#define DO_SETATN 0x0200 /* Set ATN */ -#define DO_CMDABORT 0x0100 /* Abort SCSI command */ -#define DO_RSTMODULE 0x0010 /* Reset SCSI chip */ -#define DO_RSTSCSI 0x0008 /* Reset SCSI bus */ -#define DO_CLRFIFO 0x0004 /* Clear SCSI transfer FIFO */ -#define DO_DATALATCH 0x0002 /* Enable SCSI bus data latch */ -#define DO_HWRESELECT 0x0001 /* Enable hardware reselection */ -#define TRMREG_SCSI_FIFOCNT 0x82 /* SCSI FIFO Counter 5bits(R) */ -#define TRMREG_SCSI_SIGNAL 0x83 /* SCSI low level signal (R/W) */ -#define TRMREG_SCSI_INTSTATUS 0x84 /* SCSI Interrupt Status (R) */ -/* ######### */ -#define INT_SCAM 0x80 /* SCAM selection interrupt */ -#define INT_SELECT 0x40 /* Selection interrupt */ -#define INT_SELTIMEOUT 0x20 /* Selection timeout interrupt */ -#define INT_DISCONNECT 0x10 /* Bus disconnected interrupt */ -#define INT_RESELECTED 0x08 /* Reselected interrupt */ -#define INT_SCSIRESET 0x04 /* SCSI reset detected interrupt*/ -#define INT_BUSSERVICE 0x02 /* Bus service interrupt */ -#define INT_CMDDONE 0x01 /* SCSI command done interrupt */ -#define TRMREG_SCSI_OFFSET 0x84 /* SCSI Offset Count (W) */ -/* - * Bit Name Definition - * 07-05 0 RSVD Reversed. Always 0. - * 04 0 OFFSET4 Reversed for LVDS. Always 0. - * 03-00 0 OFFSET[03:00] Offset number from 0 to 15 - */ -#define TRMREG_SCSI_SYNC 0x85 /* SCSI Synchronous Control (R/W)*/ -/* ######### */ -#define LVDS_SYNC 0x20 /* Enable LVDS synchronous */ -#define WIDE_SYNC 0x10 /* Enable WIDE synchronous */ -#define ALT_SYNC 0x08 /* Enable Fast-20 alternate synchronous */ -/* - * SYNCM 7 6 5 4 3 2 1 0 - * Name RSVD RSVD LVDS WIDE ALTPERD PERIOD2 PERIOD1 PERIOD0 - * Default 0 0 0 0 0 0 0 0 - * - * - * Bit Name Definition - * 07-06 0 RSVD Reversed. Always read 0 - * 05 0 LVDS Reversed. Always read 0 - * 04 0 WIDE/WSCSI Enable wide (16-bits) SCSI transfer. - * 03 0 ALTPERD/ALTPD Alternate (Sync./Period) mode. - * - * @@ When this bit is set, - * the synchronous period bits 2:0 - * in the Synchronous Mode register - * are used to transfer data - * at the Fast-20 rate. - * @@ When this bit is reset, - * the synchronous period bits 2:0 - * in the Synchronous Mode Register - * are used to transfer data - * at the Fast-40 rate. - * - * 02-00 0 PERIOD[2:0]/SXPD[02:00] Synchronous SCSI Transfer Rate. - * These 3 bits specify - * the Synchronous SCSI Transfer Rate - * for Fast-20 and Fast-10. - * These bits are also reset - * by a SCSI Bus reset. - * - * For Fast-10 bit ALTPD = 0 and LVDS = 0 - * and 0x00000004,0x00000002,0x00000001 is defined as follows : - * - * 000 100ns, 10.0 Mbytes/s - * 001 150ns, 6.6 Mbytes/s - * 010 200ns, 5.0 Mbytes/s - * 011 250ns, 4.0 Mbytes/s - * 100 300ns, 3.3 Mbytes/s - * 101 350ns, 2.8 Mbytes/s - * 110 400ns, 2.5 Mbytes/s - * 111 450ns, 2.2 Mbytes/s - * - * For Fast-20 bit ALTPD = 1 and LVDS = 0 - * and 0x00000004,0x00000002,0x00000001 is defined as follows : - * - * 000 50ns, 20.0 Mbytes/s - * 001 75ns, 13.3 Mbytes/s - * 010 100ns, 10.0 Mbytes/s - * 011 125ns, 8.0 Mbytes/s - * 100 150ns, 6.6 Mbytes/s - * 101 175ns, 5.7 Mbytes/s - * 110 200ns, 5.0 Mbytes/s - * 111 250ns, 4.0 Mbytes/s - * - * For Fast-40 bit ALTPD = 0 and LVDS = 1 - * and 0x00000004,0x00000002,0x00000001 is defined as follows : - * - * 000 25ns, 40.0 Mbytes/s - * 001 50ns, 20.0 Mbytes/s - * 010 75ns, 13.3 Mbytes/s - * 011 100ns, 10.0 Mbytes/s - * 100 125ns, 8.0 Mbytes/s - * 101 150ns, 6.6 Mbytes/s - * 110 175ns, 5.7 Mbytes/s - * 111 200ns, 5.0 Mbytes/s - */ - -/* - *************************************** - */ -#define TRMREG_SCSI_TARGETID 0x86 /* SCSI Target ID (R/W) */ -/* - *************************************** - */ -#define TRMREG_SCSI_IDMSG 0x87 /* SCSI Identify Message (R) */ -/* - *************************************** - */ -#define TRMREG_SCSI_HOSTID 0x87 /* SCSI Host ID (W) */ -/* - *************************************** - */ -#define TRMREG_SCSI_COUNTER 0x88 /* SCSI Transfer Counter 24bits(R/W)*/ -/* - *************************************** - */ -#define TRMREG_SCSI_INTEN 0x8C /* SCSI Interrupt Enable (R/W) */ -/* ######### */ -#define EN_SCAM 0x80 /* Enable SCAM selection interrupt*/ -#define EN_SELECT 0x40 /* Enable selection interrupt */ -#define EN_SELTIMEOUT 0x20 /* Enable selection timeout interrupt*/ -#define EN_DISCONNECT 0x10 /* Enable bus disconnected interrupt*/ -#define EN_RESELECTED 0x08 /* Enable reselected interrupt */ -#define EN_SCSIRESET 0x04 /* Enable SCSI reset detected interrupt*/ -#define EN_BUSSERVICE 0x02 /* Enable bus service interrupt */ -#define EN_CMDDONE 0x01 /* Enable SCSI command done interrupt*/ -/* - *************************************** - */ -#define TRMREG_SCSI_CONFIG0 0x8D /* SCSI Configuration 0 (R/W) */ -/* ######### */ -#define PHASELATCH 0x40 /* Enable phase latch */ -#define INITIATOR 0x20 /* Enable initiator mode */ -#define PARITYCHECK 0x10 /* Enable parity check */ -#define BLOCKRST 0x01 /* Disable SCSI reset1 */ -/* - *************************************** - */ -#define TRMREG_SCSI_CONFIG1 0x8E /* SCSI Configuration 1 (R/W) */ -/* ######### */ -#define ACTIVE_NEGPLUS 0x10 /* Enhance active negation */ -#define FILTER_DISABLE 0x08 /* Disable SCSI data filter */ -#define ACTIVE_NEG 0x02 /* Enable active negation */ -#define ACTIVE_HISLEW 0x01 /* Enable high slew rate (3/6 ns) */ -/* - *************************************** - */ -#define TRMREG_SCSI_CONFIG2 0x8F /* SCSI Configuration 2 (R/W) */ -/* - *************************************** - */ -#define TRMREG_SCSI_COMMAND 0x90 /* SCSI Command (R/W) */ -/* ######### */ -#define SCMD_COMP 0x12 /* Command complete */ -#define SCMD_SEL_ATN 0x60 /* Selection with ATN */ -#define SCMD_SEL_ATN3 0x64 /* Selection with ATN3 */ -#define SCMD_SEL_ATNSTOP 0xB8 /* Selection with ATN and Stop */ -#define SCMD_FIFO_OUT 0xC0 /* SCSI FIFO transfer out */ -#define SCMD_DMA_OUT 0xC1 /* SCSI DMA transfer out */ -#define SCMD_FIFO_IN 0xC2 /* SCSI FIFO transfer in */ -#define SCMD_DMA_IN 0xC3 /* SCSI DMA transfer in */ -#define SCMD_MSGACCEPT 0xD8 /* Message accept */ -/* - * Code Command Description - * - * 02 Enable reselection with FIFO - * 40 Select without ATN with FIFO - * 60 Select with ATN with FIFO - * 64 Select with ATN3 with FIFO - * A0 Select with ATN and stop with FIFO - * C0 Transfer information out with FIFO - * C1 Transfer information out with DMA - * C2 Transfer information in with FIFO - * C3 Transfer information in with DMA - * 12 Initiator command complete with FIFO - * 50 Initiator transfer information out sequence without ATN with FIFO - * 70 Initiator transfer information out sequence with ATN with FIFO - * 74 Initiator transfer information out sequence with ATN3 with FIFO - * 52 Initiator transfer information in sequence without ATN with FIFO - * 72 Initiator transfer information in sequence with ATN with FIFO - * 76 Initiator transfer information in sequence with ATN3 with FIFO - * 90 Initiator transfer information out command complete with FIFO - * 92 Initiator transfer information in command complete with FIFO - * D2 Enable selection - * 08 Reselection - * 48 Disconnect command with FIFO - * 88 Terminate command with FIFO - * C8 Target command complete with FIFO - * 18 SCAM Arbitration/ Selection - * 5A Enable reselection - * 98 Select without ATN with FIFO - * B8 Select with ATN with FIFO - * D8 Message Accepted - * 58 NOP - */ -/* - *************************************** - */ -#define TRMREG_SCSI_TIMEOUT 0x91 /* SCSI Time Out Value (R/W) */ -/* - *************************************** - */ -#define TRMREG_SCSI_FIFO 0x98 /* SCSI FIFO (R/W) */ -/* - *************************************** - */ -#define TRMREG_SCSI_TCR00 0x9C /* SCSI Target Control 0 (R/W) */ -/* ######### */ -#define TCR0_DO_WIDE_NEGO 0x80 /* Do wide NEGO */ -#define TCR0_DO_SYNC_NEGO 0x40 /* Do sync NEGO */ -#define TCR0_DISCONNECT_EN 0x20 /* Disconnection enable */ -#define TCR0_OFFSET_MASK 0x1F /* Offset number */ -/* - *************************************** - */ -#define TRMREG_SCSI_TCR01 0x9D /* SCSI Target Control 0 (R/W) */ -/* ######### */ -#define TCR0_ENABLE_LVDS 0xF8 /* LVD */ -#define TCR0_ENABLE_WIDE 0xF9 /* SE */ -/* -**************************************** -*/ - -/* - *************************************** - */ -#define TRMREG_SCSI_TCR1 0x9E /* SCSI Target Control 1 (R/W) */ -/* ######### */ -#define MAXTAG_MASK 0x7F00 /* Maximum tags (127) */ -#define NON_TAG_BUSY 0x0080 /* Non tag command active */ -#define ACTTAG_MASK 0x007F /* Active tags */ -/* - * - * The DMA register offset for TRM_S1040 - * - */ -#define TRMREG_DMA_COMMAND 0xA0 /* DMA Command (R/W) */ -/* ######### */ -#define XFERDATAIN 0x0103 /* Transfer data in */ -#define XFERDATAOUT 0x0102 /* Transfer data out */ -/* - *************************************** - */ -#define TRMREG_DMA_FIFOCNT 0xA1 /* DMA FIFO Counter (R) */ -/* - *************************************** - */ -#define TRMREG_DMA_CONTROL 0xA1 /* DMA Control (W) */ -/* ######### */ -#define STOPDMAXFER 0x08 /* Stop DMA transfer */ -#define ABORTXFER 0x04 /* Abort DMA transfer */ -#define CLRXFIFO 0x02 /* Clear DMA transfer FIFO */ -#define STARTDMAXFER 0x01 /* Start DMA transfer */ -/* - *************************************** - */ -#define TRMREG_DMA_STATUS 0xA3 /* DMA Interrupt Status (R/W) */ -/* ######### */ -#define XFERPENDING 0x80 /* Transfer pending */ -#define DMAXFERCOMP 0x02 /* Bus Master XFER Complete status */ -#define SCSICOMP 0x01 /* SCSI complete interrupt */ -/* - *************************************** - */ -#define TRMREG_DMA_INTEN 0xA4 /* DMA Interrupt Enable (R/W)*/ -/* ######### */ -#define EN_SCSIINTR 0x01 /* Enable SCSI complete interrupt */ -/* - *************************************** - */ -#define TRMREG_DMA_CONFIG 0xA6 /* DMA Configuration (R/W) */ -/* ######### */ -#define DMA_ENHANCE 0x8000 /* Enable DMA enhance feature */ -/* - *************************************** - */ -#define TRMREG_DMA_XCNT 0xA8 /* DMA Transfer Counter (R/W)*/ -/* - *************************************** - */ -#define TRMREG_DMA_CXCNT 0xAC /* DMA Current Transfer Counter (R) */ -/* - *************************************** - */ -#define TRMREG_DMA_XLOWADDR 0xB0 /* DMA Transfer Physical Low Address */ -/* - *************************************** - */ -#define TRMREG_DMA_XHIGHADDR 0xB4 /* DMA Transfer Physical High Address */ - -/* - * - * The general register offset for TRM_S1040 - * - */ -#define TRMREG_GEN_CONTROL 0xD4 /* Global Control */ -/* ######### */ -#define EN_EEPROM 0x10 /* Enable EEPROM programming */ -#define AUTOTERM 0x04 /* Enable Auto SCSI terminator */ -#define LOW8TERM 0x02 /* Enable Lower 8 bit SCSI terminator */ -#define UP8TERM 0x01 /* Enable Upper 8 bit SCSI terminator */ -/* - *************************************** - */ -#define TRMREG_GEN_STATUS 0xD5 /* Global Status */ -/* ######### */ -#define GTIMEOUT 0x80 /* Global timer reach 0 */ -#define CON5068 0x10 /* External 50/68 pin connected */ -#define CON68 0x08 /* Internal 68 pin connected */ -#define CON50 0x04 /* Internal 50 pin connected */ -#define WIDESCSI 0x02 /* Wide SCSI card */ -/* - *************************************** - */ -#define TRMREG_GEN_NVRAM 0xD6 /* Serial NON-VOLATILE RAM port */ -/* ######### */ -#define NVR_BITOUT 0x08 /* Serial data out */ -#define NVR_BITIN 0x04 /* Serial data in */ -#define NVR_CLOCK 0x02 /* Serial clock */ -#define NVR_SELECT 0x01 /* Serial select */ -/* - *************************************** - */ -#define TRMREG_GEN_EDATA 0xD7 /* Parallel EEPROM data port */ -/* - *************************************** - */ -#define TRMREG_GEN_EADDRESS 0xD8 /* Parallel EEPROM address */ -/* - *************************************** - */ -#define TRMREG_GEN_TIMER 0xDB /* Global timer */ - -/* - * The SEEPROM structure for TRM_S1040 - */ -typedef struct NVRAM_TARGET_STRUCT -{ - u_int8_t NvmTarCfg0; /* Target configuration byte 0 */ - u_int8_t NvmTarPeriod; /* Target period */ - u_int8_t NvmTarCfg2; /* Target configuration byte 2 */ - u_int8_t NvmTarCfg3; /* Target configuration byte 3 */ -} NVRAMTARGETTYPE; -/* NvmTarCfg0: Target configuration byte 0 :..pDCB->DevMode */ -#define NTC_DO_WIDE_NEGO 0x20 /* Wide negotiate */ -#define NTC_DO_TAG_QUEUING 0x10 /* Enable SCSI tag queuing */ -#define NTC_DO_SEND_START 0x08 /* Send start command SPINUP*/ -#define NTC_DO_DISCONNECT 0x04 /* Enable SCSI disconnect */ -#define NTC_DO_SYNC_NEGO 0x02 /* Sync negotiation */ -#define NTC_DO_PARITY_CHK 0x01 /* (it should define at NAC ) - Parity check enable */ - -/* - * - * - * - */ -typedef struct NVRAM_STRUC { - u_int8_t NvramSubVendorID[2]; /*0,1 Sub Vendor ID */ - u_int8_t NvramSubSysID[2]; /*2,3 Sub System ID*/ - u_int8_t NvramSubClass; /*4 Sub Class */ - u_int8_t NvramVendorID[2]; /*5,6 Vendor ID */ - u_int8_t NvramDeviceID[2]; /*7,8 Device ID */ - u_int8_t NvramReserved; /*9 Reserved */ - NVRAMTARGETTYPE NvramTarget[TRM_MAX_TARGETS];/* *10,11,12,13 - *14,15,16,17 * .... - * .... - *70,71,72,73 - */ - u_int8_t NvramScsiId; /*74 Host Adapter SCSI ID */ - u_int8_t NvramChannelCfg; /*75 Channel configuration */ - u_int8_t NvramDelayTime; /*76 Power on delay time */ - u_int8_t NvramMaxTag; /*77 Maximum tags */ - u_int8_t NvramReserved0; /*78 */ - u_int8_t NvramBootTarget; /*79 */ - u_int8_t NvramBootLun; /*80 */ - u_int8_t NvramReserved1; /*81 */ - u_int16_t Reserved[22]; /*82,..125 */ - u_int16_t NvramCheckSum; /*126,127*/ -} NVRAMTYPE,*PNVRAMTYPE; -/* Nvram Initiater bits definition */ -#define MORE2_DRV 0x00000001 -#define GREATER_1G 0x00000002 -#define RST_SCSI_BUS 0x00000004 -#define ACTIVE_NEGATION 0x00000008 -#define NO_SEEK 0x00000010 -#define LUN_CHECK 0x00000020 - -/* Nvram Adapter NvramChannelCfg bits definition */ -#define NAC_SCANLUN 0x20 /* Include LUN as BIOS device*/ -#define NAC_POWERON_SCSI_RESET 0x04 /* Power on reset enable */ -#define NAC_GREATER_1G 0x02 /* > 1G support enable */ -#define NAC_GT2DRIVES 0x01 /* Support more than 2 drives*/ -/* - *#define NAC_DO_PARITY_CHK 0x08 // Parity check enable - */ - -#endif /* trm_H */ Index: sys/dev/trm/trm.c =================================================================== --- sys/dev/trm/trm.c +++ sys/dev/trm/trm.c @@ -1,3563 +0,0 @@ -/* - * O.S : FreeBSD CAM - * FILE NAME : trm.c - * BY : C.L. Huang (ching@tekram.com.tw) - * Erich Chen (erich@tekram.com.tw) - * Description: Device Driver for Tekram SCSI adapters - * DC395U/UW/F ,DC315/U(TRM-S1040) - * DC395U2D/U2W(TRM-S2080) - * PCI SCSI Bus Master Host Adapter - * (SCSI chip set used Tekram ASIC TRM-S1040,TRM-S2080) - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * HISTORY: - * - * REV# DATE NAME DESCRIPTION - * 1.05 05/01/1999 ERICH CHEN First released for 3.x.x (CAM) - * 1.06 07/29/1999 ERICH CHEN Modify for NEW PCI - * 1.07 12/12/1999 ERICH CHEN Modify for 3.3.x ,DCB no free - * 1.08 06/12/2000 ERICH CHEN Modify for 4.x.x - * 1.09 11/03/2000 ERICH CHEN Modify for 4.1.R ,new sim - * 1.10 10/10/2001 Oscar Feng Fixed CAM rescan hang up bug. - * 1.11 10/13/2001 Oscar Feng Fixed wrong Async speed display bug. - */ - -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * (C)Copyright 1995-2001 Tekram Technology Co.,Ltd. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * Imported into FreeBSD source repository, and updated to compile under - * FreeBSD-3.0-DEVELOPMENT, by Stefan Esser , 1996-12-17 - */ - -/* - * Updated to compile under FreeBSD 5.0-CURRENT by Olivier Houchard - * , 2002-03-04 - */ - -#include - -#include -#include -#include -#if __FreeBSD_version >= 500000 -#include -#endif -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#define trm_reg_read8(reg) bus_space_read_1(pACB->tag, pACB->bsh, reg) -#define trm_reg_read16(reg) bus_space_read_2(pACB->tag, pACB->bsh, reg) -#define trm_reg_read32(reg) bus_space_read_4(pACB->tag, pACB->bsh, reg) -#define trm_reg_write8(value,reg) bus_space_write_1(pACB->tag, pACB->bsh,\ - reg, value) -#define trm_reg_write16(value,reg) bus_space_write_2(pACB->tag, pACB->bsh,\ - reg, value) -#define trm_reg_write32(value,reg) bus_space_write_4(pACB->tag, pACB->bsh,\ - reg, value) - -#define PCI_Vendor_ID_TEKRAM 0x1DE1 -#define PCI_Device_ID_TRM_S1040 0x0391 -#define PCI_DEVICEID_TRMS1040 0x03911DE1 -#define PCI_DEVICEID_TRMS2080 0x03921DE1 - -#ifdef trm_DEBUG1 -#define TRM_DPRINTF(fmt, arg...) printf("trm: " fmt, ##arg) -#else -#define TRM_DPRINTF(fmt, arg...) {} -#endif /* TRM_DEBUG */ - -static void trm_check_eeprom(PNVRAMTYPE pEEpromBuf,PACB pACB); -static void NVRAM_trm_read_all(PNVRAMTYPE pEEpromBuf,PACB pACB); -static u_int8_t NVRAM_trm_get_data(PACB pACB, u_int8_t bAddr); -static void NVRAM_trm_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB); -static void NVRAM_trm_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData); -static void NVRAM_trm_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr); -static void NVRAM_trm_wait_30us(PACB pACB); - -static void trm_Interrupt(void *vpACB); -static void trm_DataOutPhase0(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_DataInPhase0(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_CommandPhase0(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_StatusPhase0(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_MsgOutPhase0(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_MsgInPhase0(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_DataOutPhase1(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_DataInPhase1(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_CommandPhase1(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_StatusPhase1(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_MsgOutPhase1(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_MsgInPhase1(PACB pACB, PSRB pSRB, - u_int16_t * pscsi_status); -static void trm_Nop0(PACB pACB, PSRB pSRB, u_int16_t * pscsi_status); -static void trm_Nop1(PACB pACB, PSRB pSRB, u_int16_t * pscsi_status); -static void trm_SetXferRate(PACB pACB, PSRB pSRB,PDCB pDCB); -static void trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir); -static void trm_Disconnect(PACB pACB); -static void trm_Reselect(PACB pACB); -static void trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB); -static void trm_DoingSRB_Done(PACB pACB); -static void trm_ScsiRstDetect(PACB pACB); -static void trm_ResetSCSIBus(PACB pACB); -static void trm_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB); -static void trm_EnableMsgOutAbort2(PACB pACB, PSRB pSRB); -static void trm_EnableMsgOutAbort1(PACB pACB, PSRB pSRB); -static void trm_SendSRB(PACB pACB, PSRB pSRB); -static int trm_probe(device_t tag); -static int trm_attach(device_t tag); -static void trm_reset(PACB pACB); - -static u_int16_t trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB); - -static int trm_initAdapter(PACB pACB, u_int16_t unit); -static void trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit, - u_int32_t i, u_int32_t j); -static int trm_initSRB(PACB pACB); -static void trm_initACB(PACB pACB, u_int8_t adaptType, u_int16_t unit); -/* CAM SIM entry points */ -#define ccb_trmsrb_ptr spriv_ptr0 -#define ccb_trmacb_ptr spriv_ptr1 -static void trm_action(struct cam_sim *psim, union ccb *pccb); -static void trm_poll(struct cam_sim *psim); - - -static void * trm_SCSI_phase0[] = { - trm_DataOutPhase0, /* phase:0 */ - trm_DataInPhase0, /* phase:1 */ - trm_CommandPhase0, /* phase:2 */ - trm_StatusPhase0, /* phase:3 */ - trm_Nop0, /* phase:4 */ - trm_Nop1, /* phase:5 */ - trm_MsgOutPhase0, /* phase:6 */ - trm_MsgInPhase0, /* phase:7 */ -}; - -/* - * - * stateV = (void *) trm_SCSI_phase1[phase] - * - */ -static void * trm_SCSI_phase1[] = { - trm_DataOutPhase1, /* phase:0 */ - trm_DataInPhase1, /* phase:1 */ - trm_CommandPhase1, /* phase:2 */ - trm_StatusPhase1, /* phase:3 */ - trm_Nop0, /* phase:4 */ - trm_Nop1, /* phase:5 */ - trm_MsgOutPhase1, /* phase:6 */ - trm_MsgInPhase1, /* phase:7 */ -}; - - -NVRAMTYPE trm_eepromBuf[TRM_MAX_ADAPTER_NUM]; -/* - *Fast20: 000 50ns, 20.0 Mbytes/s - * 001 75ns, 13.3 Mbytes/s - * 010 100ns, 10.0 Mbytes/s - * 011 125ns, 8.0 Mbytes/s - * 100 150ns, 6.6 Mbytes/s - * 101 175ns, 5.7 Mbytes/s - * 110 200ns, 5.0 Mbytes/s - * 111 250ns, 4.0 Mbytes/s - * - *Fast40: 000 25ns, 40.0 Mbytes/s - * 001 50ns, 20.0 Mbytes/s - * 010 75ns, 13.3 Mbytes/s - * 011 100ns, 10.0 Mbytes/s - * 100 125ns, 8.0 Mbytes/s - * 101 150ns, 6.6 Mbytes/s - * 110 175ns, 5.7 Mbytes/s - * 111 200ns, 5.0 Mbytes/s - */ - /* real period: */ -u_int8_t dc395x_clock_period[] = { - 12,/* 48 ns 20 MB/sec */ - 18,/* 72 ns 13.3 MB/sec */ - 25,/* 100 ns 10.0 MB/sec */ - 31,/* 124 ns 8.0 MB/sec */ - 37,/* 148 ns 6.6 MB/sec */ - 43,/* 172 ns 5.7 MB/sec */ - 50,/* 200 ns 5.0 MB/sec */ - 62 /* 248 ns 4.0 MB/sec */ -}; - -u_int8_t dc395u2x_clock_period[]={ - 10,/* 25 ns 40.0 MB/sec */ - 12,/* 48 ns 20.0 MB/sec */ - 18,/* 72 ns 13.3 MB/sec */ - 25,/* 100 ns 10.0 MB/sec */ - 31,/* 124 ns 8.0 MB/sec */ - 37,/* 148 ns 6.6 MB/sec */ - 43,/* 172 ns 5.7 MB/sec */ - 50,/* 200 ns 5.0 MB/sec */ -}; - -#define dc395x_tinfo_period dc395x_clock_period -#define dc395u2x_tinfo_period dc395u2x_clock_period - -static PSRB -trm_GetSRB(PACB pACB) -{ - int intflag; - PSRB pSRB; - - intflag = splcam(); - pSRB = pACB->pFreeSRB; - if (pSRB) { - pACB->pFreeSRB = pSRB->pNextSRB; - pSRB->pNextSRB = NULL; - } - splx(intflag); - return (pSRB); -} - -static void -trm_RewaitSRB0(PDCB pDCB, PSRB pSRB) -{ - PSRB psrb1; - int intflag; - - intflag = splcam(); - if ((psrb1 = pDCB->pWaitingSRB)) { - pSRB->pNextSRB = psrb1; - pDCB->pWaitingSRB = pSRB; - } else { - pSRB->pNextSRB = NULL; - pDCB->pWaitingSRB = pSRB; - pDCB->pWaitingLastSRB = pSRB; - } - splx(intflag); -} - -static void -trm_RewaitSRB(PDCB pDCB, PSRB pSRB) -{ - PSRB psrb1; - int intflag; - - intflag = splcam(); - pDCB->GoingSRBCnt--; - psrb1 = pDCB->pGoingSRB; - if (pSRB == psrb1) - /* - * if this SRB is GoingSRB - * remove this SRB from GoingSRB Q - */ - pDCB->pGoingSRB = psrb1->pNextSRB; - else { - /* - * if this SRB is not current GoingSRB - * remove this SRB from GoingSRB Q - */ - while (pSRB != psrb1->pNextSRB) - psrb1 = psrb1->pNextSRB; - psrb1->pNextSRB = pSRB->pNextSRB; - if (pSRB == pDCB->pGoingLastSRB) - pDCB->pGoingLastSRB = psrb1; - } - if ((psrb1 = pDCB->pWaitingSRB)) { - /* - * if WaitingSRB Q is not NULL - * Q back this SRB into WaitingSRB - */ - - pSRB->pNextSRB = psrb1; - pDCB->pWaitingSRB = pSRB; - } else { - pSRB->pNextSRB = NULL; - pDCB->pWaitingSRB = pSRB; - pDCB->pWaitingLastSRB = pSRB; - } - splx(intflag); -} - -static void -trm_DoWaitingSRB(PACB pACB) -{ - int intflag; - PDCB ptr, ptr1; - PSRB pSRB; - - intflag = splcam(); - if (!(pACB->pActiveDCB) && - !(pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV))) { - ptr = pACB->pDCBRunRobin; - if (!ptr) { - ptr = pACB->pLinkDCB; - pACB->pDCBRunRobin = ptr; - } - ptr1 = ptr; - for (;ptr1 ;) { - pACB->pDCBRunRobin = ptr1->pNextDCB; - if (!(ptr1->MaxActiveCommandCnt > ptr1->GoingSRBCnt) - || !(pSRB = ptr1->pWaitingSRB)) { - if (pACB->pDCBRunRobin == ptr) - break; - ptr1 = ptr1->pNextDCB; - } else { - if (!trm_StartSCSI(pACB, ptr1, pSRB)) { - /* - * If trm_StartSCSI return 0 : - * current interrupt status is interrupt enable - * It's said that SCSI processor is unoccupied - */ - ptr1->GoingSRBCnt++; - if (ptr1->pWaitingLastSRB == pSRB) { - ptr1->pWaitingSRB = NULL; - ptr1->pWaitingLastSRB = NULL; - } else - ptr1->pWaitingSRB = pSRB->pNextSRB; - pSRB->pNextSRB = NULL; - if (ptr1->pGoingSRB) - ptr1->pGoingLastSRB->pNextSRB = pSRB; - else - ptr1->pGoingSRB = pSRB; - ptr1->pGoingLastSRB = pSRB; - } - break; - } - } - } - splx(intflag); - return; -} - -static void -trm_SRBwaiting(PDCB pDCB, PSRB pSRB) -{ - - if (pDCB->pWaitingSRB) { - pDCB->pWaitingLastSRB->pNextSRB = pSRB; - pDCB->pWaitingLastSRB = pSRB; - pSRB->pNextSRB = NULL; - } else { - pDCB->pWaitingSRB = pSRB; - pDCB->pWaitingLastSRB = pSRB; - } -} - -static u_int32_t -trm_get_sense_bufaddr(PACB pACB, PSRB pSRB) -{ - int offset; - - offset = pSRB->TagNumber; - return (pACB->sense_busaddr + - (offset * sizeof(struct scsi_sense_data))); -} - -static struct scsi_sense_data * -trm_get_sense_buf(PACB pACB, PSRB pSRB) -{ - int offset; - - offset = pSRB->TagNumber; - return (&pACB->sense_buffers[offset]); -} -static void -trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) -{ - int flags; - PACB pACB; - PSRB pSRB; - union ccb *ccb; - u_long totalxferlen=0; - - flags = splcam(); - pSRB = (PSRB)arg; - ccb = pSRB->pccb; - pACB = (PACB)ccb->ccb_h.ccb_trmacb_ptr; - TRM_DPRINTF("trm_ExecuteSRB..........\n"); - if (nseg != 0) { - PSEG psg; - bus_dma_segment_t *end_seg; - int op; - - /* Copy the segments into our SG list */ - end_seg = dm_segs + nseg; - psg = pSRB->pSRBSGL; - while (dm_segs < end_seg) { - psg->address = dm_segs->ds_addr; - psg->length = (u_long)dm_segs->ds_len; - totalxferlen += dm_segs->ds_len; - psg++; - dm_segs++; - } - if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { - op = BUS_DMASYNC_PREREAD; - } else { - op = BUS_DMASYNC_PREWRITE; - } - bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op); - } - pSRB->RetryCnt = 0; - pSRB->SRBTotalXferLength = totalxferlen; - pSRB->SRBSGCount = nseg; - pSRB->SRBSGIndex = 0; - pSRB->AdaptStatus = 0; - pSRB->TargetStatus = 0; - pSRB->MsgCnt = 0; - pSRB->SRBStatus = 0; - pSRB->SRBFlag = 0; - pSRB->SRBState = 0; - pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */ - - if (ccb->ccb_h.status != CAM_REQ_INPROG) { - if (nseg != 0) - bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap); - pSRB->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB = pSRB; - xpt_done(ccb); - splx(flags); - return; - } - ccb->ccb_h.status |= CAM_SIM_QUEUED; - trm_SendSRB(pACB, pSRB); - splx(flags); - return; -} - -static void -trm_SendSRB(PACB pACB, PSRB pSRB) -{ - PDCB pDCB; - - pDCB = pSRB->pSRBDCB; - if (!(pDCB->MaxActiveCommandCnt > pDCB->GoingSRBCnt) || (pACB->pActiveDCB) - || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV))) { - TRM_DPRINTF("pDCB->MaxCommand=%d \n",pDCB->MaxActiveCommandCnt); - TRM_DPRINTF("pDCB->GoingSRBCnt=%d \n",pDCB->GoingSRBCnt); - TRM_DPRINTF("pACB->pActiveDCB=%8x \n",(u_int)pACB->pActiveDCB); - TRM_DPRINTF("pACB->ACBFlag=%x \n",pACB->ACBFlag); - trm_SRBwaiting(pDCB, pSRB); - goto SND_EXIT; - } - - if (pDCB->pWaitingSRB) { - trm_SRBwaiting(pDCB, pSRB); - pSRB = pDCB->pWaitingSRB; - pDCB->pWaitingSRB = pSRB->pNextSRB; - pSRB->pNextSRB = NULL; - } - - if (!trm_StartSCSI(pACB, pDCB, pSRB)) { - /* - * If trm_StartSCSI return 0 : - * current interrupt status is interrupt enable - * It's said that SCSI processor is unoccupied - */ - pDCB->GoingSRBCnt++; /* stack waiting SRB*/ - if (pDCB->pGoingSRB) { - pDCB->pGoingLastSRB->pNextSRB = pSRB; - pDCB->pGoingLastSRB = pSRB; - } else { - pDCB->pGoingSRB = pSRB; - pDCB->pGoingLastSRB = pSRB; - } - } else { - /* - * If trm_StartSCSI return 1 : - * current interrupt status is interrupt disreenable - * It's said that SCSI processor has more one SRB need to do - */ - trm_RewaitSRB0(pDCB, pSRB); - } -SND_EXIT: - return; -} - - -static void -trm_action(struct cam_sim *psim, union ccb *pccb) -{ - PACB pACB; - int actionflags; - u_int target_id,target_lun; - - CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE, ("trm_action\n")); - - actionflags = splcam(); - pACB = (PACB) cam_sim_softc(psim); - target_id = pccb->ccb_h.target_id; - target_lun = pccb->ccb_h.target_lun; - - switch (pccb->ccb_h.func_code) { - /* - * Execute the requested I/O operation - */ - case XPT_SCSI_IO: { - PDCB pDCB = NULL; - PSRB pSRB; - struct ccb_scsiio *pcsio; - int error; - - pcsio = &pccb->csio; - TRM_DPRINTF(" XPT_SCSI_IO \n"); - TRM_DPRINTF("trm: target_id= %d target_lun= %d \n" - ,target_id, target_lun); - TRM_DPRINTF( - "pACB->scan_devices[target_id][target_lun]= %d \n" - ,pACB->scan_devices[target_id][target_lun]); - if ((pccb->ccb_h.status & CAM_STATUS_MASK) != - CAM_REQ_INPROG) { - xpt_done(pccb); - splx(actionflags); - return; - } - pDCB = &pACB->DCBarray[target_id][target_lun]; - if (!(pDCB->DCBstatus & DS_IN_QUEUE)) { - pACB->scan_devices[target_id][target_lun] = 1; - trm_initDCB(pACB, pDCB, pACB->AdapterUnit, - target_id, target_lun); - } - /* - * Assign an SRB and connect it with this ccb. - */ - pSRB = trm_GetSRB(pACB); - if (!pSRB) { - /* Freeze SIMQ */ - pccb->ccb_h.status = CAM_RESRC_UNAVAIL; - xpt_done(pccb); - splx(actionflags); - return; - } - pSRB->pSRBDCB = pDCB; - pccb->ccb_h.ccb_trmsrb_ptr = pSRB; - pccb->ccb_h.ccb_trmacb_ptr = pACB; - pSRB->pccb = pccb; - pSRB->ScsiCmdLen = pcsio->cdb_len; - /* - * move layer of CAM command block to layer of SCSI - * Request Block for SCSI processor command doing - */ - if ((pccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { - if ((pccb->ccb_h.flags & CAM_CDB_PHYS) == 0) { - bcopy(pcsio->cdb_io.cdb_ptr,pSRB->CmdBlock - ,pcsio->cdb_len); - } else { - pccb->ccb_h.status = CAM_REQ_INVALID; - pSRB->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB= pSRB; - xpt_done(pccb); - splx(actionflags); - return; - } - } else - bcopy(pcsio->cdb_io.cdb_bytes, - pSRB->CmdBlock, pcsio->cdb_len); - error = bus_dmamap_load_ccb(pACB->buffer_dmat, - pSRB->dmamap, - pccb, - trm_ExecuteSRB, - pSRB, - 0); - if (error == EINPROGRESS) { - xpt_freeze_simq(pACB->psim, 1); - pccb->ccb_h.status |= CAM_RELEASE_SIMQ; - } - break; - } - /* - * Path routing inquiry - * Path Inquiry CCB - */ - case XPT_PATH_INQ: { - struct ccb_pathinq *cpi = &pccb->cpi; - - TRM_DPRINTF(" XPT_PATH_INQ \n"); - cpi->version_num = 1; - cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; - cpi->target_sprt = 0; - cpi->hba_misc = 0; - cpi->hba_eng_cnt = 0; - cpi->max_target = 15 ; - cpi->max_lun = pACB->max_lun; /* 7 or 0 */ - cpi->initiator_id = pACB->AdaptSCSIID; - cpi->bus_id = cam_sim_bus(psim); - cpi->base_transfer_speed = 3300; - strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); - strlcpy(cpi->hba_vid, "Tekram_TRM", HBA_IDLEN); - strlcpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN); - cpi->unit_number = cam_sim_unit(psim); - cpi->transport = XPORT_SPI; - cpi->transport_version = 2; - cpi->protocol = PROTO_SCSI; - cpi->protocol_version = SCSI_REV_2; - cpi->ccb_h.status = CAM_REQ_CMP; - xpt_done(pccb); - break; - } - /* - * XPT_ABORT = 0x10, Abort the specified CCB - * Abort XPT request CCB - */ - case XPT_ABORT: - TRM_DPRINTF(" XPT_ABORT \n"); - pccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(pccb); - break; - /* - * Reset the specified SCSI bus - * Reset SCSI Bus CCB - */ - case XPT_RESET_BUS: { - int i; - - TRM_DPRINTF(" XPT_RESET_BUS \n"); - trm_reset(pACB); - pACB->ACBFlag=0; - for (i=0; i<500; i++) - DELAY(1000); - pccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(pccb); - break; - } - /* - * Bus Device Reset the specified SCSI device - * Reset SCSI Device CCB - */ - case XPT_RESET_DEV: - /* - * Don't (yet?) support vendor - * specific commands. - */ - TRM_DPRINTF(" XPT_RESET_DEV \n"); - pccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(pccb); - break; - /* - * Terminate the I/O process - * Terminate I/O Process Request CCB - */ - case XPT_TERM_IO: - TRM_DPRINTF(" XPT_TERM_IO \n"); - pccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(pccb); - break; - /* - * Get/Set transfer rate/width/disconnection/tag queueing - * settings - * (GET) default/user transfer settings for the target - */ - case XPT_GET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts = &pccb->cts; - int intflag; - struct trm_transinfo *tinfo; - PDCB pDCB; - struct ccb_trans_settings_scsi *scsi = - &cts->proto_specific.scsi; - struct ccb_trans_settings_spi *spi = - &cts->xport_specific.spi; - - cts->protocol = PROTO_SCSI; - cts->protocol_version = SCSI_REV_2; - cts->transport = XPORT_SPI; - cts->transport_version = 2; - - TRM_DPRINTF(" XPT_GET_TRAN_SETTINGS \n"); - pDCB = &pACB->DCBarray[target_id][target_lun]; - intflag = splcam(); - /* - * disable interrupt - */ - if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { - /* current transfer settings */ - if (pDCB->tinfo.disc_tag & TRM_CUR_DISCENB) - spi->flags = CTS_SPI_FLAGS_DISC_ENB; - else - spi->flags = 0;/* no tag & disconnect */ - if (pDCB->tinfo.disc_tag & TRM_CUR_TAGENB) - scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; - tinfo = &pDCB->tinfo.current; - TRM_DPRINTF("CURRENT: cts->flags= %2x \n", - cts->flags); - } else { - /* default(user) transfer settings */ - if (pDCB->tinfo.disc_tag & TRM_USR_DISCENB) - spi->flags = CTS_SPI_FLAGS_DISC_ENB; - else - spi->flags = 0; - if (pDCB->tinfo.disc_tag & TRM_USR_TAGENB) - scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; - tinfo = &pDCB->tinfo.user; - TRM_DPRINTF("USER: cts->flags= %2x \n", - cts->flags); - } - spi->sync_period = tinfo->period; - spi->sync_offset = tinfo->offset; - spi->bus_width = tinfo->width; - TRM_DPRINTF("pDCB->SyncPeriod: %d \n", - pDCB->SyncPeriod); - TRM_DPRINTF("period: %d \n", tinfo->period); - TRM_DPRINTF("offset: %d \n", tinfo->offset); - TRM_DPRINTF("width: %d \n", tinfo->width); - - splx(intflag); - spi->valid = CTS_SPI_VALID_SYNC_RATE | - CTS_SPI_VALID_SYNC_OFFSET | - CTS_SPI_VALID_BUS_WIDTH | - CTS_SPI_VALID_DISC; - scsi->valid = CTS_SCSI_VALID_TQ; - pccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(pccb); - } - break; - /* - * Get/Set transfer rate/width/disconnection/tag queueing - * settings - * (Set) transfer rate/width negotiation settings - */ - case XPT_SET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts = &pccb->cts; - u_int update_type; - int intflag; - PDCB pDCB; - struct ccb_trans_settings_scsi *scsi = - &cts->proto_specific.scsi; - struct ccb_trans_settings_spi *spi = - &cts->xport_specific.spi; - - TRM_DPRINTF(" XPT_SET_TRAN_SETTINGS \n"); - update_type = 0; - if (cts->type == CTS_TYPE_CURRENT_SETTINGS) - update_type |= TRM_TRANS_GOAL; - if (cts->type == CTS_TYPE_USER_SETTINGS) - update_type |= TRM_TRANS_USER; - intflag = splcam(); - pDCB = &pACB->DCBarray[target_id][target_lun]; - - if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { - /*ccb disc enables */ - if (update_type & TRM_TRANS_GOAL) { - if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) - != 0) - pDCB->tinfo.disc_tag - |= TRM_CUR_DISCENB; - else - pDCB->tinfo.disc_tag &= - ~TRM_CUR_DISCENB; - } - if (update_type & TRM_TRANS_USER) { - if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) - != 0) - pDCB->tinfo.disc_tag - |= TRM_USR_DISCENB; - else - pDCB->tinfo.disc_tag &= - ~TRM_USR_DISCENB; - } - } - if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { - /* if ccb tag q active */ - if (update_type & TRM_TRANS_GOAL) { - if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) - != 0) - pDCB->tinfo.disc_tag |= - TRM_CUR_TAGENB; - else - pDCB->tinfo.disc_tag &= - ~TRM_CUR_TAGENB; - } - if (update_type & TRM_TRANS_USER) { - if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) - != 0) - pDCB->tinfo.disc_tag |= - TRM_USR_TAGENB; - else - pDCB->tinfo.disc_tag &= - ~TRM_USR_TAGENB; - } - } - /* Minimum sync period factor */ - - if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { - /* if ccb sync active */ - /* TRM-S1040 MinSyncPeriod = 4 clocks/byte */ - if ((spi->sync_period != 0) && - (spi->sync_period < 125)) - spi->sync_period = 125; - /* 1/(125*4) minsync 2 MByte/sec */ - if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) - != 0) { - if (spi->sync_offset == 0) - spi->sync_period = 0; - /* TRM-S1040 MaxSyncOffset = 15 bytes*/ - if (spi->sync_offset > 15) - spi->sync_offset = 15; - } - } - if ((update_type & TRM_TRANS_USER) != 0) { - pDCB->tinfo.user.period = spi->sync_period; - pDCB->tinfo.user.offset = spi->sync_offset; - pDCB->tinfo.user.width = spi->bus_width; - } - if ((update_type & TRM_TRANS_GOAL) != 0) { - pDCB->tinfo.goal.period = spi->sync_period; - pDCB->tinfo.goal.offset = spi->sync_offset; - pDCB->tinfo.goal.width = spi->bus_width; - } - splx(intflag); - pccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(pccb); - break; - } - /* - * Calculate the geometry parameters for a device give - * the sector size and volume size. - */ - case XPT_CALC_GEOMETRY: - TRM_DPRINTF(" XPT_CALC_GEOMETRY \n"); - cam_calc_geometry(&pccb->ccg, /*extended*/1); - xpt_done(pccb); - break; - default: - pccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(pccb); - break; - } - splx(actionflags); -} - -static void -trm_poll(struct cam_sim *psim) -{ - trm_Interrupt(cam_sim_softc(psim)); -} - -static void -trm_ResetDevParam(PACB pACB) -{ - PDCB pDCB, pdcb; - PNVRAMTYPE pEEpromBuf; - u_int8_t PeriodIndex; - - pDCB = pACB->pLinkDCB; - if (pDCB == NULL) - return; - pdcb = pDCB; - do { - pDCB->SyncMode &= ~(SYNC_NEGO_DONE+ WIDE_NEGO_DONE); - pDCB->SyncPeriod = 0; - pDCB->SyncOffset = 0; - pEEpromBuf = &trm_eepromBuf[pACB->AdapterUnit]; - pDCB->DevMode = - pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarCfg0; - pDCB->AdpMode = pEEpromBuf->NvramChannelCfg; - PeriodIndex = - pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarPeriod & 0x07; - if (pACB->AdaptType == 1) /* is U2? */ - pDCB->MaxNegoPeriod = dc395u2x_clock_period[PeriodIndex]; - else - pDCB->MaxNegoPeriod = dc395x_clock_period[PeriodIndex]; - if ((pDCB->DevMode & NTC_DO_WIDE_NEGO) && - (pACB->Config & HCC_WIDE_CARD)) - pDCB->SyncMode |= WIDE_NEGO_ENABLE; - pDCB = pDCB->pNextDCB; - } - while (pdcb != pDCB); -} - -static void -trm_RecoverSRB(PACB pACB) -{ - PDCB pDCB, pdcb; - PSRB psrb, psrb2; - u_int16_t cnt, i; - - pDCB = pACB->pLinkDCB; - if (pDCB == NULL) - return; - pdcb = pDCB; - do { - cnt = pdcb->GoingSRBCnt; - psrb = pdcb->pGoingSRB; - for (i = 0; i < cnt; i++) { - psrb2 = psrb; - psrb = psrb->pNextSRB; - if (pdcb->pWaitingSRB) { - psrb2->pNextSRB = pdcb->pWaitingSRB; - pdcb->pWaitingSRB = psrb2; - } else { - pdcb->pWaitingSRB = psrb2; - pdcb->pWaitingLastSRB = psrb2; - psrb2->pNextSRB = NULL; - } - } - pdcb->GoingSRBCnt = 0; - pdcb->pGoingSRB = NULL; - pdcb = pdcb->pNextDCB; - } - while (pdcb != pDCB); -} - -static void -trm_reset(PACB pACB) -{ - int intflag; - u_int16_t i; - - TRM_DPRINTF("trm: RESET"); - intflag = splcam(); - trm_reg_write8(0x00, TRMREG_DMA_INTEN); - trm_reg_write8(0x00, TRMREG_SCSI_INTEN); - - trm_ResetSCSIBus(pACB); - for (i = 0; i < 500; i++) - DELAY(1000); - trm_reg_write8(0x7F, TRMREG_SCSI_INTEN); - /* Enable DMA interrupt */ - trm_reg_write8(EN_SCSIINTR, TRMREG_DMA_INTEN); - /* Clear DMA FIFO */ - trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL); - /* Clear SCSI FIFO */ - trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL); - trm_ResetDevParam(pACB); - trm_DoingSRB_Done(pACB); - pACB->pActiveDCB = NULL; - pACB->ACBFlag = 0;/* RESET_DETECT, RESET_DONE ,RESET_DEV */ - trm_DoWaitingSRB(pACB); - /* Tell the XPT layer that a bus reset occurred */ - if (pACB->ppath != NULL) - xpt_async(AC_BUS_RESET, pACB->ppath, NULL); - splx(intflag); - return; -} - -static u_int16_t -trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB) -{ - u_int16_t return_code; - u_int8_t scsicommand, i,command,identify_message; - u_int8_t * ptr; - union ccb *pccb; - struct ccb_scsiio *pcsio; - - pccb = pSRB->pccb; - pcsio = &pccb->csio; - - trm_reg_write8(pACB->AdaptSCSIID, TRMREG_SCSI_HOSTID); - trm_reg_write8(pDCB->TargetID, TRMREG_SCSI_TARGETID); - trm_reg_write8(pDCB->SyncPeriod, TRMREG_SCSI_SYNC); - trm_reg_write8(pDCB->SyncOffset, TRMREG_SCSI_OFFSET); - pSRB->ScsiPhase = PH_BUS_FREE;/* initial phase */ - /* Flush FIFO */ - trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL); - - identify_message = pDCB->IdentifyMsg; - - if ((pSRB->CmdBlock[0] == INQUIRY) || - (pSRB->CmdBlock[0] == REQUEST_SENSE) || - (pSRB->SRBFlag & AUTO_REQSENSE)) { - if (((pDCB->SyncMode & WIDE_NEGO_ENABLE) && - !(pDCB->SyncMode & WIDE_NEGO_DONE)) - || ((pDCB->SyncMode & SYNC_NEGO_ENABLE) && - !(pDCB->SyncMode & SYNC_NEGO_DONE))) { - if (!(pDCB->IdentifyMsg & 7) || - (pSRB->CmdBlock[0] != INQUIRY)) { - scsicommand = SCMD_SEL_ATNSTOP; - pSRB->SRBState = SRB_MSGOUT; - goto polling; - } - } - /* - * Send identify message - */ - trm_reg_write8((identify_message & 0xBF) ,TRMREG_SCSI_FIFO); - scsicommand = SCMD_SEL_ATN; - pSRB->SRBState = SRB_START_; - } else { - /* not inquiry,request sense,auto request sense */ - /* - * Send identify message - */ - trm_reg_write8(identify_message,TRMREG_SCSI_FIFO); - scsicommand = SCMD_SEL_ATN; - pSRB->SRBState = SRB_START_; - if (pDCB->SyncMode & EN_TAG_QUEUING) { - /* Send Tag message */ - trm_reg_write8(MSG_SIMPLE_QTAG, TRMREG_SCSI_FIFO); - trm_reg_write8(pSRB->TagNumber, TRMREG_SCSI_FIFO); - scsicommand = SCMD_SEL_ATN3; - } - } -polling: - /* - * Send CDB ..command block ......... - */ - if (pSRB->SRBFlag & AUTO_REQSENSE) { - trm_reg_write8(REQUEST_SENSE, TRMREG_SCSI_FIFO); - trm_reg_write8((pDCB->IdentifyMsg << 5), TRMREG_SCSI_FIFO); - trm_reg_write8(0, TRMREG_SCSI_FIFO); - trm_reg_write8(0, TRMREG_SCSI_FIFO); - trm_reg_write8(pcsio->sense_len, TRMREG_SCSI_FIFO); - trm_reg_write8(0, TRMREG_SCSI_FIFO); - } else { - ptr = (u_int8_t *) pSRB->CmdBlock; - for (i = 0; i < pSRB->ScsiCmdLen ; i++) { - command = *ptr++; - trm_reg_write8(command,TRMREG_SCSI_FIFO); - } - } - if (trm_reg_read16(TRMREG_SCSI_STATUS) & SCSIINTERRUPT) { - /* - * If trm_StartSCSI return 1 : - * current interrupt status is interrupt disreenable - * It's said that SCSI processor has more one SRB need to do, - * SCSI processor has been occupied by one SRB. - */ - pSRB->SRBState = SRB_READY; - return_code = 1; - } else { - /* - * If trm_StartSCSI return 0 : - * current interrupt status is interrupt enable - * It's said that SCSI processor is unoccupied - */ - pSRB->ScsiPhase = SCSI_NOP1; /* SCSI bus free Phase */ - pACB->pActiveDCB = pDCB; - pDCB->pActiveSRB = pSRB; - return_code = 0; - trm_reg_write16(DO_DATALATCH | DO_HWRESELECT, - TRMREG_SCSI_CONTROL);/* it's important for atn stop*/ - /* - * SCSI cammand - */ - trm_reg_write8(scsicommand,TRMREG_SCSI_COMMAND); - } - return (return_code); -} - -static void -trm_Interrupt(vpACB) -void *vpACB; -{ - PACB pACB; - PDCB pDCB; - PSRB pSRB; - u_int16_t phase; - void (*stateV)(PACB, PSRB, u_int16_t *); - u_int16_t scsi_status=0; - u_int8_t scsi_intstatus; - - pACB = vpACB; - - scsi_status = trm_reg_read16(TRMREG_SCSI_STATUS); - if (!(scsi_status & SCSIINTERRUPT)) { - TRM_DPRINTF("trm_Interrupt: TRMREG_SCSI_STATUS scsi_status = NULL ,return......"); - return; - } - TRM_DPRINTF("scsi_status=%2x,",scsi_status); - - scsi_intstatus = trm_reg_read8(TRMREG_SCSI_INTSTATUS); - - TRM_DPRINTF("scsi_intstatus=%2x,",scsi_intstatus); - - if (scsi_intstatus & (INT_SELTIMEOUT | INT_DISCONNECT)) { - trm_Disconnect(pACB); - return; - } - - if (scsi_intstatus & INT_RESELECTED) { - trm_Reselect(pACB); - return; - } - if (scsi_intstatus & INT_SCSIRESET) { - trm_ScsiRstDetect(pACB); - return; - } - - if (scsi_intstatus & (INT_BUSSERVICE | INT_CMDDONE)) { - pDCB = pACB->pActiveDCB; - KASSERT(pDCB != NULL, ("no active DCB")); - pSRB = pDCB->pActiveSRB; - if (pDCB->DCBFlag & ABORT_DEV_) - trm_EnableMsgOutAbort1(pACB, pSRB); - phase = (u_int16_t) pSRB->ScsiPhase; /* phase: */ - stateV = (void *) trm_SCSI_phase0[phase]; - stateV(pACB, pSRB, &scsi_status); - pSRB->ScsiPhase = scsi_status & PHASEMASK; - /* phase:0,1,2,3,4,5,6,7 */ - phase = (u_int16_t) scsi_status & PHASEMASK; - stateV = (void *) trm_SCSI_phase1[phase]; - stateV(pACB, pSRB, &scsi_status); - } -} - -static void -trm_MsgOutPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - - if (pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT)) - *pscsi_status = PH_BUS_FREE; - /*.. initial phase*/ -} - -static void -trm_MsgOutPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - u_int8_t bval; - u_int16_t i, cnt; - u_int8_t * ptr; - PDCB pDCB; - - trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL); - pDCB = pACB->pActiveDCB; - if (!(pSRB->SRBState & SRB_MSGOUT)) { - cnt = pSRB->MsgCnt; - if (cnt) { - ptr = (u_int8_t *) pSRB->MsgOutBuf; - for (i = 0; i < cnt; i++) { - trm_reg_write8(*ptr, TRMREG_SCSI_FIFO); - ptr++; - } - pSRB->MsgCnt = 0; - if ((pDCB->DCBFlag & ABORT_DEV_) && - (pSRB->MsgOutBuf[0] == MSG_ABORT)) { - pSRB->SRBState = SRB_ABORT_SENT; - } - } else { - bval = MSG_ABORT; - if ((pSRB->CmdBlock[0] == INQUIRY) || - (pSRB->CmdBlock[0] == REQUEST_SENSE) || - (pSRB->SRBFlag & AUTO_REQSENSE)) { - if (pDCB->SyncMode & SYNC_NEGO_ENABLE) { - goto mop1; - } - } - trm_reg_write8(bval, TRMREG_SCSI_FIFO); - } - } else { -mop1: /* message out phase */ - if (!(pSRB->SRBState & SRB_DO_WIDE_NEGO) - && (pDCB->SyncMode & WIDE_NEGO_ENABLE)) { - /* - * WIDE DATA TRANSFER REQUEST code (03h) - */ - pDCB->SyncMode &= ~(SYNC_NEGO_DONE | EN_ATN_STOP); - trm_reg_write8((pDCB->IdentifyMsg & 0xBF), - TRMREG_SCSI_FIFO); - trm_reg_write8(MSG_EXTENDED,TRMREG_SCSI_FIFO); - /* (01h) */ - trm_reg_write8(2,TRMREG_SCSI_FIFO); - /* Message length (02h) */ - trm_reg_write8(3,TRMREG_SCSI_FIFO); - /* wide data xfer (03h) */ - trm_reg_write8(1,TRMREG_SCSI_FIFO); - /* width:0(8bit),1(16bit),2(32bit) */ - pSRB->SRBState |= SRB_DO_WIDE_NEGO; - } else if (!(pSRB->SRBState & SRB_DO_SYNC_NEGO) - && (pDCB->SyncMode & SYNC_NEGO_ENABLE)) { - /* - * SYNCHRONOUS DATA TRANSFER REQUEST code (01h) - */ - if (!(pDCB->SyncMode & WIDE_NEGO_DONE)) - trm_reg_write8((pDCB->IdentifyMsg & 0xBF), - TRMREG_SCSI_FIFO); - trm_reg_write8(MSG_EXTENDED,TRMREG_SCSI_FIFO); - /* (01h) */ - trm_reg_write8(3,TRMREG_SCSI_FIFO); - /* Message length (03h) */ - trm_reg_write8(1,TRMREG_SCSI_FIFO); - /* SYNCHRONOUS DATA TRANSFER REQUEST code (01h) */ - trm_reg_write8(pDCB->MaxNegoPeriod,TRMREG_SCSI_FIFO); - /* Transfer peeriod factor */ - trm_reg_write8((pACB->AdaptType == 1) ? 31 : 15, - TRMREG_SCSI_FIFO); - /* REQ/ACK offset */ - pSRB->SRBState |= SRB_DO_SYNC_NEGO; - } - } - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop */ - /* - * SCSI cammand - */ - trm_reg_write8(SCMD_FIFO_OUT, TRMREG_SCSI_COMMAND); -} - -static void -trm_CommandPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - -} - -static void -trm_CommandPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - PDCB pDCB; - u_int8_t * ptr; - u_int16_t i, cnt; - union ccb *pccb; - struct ccb_scsiio *pcsio; - - pccb = pSRB->pccb; - pcsio = &pccb->csio; - - trm_reg_write16(DO_CLRATN | DO_CLRFIFO , TRMREG_SCSI_CONTROL); - if (!(pSRB->SRBFlag & AUTO_REQSENSE)) { - cnt = (u_int16_t) pSRB->ScsiCmdLen; - ptr = (u_int8_t *) pSRB->CmdBlock; - for (i = 0; i < cnt; i++) { - trm_reg_write8(*ptr, TRMREG_SCSI_FIFO); - ptr++; - } - } else { - trm_reg_write8(REQUEST_SENSE, TRMREG_SCSI_FIFO); - pDCB = pACB->pActiveDCB; - /* target id */ - trm_reg_write8((pDCB->IdentifyMsg << 5), TRMREG_SCSI_FIFO); - trm_reg_write8(0, TRMREG_SCSI_FIFO); - trm_reg_write8(0, TRMREG_SCSI_FIFO); - /* sizeof(struct scsi_sense_data) */ - trm_reg_write8(pcsio->sense_len, TRMREG_SCSI_FIFO); - trm_reg_write8(0, TRMREG_SCSI_FIFO); - } - pSRB->SRBState = SRB_COMMAND; - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop*/ - /* - * SCSI cammand - */ - trm_reg_write8(SCMD_FIFO_OUT, TRMREG_SCSI_COMMAND); -} - -static void -trm_DataOutPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - PDCB pDCB; - u_int8_t TempDMAstatus,SGIndexTemp; - u_int16_t scsi_status; - PSEG pseg; - u_long TempSRBXferredLength,dLeftCounter=0; - - pDCB = pSRB->pSRBDCB; - scsi_status = *pscsi_status; - - if (!(pSRB->SRBState & SRB_XFERPAD)) { - if (scsi_status & PARITYERROR) - pSRB->SRBStatus |= PARITY_ERROR; - if (!(scsi_status & SCSIXFERDONE)) { - /* - * when data transfer from DMA FIFO to SCSI FIFO - * if there was some data left in SCSI FIFO - */ - dLeftCounter = (u_long) - (trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x3F); - if (pDCB->SyncPeriod & WIDE_SYNC) { - /* - * if WIDE scsi SCSI FIFOCNT unit is word - * so need to * 2 - */ - dLeftCounter <<= 1; - } - } - /* - * caculate all the residue data that not yet tranfered - * SCSI transfer counter + left in SCSI FIFO data - * - * .....TRM_SCSI_COUNTER (24bits) - * The counter always decrement by one for every SCSI byte - *transfer. - * .....TRM_SCSI_FIFOCNT (5bits) - * The counter is SCSI FIFO offset counter - */ - dLeftCounter += trm_reg_read32(TRMREG_SCSI_COUNTER); - if (dLeftCounter == 1) { - dLeftCounter = 0; - trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL); - } - if ((dLeftCounter == 0) || - (scsi_status & SCSIXFERCNT_2_ZERO)) { - TempDMAstatus = trm_reg_read8(TRMREG_DMA_STATUS); - while (!(TempDMAstatus & DMAXFERCOMP)) { - TempDMAstatus = - trm_reg_read8(TRMREG_DMA_STATUS); - } - pSRB->SRBTotalXferLength = 0; - } else { - /* Update SG list */ - /* - * if transfer not yet complete - * there were some data residue in SCSI FIFO or - * SCSI transfer counter not empty - */ - if (pSRB->SRBTotalXferLength != dLeftCounter) { - /* - * data that had transferred length - */ - TempSRBXferredLength = - pSRB->SRBTotalXferLength - dLeftCounter; - /* - * next time to be transferred length - */ - pSRB->SRBTotalXferLength = dLeftCounter; - /* - * parsing from last time disconnect SRBSGIndex - */ - pseg = - pSRB->pSRBSGL + pSRB->SRBSGIndex; - for (SGIndexTemp = pSRB->SRBSGIndex; - SGIndexTemp < pSRB->SRBSGCount; - SGIndexTemp++) { - /* - * find last time which SG transfer be - * disconnect - */ - if (TempSRBXferredLength >= - pseg->length) - TempSRBXferredLength -= - pseg->length; - else { - /* - * update last time disconnected SG - * list - */ - pseg->length -= - TempSRBXferredLength; - /* residue data length */ - pseg->address += - TempSRBXferredLength; - /* residue data pointer */ - pSRB->SRBSGIndex = SGIndexTemp; - break; - } - pseg++; - } - } - } - } - trm_reg_write8(STOPDMAXFER ,TRMREG_DMA_CONTROL); -} - - -static void -trm_DataOutPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - u_int16_t ioDir; - /* - * do prepare befor transfer when data out phase - */ - - ioDir = XFERDATAOUT; - trm_DataIO_transfer(pACB, pSRB, ioDir); -} - -static void -trm_DataInPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - u_int8_t TempDMAstatus, SGIndexTemp; - u_int16_t scsi_status; - PSEG pseg; - u_long TempSRBXferredLength,dLeftCounter = 0; - - scsi_status = *pscsi_status; - if (!(pSRB->SRBState & SRB_XFERPAD)) { - if (scsi_status & PARITYERROR) - pSRB->SRBStatus |= PARITY_ERROR; - dLeftCounter += trm_reg_read32(TRMREG_SCSI_COUNTER); - if ((dLeftCounter == 0) || (scsi_status & SCSIXFERCNT_2_ZERO)) { - TempDMAstatus = trm_reg_read8(TRMREG_DMA_STATUS); - while (!(TempDMAstatus & DMAXFERCOMP)) - TempDMAstatus = trm_reg_read8(TRMREG_DMA_STATUS); - pSRB->SRBTotalXferLength = 0; - } else { - /* - * parsing the case: - * when a transfer not yet complete - * but be disconnected by uper layer - * if transfer not yet complete - * there were some data residue in SCSI FIFO or - * SCSI transfer counter not empty - */ - if (pSRB->SRBTotalXferLength != dLeftCounter) { - /* - * data that had transferred length - */ - TempSRBXferredLength = - pSRB->SRBTotalXferLength - dLeftCounter; - /* - * next time to be transferred length - */ - pSRB->SRBTotalXferLength = dLeftCounter; - /* - * parsing from last time disconnect SRBSGIndex - */ - pseg = pSRB->pSRBSGL + pSRB->SRBSGIndex; - for (SGIndexTemp = pSRB->SRBSGIndex; - SGIndexTemp < pSRB->SRBSGCount; - SGIndexTemp++) { - /* - * find last time which SG transfer be disconnect - */ - if (TempSRBXferredLength >= pseg->length) - TempSRBXferredLength -= pseg->length; - else { - /* - * update last time disconnected SG list - */ - pseg->length -= TempSRBXferredLength; - /* residue data length */ - pseg->address += TempSRBXferredLength; - /* residue data pointer */ - pSRB->SRBSGIndex = SGIndexTemp; - break; - } - pseg++; - } - } - } - } -} - -static void -trm_DataInPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - u_int16_t ioDir; - /* - * do prepare befor transfer when data in phase - */ - - ioDir = XFERDATAIN; - trm_DataIO_transfer(pACB, pSRB, ioDir); -} - -static void -trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir) -{ - u_int8_t bval; - PDCB pDCB; - - pDCB = pSRB->pSRBDCB; - if (pSRB->SRBSGIndex < pSRB->SRBSGCount) { - if (pSRB->SRBTotalXferLength != 0) { - /* - * load what physical address of Scatter/Gather list - table want to be transfer - */ - TRM_DPRINTF(" SG->address=%8x \n",pSRB->pSRBSGL->address); - TRM_DPRINTF(" SG->length=%8x \n",pSRB->pSRBSGL->length); - TRM_DPRINTF(" pDCB->SyncPeriod=%x \n",pDCB->SyncPeriod); - TRM_DPRINTF(" pSRB->pSRBSGL=%8x \n",(unsigned int)pSRB->pSRBSGL); - TRM_DPRINTF(" pSRB->SRBSGPhyAddr=%8x \n",pSRB->SRBSGPhyAddr); - TRM_DPRINTF(" pSRB->SRBSGIndex=%d \n",pSRB->SRBSGIndex); - TRM_DPRINTF(" pSRB->SRBSGCount=%d \n",pSRB->SRBSGCount); - TRM_DPRINTF(" pSRB->SRBTotalXferLength=%d \n",pSRB->SRBTotalXferLength); - - pSRB->SRBState = SRB_DATA_XFER; - trm_reg_write32(0, TRMREG_DMA_XHIGHADDR); - trm_reg_write32( - (pSRB->SRBSGPhyAddr + - ((u_long)pSRB->SRBSGIndex << 3)), - TRMREG_DMA_XLOWADDR); - /* - * load how many bytes in the Scatter/Gather - * list table - */ - trm_reg_write32( - ((u_long)(pSRB->SRBSGCount - pSRB->SRBSGIndex) << 3), - TRMREG_DMA_XCNT); - /* - * load total transfer length (24bits) max value - * 16Mbyte - */ - trm_reg_write32(pSRB->SRBTotalXferLength, - TRMREG_SCSI_COUNTER); - /* Start DMA transfer */ - trm_reg_write16(ioDir, TRMREG_DMA_COMMAND); - /* Start SCSI transfer */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop */ - /* - * SCSI cammand - */ - bval = (ioDir == XFERDATAOUT) ? - SCMD_DMA_OUT : SCMD_DMA_IN; - trm_reg_write8(bval, TRMREG_SCSI_COMMAND); - } else { - /* xfer pad */ - if (pSRB->SRBSGCount) { - pSRB->AdaptStatus = H_OVER_UNDER_RUN; - pSRB->SRBStatus |= OVER_RUN; - } - if (pDCB->SyncPeriod & WIDE_SYNC) - trm_reg_write32(2,TRMREG_SCSI_COUNTER); - else - trm_reg_write32(1,TRMREG_SCSI_COUNTER); - if (ioDir == XFERDATAOUT) - trm_reg_write16(0, TRMREG_SCSI_FIFO); - else - trm_reg_read16(TRMREG_SCSI_FIFO); - pSRB->SRBState |= SRB_XFERPAD; - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop */ - /* - * SCSI cammand - */ - bval = (ioDir == XFERDATAOUT) ? - SCMD_FIFO_OUT : SCMD_FIFO_IN; - trm_reg_write8(bval, TRMREG_SCSI_COMMAND); - } - } -} - -static void -trm_StatusPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - - pSRB->TargetStatus = trm_reg_read8(TRMREG_SCSI_FIFO); - pSRB->SRBState = SRB_COMPLETED; - *pscsi_status = PH_BUS_FREE; - /*.. initial phase*/ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop */ - /* - * SCSI cammand - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); -} - - - -static void -trm_StatusPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - - if (trm_reg_read16(TRMREG_DMA_COMMAND) & 0x0001) { - if (!(trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x40)) - trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL); - if (!(trm_reg_read16(TRMREG_DMA_FIFOCNT) & 0x8000)) - trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL); - } else { - if (!(trm_reg_read16(TRMREG_DMA_FIFOCNT) & 0x8000)) - trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL); - if (!(trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x40)) - trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL); - } - pSRB->SRBState = SRB_STATUS; - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop */ - /* - * SCSI cammand - */ - trm_reg_write8(SCMD_COMP, TRMREG_SCSI_COMMAND); -} - -/* - *scsiiom - * trm_MsgInPhase0: one of trm_SCSI_phase0[] vectors - * stateV = (void *) trm_SCSI_phase0[phase] - * if phase =7 - * extended message codes: - * - * code description - * - * 02h Reserved - * 00h MODIFY DATA POINTER - * 01h SYNCHRONOUS DATA TRANSFER REQUEST - * 03h WIDE DATA TRANSFER REQUEST - * 04h - 7Fh Reserved - * 80h - FFh Vendor specific - * - */ - -static void -trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - u_int8_t message_in_code,bIndex,message_in_tag_id; - PDCB pDCB; - PSRB pSRBTemp; - - pDCB = pACB->pActiveDCB; - - message_in_code = trm_reg_read8(TRMREG_SCSI_FIFO); - if (!(pSRB->SRBState & SRB_EXTEND_MSGIN)) { - if (message_in_code == MSG_DISCONNECT) { - pSRB->SRBState = SRB_DISCONNECT; - *pscsi_status = PH_BUS_FREE; /* .. initial phase */ - /* it's important for atn stop */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* - * SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } else if (message_in_code == MSG_SAVE_PTR) { - *pscsi_status = PH_BUS_FREE; /* .. initial phase */ - /* it's important for atn stop */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* - * SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } else if ((message_in_code == MSG_EXTENDED) || - ((message_in_code >= MSG_SIMPLE_QTAG) && - (message_in_code <= MSG_ORDER_QTAG))) { - pSRB->SRBState |= SRB_EXTEND_MSGIN; - pSRB->MsgInBuf[0] = message_in_code; - /* extended message (01h) */ - pSRB->MsgCnt = 1; - pSRB->pMsgPtr = &pSRB->MsgInBuf[1]; - /* extended message length (n) */ - *pscsi_status = PH_BUS_FREE; /* .. initial phase */ - /* it's important for atn stop */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* - * SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } else if (message_in_code == MSG_REJECT_) { - /* Reject message */ - if (pDCB->SyncMode & WIDE_NEGO_ENABLE) { - /* do wide nego reject */ - pDCB = pSRB->pSRBDCB; - pDCB->SyncMode |= WIDE_NEGO_DONE; - pDCB->SyncMode &= ~(SYNC_NEGO_DONE | - EN_ATN_STOP | WIDE_NEGO_ENABLE); - pSRB->SRBState &= ~(SRB_DO_WIDE_NEGO+SRB_MSGIN); - if ((pDCB->SyncMode & SYNC_NEGO_ENABLE) - && !(pDCB->SyncMode & SYNC_NEGO_DONE)) { - /* Set ATN, in case ATN was clear */ - pSRB->SRBState |= SRB_MSGOUT; - trm_reg_write16( - DO_SETATN, - TRMREG_SCSI_CONTROL); - } else { - /* Clear ATN */ - trm_reg_write16( - DO_CLRATN, - TRMREG_SCSI_CONTROL); - } - } else if (pDCB->SyncMode & SYNC_NEGO_ENABLE) { - /* do sync nego reject */ - trm_reg_write16(DO_CLRATN,TRMREG_SCSI_CONTROL); - if (pSRB->SRBState & SRB_DO_SYNC_NEGO) { - pDCB = pSRB->pSRBDCB; - pDCB->SyncMode &= - ~(SYNC_NEGO_ENABLE+SYNC_NEGO_DONE); - pDCB->SyncPeriod = 0; - pDCB->SyncOffset = 0; - /* - * - * program SCSI control register - * - */ - trm_reg_write8(pDCB->SyncPeriod, - TRMREG_SCSI_SYNC); - trm_reg_write8(pDCB->SyncOffset, - TRMREG_SCSI_OFFSET); - trm_SetXferRate(pACB,pSRB,pDCB); - } - } - *pscsi_status = PH_BUS_FREE; /* .. initial phase */ - /* it's important for atn stop */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* - * SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } else if (message_in_code == MSG_IGNOREWIDE) { - trm_reg_write32(1, TRMREG_SCSI_COUNTER); - trm_reg_read8(TRMREG_SCSI_FIFO); - *pscsi_status = PH_BUS_FREE; /* .. initial phase */ - /* it's important for atn stop */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* - * SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } else { - /* Restore data pointer message */ - /* Save data pointer message */ - /* Completion message */ - /* NOP message */ - *pscsi_status = PH_BUS_FREE; /* .. initial phase */ - /* it's important for atn stop */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* - * SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } - } else { - /* - * Parsing incoming extented messages - */ - *pSRB->pMsgPtr = message_in_code; - pSRB->MsgCnt++; - pSRB->pMsgPtr++; - TRM_DPRINTF("pSRB->MsgInBuf[0]=%2x \n ",pSRB->MsgInBuf[0]); - TRM_DPRINTF("pSRB->MsgInBuf[1]=%2x \n ",pSRB->MsgInBuf[1]); - TRM_DPRINTF("pSRB->MsgInBuf[2]=%2x \n ",pSRB->MsgInBuf[2]); - TRM_DPRINTF("pSRB->MsgInBuf[3]=%2x \n ",pSRB->MsgInBuf[3]); - TRM_DPRINTF("pSRB->MsgInBuf[4]=%2x \n ",pSRB->MsgInBuf[4]); - if ((pSRB->MsgInBuf[0] >= MSG_SIMPLE_QTAG) - && (pSRB->MsgInBuf[0] <= MSG_ORDER_QTAG)) { - /* - * is QUEUE tag message : - * - * byte 0: - * HEAD QUEUE TAG (20h) - * ORDERED QUEUE TAG (21h) - * SIMPLE QUEUE TAG (22h) - * byte 1: - * Queue tag (00h - FFh) - */ - if (pSRB->MsgCnt == 2) { - pSRB->SRBState = 0; - message_in_tag_id = pSRB->MsgInBuf[1]; - pSRB = pDCB->pGoingSRB; - pSRBTemp = pDCB->pGoingLastSRB; - if (pSRB) { - for (;;) { - if (pSRB->TagNumber != - message_in_tag_id) { - if (pSRB == pSRBTemp) { - goto mingx0; - } - pSRB = pSRB->pNextSRB; - } else - break; - } - if (pDCB->DCBFlag & ABORT_DEV_) { - pSRB->SRBState = SRB_ABORT_SENT; - trm_EnableMsgOutAbort1( - pACB, pSRB); - } - if (!(pSRB->SRBState & SRB_DISCONNECT)) { - TRM_DPRINTF("SRB not yet disconnect........ \n "); - goto mingx0; - } - pDCB->pActiveSRB = pSRB; - pSRB->SRBState = SRB_DATA_XFER; - } else { -mingx0: - pSRB = &pACB->TmpSRB; - pSRB->SRBState = SRB_UNEXPECT_RESEL; - pDCB->pActiveSRB = pSRB; - pSRB->MsgOutBuf[0] = MSG_ABORT_TAG; - trm_EnableMsgOutAbort2( - pACB, - pSRB); - } - } - *pscsi_status = PH_BUS_FREE; - /* .. initial phase */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop */ - /* - * SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) && - (pSRB->MsgInBuf[2] == 3) && (pSRB->MsgCnt == 4)) { - /* - * is Wide data xfer Extended message : - * ====================================== - * WIDE DATA TRANSFER REQUEST - * ====================================== - * byte 0 : Extended message (01h) - * byte 1 : Extended message length (02h) - * byte 2 : WIDE DATA TRANSFER code (03h) - * byte 3 : Transfer width exponent - */ - pDCB = pSRB->pSRBDCB; - pSRB->SRBState &= ~(SRB_EXTEND_MSGIN+SRB_DO_WIDE_NEGO); - if ((pSRB->MsgInBuf[1] != 2)) { - /* Length is wrong, reject it */ - pDCB->SyncMode &= - ~(WIDE_NEGO_ENABLE+WIDE_NEGO_DONE); - pSRB->MsgCnt = 1; - pSRB->MsgInBuf[0] = MSG_REJECT_; - trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL); - *pscsi_status = PH_BUS_FREE; /* .. initial phase */ - /* it's important for atn stop */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* - * SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } - if (pDCB->SyncMode & WIDE_NEGO_ENABLE) { - /* Do wide negoniation */ - if (pSRB->MsgInBuf[3] > 2) { - /* > 32 bit */ - /* reject_msg: */ - pDCB->SyncMode &= - ~(WIDE_NEGO_ENABLE+WIDE_NEGO_DONE); - pSRB->MsgCnt = 1; - pSRB->MsgInBuf[0] = MSG_REJECT_; - trm_reg_write16(DO_SETATN, - TRMREG_SCSI_CONTROL); - *pscsi_status = PH_BUS_FREE; /* .. initial phase */ - /* it's important for atn stop */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* - * SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } - if (pSRB->MsgInBuf[3] == 2) { - pSRB->MsgInBuf[3] = 1; - /* do 16 bits */ - } else { - if (!(pDCB->SyncMode - & WIDE_NEGO_DONE)) { - pSRB->SRBState &= - ~(SRB_DO_WIDE_NEGO+SRB_MSGIN); - pDCB->SyncMode |= - WIDE_NEGO_DONE; - pDCB->SyncMode &= - ~(SYNC_NEGO_DONE | - EN_ATN_STOP | - WIDE_NEGO_ENABLE); - if (pSRB->MsgInBuf[3] != 0) { - /* is Wide data xfer */ - pDCB->SyncPeriod |= - WIDE_SYNC; - pDCB->tinfo.current.width - = MSG_EXT_WDTR_BUS_16_BIT; - pDCB->tinfo.goal.width - = MSG_EXT_WDTR_BUS_16_BIT; - } - } - } - } else - pSRB->MsgInBuf[3] = 0; - pSRB->SRBState |= SRB_MSGOUT; - trm_reg_write16(DO_SETATN,TRMREG_SCSI_CONTROL); - *pscsi_status = PH_BUS_FREE; /* .. initial phase */ - /* it's important for atn stop */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* - * SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) && - (pSRB->MsgInBuf[2] == 1) && (pSRB->MsgCnt == 5)) { - /* - * is 8bit transfer Extended message : - * ================================= - * SYNCHRONOUS DATA TRANSFER REQUEST - * ================================= - * byte 0 : Extended message (01h) - * byte 1 : Extended message length (03) - * byte 2 : SYNCHRONOUS DATA TRANSFER code (01h) - * byte 3 : Transfer period factor - * byte 4 : REQ/ACK offset - */ - pSRB->SRBState &= ~(SRB_EXTEND_MSGIN+SRB_DO_SYNC_NEGO); - if ((pSRB->MsgInBuf[1] != 3) || - (pSRB->MsgInBuf[2] != 1)) { - /* reject_msg: */ - pSRB->MsgCnt = 1; - pSRB->MsgInBuf[0] = MSG_REJECT_; - trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL); - *pscsi_status = PH_BUS_FREE; - /* .. initial phase */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop */ - /* - * SCSI cammand - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } else if (!(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4])) { - /* set async */ - pDCB = pSRB->pSRBDCB; - /* disable sync & sync nego */ - pDCB->SyncMode &= - ~(SYNC_NEGO_ENABLE+SYNC_NEGO_DONE); - pDCB->SyncPeriod = 0; - pDCB->SyncOffset = 0; - pDCB->tinfo.goal.period = 0; - pDCB->tinfo.goal.offset = 0; - pDCB->tinfo.current.period = 0; - pDCB->tinfo.current.offset = 0; - pDCB->tinfo.current.width = - MSG_EXT_WDTR_BUS_8_BIT; - /* - * - * program SCSI control register - * - */ - trm_reg_write8(pDCB->SyncPeriod,TRMREG_SCSI_SYNC); - trm_reg_write8(pDCB->SyncOffset,TRMREG_SCSI_OFFSET); - trm_SetXferRate(pACB,pSRB,pDCB); - *pscsi_status = PH_BUS_FREE; - /* .. initial phase */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop */ - /* - * SCSI cammand - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - return; - } else { - /* set sync */ - pDCB = pSRB->pSRBDCB; - pDCB->SyncMode |= - SYNC_NEGO_ENABLE+SYNC_NEGO_DONE; - pDCB->MaxNegoPeriod = pSRB->MsgInBuf[3]; - /* Transfer period factor */ - pDCB->SyncOffset = pSRB->MsgInBuf[4]; - /* REQ/ACK offset */ - if (pACB->AdaptType == 1) { - for(bIndex = 0; bIndex < 7; bIndex++) { - if (pSRB->MsgInBuf[3] <= - dc395u2x_clock_period[bIndex]) { - pDCB->tinfo.goal.period = - dc395u2x_tinfo_period[bIndex]; - pDCB->tinfo.current.period = - dc395u2x_tinfo_period[bIndex]; - pDCB->tinfo.goal.offset = - pDCB->SyncOffset; - pDCB->tinfo.current.offset = - pDCB->SyncOffset; - pDCB->SyncPeriod |= (bIndex|LVDS_SYNC); - break; - } - } - } else { - for(bIndex = 0; bIndex < 7; bIndex++) { - if (pSRB->MsgInBuf[3] <= - dc395x_clock_period[bIndex]) { - pDCB->tinfo.goal.period = - dc395x_tinfo_period[bIndex]; - pDCB->tinfo.current.period = - dc395x_tinfo_period[bIndex]; - pDCB->tinfo.goal.offset = - pDCB->SyncOffset; - pDCB->tinfo.current.offset = - pDCB->SyncOffset; - pDCB->SyncPeriod |= - (bIndex|ALT_SYNC); - break; - } - } - } - /* - * - * program SCSI control register - * - */ - trm_reg_write8(pDCB->SyncPeriod, - TRMREG_SCSI_SYNC); - trm_reg_write8(pDCB->SyncOffset, - TRMREG_SCSI_OFFSET); - trm_SetXferRate(pACB,pSRB,pDCB); - *pscsi_status=PH_BUS_FREE;/*.. initial phase*/ - trm_reg_write16(DO_DATALATCH,TRMREG_SCSI_CONTROL);/* it's important for atn stop*/ - /* - ** SCSI command - */ - trm_reg_write8(SCMD_MSGACCEPT,TRMREG_SCSI_COMMAND); - return; - } - } - *pscsi_status = PH_BUS_FREE; - /* .. initial phase */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop */ - /* - * SCSI cammand - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - } -} - -static void -trm_MsgInPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - - trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL); - trm_reg_write32(1,TRMREG_SCSI_COUNTER); - if (!(pSRB->SRBState & SRB_MSGIN)) { - pSRB->SRBState &= SRB_DISCONNECT; - pSRB->SRBState |= SRB_MSGIN; - } - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop*/ - /* - * SCSI cammand - */ - trm_reg_write8(SCMD_FIFO_IN, TRMREG_SCSI_COMMAND); -} - -static void -trm_Nop0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - -} - -static void -trm_Nop1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status) -{ - -} - -static void -trm_SetXferRate(PACB pACB,PSRB pSRB, PDCB pDCB) -{ - union ccb *pccb; - struct ccb_trans_settings neg; - u_int16_t cnt, i; - u_int8_t bval; - PDCB pDCBTemp; - - /* - * set all lun device's period , offset - */ - TRM_DPRINTF("trm_SetXferRate\n"); - pccb = pSRB->pccb; - memset(&neg, 0, sizeof (neg)); - neg.xport_specific.spi.sync_period = pDCB->tinfo.goal.period; - neg.xport_specific.spi.sync_offset = pDCB->tinfo.goal.offset; - neg.xport_specific.spi.valid = - CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_SYNC_OFFSET; - xpt_setup_ccb(&neg.ccb_h, pccb->ccb_h.path, /* priority */1); - xpt_async(AC_TRANSFER_NEG, pccb->ccb_h.path, &neg); - if (!(pDCB->IdentifyMsg & 0x07)) { - pDCBTemp = pACB->pLinkDCB; - cnt = pACB->DeviceCnt; - bval = pDCB->TargetID; - for (i = 0; i < cnt; i++) { - if (pDCBTemp->TargetID == bval) { - pDCBTemp->SyncPeriod = pDCB->SyncPeriod; - pDCBTemp->SyncOffset = pDCB->SyncOffset; - pDCBTemp->SyncMode = pDCB->SyncMode; - } - pDCBTemp = pDCBTemp->pNextDCB; - } - } - return; -} - -/* - * scsiiom - * trm_Interrupt - * - * - * ---SCSI bus phase - * - * PH_DATA_OUT 0x00 Data out phase - * PH_DATA_IN 0x01 Data in phase - * PH_COMMAND 0x02 Command phase - * PH_STATUS 0x03 Status phase - * PH_BUS_FREE 0x04 Invalid phase used as bus free - * PH_BUS_FREE 0x05 Invalid phase used as bus free - * PH_MSG_OUT 0x06 Message out phase - * PH_MSG_IN 0x07 Message in phase - * - */ -static void -trm_Disconnect(PACB pACB) -{ - PDCB pDCB; - PSRB pSRB, psrb; - u_int16_t i,j, cnt; - u_int target_id,target_lun; - - TRM_DPRINTF("trm_Disconnect...............\n "); - - pDCB = pACB->pActiveDCB; - if (!pDCB) { - TRM_DPRINTF(" Exception Disconnect DCB=NULL..............\n "); - j = 400; - while (--j) - DELAY(1); - /* 1 msec */ - trm_reg_write16((DO_CLRFIFO | DO_HWRESELECT), - TRMREG_SCSI_CONTROL); - return; - } - pSRB = pDCB->pActiveSRB; - /* bug pSRB=0 */ - target_id = pSRB->pccb->ccb_h.target_id; - target_lun = pSRB->pccb->ccb_h.target_lun; - TRM_DPRINTF(":pDCB->pActiveSRB= %8x \n ",(u_int) pDCB->pActiveSRB); - pACB->pActiveDCB = 0; - pSRB->ScsiPhase = PH_BUS_FREE; - /* SCSI bus free Phase */ - trm_reg_write16((DO_CLRFIFO | DO_HWRESELECT), TRMREG_SCSI_CONTROL); - if (pSRB->SRBState & SRB_UNEXPECT_RESEL) { - pSRB->SRBState = 0; - trm_DoWaitingSRB(pACB); - } else if (pSRB->SRBState & SRB_ABORT_SENT) { - pDCB->DCBFlag = 0; - cnt = pDCB->GoingSRBCnt; - pDCB->GoingSRBCnt = 0; - pSRB = pDCB->pGoingSRB; - for (i = 0; i < cnt; i++) { - psrb = pSRB->pNextSRB; - pSRB->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB = pSRB; - pSRB = psrb; - } - pDCB->pGoingSRB = 0; - trm_DoWaitingSRB(pACB); - } else { - if ((pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) || - !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED))) { - /* Selection time out */ - if (!(pACB->scan_devices[target_id][target_lun]) && - pSRB->CmdBlock[0] != 0x00 && /* TEST UNIT READY */ - pSRB->CmdBlock[0] != INQUIRY) { - pSRB->SRBState = SRB_READY; - trm_RewaitSRB(pDCB, pSRB); - } else { - pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT; - goto disc1; - } - } else if (pSRB->SRBState & SRB_DISCONNECT) { - /* - * SRB_DISCONNECT - */ - trm_DoWaitingSRB(pACB); - } else if (pSRB->SRBState & SRB_COMPLETED) { -disc1: - /* - * SRB_COMPLETED - */ - pDCB->pActiveSRB = 0; - pSRB->SRBState = SRB_FREE; - trm_SRBdone(pACB, pDCB, pSRB); - } - } - return; -} - -static void -trm_Reselect(PACB pACB) -{ - PDCB pDCB; - PSRB pSRB; - u_int16_t RselTarLunId; - - TRM_DPRINTF("trm_Reselect................. \n"); - pDCB = pACB->pActiveDCB; - if (pDCB) { - /* Arbitration lost but Reselection win */ - pSRB = pDCB->pActiveSRB; - pSRB->SRBState = SRB_READY; - trm_RewaitSRB(pDCB, pSRB); - } - /* Read Reselected Target Id and LUN */ - RselTarLunId = trm_reg_read16(TRMREG_SCSI_TARGETID) & 0x1FFF; - pDCB = pACB->pLinkDCB; - while (RselTarLunId != *((u_int16_t *) &pDCB->TargetID)) { - /* get pDCB of the reselect id */ - pDCB = pDCB->pNextDCB; - } - - pACB->pActiveDCB = pDCB; - if (pDCB->SyncMode & EN_TAG_QUEUING) { - pSRB = &pACB->TmpSRB; - pDCB->pActiveSRB = pSRB; - } else { - pSRB = pDCB->pActiveSRB; - if (!pSRB || !(pSRB->SRBState & SRB_DISCONNECT)) { - /* - * abort command - */ - pSRB = &pACB->TmpSRB; - pSRB->SRBState = SRB_UNEXPECT_RESEL; - pDCB->pActiveSRB = pSRB; - trm_EnableMsgOutAbort1(pACB, pSRB); - } else { - if (pDCB->DCBFlag & ABORT_DEV_) { - pSRB->SRBState = SRB_ABORT_SENT; - trm_EnableMsgOutAbort1(pACB, pSRB); - } else - pSRB->SRBState = SRB_DATA_XFER; - } - } - pSRB->ScsiPhase = PH_BUS_FREE; - /* SCSI bus free Phase */ - /* - * Program HA ID, target ID, period and offset - */ - trm_reg_write8((u_int8_t) RselTarLunId,TRMREG_SCSI_TARGETID); - /* target ID */ - trm_reg_write8(pACB->AdaptSCSIID,TRMREG_SCSI_HOSTID); - /* host ID */ - trm_reg_write8(pDCB->SyncPeriod,TRMREG_SCSI_SYNC); - /* period */ - trm_reg_write8(pDCB->SyncOffset,TRMREG_SCSI_OFFSET); - /* offset */ - trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL); - /* it's important for atn stop*/ - /* - * SCSI cammand - */ - trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND); - /* to rls the /ACK signal */ -} - -static void -trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB) -{ - PSRB psrb; - u_int8_t bval, bval1,status; - union ccb *pccb; - struct ccb_scsiio *pcsio; - PSCSI_INQDATA ptr; - int intflag; - u_int target_id,target_lun; - PDCB pTempDCB; - - pccb = pSRB->pccb; - if (pccb == NULL) - return; - pcsio = &pccb->csio; - target_id = pSRB->pccb->ccb_h.target_id; - target_lun = pSRB->pccb->ccb_h.target_lun; - if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - bus_dmasync_op_t op; - if ((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) - op = BUS_DMASYNC_POSTREAD; - else - op = BUS_DMASYNC_POSTWRITE; - bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op); - bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap); - } - /* - * - * target status - * - */ - status = pSRB->TargetStatus; - pcsio->scsi_status=SCSI_STAT_GOOD; - pccb->ccb_h.status = CAM_REQ_CMP; - if (pSRB->SRBFlag & AUTO_REQSENSE) { - /* - * status of auto request sense - */ - pSRB->SRBFlag &= ~AUTO_REQSENSE; - pSRB->AdaptStatus = 0; - pSRB->TargetStatus = SCSI_STATUS_CHECK_COND; - - if (status == SCSI_STATUS_CHECK_COND) { - pccb->ccb_h.status = CAM_SEL_TIMEOUT; - goto ckc_e; - } - *((u_long *) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0]; - *((u_long *) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1]; - pSRB->SRBTotalXferLength = pSRB->Segment1[1]; - pSRB->pSRBSGL->address = pSRB->SgSenseTemp.address; - pSRB->pSRBSGL->length = pSRB->SgSenseTemp.length; - pcsio->scsi_status = SCSI_STATUS_CHECK_COND; - bcopy(trm_get_sense_buf(pACB, pSRB), &pcsio->sense_data, - pcsio->sense_len); - pcsio->ccb_h.status = CAM_SCSI_STATUS_ERROR - | CAM_AUTOSNS_VALID; - goto ckc_e; - } - /* - * target status - */ - if (status) { - if (status == SCSI_STATUS_CHECK_COND) { - if ((pcsio->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) { - TRM_DPRINTF("trm_RequestSense..................\n"); - trm_RequestSense(pACB, pDCB, pSRB); - return; - } - pcsio->scsi_status = SCSI_STATUS_CHECK_COND; - pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; - goto ckc_e; - } else if (status == SCSI_STAT_QUEUEFULL) { - bval = (u_int8_t) pDCB->GoingSRBCnt; - bval--; - pDCB->MaxActiveCommandCnt = bval; - trm_RewaitSRB(pDCB, pSRB); - pSRB->AdaptStatus = 0; - pSRB->TargetStatus = 0; - return; - } else if (status == SCSI_STAT_SEL_TIMEOUT) { - pSRB->AdaptStatus = H_SEL_TIMEOUT; - pSRB->TargetStatus = 0; - pcsio->scsi_status = SCSI_STAT_SEL_TIMEOUT; - pccb->ccb_h.status = CAM_SEL_TIMEOUT; - } else if (status == SCSI_STAT_BUSY) { - TRM_DPRINTF("trm: target busy at %s %d\n", - __FILE__, __LINE__); - pcsio->scsi_status = SCSI_STAT_BUSY; - pccb->ccb_h.status = CAM_SCSI_BUSY; - return; - /* The device busy, try again later? */ - } else if (status == SCSI_STAT_RESCONFLICT) { - TRM_DPRINTF("trm: target reserved at %s %d\n", - __FILE__, __LINE__); - pcsio->scsi_status = SCSI_STAT_RESCONFLICT; - pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; /*XXX*/ - return; - } else { - pSRB->AdaptStatus = 0; - if (pSRB->RetryCnt) { - pSRB->RetryCnt--; - pSRB->TargetStatus = 0; - pSRB->SRBSGIndex = 0; - if (trm_StartSCSI(pACB, pDCB, pSRB)) { - /* - * If trm_StartSCSI return 1 : - * current interrupt status is interrupt - * disreenable - * It's said that SCSI processor has more - * one SRB need to do - */ - trm_RewaitSRB(pDCB, pSRB); - } - return; - } else { - TRM_DPRINTF("trm: driver stuffup at %s %d\n", - __FILE__, __LINE__); - pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; - } - } - } else { - /* - * process initiator status.......................... - * Adapter (initiator) status - */ - status = pSRB->AdaptStatus; - if (status & H_OVER_UNDER_RUN) { - pSRB->TargetStatus = 0; - pccb->ccb_h.status = CAM_DATA_RUN_ERR; - /* Illegal length (over/under run) */ - } else if (pSRB->SRBStatus & PARITY_ERROR) { - TRM_DPRINTF("trm: driver stuffup %s %d\n", - __FILE__, __LINE__); - pDCB->tinfo.goal.period = 0; - pDCB->tinfo.goal.offset = 0; - /* Driver failed to perform operation */ - pccb->ccb_h.status = CAM_UNCOR_PARITY; - } else { - /* no error */ - pSRB->AdaptStatus = 0; - pSRB->TargetStatus = 0; - pccb->ccb_h.status = CAM_REQ_CMP; - /* there is no error, (sense is invalid) */ - } - } -ckc_e: - if (pACB->scan_devices[target_id][target_lun]) { - /* - * if SCSI command in "scan devices" duty - */ - if (pSRB->CmdBlock[0] == TEST_UNIT_READY) - pACB->scan_devices[target_id][target_lun] = 0; - /* SCSI command phase :test unit ready */ - else if (pSRB->CmdBlock[0] == INQUIRY) { - /* - * SCSI command phase :inquiry scsi device data - * (type,capacity,manufacture.... - */ - if (pccb->ccb_h.status == CAM_SEL_TIMEOUT) - goto NO_DEV; - ptr = (PSCSI_INQDATA) pcsio->data_ptr; - /* page fault */ - TRM_DPRINTF("trm_SRBdone..PSCSI_INQDATA:%2x \n", - ptr->DevType); - bval1 = ptr->DevType & SCSI_DEVTYPE; - if (bval1 == SCSI_NODEV) { -NO_DEV: - TRM_DPRINTF("trm_SRBdone NO Device:target_id= %d ,target_lun= %d \n", - target_id, - target_lun); - intflag = splcam(); - pACB->scan_devices[target_id][target_lun] = 0; - /* no device set scan device flag =0*/ - /* pDCB Q link */ - /* move the head of DCB to tempDCB*/ - pTempDCB=pACB->pLinkDCB; - /* search current DCB for pass link */ - while (pTempDCB->pNextDCB != pDCB) { - pTempDCB = pTempDCB->pNextDCB; - } - /* - * when the current DCB found than connect - * current DCB tail - */ - /* to the DCB tail that before current DCB */ - pTempDCB->pNextDCB = pDCB->pNextDCB; - /* - * if there was only one DCB ,connect his tail - * to his head - */ - if (pACB->pLinkDCB == pDCB) - pACB->pLinkDCB = pTempDCB->pNextDCB; - if (pACB->pDCBRunRobin == pDCB) - pACB->pDCBRunRobin = pTempDCB->pNextDCB; - pDCB->DCBstatus &= ~DS_IN_QUEUE; - pACB->DeviceCnt--; - if (pACB->DeviceCnt == 0) { - pACB->pLinkDCB = NULL; - pACB->pDCBRunRobin = NULL; - } - splx(intflag); - } else { -#ifdef trm_DEBUG1 - int j; - for (j = 0; j < 28; j++) { - TRM_DPRINTF("ptr=%2x ", - ((u_int8_t *)ptr)[j]); - } -#endif - pDCB->DevType = bval1; - if (bval1 == SCSI_DASD || - bval1 == SCSI_OPTICAL) { - if ((((ptr->Vers & 0x07) >= 2) || - ((ptr->RDF & 0x0F) == 2)) && - (ptr->Flags & SCSI_INQ_CMDQUEUE) && - (pDCB->DevMode & TAG_QUEUING_) && - (pDCB->DevMode & EN_DISCONNECT_)) { - if (pDCB->DevMode & - TAG_QUEUING_) { - pDCB-> - MaxActiveCommandCnt = - pACB->TagMaxNum; - pDCB->SyncMode |= - EN_TAG_QUEUING; - pDCB->tinfo.disc_tag |= - TRM_CUR_TAGENB; - } else { - pDCB->SyncMode |= - EN_ATN_STOP; - pDCB->tinfo.disc_tag &= - ~TRM_CUR_TAGENB; - } - } - } - } - /* pSRB->CmdBlock[0] == INQUIRY */ - } - /* pACB->scan_devices[target_id][target_lun] */ - } - intflag = splcam(); - /* ReleaseSRB(pDCB, pSRB); */ - if (pSRB == pDCB->pGoingSRB) - pDCB->pGoingSRB = pSRB->pNextSRB; - else { - psrb = pDCB->pGoingSRB; - while (psrb->pNextSRB != pSRB) { - psrb = psrb->pNextSRB; - } - psrb->pNextSRB = pSRB->pNextSRB; - if (pSRB == pDCB->pGoingLastSRB) { - pDCB->pGoingLastSRB = psrb; - } - } - pSRB->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB = pSRB; - pDCB->GoingSRBCnt--; - trm_DoWaitingSRB(pACB); - - splx(intflag); - /* Notify cmd done */ - xpt_done (pccb); -} - -static void -trm_DoingSRB_Done(PACB pACB) -{ - PDCB pDCB, pdcb; - PSRB psrb, psrb2; - u_int16_t cnt, i; - union ccb *pccb; - - pDCB = pACB->pLinkDCB; - if (pDCB == NULL) - return; - pdcb = pDCB; - do { - cnt = pdcb->GoingSRBCnt; - psrb = pdcb->pGoingSRB; - for (i = 0; i < cnt; i++) { - psrb2 = psrb->pNextSRB; - pccb = psrb->pccb; - pccb->ccb_h.status = CAM_SEL_TIMEOUT; - /* ReleaseSRB(pDCB, pSRB); */ - psrb->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB = psrb; - xpt_done(pccb); - psrb = psrb2; - } - pdcb->GoingSRBCnt = 0; - pdcb->pGoingSRB = NULL; - pdcb = pdcb->pNextDCB; - } - while (pdcb != pDCB); -} - -static void -trm_ResetSCSIBus(PACB pACB) -{ - int intflag; - - intflag = splcam(); - pACB->ACBFlag |= RESET_DEV; - - trm_reg_write16(DO_RSTSCSI,TRMREG_SCSI_CONTROL); - while (!(trm_reg_read16(TRMREG_SCSI_INTSTATUS) & INT_SCSIRESET)); - splx(intflag); - return; -} - -static void -trm_ScsiRstDetect(PACB pACB) -{ - int intflag; - u_long wlval; - - TRM_DPRINTF("trm_ScsiRstDetect \n"); - wlval = 1000; - while (--wlval) - DELAY(1000); - intflag = splcam(); - trm_reg_write8(STOPDMAXFER,TRMREG_DMA_CONTROL); - - trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL); - - if (pACB->ACBFlag & RESET_DEV) - pACB->ACBFlag |= RESET_DONE; - else { - pACB->ACBFlag |= RESET_DETECT; - trm_ResetDevParam(pACB); - /* trm_DoingSRB_Done(pACB); ???? */ - trm_RecoverSRB(pACB); - pACB->pActiveDCB = NULL; - pACB->ACBFlag = 0; - trm_DoWaitingSRB(pACB); - } - splx(intflag); - return; -} - -static void -trm_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB) -{ - union ccb *pccb; - struct ccb_scsiio *pcsio; - - pccb = pSRB->pccb; - pcsio = &pccb->csio; - - pSRB->SRBFlag |= AUTO_REQSENSE; - pSRB->Segment0[0] = *((u_long *) &(pSRB->CmdBlock[0])); - pSRB->Segment0[1] = *((u_long *) &(pSRB->CmdBlock[4])); - pSRB->Segment1[0] = (u_long) ((pSRB->ScsiCmdLen << 8) + - pSRB->SRBSGCount); - pSRB->Segment1[1] = pSRB->SRBTotalXferLength; /* ?????????? */ - - /* $$$$$$ Status of initiator/target $$$$$$$$ */ - pSRB->AdaptStatus = 0; - pSRB->TargetStatus = 0; - /* $$$$$$ Status of initiator/target $$$$$$$$ */ - - pSRB->SRBTotalXferLength = sizeof(pcsio->sense_data); - pSRB->SgSenseTemp.address = pSRB->pSRBSGL->address; - pSRB->SgSenseTemp.length = pSRB->pSRBSGL->length; - pSRB->pSRBSGL->address = trm_get_sense_bufaddr(pACB, pSRB); - pSRB->pSRBSGL->length = (u_long) sizeof(struct scsi_sense_data); - pSRB->SRBSGCount = 1; - pSRB->SRBSGIndex = 0; - - *((u_long *) &(pSRB->CmdBlock[0])) = 0x00000003; - pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5; - *((u_int16_t *) &(pSRB->CmdBlock[4])) = pcsio->sense_len; - pSRB->ScsiCmdLen = 6; - - if (trm_StartSCSI(pACB, pDCB, pSRB)) - /* - * If trm_StartSCSI return 1 : - * current interrupt status is interrupt disreenable - * It's said that SCSI processor has more one SRB need to do - */ - trm_RewaitSRB(pDCB, pSRB); -} - -static void -trm_EnableMsgOutAbort2(PACB pACB, PSRB pSRB) -{ - - pSRB->MsgCnt = 1; - trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL); -} - -static void -trm_EnableMsgOutAbort1(PACB pACB, PSRB pSRB) -{ - - pSRB->MsgOutBuf[0] = MSG_ABORT; - trm_EnableMsgOutAbort2(pACB, pSRB); -} - -static void -trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,u_int32_t i,u_int32_t j) -{ - PNVRAMTYPE pEEpromBuf; - u_int8_t bval,PeriodIndex; - u_int target_id,target_lun; - PDCB pTempDCB; - int intflag; - - target_id = i; - target_lun = j; - - /* - * Using the lun 0 device to init other DCB first, if the device - * has been initialized. - * I don't want init sync arguments one by one, it is the same. - */ - if (target_lun != 0 && - (pACB->DCBarray[target_id][0].DCBstatus & DS_IN_QUEUE)) - bcopy(&pACB->DCBarray[target_id][0], pDCB, - sizeof(TRM_DCB)); - intflag = splcam(); - if (pACB->pLinkDCB == 0) { - pACB->pLinkDCB = pDCB; - /* - * RunRobin impersonate the role - * that let each device had good proportion - * about SCSI command proceeding - */ - pACB->pDCBRunRobin = pDCB; - pDCB->pNextDCB = pDCB; - } else { - pTempDCB=pACB->pLinkDCB; - /* search the last nod of DCB link */ - while (pTempDCB->pNextDCB != pACB->pLinkDCB) - pTempDCB = pTempDCB->pNextDCB; - /* connect current DCB with last DCB tail */ - pTempDCB->pNextDCB = pDCB; - /* connect current DCB tail to this DCB Q head */ - pDCB->pNextDCB=pACB->pLinkDCB; - } - splx(intflag); - - pACB->DeviceCnt++; - pDCB->TargetID = target_id; - pDCB->TargetLUN = target_lun; - pDCB->pWaitingSRB = NULL; - pDCB->pGoingSRB = NULL; - pDCB->GoingSRBCnt = 0; - pDCB->pActiveSRB = NULL; - pDCB->MaxActiveCommandCnt = 1; - pDCB->DCBFlag = 0; - pDCB->DCBstatus |= DS_IN_QUEUE; - /* $$$$$$$ */ - pEEpromBuf = &trm_eepromBuf[unit]; - pDCB->DevMode = pEEpromBuf->NvramTarget[target_id].NvmTarCfg0; - pDCB->AdpMode = pEEpromBuf->NvramChannelCfg; - /* $$$$$$$ */ - /* - * disconnect enable ? - */ - if (pDCB->DevMode & NTC_DO_DISCONNECT) { - bval = 0xC0; - pDCB->tinfo.disc_tag |= TRM_USR_DISCENB ; - } else { - bval = 0x80; - pDCB->tinfo.disc_tag &= ~(TRM_USR_DISCENB); - } - bval |= target_lun; - pDCB->IdentifyMsg = bval; - if (target_lun != 0 && - (pACB->DCBarray[target_id][0].DCBstatus & DS_IN_QUEUE)) - return; - /* $$$$$$$ */ - /* - * tag Qing enable ? - */ - if (pDCB->DevMode & TAG_QUEUING_) { - pDCB->tinfo.disc_tag |= TRM_USR_TAGENB ; - } else - pDCB->tinfo.disc_tag &= ~(TRM_USR_TAGENB); - /* $$$$$$$ */ - /* - * wide nego ,sync nego enable ? - */ - pDCB->SyncPeriod = 0; - pDCB->SyncOffset = 0; - PeriodIndex = pEEpromBuf->NvramTarget[target_id].NvmTarPeriod & 0x07; - if (pACB->AdaptType==1) {/* is U2? */ - pDCB->MaxNegoPeriod=dc395u2x_clock_period[ PeriodIndex ]; - pDCB->tinfo.user.period=pDCB->MaxNegoPeriod; - pDCB->tinfo.user.offset=(pDCB->SyncMode & SYNC_NEGO_ENABLE) ? 31 : 0; - } else { - pDCB->MaxNegoPeriod=dc395x_clock_period[ PeriodIndex ]; - pDCB->tinfo.user.period=pDCB->MaxNegoPeriod; - pDCB->tinfo.user.offset=(pDCB->SyncMode & SYNC_NEGO_ENABLE) ? 15 : 0; - } - pDCB->SyncMode = 0; - if ((pDCB->DevMode & NTC_DO_WIDE_NEGO) && - (pACB->Config & HCC_WIDE_CARD)) - pDCB->SyncMode |= WIDE_NEGO_ENABLE; - /* enable wide nego */ - if (pDCB->DevMode & NTC_DO_SYNC_NEGO) - pDCB->SyncMode |= SYNC_NEGO_ENABLE; - /* enable sync nego */ - /* $$$$$$$ */ - /* - * Fill in tinfo structure. - */ - pDCB->tinfo.user.width = (pDCB->SyncMode & WIDE_NEGO_ENABLE) ? - MSG_EXT_WDTR_BUS_16_BIT : MSG_EXT_WDTR_BUS_8_BIT; - - pDCB->tinfo.current.period = 0; - pDCB->tinfo.current.offset = 0; - pDCB->tinfo.current.width = MSG_EXT_WDTR_BUS_8_BIT; -} - -static void -trm_srbmapSG(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - PSRB pSRB; - - pSRB=(PSRB) arg; - pSRB->SRBSGPhyAddr=segs->ds_addr; - return; -} - -static void -trm_destroySRB(PACB pACB) -{ - PSRB pSRB; - - pSRB = pACB->pFreeSRB; - while (pSRB) { - if (pSRB->SRBSGPhyAddr) - bus_dmamap_unload(pACB->sg_dmat, pSRB->sg_dmamap); - if (pSRB->pSRBSGL) - bus_dmamem_free(pACB->sg_dmat, pSRB->pSRBSGL, - pSRB->sg_dmamap); - if (pSRB->dmamap) - bus_dmamap_destroy(pACB->buffer_dmat, pSRB->dmamap); - pSRB = pSRB->pNextSRB; - } -} - -static int -trm_initSRB(PACB pACB) -{ - u_int16_t i; - PSRB pSRB; - int error; - - for (i = 0; i < TRM_MAX_SRB_CNT; i++) { - pSRB = (PSRB)&pACB->pFreeSRB[i]; - - if (bus_dmamem_alloc(pACB->sg_dmat, (void **)&pSRB->pSRBSGL, - BUS_DMA_NOWAIT, &pSRB->sg_dmamap) !=0 ) { - return ENXIO; - } - bus_dmamap_load(pACB->sg_dmat, pSRB->sg_dmamap, pSRB->pSRBSGL, - TRM_MAX_SG_LISTENTRY * sizeof(SGentry), - trm_srbmapSG, pSRB, /*flags*/0); - if (i != TRM_MAX_SRB_CNT - 1) { - /* - * link all SRB - */ - pSRB->pNextSRB = &pACB->pFreeSRB[i+1]; - } else { - /* - * load NULL to NextSRB of the last SRB - */ - pSRB->pNextSRB = NULL; - } - pSRB->TagNumber = i; - - /* - * Create the dmamap. This is no longer optional! - */ - if ((error = bus_dmamap_create(pACB->buffer_dmat, 0, - &pSRB->dmamap)) != 0) - return (error); - - } - return (0); -} - - - - -static void -trm_initACB(PACB pACB, u_int8_t adaptType, u_int16_t unit) -{ - PNVRAMTYPE pEEpromBuf; - - pEEpromBuf = &trm_eepromBuf[unit]; - pACB->max_id = 15; - - if (pEEpromBuf->NvramChannelCfg & NAC_SCANLUN) - pACB->max_lun = 7; - else - pACB->max_lun = 0; - - TRM_DPRINTF("trm: pACB->max_id= %d pACB->max_lun= %d \n", - pACB->max_id, pACB->max_lun); - pACB->pLinkDCB = NULL; - pACB->pDCBRunRobin = NULL; - pACB->pActiveDCB = NULL; - pACB->AdapterUnit = (u_int8_t)unit; - pACB->AdaptSCSIID = pEEpromBuf->NvramScsiId; - pACB->AdaptSCSILUN = 0; - pACB->DeviceCnt = 0; - pACB->AdaptType = adaptType; - pACB->TagMaxNum = 2 << pEEpromBuf->NvramMaxTag; - pACB->ACBFlag = 0; - return; -} - -static void -NVRAM_trm_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB) -{ - u_int8_t *bpEeprom = (u_int8_t *) pEEpromBuf; - u_int8_t bAddr; - - /* Enable SEEPROM */ - trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) | EN_EEPROM), - TRMREG_GEN_CONTROL); - /* - * Write enable - */ - NVRAM_trm_write_cmd(pACB, 0x04, 0xFF); - trm_reg_write8(0, TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++) { - NVRAM_trm_set_data(pACB, bAddr, *bpEeprom); - } - /* - * Write disable - */ - NVRAM_trm_write_cmd(pACB, 0x04, 0x00); - trm_reg_write8(0 , TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - /* Disable SEEPROM */ - trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) & ~EN_EEPROM), - TRMREG_GEN_CONTROL); - return; -} - -static void -NVRAM_trm_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData) -{ - int i; - u_int8_t bSendData; - /* - * Send write command & address - */ - - NVRAM_trm_write_cmd(pACB, 0x05, bAddr); - /* - * Write data - */ - for (i = 0; i < 8; i++, bData <<= 1) { - bSendData = NVR_SELECT; - if (bData & 0x80) - /* Start from bit 7 */ - bSendData |= NVR_BITOUT; - trm_reg_write8(bSendData , TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - } - trm_reg_write8(NVR_SELECT , TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - /* - * Disable chip select - */ - trm_reg_write8(0 , TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - trm_reg_write8(NVR_SELECT ,TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - /* - * Wait for write ready - */ - while (1) { - trm_reg_write8((NVR_SELECT | NVR_CLOCK), TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - trm_reg_write8(NVR_SELECT, TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - if (trm_reg_read8(TRMREG_GEN_NVRAM) & NVR_BITIN) { - break; - } - } - /* - * Disable chip select - */ - trm_reg_write8(0, TRMREG_GEN_NVRAM); - return; -} - -static void -NVRAM_trm_read_all(PNVRAMTYPE pEEpromBuf, PACB pACB) -{ - u_int8_t *bpEeprom = (u_int8_t*) pEEpromBuf; - u_int8_t bAddr; - - /* - * Enable SEEPROM - */ - trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) | EN_EEPROM), - TRMREG_GEN_CONTROL); - for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++) - *bpEeprom = NVRAM_trm_get_data(pACB, bAddr); - /* - * Disable SEEPROM - */ - trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) & ~EN_EEPROM), - TRMREG_GEN_CONTROL); - return; -} - -static u_int8_t -NVRAM_trm_get_data(PACB pACB, u_int8_t bAddr) -{ - int i; - u_int8_t bReadData, bData = 0; - /* - * Send read command & address - */ - - NVRAM_trm_write_cmd(pACB, 0x06, bAddr); - - for (i = 0; i < 8; i++) { - /* - * Read data - */ - trm_reg_write8((NVR_SELECT | NVR_CLOCK) , TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - trm_reg_write8(NVR_SELECT , TRMREG_GEN_NVRAM); - /* - * Get data bit while falling edge - */ - bReadData = trm_reg_read8(TRMREG_GEN_NVRAM); - bData <<= 1; - if (bReadData & NVR_BITIN) { - bData |= 1; - } - NVRAM_trm_wait_30us(pACB); - } - /* - * Disable chip select - */ - trm_reg_write8(0, TRMREG_GEN_NVRAM); - return (bData); -} - -static void -NVRAM_trm_wait_30us(PACB pACB) -{ - - /* ScsiPortStallExecution(30); wait 30 us */ - trm_reg_write8(5, TRMREG_GEN_TIMER); - while (!(trm_reg_read8(TRMREG_GEN_STATUS) & GTIMEOUT)); - return; -} - -static void -NVRAM_trm_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr) -{ - int i; - u_int8_t bSendData; - - for (i = 0; i < 3; i++, bCmd <<= 1) { - /* - * Program SB+OP code - */ - bSendData = NVR_SELECT; - if (bCmd & 0x04) - bSendData |= NVR_BITOUT; - /* start from bit 2 */ - trm_reg_write8(bSendData, TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - } - for (i = 0; i < 7; i++, bAddr <<= 1) { - /* - * Program address - */ - bSendData = NVR_SELECT; - if (bAddr & 0x40) - /* Start from bit 6 */ - bSendData |= NVR_BITOUT; - trm_reg_write8(bSendData , TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); - } - trm_reg_write8(NVR_SELECT, TRMREG_GEN_NVRAM); - NVRAM_trm_wait_30us(pACB); -} - -static void -trm_check_eeprom(PNVRAMTYPE pEEpromBuf, PACB pACB) -{ - u_int16_t *wpEeprom = (u_int16_t *) pEEpromBuf; - u_int16_t wAddr, wCheckSum; - u_long dAddr, *dpEeprom; - - NVRAM_trm_read_all(pEEpromBuf,pACB); - wCheckSum = 0; - for (wAddr = 0, wpEeprom = (u_int16_t *) pEEpromBuf; - wAddr < 64; wAddr++, wpEeprom++) { - wCheckSum += *wpEeprom; - } - if (wCheckSum != 0x1234) { - /* - * Checksum error, load default - */ - pEEpromBuf->NvramSubVendorID[0] = (u_int8_t) PCI_Vendor_ID_TEKRAM; - pEEpromBuf->NvramSubVendorID[1] = - (u_int8_t) (PCI_Vendor_ID_TEKRAM >> 8); - pEEpromBuf->NvramSubSysID[0] = (u_int8_t) PCI_Device_ID_TRM_S1040; - pEEpromBuf->NvramSubSysID[1] = - (u_int8_t) (PCI_Device_ID_TRM_S1040 >> 8); - pEEpromBuf->NvramSubClass = 0x00; - pEEpromBuf->NvramVendorID[0] = (u_int8_t) PCI_Vendor_ID_TEKRAM; - pEEpromBuf->NvramVendorID[1] = - (u_int8_t) (PCI_Vendor_ID_TEKRAM >> 8); - pEEpromBuf->NvramDeviceID[0] = (u_int8_t) PCI_Device_ID_TRM_S1040; - pEEpromBuf->NvramDeviceID[1] = - (u_int8_t) (PCI_Device_ID_TRM_S1040 >> 8); - pEEpromBuf->NvramReserved = 0x00; - - for (dAddr = 0, dpEeprom = (u_long *) pEEpromBuf->NvramTarget; - dAddr < 16; dAddr++, dpEeprom++) { - *dpEeprom = 0x00000077; - /* NvmTarCfg3,NvmTarCfg2,NvmTarPeriod,NvmTarCfg0 */ - } - - *dpEeprom++ = 0x04000F07; - /* NvramMaxTag,NvramDelayTime,NvramChannelCfg,NvramScsiId */ - *dpEeprom++ = 0x00000015; - /* NvramReserved1,NvramBootLun,NvramBootTarget,NvramReserved0 */ - for (dAddr = 0; dAddr < 12; dAddr++, dpEeprom++) - *dpEeprom = 0x00; - pEEpromBuf->NvramCheckSum = 0x00; - for (wAddr = 0, wCheckSum = 0, wpEeprom = (u_int16_t *) pEEpromBuf; - wAddr < 63; wAddr++, wpEeprom++) - wCheckSum += *wpEeprom; - *wpEeprom = 0x1234 - wCheckSum; - NVRAM_trm_write_all(pEEpromBuf,pACB); - } - return; -} -static int -trm_initAdapter(PACB pACB, u_int16_t unit) -{ - PNVRAMTYPE pEEpromBuf; - u_int16_t wval; - u_int8_t bval; - - pEEpromBuf = &trm_eepromBuf[unit]; - - /* 250ms selection timeout */ - trm_reg_write8(SEL_TIMEOUT, TRMREG_SCSI_TIMEOUT); - /* Mask all the interrupt */ - trm_reg_write8(0x00, TRMREG_DMA_INTEN); - trm_reg_write8(0x00, TRMREG_SCSI_INTEN); - /* Reset SCSI module */ - trm_reg_write16(DO_RSTMODULE, TRMREG_SCSI_CONTROL); - /* program configuration 0 */ - pACB->Config = HCC_AUTOTERM | HCC_PARITY; - if (trm_reg_read8(TRMREG_GEN_STATUS) & WIDESCSI) - pACB->Config |= HCC_WIDE_CARD; - if (pEEpromBuf->NvramChannelCfg & NAC_POWERON_SCSI_RESET) - pACB->Config |= HCC_SCSI_RESET; - if (pACB->Config & HCC_PARITY) - bval = PHASELATCH | INITIATOR | BLOCKRST | PARITYCHECK; - else - bval = PHASELATCH | INITIATOR | BLOCKRST ; - trm_reg_write8(bval,TRMREG_SCSI_CONFIG0); - /* program configuration 1 */ - trm_reg_write8(0x13, TRMREG_SCSI_CONFIG1); - /* program Host ID */ - bval = pEEpromBuf->NvramScsiId; - trm_reg_write8(bval, TRMREG_SCSI_HOSTID); - /* set ansynchronous transfer */ - trm_reg_write8(0x00, TRMREG_SCSI_OFFSET); - /* Trun LED control off*/ - wval = trm_reg_read16(TRMREG_GEN_CONTROL) & 0x7F; - trm_reg_write16(wval, TRMREG_GEN_CONTROL); - /* DMA config */ - wval = trm_reg_read16(TRMREG_DMA_CONFIG) | DMA_ENHANCE; - trm_reg_write16(wval, TRMREG_DMA_CONFIG); - /* Clear pending interrupt status */ - trm_reg_read8(TRMREG_SCSI_INTSTATUS); - /* Enable SCSI interrupt */ - trm_reg_write8(0x7F, TRMREG_SCSI_INTEN); - trm_reg_write8(EN_SCSIINTR, TRMREG_DMA_INTEN); - return (0); -} - -static void -trm_mapSRB(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - PACB pACB; - - pACB = (PACB)arg; - pACB->srb_physbase = segs->ds_addr; -} - -static void -trm_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - bus_addr_t *baddr; - - baddr = (bus_addr_t *)arg; - *baddr = segs->ds_addr; -} - -static PACB -trm_init(u_int16_t unit, device_t dev) -{ - PACB pACB; - int rid = PCIR_BAR(0), i = 0, j = 0; - u_int16_t adaptType = 0; - - pACB = (PACB) device_get_softc(dev); - if (!pACB) { - printf("trm%d: cannot allocate ACB !\n", unit); - return (NULL); - } - pACB->iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, - &rid, RF_ACTIVE); - if (pACB->iores == NULL) { - printf("trm_init: bus_alloc_resource failed!\n"); - return (NULL); - } - switch (pci_get_devid(dev)) { - case PCI_DEVICEID_TRMS1040: - adaptType = 0; - break; - case PCI_DEVICEID_TRMS2080: - adaptType = 1; - break; - default: - printf("trm_init %d: unknown adapter type!\n", unit); - goto bad; - } - pACB->dev = dev; - pACB->tag = rman_get_bustag(pACB->iores); - pACB->bsh = rman_get_bushandle(pACB->iores); - if (bus_dma_tag_create( - /*parent_dmat*/ bus_get_dma_tag(dev), - /*alignment*/ 1, - /*boundary*/ 0, - /*lowaddr*/ BUS_SPACE_MAXADDR, - /*highaddr*/ BUS_SPACE_MAXADDR, - /*filter*/ NULL, - /*filterarg*/ NULL, - /*maxsize*/ BUS_SPACE_MAXSIZE_32BIT, - /*nsegments*/ BUS_SPACE_UNRESTRICTED, - /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT, - /*flags*/ 0, - /*lockfunc*/ NULL, - /*lockarg*/ NULL, - /* dmat */ &pACB->parent_dmat) != 0) - goto bad; - if (bus_dma_tag_create( - /*parent_dmat*/ pACB->parent_dmat, - /*alignment*/ 1, - /*boundary*/ 0, - /*lowaddr*/ BUS_SPACE_MAXADDR, - /*highaddr*/ BUS_SPACE_MAXADDR, - /*filter*/ NULL, - /*filterarg*/ NULL, - /*maxsize*/ TRM_MAXPHYS, - /*nsegments*/ TRM_NSEG, - /*maxsegsz*/ TRM_MAXTRANSFER_SIZE, - /*flags*/ BUS_DMA_ALLOCNOW, - /*lockfunc*/ busdma_lock_mutex, - /*lockarg*/ &Giant, - /* dmat */ &pACB->buffer_dmat) != 0) - goto bad; - /* DMA tag for our ccb structures */ - if (bus_dma_tag_create( - /*parent_dmat*/pACB->parent_dmat, - /*alignment*/ 1, - /*boundary*/ 0, - /*lowaddr*/ BUS_SPACE_MAXADDR, - /*highaddr*/ BUS_SPACE_MAXADDR, - /*filter*/ NULL, - /*filterarg*/ NULL, - /*maxsize*/ TRM_MAX_SRB_CNT * sizeof(TRM_SRB), - /*nsegments*/ 1, - /*maxsegsz*/ TRM_MAXTRANSFER_SIZE, - /*flags*/ 0, - /*lockfunc*/ busdma_lock_mutex, - /*lockarg*/ &Giant, - /*dmat*/ &pACB->srb_dmat) != 0) { - printf("trm_init %d: bus_dma_tag_create SRB failure\n", unit); - goto bad; - } - if (bus_dmamem_alloc(pACB->srb_dmat, (void **)&pACB->pFreeSRB, - BUS_DMA_NOWAIT, &pACB->srb_dmamap) != 0) { - printf("trm_init %d: bus_dmamem_alloc SRB failure\n", unit); - goto bad; - } - bus_dmamap_load(pACB->srb_dmat, pACB->srb_dmamap, pACB->pFreeSRB, - TRM_MAX_SRB_CNT * sizeof(TRM_SRB), trm_mapSRB, pACB, - /* flags */0); - /* Create, allocate, and map DMA buffers for autosense data */ - if (bus_dma_tag_create( - /*parent_dmat*/pACB->parent_dmat, - /*alignment*/1, - /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - sizeof(struct scsi_sense_data) * TRM_MAX_SRB_CNT, - /*nsegments*/1, - /*maxsegsz*/TRM_MAXTRANSFER_SIZE, - /*flags*/0, /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, &pACB->sense_dmat) != 0) { - if (bootverbose) - device_printf(dev, "cannot create sense buffer dmat\n"); - goto bad; - } - - if (bus_dmamem_alloc(pACB->sense_dmat, (void **)&pACB->sense_buffers, - BUS_DMA_NOWAIT, &pACB->sense_dmamap) != 0) - goto bad; - - bus_dmamap_load(pACB->sense_dmat, pACB->sense_dmamap, - pACB->sense_buffers, - sizeof(struct scsi_sense_data) * TRM_MAX_SRB_CNT, - trm_dmamap_cb, &pACB->sense_busaddr, /*flags*/0); - - trm_check_eeprom(&trm_eepromBuf[unit],pACB); - trm_initACB(pACB, adaptType, unit); - for (i = 0; i < (pACB->max_id + 1); i++) { - if (pACB->AdaptSCSIID == i) - continue; - for(j = 0; j < (pACB->max_lun + 1); j++) { - pACB->scan_devices[i][j] = 1; - /* we assume we need to scan all devices */ - trm_initDCB(pACB, &pACB->DCBarray[i][j], unit, i, j); - } - } - bzero(pACB->pFreeSRB, TRM_MAX_SRB_CNT * sizeof(TRM_SRB)); - if (bus_dma_tag_create( - /*parent_dmat*/pACB->parent_dmat, - /*alignment*/ 1, - /*boundary*/ 0, - /*lowaddr*/ BUS_SPACE_MAXADDR, - /*highaddr*/ BUS_SPACE_MAXADDR, - /*filter*/ NULL, - /*filterarg*/ NULL, - /*maxsize*/ TRM_MAX_SG_LISTENTRY * sizeof(SGentry), - /*nsegments*/ 1, - /*maxsegsz*/ TRM_MAXTRANSFER_SIZE, - /*flags*/ 0, - /*lockfunc*/ busdma_lock_mutex, - /*lockarg*/ &Giant, - /*dmat*/ &pACB->sg_dmat) != 0) - goto bad; - - if (trm_initSRB(pACB)) { - printf("trm_initSRB: error\n"); - goto bad; - } - if (trm_initAdapter(pACB, unit)) { - printf("trm_initAdapter: initial ERROR\n"); - goto bad; - } - return (pACB); -bad: - if (pACB->iores) - bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), - pACB->iores); - if (pACB->sense_dmamap) { - bus_dmamap_unload(pACB->sense_dmat, pACB->sense_dmamap); - bus_dmamem_free(pACB->sense_dmat, pACB->sense_buffers, - pACB->sense_dmamap); - } - if (pACB->sense_dmat) - bus_dma_tag_destroy(pACB->sense_dmat); - if (pACB->sg_dmat) { - trm_destroySRB(pACB); - bus_dma_tag_destroy(pACB->sg_dmat); - } - if (pACB->pFreeSRB) { - bus_dmamap_unload(pACB->srb_dmat, pACB->srb_dmamap); - bus_dmamem_free(pACB->srb_dmat, pACB->pFreeSRB, - pACB->srb_dmamap); - } - if (pACB->srb_dmat) - bus_dma_tag_destroy(pACB->srb_dmat); - if (pACB->buffer_dmat) - bus_dma_tag_destroy(pACB->buffer_dmat); - if (pACB->parent_dmat) - bus_dma_tag_destroy(pACB->parent_dmat); - return (NULL); -} - -static int -trm_attach(device_t dev) -{ - struct cam_devq *device_Q; - u_long device_id; - PACB pACB = 0; - int rid = 0; - int unit = device_get_unit(dev); - - gone_in(13, "Giant locked CAM drivers"); - - device_id = pci_get_devid(dev); - /* - * These cards do not allow memory mapped accesses - */ - if ((pACB = trm_init((u_int16_t) unit, - dev)) == NULL) { - printf("trm%d: trm_init error!\n",unit); - return (ENXIO); - } - /* After setting up the adapter, map our interrupt */ - /* - * Now let the CAM generic SCSI layer find the SCSI devices on the bus - * start queue to reset to the idle loop. - * Create device queue of SIM(s) - * (MAX_START_JOB - 1) : max_sim_transactions - */ - pACB->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_SHAREABLE | RF_ACTIVE); - if (pACB->irq == NULL || - bus_setup_intr(dev, pACB->irq, - INTR_TYPE_CAM, NULL, trm_Interrupt, pACB, &pACB->ih)) { - printf("trm%d: register Interrupt handler error!\n", unit); - goto bad; - } - device_Q = cam_simq_alloc(TRM_MAX_START_JOB); - if (device_Q == NULL){ - printf("trm%d: device_Q == NULL !\n",unit); - goto bad; - } - /* - * Now tell the generic SCSI layer - * about our bus. - * If this is the xpt layer creating a sim, then it's OK - * to wait for an allocation. - * XXX Should we pass in a flag to indicate that wait is OK? - * - * SIM allocation - * - * SCSI Interface Modules - * The sim driver creates a sim for each controller. The sim device - * queue is separately created in order to allow resource sharing betwee - * sims. For instance, a driver may create one sim for each channel of - * a multi-channel controller and use the same queue for each channel. - * In this way, the queue resources are shared across all the channels - * of the multi-channel controller. - * trm_action : sim_action_func - * trm_poll : sim_poll_func - * "trm" : sim_name ,if sim_name = "xpt" ..M_DEVBUF,M_WAITOK - * pACB : *softc if sim_name <> "xpt" ..M_DEVBUF,M_NOWAIT - * pACB->unit : unit - * 1 : max_dev_transactions - * MAX_TAGS : max_tagged_dev_transactions - * - * *******Construct our first channel SIM entry - */ - pACB->psim = cam_sim_alloc(trm_action, - trm_poll, - "trm", - pACB, - unit, - &Giant, - 1, - TRM_MAX_TAGS_CMD_QUEUE, - device_Q); - if (pACB->psim == NULL) { - printf("trm%d: SIM allocate fault !\n",unit); - cam_simq_free(device_Q); /* SIM allocate fault*/ - goto bad; - } - if (xpt_bus_register(pACB->psim, dev, 0) != CAM_SUCCESS) { - printf("trm%d: xpt_bus_register fault !\n",unit); - goto bad; - } - if (xpt_create_path(&pACB->ppath, - NULL, - cam_sim_path(pACB->psim), - CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - printf("trm%d: xpt_create_path fault !\n",unit); - xpt_bus_deregister(cam_sim_path(pACB->psim)); - goto bad; - } - return (0); -bad: - if (pACB->iores) - bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), - pACB->iores); - if (pACB->sg_dmat) { - trm_destroySRB(pACB); - bus_dma_tag_destroy(pACB->sg_dmat); - } - - if (pACB->pFreeSRB) { - bus_dmamap_unload(pACB->srb_dmat, pACB->srb_dmamap); - bus_dmamem_free(pACB->srb_dmat, pACB->pFreeSRB, - pACB->srb_dmamap); - } - if (pACB->srb_dmat) - bus_dma_tag_destroy(pACB->srb_dmat); - if (pACB->sense_buffers) { - bus_dmamap_unload(pACB->sense_dmat, pACB->sense_dmamap); - bus_dmamem_free(pACB->sense_dmat, pACB->sense_buffers, - pACB->sense_dmamap); - } - if (pACB->sense_dmat) - bus_dma_tag_destroy(pACB->sense_dmat); - if (pACB->buffer_dmat) - bus_dma_tag_destroy(pACB->buffer_dmat); - if (pACB->ih) - bus_teardown_intr(dev, pACB->irq, pACB->ih); - if (pACB->irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irq); - if (pACB->psim) - cam_sim_free(pACB->psim, TRUE); - - return (ENXIO); - -} - -/* -* pci_device -* trm_probe (device_t tag, pcidi_t type) -* -*/ -static int -trm_probe(device_t dev) -{ - switch (pci_get_devid(dev)) { - case PCI_DEVICEID_TRMS1040: - device_set_desc(dev, - "Tekram DC395U/UW/F DC315/U Fast20 Wide SCSI Adapter"); - return (BUS_PROBE_DEFAULT); - case PCI_DEVICEID_TRMS2080: - device_set_desc(dev, - "Tekram DC395U2D/U2W Fast40 Wide SCSI Adapter"); - return (BUS_PROBE_DEFAULT); - default: - return (ENXIO); - } -} - -static int -trm_detach(device_t dev) -{ - PACB pACB = device_get_softc(dev); - - bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), pACB->iores); - trm_destroySRB(pACB); - bus_dma_tag_destroy(pACB->sg_dmat); - bus_dmamap_unload(pACB->srb_dmat, pACB->srb_dmamap); - bus_dmamem_free(pACB->srb_dmat, pACB->pFreeSRB, - pACB->srb_dmamap); - bus_dma_tag_destroy(pACB->srb_dmat); - bus_dmamap_unload(pACB->sense_dmat, pACB->sense_dmamap); - bus_dmamem_free(pACB->sense_dmat, pACB->sense_buffers, - pACB->sense_dmamap); - bus_dma_tag_destroy(pACB->sense_dmat); - bus_dma_tag_destroy(pACB->buffer_dmat); - bus_teardown_intr(dev, pACB->irq, pACB->ih); - bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irq); - xpt_async(AC_LOST_DEVICE, pACB->ppath, NULL); - xpt_free_path(pACB->ppath); - xpt_bus_deregister(cam_sim_path(pACB->psim)); - cam_sim_free(pACB->psim, TRUE); - return (0); -} -static device_method_t trm_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, trm_probe), - DEVMETHOD(device_attach, trm_attach), - DEVMETHOD(device_detach, trm_detach), - { 0, 0 } -}; - -static driver_t trm_driver = { - "trm", trm_methods, sizeof(struct _ACB) -}; - -static devclass_t trm_devclass; -DRIVER_MODULE(trm, pci, trm_driver, trm_devclass, 0, 0); -MODULE_DEPEND(trm, pci, 1, 1, 1); -MODULE_DEPEND(trm, cam, 1, 1, 1); Index: sys/i386/conf/GENERIC =================================================================== --- sys/i386/conf/GENERIC +++ sys/i386/conf/GENERIC @@ -136,7 +136,6 @@ device mps # LSI-Logic MPT-Fusion 2 device mpr # LSI-Logic MPT-Fusion 3 device sym # NCR/Symbios Logic -device trm # Tekram DC395U/UW/F DC315U adapters device isci # Intel C600 SAS controller device pvscsi # VMware PVSCSI Index: sys/modules/Makefile =================================================================== --- sys/modules/Makefile +++ sys/modules/Makefile @@ -352,7 +352,6 @@ tmpfs \ ${_toecore} \ ${_tpm} \ - trm \ ${_twa} \ twe \ tws \ Index: sys/modules/trm/Makefile =================================================================== --- sys/modules/trm/Makefile +++ sys/modules/trm/Makefile @@ -1,9 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/trm - -KMOD= trm -SRCS= trm.c trm.h opt_cam.h device_if.h bus_if.h \ - opt_scsi.h pci_if.h - -.include