diff options
Diffstat (limited to 'linux/src/drivers/scsi/tmscsiw.c')
-rw-r--r-- | linux/src/drivers/scsi/tmscsiw.c | 2096 |
1 files changed, 0 insertions, 2096 deletions
diff --git a/linux/src/drivers/scsi/tmscsiw.c b/linux/src/drivers/scsi/tmscsiw.c deleted file mode 100644 index d32b9fc..0000000 --- a/linux/src/drivers/scsi/tmscsiw.c +++ /dev/null @@ -1,2096 +0,0 @@ -/*********************************************************************** - * FILE NAME : TMSCSIW.C * - * BY : C.L. Huang (ching@tekram.com.tw) * - * Description: Device Driver for Tekram DC-390W/U/F (T) PCI SCSI * - * Bus Master Host Adapter * - * (C)Copyright 1995-1996 Tekram Technology Co., Ltd. * - ***********************************************************************/ -/* Minor enhancements and bugfixes by * - * Kurt Garloff <K.Garloff@ping.de> * - ***********************************************************************/ -/* HISTORY: * - * * - * REV# DATE NAME DESCRIPTION * - * 1.00 04/03/96 CLH First release * - * 1.01 04/11/96 CLH Maximum support up to 4 Adapters, * - * support KV 1_3_85 * - * 1.02 04/26/96 CLH fixed bug about EEpromBuf when >1 HA * - * 1.03 06/12/96 CLH fixed bug of Media Change for Removable * - * Device, scan all LUN. Support Pre2.0.10 * - * 1.04 06/18/96 CLH fixed bug of Command timeout .... * - * 1.05 10/04/96 CLH Updating for support KV 2.0.0, 2.0.20 * - * 1.06 10/30/96 KG Fixed bug in DC390W_abort(), module * - * support, added tmscsiw_proc_info() * - * 1.07 11/09/96 KG Fixed bug in tmscsiw_proc_info() * - * 1.08 11/18/96 CLH/KG ditto, null ptr in DC390W_Disconnect() * - * 1.09 11/30/96 KG Fixed bug in CheckEEpromCheckSum(), * - * add register the allocated IO space * - * 1.10 12/05/96 CLH Modify in tmscsiw_proc_info() and add * - * in DC390W_initAdapter() for 53C875 * - * Rev. F with double clock. * - * 1.11 02/04/97 CLH Fixed bug of Formatting a partition that* - * across 1GB boundary, with bad sector * - * checking. * - * 1.12 02/17/97 CLH Fixed bug in CheckEEpromCheckSum() * - ***********************************************************************/ - - -#define DC390W_DEBUG -/* #define CHK_UNDER_RUN */ - -#define SCSI_MALLOC - -#ifdef MODULE -#include <linux/module.h> -#endif - -#include <asm/dma.h> -#include <asm/io.h> -#include <asm/system.h> -#include <linux/delay.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/ioport.h> -#include <linux/bios32.h> -#include <linux/pci.h> -#include <linux/proc_fs.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/config.h> - -#include <linux/version.h> -#if LINUX_VERSION_CODE < 66354 /* 1.3.50 */ -#include "../block/blk.h" -#else -#include <linux/blk.h> -#endif - -#include "scsi.h" -#include "hosts.h" -#include "tmscsiw.h" -#include "constants.h" -#include "sd.h" -#include "scripts.h" -#include <linux/stat.h> - -#include "dc390w.h" - -#ifndef VERSION_ELF_1_2_13 -struct proc_dir_entry proc_scsi_tmscsiw ={ - PROC_SCSI_DC390WUF, 7 ,"tmscsiw", - S_IFDIR | S_IRUGO | S_IXUGO, 2 - }; -#endif - -static void DC390W_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB ); -static void PrepareSG( PACB pACB, PDCB pDCB, PSRB pSRB ); -static void DoingSRB_Done( PACB pACB ); -static void ExceptionHandler(ULONG wlval, PACB pACB, PDCB pDCB); -static void ParityError( PACB pACB, PDCB pDCB ); -static void PhaseMismatch( PACB pACB ); -static void DC390W_ScsiRstDetect( PACB pACB ); -static void DC390W_ResetSCSIBus( PACB pACB ); -static void DC390W_ResetSCSIBus2( PACB pACB ); -static void AdjustTemp( PACB pACB, PDCB pDCB, PSRB pSRB ); -static void SetXferRate( PACB pACB, PDCB pDCB ); -static void DataIOcommon( PACB pACB, ULONG Swlval, ULONG Cwlval ); -static void SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB ); -static void RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB ); - -static void DC390W_CmdCompleted( PACB pACB ); -static void DC390W_Reselected( PACB pACB ); -static void DC390W_Reselected1( PACB pACB ); -static void DC390W_ReselectedT( PACB pACB ); -static void DC390W_Disconnected( PACB pACB ); -static void DC390W_MessageExtnd( PACB pACB ); -static void DC390W_Signal( PACB pACB ); -static void DC390W_UnknownMsg( PACB pACB ); -static void DC390W_MessageOut( PACB pACB ); -static void DC390W_FatalError( PACB pACB ); -static void DC390W_MessageSync( PACB pACB ); -static void DC390W_MessageWide( PACB pACB ); -static void DC390W_RestorePtr( PACB pACB ); -static void DC390W_MsgReject( PACB pACB ); -static void DC390W_Debug( PACB pACB ); -static void DC390W_download_script (struct Scsi_Host *host); - -int DC390W_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index); -void DC390W_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd ); -void MyDelay( void ); -void EnDisableCE( UCHAR Flag, USHORT scsiIOPort ); -void EEpromOutDI( USHORT Carry, USHORT scsiIOPort ); -void EEpromPrepare( UCHAR EEpromCmd, USHORT scsiIOPort ); -void ReadEEprom( PUCHAR EEpromBuf, USHORT scsiIOPort ); -UCHAR EEpromInDo(USHORT scsiIOPort); -USHORT EEpromGetData(USHORT scsiIOPort); -USHORT CheckEEpromCheckSum( PUCHAR EEpromBuf, USHORT scsiIOPort); - -#ifdef MODULE -static int DC390W_release(struct Scsi_Host *host); -static int DC390W_shutdown (struct Scsi_Host *host); -#endif - - -static ULONG jmp_table16; -static ULONG jmp_din16; -static ULONG jmp_dout16; -static PSHT pSHT_start = NULL; -static PSH pSH_start = NULL; -static PSH pSH_current = NULL; -static PACB pACB_start= NULL; -static PACB pACB_current = NULL; -static PDCB pPrevDCB = NULL; -static USHORT adapterCnt = 0; -static USHORT InitialTime = 0; -static USHORT CurrDCBscntl3 = 0; -static UCHAR pad_buffer[128]; - -static PVOID IntVector[]={ - DC390W_CmdCompleted, - DC390W_Reselected, - DC390W_Reselected1, - DC390W_ReselectedT, - DC390W_Disconnected, - DC390W_MessageExtnd, - DC390W_Signal, - DC390W_UnknownMsg, - DC390W_MessageOut, - DC390W_FatalError, - DC390W_MessageSync, - DC390W_MessageWide, - DC390W_RestorePtr, - DC390W_MsgReject, - DC390W_Debug, - DC390W_FatalError - }; - -UCHAR eepromBuf[MAX_ADAPTER_NUM][128]; - -UCHAR clock_period[12] = {25, 31, 37, 43, 50, 62, 75, 125, 12, 15, 18, 21}; -UCHAR baddevname[2][28] ={ - "SEAGATE ST3390N 9546", - "SEAGATE ST3390N ??? 0399"}; - -#define BADDEVCNT 2 - -/*********************************************************************** - * - * - * - **********************************************************************/ -static void -QLinkcmd( PSCSICMD cmd, PDCB pDCB ) -{ - ULONG flags; - PSCSICMD pcmd; - - save_flags(flags); - cli(); - - if( !pDCB->QIORBCnt ) - { - pDCB->pQIORBhead = cmd; - pDCB->pQIORBtail = cmd; - pDCB->QIORBCnt++; - cmd->next = NULL; - } - else - { - pcmd = pDCB->pQIORBtail; - pcmd->next = cmd; - pDCB->pQIORBtail = cmd; - pDCB->QIORBCnt++; - cmd->next = NULL; - } - - restore_flags(flags); -} - - -static PSCSICMD -Getcmd( PDCB pDCB ) -{ - ULONG flags; - PSCSICMD pcmd; - - save_flags(flags); - cli(); - - pcmd = pDCB->pQIORBhead; - pDCB->pQIORBhead = pcmd->next; - pcmd->next = NULL; - pDCB->QIORBCnt--; - - restore_flags(flags); - return( pcmd ); -} - - -static PSRB -GetSRB( PACB pACB ) -{ - ULONG flags; - PSRB pSRB; - - save_flags(flags); - cli(); - - pSRB = pACB->pFreeSRB; - if( pSRB ) - { - pACB->pFreeSRB = pSRB->pNextSRB; - pSRB->pNextSRB = NULL; - } - restore_flags(flags); - return( pSRB ); -} - - -static void -RewaitSRB( PDCB pDCB, PSRB pSRB ) -{ - PSRB psrb1; - ULONG flags; - UCHAR bval; - - save_flags(flags); - cli(); - pDCB->GoingSRBCnt--; - psrb1 = pDCB->pGoingSRB; - if( pSRB == psrb1 ) - { - pDCB->pGoingSRB = psrb1->pNextSRB; - } - else - { - while( pSRB != psrb1->pNextSRB ) - psrb1 = psrb1->pNextSRB; - psrb1->pNextSRB = pSRB->pNextSRB; - if( pSRB == pDCB->pGoingLast ) - pDCB->pGoingLast = psrb1; - } - if( (psrb1 = pDCB->pWaitingSRB) ) - { - pSRB->pNextSRB = psrb1; - pDCB->pWaitingSRB = pSRB; - } - else - { - pSRB->pNextSRB = NULL; - pDCB->pWaitingSRB = pSRB; - pDCB->pWaitLast = pSRB; - } - - bval = pSRB->TagNumber; - pDCB->TagMask &= (~(1 << bval)); /* Free TAG number */ - restore_flags(flags); -} - - -static void -DoWaitingSRB( PACB pACB ) -{ - ULONG flags; - PDCB ptr, ptr1; - PSRB pSRB; - - save_flags(flags); - cli(); - - 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->MaxCommand > ptr1->GoingSRBCnt ) || - !( pSRB = ptr1->pWaitingSRB ) ) - { - if(pACB->pDCBRunRobin == ptr) - break; - ptr1 = ptr1->pNextDCB; - } - else - { - DC390W_StartSCSI(pACB, ptr1, pSRB); - ptr1->GoingSRBCnt++; - if( ptr1->pWaitLast == pSRB ) - { - ptr1->pWaitingSRB = NULL; - ptr1->pWaitLast = NULL; - } - else - { - ptr1->pWaitingSRB = pSRB->pNextSRB; - } - pSRB->pNextSRB = NULL; - - if( ptr1->pGoingSRB ) - ptr1->pGoingLast->pNextSRB = pSRB; - else - ptr1->pGoingSRB = pSRB; - ptr1->pGoingLast = pSRB; - - break; - } - } - } - restore_flags(flags); - return; -} - - -static void -SRBwaiting( PDCB pDCB, PSRB pSRB) -{ - if( pDCB->pWaitingSRB ) - { - pDCB->pWaitLast->pNextSRB = pSRB; - pDCB->pWaitLast = pSRB; - pSRB->pNextSRB = NULL; - } - else - { - pDCB->pWaitingSRB = pSRB; - pDCB->pWaitLast = pSRB; - } -} - - -static void -SendSRB( PSCSICMD pcmd, PACB pACB, PSRB pSRB ) -{ - ULONG flags; - PDCB pDCB; - - save_flags(flags); - cli(); - - pDCB = pSRB->pSRBDCB; - PrepareSG( pACB, pDCB, pSRB ); - if( !(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB) || - (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV)) ) - { - SRBwaiting(pDCB, pSRB); - goto SND_EXIT; - } - - if( pDCB->pWaitingSRB ) - { - SRBwaiting(pDCB, pSRB); -/* pSRB = GetWaitingSRB(pDCB); */ - pSRB = pDCB->pWaitingSRB; - pDCB->pWaitingSRB = pSRB->pNextSRB; - pSRB->pNextSRB = NULL; - } - - DC390W_StartSCSI(pACB, pDCB, pSRB); - pDCB->GoingSRBCnt++; - if( pDCB->pGoingSRB ) - { - pDCB->pGoingLast->pNextSRB = pSRB; - pDCB->pGoingLast = pSRB; - } - else - { - pDCB->pGoingSRB = pSRB; - pDCB->pGoingLast = pSRB; - } - -SND_EXIT: - restore_flags(flags); - return; -} - - -/*********************************************************************** - * Function : static int DC390W_queue_command (Scsi_Cmnd *cmd, - * void (*done)(Scsi_Cmnd *)) - * - * Purpose : enqueues a SCSI command - * - * Inputs : cmd - SCSI command, done - function called on completion, with - * a pointer to the command descriptor. - * - * Returns : 0 - * - ***********************************************************************/ - -int -DC390W_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) -{ - USHORT ioport, i; - Scsi_Cmnd *pcmd; - struct Scsi_Host *psh; - PACB pACB; - PDCB pDCB; - PSRB pSRB; - ULONG flags; - PUCHAR ptr,ptr1; - - psh = cmd->host; - pACB = (PACB ) psh->hostdata; - ioport = pACB->IOPortBase; - -#ifdef DC390W_DEBUG0 - printk("Cmd=%x,",cmd->cmnd[0]); -#endif - - if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) ) - { - pACB->scan_devices = 0; - pPrevDCB->pNextDCB = pACB->pLinkDCB; - } - else if( (pACB->scan_devices) && (cmd->cmnd[0] == 8) ) - { - pACB->scan_devices = 0; - pPrevDCB->pNextDCB = pACB->pLinkDCB; - } - - if ( ( cmd->target > pACB->max_id ) || (cmd->lun > pACB->max_lun) ) - { -/* printk("DC390W: Ignore target %d lun %d\n", - cmd->target, cmd->lun); */ - cmd->result = (DID_BAD_TARGET << 16); - done(cmd); - return( 0 ); - } - - if( (pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) ) - { - if( pACB->DeviceCnt < MAX_DEVICES ) - { - pACB->DCBmap[cmd->target] |= (1 << cmd->lun); - pDCB = pACB->pDCB_free; -#ifdef DC390W_DEBUG0 - printk("pDCB=%8x,ID=%2x,", (UINT) pDCB, cmd->target); -#endif - DC390W_initDCB( pACB, pDCB, cmd ); - } - else /* ???? */ - { -/* printk("DC390W: Ignore target %d lun %d\n", - cmd->target, cmd->lun); */ - cmd->result = (DID_BAD_TARGET << 16); - done(cmd); - return(0); - } - } - else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) ) - { -/* printk("DC390W: Ignore target %d lun %d\n", - cmd->target, cmd->lun); */ - cmd->result = (DID_BAD_TARGET << 16); - done(cmd); - return(0); - } - else - { - pDCB = pACB->pLinkDCB; - while( (pDCB->UnitSCSIID != cmd->target) || - (pDCB->UnitSCSILUN != cmd->lun) ) - { - pDCB = pDCB->pNextDCB; - } -#ifdef DC390W_DEBUG0 - printk("pDCB=%8x,ID=%2x,Scan=%1x", (UINT) pDCB, cmd->target, - pACB->scan_devices); -#endif - } - - cmd->scsi_done = done; - cmd->result = 0; - - save_flags(flags); - cli(); - - if( pDCB->QIORBCnt ) - { - QLinkcmd( cmd, pDCB ); - pcmd = Getcmd( pDCB ); - } - else - pcmd = cmd; - - pSRB = GetSRB( pACB ); - - if( !pSRB ) - { - QLinkcmd( pcmd, pDCB ); - restore_flags(flags); - return(0); - } - -/* BuildSRB(pSRB); */ - - pSRB->pSRBDCB = pDCB; - pSRB->pcmd = pcmd; - ptr = (PUCHAR) pSRB->CmdBlock; - ptr1 = (PUCHAR) pcmd->cmnd; - (UCHAR) pSRB->__command[0] = pcmd->cmd_len; - for(i=0; i< pcmd->cmd_len; i++) - { - *ptr = *ptr1; - ptr++; - ptr1++; - } - if( pcmd->use_sg ) - { - pSRB->SGcount = (UCHAR) pcmd->use_sg; - pSRB->pSegmentList = (PSGL) pcmd->request_buffer; - } - else if( pcmd->request_buffer ) - { - pSRB->SGcount = 1; - pSRB->pSegmentList = (PSGL) &pSRB->Segmentx; - pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer; - pSRB->Segmentx.length = pcmd->request_bufflen; - } - else - pSRB->SGcount = 0; - - pSRB->AdaptStatus = 0; - pSRB->TargetStatus = 0; - pSRB->MsgCnt = 0; - if( pDCB->DevType != TYPE_TAPE ) - pSRB->RetryCnt = 1; - else - pSRB->RetryCnt = 0; - pSRB->SRBStatus = 0; - pSRB->SRBFlag = 0; - pSRB->ScratchABuf = 0; - pSRB->SRBState = 0; - pSRB->RemainSegPtr = 0; - pSRB->XferredLen = 0; - SendSRB( pcmd, pACB, pSRB ); - - restore_flags(flags); - return(0); -} - - -static void -DoNextCmd( PACB pACB, PDCB pDCB ) -{ - Scsi_Cmnd *pcmd; - PSRB pSRB; - ULONG flags; - PUCHAR ptr,ptr1; - USHORT i; - - - if( pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) - return; - save_flags(flags); - cli(); - - pcmd = Getcmd( pDCB ); - pSRB = GetSRB( pACB ); - if( !pSRB ) - { - QLinkcmd( pcmd, pDCB ); - restore_flags(flags); - return; - } - - pSRB->pSRBDCB = pDCB; - pSRB->pcmd = pcmd; - ptr = (PUCHAR) pSRB->CmdBlock; - ptr1 = (PUCHAR) pcmd->cmnd; - (UCHAR) pSRB->__command[0] = pcmd->cmd_len; - for(i=0; i< pcmd->cmd_len; i++) - { - *ptr = *ptr1; - ptr++; - ptr1++; - } - if( pcmd->use_sg ) - { - pSRB->SGcount = (UCHAR) pcmd->use_sg; - pSRB->pSegmentList = (PSGL) pcmd->request_buffer; - } - else if( pcmd->request_buffer ) - { - pSRB->SGcount = 1; - pSRB->pSegmentList = (PSGL) &pSRB->Segmentx; - pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer; - pSRB->Segmentx.length = pcmd->request_bufflen; - } - else - pSRB->SGcount = 0; - - pSRB->AdaptStatus = 0; - pSRB->TargetStatus = 0; - pSRB->MsgCnt = 0; - if( pDCB->DevType != TYPE_TAPE ) - pSRB->RetryCnt = 1; - else - pSRB->RetryCnt = 0; - pSRB->SRBStatus = 0; - pSRB->SRBFlag = 0; - pSRB->ScratchABuf = 0; - pSRB->SRBState = 0; - SendSRB( pcmd, pACB, pSRB ); - - restore_flags(flags); - return; -} - - -/*********************************************************************** - * Function: - * DC390W_bios_param - * - * Description: - * Return the disk geometry for the given SCSI device. - ***********************************************************************/ -#ifdef VERSION_ELF_1_2_13 -int DC390W_bios_param(Disk *disk, int devno, int geom[]) -#else -int DC390W_bios_param(Disk *disk, kdev_t devno, int geom[]) -#endif -{ - int heads, sectors, cylinders; - PACB pACB; - - pACB = (PACB) disk->device->host->hostdata; - heads = 64; - sectors = 32; - cylinders = disk->capacity / (heads * sectors); - - if ( (pACB->Gmode2 & GREATER_1G) && (cylinders > 1024) ) - { - heads = 255; - sectors = 63; - cylinders = disk->capacity / (heads * sectors); - } - - geom[0] = heads; - geom[1] = sectors; - geom[2] = cylinders; - - return (0); -} - - -/*********************************************************************** - * Function : int DC390W_abort (Scsi_Cmnd *cmd) - * - * Purpose : Abort an errant SCSI command - * - * Inputs : cmd - command to abort - * - * Returns : 0 on success, -1 on failure. - ***********************************************************************/ - -int -DC390W_abort (Scsi_Cmnd *cmd) -{ - ULONG flags; - PACB pACB; - PDCB pDCB, pdcb; - PSRB pSRB, psrb; - USHORT count, i; - PSCSICMD pcmd, pcmd1; - int status; - - -#ifdef DC390W_DEBUG0 - printk("DC390W : Abort Cmd."); -#endif - - save_flags(flags); - cli(); - - pACB = (PACB) cmd->host->hostdata; - pDCB = pACB->pLinkDCB; - pdcb = pDCB; - while( (pDCB->UnitSCSIID != cmd->target) || - (pDCB->UnitSCSILUN != cmd->lun) ) - { - pDCB = pDCB->pNextDCB; - if( pDCB == pdcb ) - goto NOT_RUN; - } - - if( pDCB->QIORBCnt ) - { - pcmd = pDCB->pQIORBhead; - if( pcmd == cmd ) - { - pDCB->pQIORBhead = pcmd->next; - pcmd->next = NULL; - pDCB->QIORBCnt--; - status = SCSI_ABORT_SUCCESS; - goto ABO_X; - } - for( count = pDCB->QIORBCnt, i=0; i<count-1; i++) - { - if( pcmd->next == cmd ) - { - pcmd1 = pcmd->next; - pcmd->next = pcmd1->next; - pcmd1->next = NULL; - pDCB->QIORBCnt--; - status = SCSI_ABORT_SUCCESS; - goto ABO_X; - } - else - { - pcmd = pcmd->next; - } - } - } - - pSRB = pDCB->pWaitingSRB; - if( !pSRB ) - goto ON_GOING; - if( pSRB->pcmd == cmd ) - { - pDCB->pWaitingSRB = pSRB->pNextSRB; - goto IN_WAIT; - } - else - { - psrb = pSRB; - if( !(psrb->pNextSRB) ) - goto ON_GOING; - while( psrb->pNextSRB->pcmd != cmd ) - { - psrb = psrb->pNextSRB; - if( !(psrb->pNextSRB) ) - goto ON_GOING; - } - pSRB = psrb->pNextSRB; - psrb->pNextSRB = pSRB->pNextSRB; - if( pSRB == pDCB->pWaitLast ) - pDCB->pWaitLast = psrb; -IN_WAIT: - pSRB->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB = pSRB; - cmd->next = NULL; - status = SCSI_ABORT_SUCCESS; - goto ABO_X; - } - -ON_GOING: - pSRB = pDCB->pGoingSRB; - for( count = pDCB->GoingSRBCnt, i=0; i<count; i++) - { - if( pSRB->pcmd != cmd ) - pSRB = pSRB->pNextSRB; - else - { - if( (pACB->pActiveDCB == pDCB) && (pDCB->pActiveSRB == pSRB) ) - { - status = SCSI_ABORT_BUSY; - goto ABO_X; - } - else - { - status = SCSI_ABORT_SNOOZE; - goto ABO_X; - } - } - } - -NOT_RUN: - status = SCSI_ABORT_NOT_RUNNING; - -ABO_X: - cmd->result = DID_ABORT << 16; - cmd->scsi_done(cmd); - restore_flags(flags); - return( status ); -} - - -static void -ResetDevParam( PACB pACB ) -{ - PDCB pDCB, pdcb; - - pDCB = pACB->pLinkDCB; - if( pDCB == NULL ) - return; - pdcb = pDCB; - do - { - if( pACB->AdaptType == DC390W ) - pdcb->DCBscntl3 = SYNC_CLK_F2+ASYNC_CLK_F2; - else - pdcb->DCBscntl3 = SYNC_CLK_F4+ASYNC_CLK_F4; - pdcb->DCBsxfer = 0; - pdcb = pdcb->pNextDCB; - } - while( pdcb != pDCB ); -} - - -static void -RecoverSRB( PACB pACB ) -{ - PDCB pDCB, pdcb; - PSRB psrb, psrb2; - USHORT cnt, i; - - pDCB = pACB->pLinkDCB; - if( pDCB == NULL ) - return; - pdcb = pDCB; - do - { - cnt = pdcb->GoingSRBCnt; - psrb = pdcb->pGoingSRB; - for (i=0; i<cnt; i++) - { - PrepareSG( pACB, pdcb, psrb ); - psrb2 = psrb; - psrb = psrb->pNextSRB; -/* RewaitSRB( pDCB, psrb ); */ - if( pdcb->pWaitingSRB ) - { - psrb2->pNextSRB = pdcb->pWaitingSRB; - pdcb->pWaitingSRB = psrb2; - } - else - { - pdcb->pWaitingSRB = psrb2; - pdcb->pWaitLast = psrb2; - psrb2->pNextSRB = NULL; - } - } - pdcb->GoingSRBCnt = 0; - pdcb->pGoingSRB = NULL; - pdcb->TagMask = 0; - pdcb = pdcb->pNextDCB; - } - while( pdcb != pDCB ); -} - - -/*********************************************************************** - * Function : int DC390W_reset (Scsi_Cmnd *cmd, ...) - * - * Purpose : perform a hard reset on the SCSI bus( and NCR chip). - * - * Inputs : cmd - command which caused the SCSI RESET - * - * Returns : 0 on success. - ***********************************************************************/ - -#ifdef VERSION_2_0_0 -int DC390W_reset(Scsi_Cmnd *cmd, unsigned int resetFlags) -#else -int DC390W_reset (Scsi_Cmnd *cmd) -#endif -{ - USHORT ioport; - unsigned long flags; - PACB pACB; - ULONG wlval; - UCHAR bval; - USHORT wval; - USHORT i; - - -#ifdef DC390W_DEBUG0 - printk("DC390W : Reset Cmd0,"); -#endif - - pACB = (PACB ) cmd->host->hostdata; - ioport = pACB->IOPortBase; - save_flags(flags); - cli(); - bval = inb(ioport+DCNTL); - bval |= IRQ_DISABLE; - outb(bval,ioport+DCNTL); /* disable interrupt */ - DC390W_ResetSCSIBus( pACB ); - for( i=0; i<500; i++ ) - udelay(1000); - for(;;) - { - bval = inb(ioport+ISTAT); - if( bval & SCSI_INT_PENDING ) - { - wval = inw( ioport+SIST0 ); - if( wval & (SCSI_RESET+SCSI_GERROR) ) - break; - } - if(bval & DMA_INT_PENDING) - { - bval = inb(ioport+DSTAT); - if(bval & ABORT_) - { - wval = inw( ioport+SIST0 ); - break; - } - } - } - bval = inb(ioport+DCNTL); - bval &= ~IRQ_DISABLE; - outb(bval,ioport+DCNTL); /* re-enable interrupt */ - - ioport = pACB->IOPortBase; - bval = inb(ioport+STEST3); - bval |= CLR_SCSI_FIFO; - outb(bval,ioport+STEST3); - bval = CLR_DMA_FIFO; - outb(bval,ioport+CTEST3); - ResetDevParam( pACB ); - DoingSRB_Done( pACB ); - pACB->pActiveDCB = NULL; - wlval = pACB->jmp_reselect; - outl(wlval,(ioport+DSP)); - - pACB->ACBFlag = 0; - DoWaitingSRB( pACB ); - restore_flags(flags); - return( SCSI_RESET_SUCCESS ); -} - - -#include "scsiio.c" - - -/*********************************************************************** - * Function : static void DC390W_initDCB - * - * Purpose : initialize the internal structures for a given DCB - * - * Inputs : cmd - pointer to this scsi cmd request block structure - * - ***********************************************************************/ -void DC390W_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd ) -{ - PEEprom prom; - UCHAR bval; - USHORT index; - - if( pACB->DeviceCnt == 0 ) - { - pACB->pLinkDCB = pDCB; - pACB->pDCBRunRobin = pDCB; - pDCB->pNextDCB = pDCB; - pPrevDCB = pDCB; - } - else - pPrevDCB->pNextDCB = pDCB; - - pDCB->pDCBACB = pACB; - pDCB->QIORBCnt = 0; - pDCB->DCBselect = 0; - pDCB->DCBsxfer = 0; - pDCB->DCBsdid = cmd->target; - pDCB->UnitSCSIID = cmd->target; - pDCB->UnitSCSILUN = cmd->lun; - pDCB->pWaitingSRB = NULL; - pDCB->GoingSRBCnt = 0; - pDCB->TagMask = 0; - - pDCB->MaxCommand = 1; - pDCB->AdaptIndex = pACB->AdapterIndex; - index = pACB->AdapterIndex; - - prom = (PEEprom) &eepromBuf[index][cmd->target << 2]; - pDCB->DevMode = prom->EE_MODE1; - pDCB->NegoPeriod = clock_period[prom->EE_SPEED]; - - if( pACB->AdaptType == DC390W ) - pDCB->DCBscntl3 = SYNC_CLK_F2+ASYNC_CLK_F2; - else - pDCB->DCBscntl3 = SYNC_CLK_F4+ASYNC_CLK_F4; - - if( pDCB->DevMode & PARITY_CHK_ ) - pDCB->DCBscntl0 = EN_PARITY_CHK+SATN_IF_PARITY_ERR+FULL_ARBITRATION; - else - pDCB->DCBscntl0 = FULL_ARBITRATION; - - pDCB->AdpMode = eepromBuf[index][EE_MODE2]; - - if( pDCB->DevMode & EN_DISCONNECT_ ) - bval = 0xC0; - else - bval = 0x80; - bval |= cmd->lun; - pDCB->IdentifyMsg = bval; - - if( pDCB->DevMode & SYNC_NEGO_ ) - { - pDCB->SyncMode = SYNC_ENABLE; - pDCB->SyncOffset = SYNC_NEGO_OFFSET; - } - - if( pDCB->DevMode & WIDE_NEGO_ ) - { - if( cmd->lun ) - { - if( !(CurrDCBscntl3 & EN_WIDE_SCSI) ) - pDCB->DevMode &= ~WIDE_NEGO_; - } - else - CurrDCBscntl3 = 0; - } - pDCB->DCBFlag = 0; -} - - -/*********************************************************************** - * Function : static void DC390W_initSRB - * - * Purpose : initialize the internal structures for a given SRB - * - * Inputs : psrb - pointer to this scsi request block structure - * - ***********************************************************************/ -void DC390W_initSRB( PSRB psrb ) -{ -#ifndef VERSION_ELF_1_2_13 - psrb->PhysSRB = virt_to_phys( psrb ); - psrb->__command[1] = virt_to_phys( psrb->CmdBlock ); - psrb->__msgout0[0] = 1; - psrb->__msgout0[1] = virt_to_phys( psrb->MsgOutBuf ); - psrb->SegmentPad[0] = 16; - psrb->SegmentPad[1] = virt_to_phys( pad_buffer ); -#else - psrb->PhysSRB = (ULONG) psrb; - psrb->__command[1] = (ULONG) psrb->CmdBlock; - psrb->__msgout0[0] = 1; - psrb->__msgout0[1] = (ULONG) psrb->MsgOutBuf; - psrb->SegmentPad[0] = 16; - psrb->SegmentPad[1] = (ULONG) pad_buffer; -#endif -} - - -void DC390W_linkSRB( PACB pACB ) -{ - USHORT count, i; - PSRB psrb; - - count = pACB->SRBCount; - - for( i=0; i< count; i++) - { - if( i != count - 1) - pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1]; - else - pACB->SRB_array[i].pNextSRB = NULL; - psrb = (PSRB) &pACB->SRB_array[i]; - DC390W_initSRB( psrb ); - } -} - - -/*********************************************************************** - * Function : static void DC390W_initACB - * - * Purpose : initialize the internal structures for a given SCSI host - * - * Inputs : psh - pointer to this host adapter's structure - * - ***********************************************************************/ -void DC390W_initACB( PSH psh, USHORT chipType, ULONG io_port, UCHAR Irq, USHORT index ) -{ - PACB pACB; - USHORT i; - UCHAR adaptType, bval; - - - psh->can_queue = MAX_CMD_QUEUE; - psh->cmd_per_lun = MAX_CMD_PER_LUN; - psh->this_id = (int) eepromBuf[index][EE_ADAPT_SCSI_ID]; - psh->io_port = io_port; - psh->n_io_port = 0x80; - psh->irq = Irq; - - if( chipType == PCI_DEVICE_ID_NCR53C825A ) - adaptType = DC390W; - else - { - outb( 2, io_port+GPREG ); - bval = inb( io_port+GPREG ); - if( bval & 8 ) - adaptType = DC390U; - else - adaptType = DC390F; - } - - pACB = (PACB) psh->hostdata; - -#ifndef VERSION_ELF_1_2_13 - if( adaptType == DC390U ) - { - psh->max_id = 8; - pACB->max_id = 7; - } - else - { - psh->max_id = 16; - pACB->max_id = 15; - } - -#ifdef CONFIG_SCSI_MULTI_LUN - if( eepromBuf[index][EE_MODE2] & LUN_CHECK ) - psh->max_lun = 8; - else -#endif - psh->max_lun = 1; - -#else - pACB->max_id = 7; -#endif - if( pACB->max_id == eepromBuf[index][EE_ADAPT_SCSI_ID] ) - pACB->max_id--; - -#ifdef CONFIG_SCSI_MULTI_LUN - if( eepromBuf[index][EE_MODE2] & LUN_CHECK ) - pACB->max_lun = 7; - else -#endif - pACB->max_lun = 0; - - pACB->pScsiHost = psh; - pACB->IOPortBase = (USHORT) io_port; - pACB->pLinkDCB = NULL; - pACB->pDCBRunRobin = NULL; - pACB->pActiveDCB = NULL; - pACB->pFreeSRB = pACB->SRB_array; - pACB->SRBCount = MAX_SRB_CNT; - pACB->AdapterIndex = index; - pACB->status = 0; - pACB->AdaptSCSIID = eepromBuf[index][EE_ADAPT_SCSI_ID]; - pACB->AdaptSCSILUN = 0; - pACB->DeviceCnt = 0; - pACB->IRQLevel = Irq; - pACB->AdaptType = adaptType; - pACB->TagMaxNum = eepromBuf[index][EE_TAG_CMD_NUM] << 2; - pACB->ACBFlag = 0; - pACB->scan_devices = 1; - pACB->Gmode2 = eepromBuf[index][EE_MODE2]; - if( eepromBuf[index][EE_MODE2] & LUN_CHECK ) - pACB->LUNchk = 1; - pACB->pDCB_free = &pACB->DCB_array[0]; - DC390W_linkSRB( pACB ); - for(i=0; i<MAX_SCSI_ID; i++) - pACB->DCBmap[i] = 0; -} - - -/*********************************************************************** - * Function : static int DC390W_initAdapter - * - * Purpose : initialize the SCSI chip ctrl registers - * - * Inputs : psh - pointer to this host adapter's structure - * - ***********************************************************************/ -int DC390W_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index ) -{ - USHORT ioport, wval; - UCHAR bval; - PACB pACB, pacb; - USHORT used_irq = 0; - - pacb = pACB_start; - if( pacb != NULL ) - { - for ( ; (pacb != (PACB) -1) ; ) - { - if( pacb->IRQLevel == Irq ) - { - used_irq = 1; - break; - } - else - pacb = pacb->pNextACB; - } - } - - if( !used_irq ) - { -#ifdef VERSION_ELF_1_2_13 - if( request_irq(Irq, DC390W_Interrupt, SA_INTERRUPT, "tmscsiw")) -#else - if( request_irq(Irq, DC390W_Interrupt, SA_INTERRUPT | SA_SHIRQ, "tmscsiw", NULL)) -#endif - { - printk("DC390W : register IRQ error!\n"); - return( -1 ); - } - } - request_region(io_port,psh->n_io_port,"tmscsiw"); - - ioport = (USHORT) io_port; - outb(IRQ_DISABLE, ioport+DCNTL); - outb(ABORT_OP, ioport+ISTAT); - udelay(100000); - outb(0, ioport+ISTAT); - bval = inb(ioport+DSTAT); - bval = inb(ioport+ISTAT); - wval = inw(ioport+SIST0); - - pACB = (PACB) psh->hostdata; - bval = pACB->AdaptSCSIID; - bval |= ENABLE_RESEL; - outb(bval,ioport+SCID); - - if(pACB->AdaptType == DC390W) - bval = SYNC_CLK_F2+ASYNC_CLK_F2; - else - { /* @1.09 */ - bval = inb(ioport+CTEST3); - if( (bval & CHIP_REV_MASK) < 0x30 ) /* 53C875 Rev. F or later ? */ - goto REVF; - bval = inb(ioport+STEST1); - if( (bval & 0x0C) == 0x0C ) /* double clock already enable ? */ - goto REVF; - outb(8,ioport+STEST1); /* enable clock doubler */ - udelay(20); - outb(HALT_SCSI_CLK,ioport+STEST3); /* halt clock */ - outb(0x0C,ioport+STEST1); /* select double SCSI clock */ - outb(0,ioport+STEST3); /* re-enable clock */ -REVF: - bval = SYNC_CLK_F4+ASYNC_CLK_F4; - } - outb(bval,ioport+SCNTL3); - - bval = SYNC_PERIOD_F4+ASYNCHRONOUS; /* set to async */ - outb(bval,ioport+SXFER); - - bval = WRT_EN_INVALIDATE; /* Enable write and invalidate */ - outb(bval,ioport+CTEST3); - - bval = EN_DMA_FIFO_536+BURST_LEN_MSB; /* select 536 bytes DMA FIFO, burst len bit2=1 */ - outb(bval,ioport+CTEST5); - - bval = BURST_LEN8+EN_READ_LINE+EN_READ_MULTIPLE+BURST_OPCODE_FETCH+AUTO_START; /* set DMA parameter */ - outb(bval,ioport+DMODE); - - bval = EN_ABORTED+EN_SCRIPT_INT+EN_ILLEGAL_INST; /* enable DMA interrupt */ - outb(bval,ioport+DIEN); - - bval = EN_CACHE_LINE_SIZE+EN_PRE_FETCH+TOTEM_POLE_IRQ+COMPATIBLE_700; - outb(bval,ioport+DCNTL); - - bval = EN_PHASE_MISMATCH+EN_SCSI_GERROR+EN_UNEXPECT_DISC+EN_SCSI_RESET+EN_PARITY_ERROR; - outb(bval,ioport+SIEN0); - - bval = EN_SEL_TIMEOUT+EN_GENERAL_TIMEOUT; - outb(bval,ioport+SIEN1); - - bval = SEL_TO_204ms; /* 250ms selection timeout */ - outb(bval,ioport+STIME0); - - wval = 1 << (eepromBuf[index][EE_ADAPT_SCSI_ID]); /* @1.11 */ - outw(wval,ioport+RESPID0); - - bval = DIS_SINGLE_INIT; - if( eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION ) - bval |= ACTIVE_NEGATION_; - outb(bval,ioport+STEST3); - - return(0); -} - - -/*********************************************************************** - * Function : static int DC390W_init (struct Scsi_Host *host) - * - * Purpose : initialize the internal structures for a given SCSI host - * - * Inputs : host - pointer to this host adapter's structure/ - * - * Preconditions : when this function is called, the chip_type - * field of the pACB structure MUST have been set. - ***********************************************************************/ - -static int -DC390W_init (PSHT psht, USHORT chipType, ULONG io_port, UCHAR Irq, USHORT index) -{ - PSH psh; - PACB pACB; - - if( ! CheckEEpromCheckSum( &eepromBuf[index][0], (USHORT) io_port) ) - { - psh = scsi_register( psht, sizeof(DC390W_ACB) ); - if( !psh ) - return( -1 ); - if( !pSH_start ) - { - pSH_start = psh; - pSH_current = psh; - } - else - { - pSH_current->next = psh; - pSH_current = psh; - } - -#ifdef DC390W_DEBUG0 - printk("DC390W : pSH = %8x,", (UINT) psh); -#endif - - DC390W_initACB( psh, chipType, io_port, Irq, index ); - if( !DC390W_initAdapter( psh, io_port, Irq, index ) ) - { - pACB = (PACB) psh->hostdata; - if( !pACB_start ) - { - pACB_start = pACB; - pACB_current = pACB; - pACB->pNextACB = (PACB) -1; - } - else - { - pACB_current->pNextACB = pACB; - pACB_current = pACB; - pACB->pNextACB = (PACB) -1; - } - -#ifdef DC390W_DEBUG0 - printk("DC390W : pACB = %8x, pDCB_array = %8x, pSRB_array = %8x\n", - (UINT) pACB, (UINT) pACB->DCB_array, (UINT) pACB->SRB_array); - printk("DC390W : ACB size= %4x, DCB size= %4x, SRB size= %4x\n", - sizeof(DC390W_ACB), sizeof(DC390W_DCB), sizeof(DC390W_SRB) ); -#endif - - } - else - { - pSH_start = NULL; - scsi_unregister( psh ); - return( -1 ); - } - DC390W_download_script( psh ); - return( 0 ); - } - else - { - printk("DC390W_init: EEPROM reading error!\n"); - return( -1 ); - } -} - - -void MyDelay( void ) -{ - UCHAR i,j; - - j = inb(0x61) & 0x10; - - for(;;) - { - i = inb(0x61) & 0x10; - if( j ^ i) - break; - } -} - - -void EnDisableCE( UCHAR Flag, USHORT scsiIOPort ) -{ - - UCHAR bval; - USHORT port; - - port = (scsiIOPort & 0xff00) + GPREG; - if(Flag == ENABLE_CE) - bval = 0x10; - else - bval = 0x00; - outb(bval,port); - udelay(8); /* Delay();*/ -} - - -void EEpromOutDI( USHORT Carry, USHORT scsiIOPort ) -{ - UCHAR bval; - USHORT port; - - port = (scsiIOPort & 0xff00) + GPREG; - bval = 0x10; - if(Carry) - bval |= 0x02; /* SK=0, DI */ - outb(bval,port); - udelay(8); /* Delay();*/ - bval |= 0x04; /* SK=1, DI */ - outb(bval,port); - udelay(8); /* Delay();*/ - bval &= 0xfb; /* SK=0, DI */ - outb(bval,port); - udelay(8); /* Delay();*/ -} - - -void EEpromPrepare( UCHAR EEpromCmd, USHORT scsiIOPort ) -{ - UCHAR i,j; - USHORT carryFlag; - - carryFlag = 1; - j = 0x80; - for(i=0;i<9;i++) - { - EEpromOutDI(carryFlag,scsiIOPort); - carryFlag = (EEpromCmd & j) ? 1 : 0; - j >>= 1; - } -} - - -UCHAR EEpromInDo(USHORT scsiIOPort) -{ - UCHAR bval; - USHORT port; - - port = (scsiIOPort & 0xff00) + GPREG; - bval = 0x14; /* SK=1 */ - outb(bval,port); - udelay(8); /* Delay();*/ - bval = 0x10; /* SK=0 */ - outb(bval,port); - udelay(8); /* Delay();*/ - bval = inb(port); - if(bval & 0x01) - return( 1 ); - else - return( 0 ); -} - - -USHORT EEpromGetData(USHORT scsiIOPort) -{ - UCHAR i; - UCHAR carryFlag; - USHORT wval; - - wval = 0; - for(i=0;i<16;i++) - { - wval <<= 1; - carryFlag = EEpromInDo(scsiIOPort); - wval |= carryFlag; - } - return( wval ); -} - - -void ReadEEprom( PUCHAR EEpromBuf, USHORT scsiIOPort ) -{ - UCHAR cmd; - - cmd = EEPROM_READ; -loop_rd: - EnDisableCE(ENABLE_CE, scsiIOPort); - EEpromPrepare(cmd, scsiIOPort); - *((PUSHORT)EEpromBuf) = EEpromGetData(scsiIOPort); - EEpromBuf++; - EEpromBuf++; - cmd++; - EnDisableCE(DISABLE_CE, scsiIOPort); - if(cmd & 0x3f) - goto loop_rd; -} - - -USHORT CheckEEpromCheckSum( PUCHAR EEpromBuf, USHORT scsiIOPort) -{ - USHORT wval,port, *ptr; - UCHAR i,bval; - - port = (scsiIOPort & 0xff00) + GPCNTL; - bval = 0x09; /* configure IO Pin */ - outb(bval,port); - ReadEEprom(EEpromBuf,scsiIOPort); /* read eeprom data */ - wval = 0; - ptr = (PUSHORT) EEpromBuf; - for(i=0; i<128 ;i+=2, ptr++) - wval += *ptr; - return( (wval == 0x1234) ? 0 : -1); -} - - - -static void -DC390W_download_script (struct Scsi_Host *host) -{ - ULONG wlval, wlval1, length, alignm; - USHORT j, k, m; - USHORT ioport; - UCHAR bval; - PACB pACB; - PSRB pSRB; - void *pSrc, *pSrc1; - ULONG *pStart; - ULONG Ent_reselected; - ULONG Ent_reselecttag; - ULONG Ent_select0; - ULONG Ent_select1; - ULONG Ent_check_phase; - ULONG Ent_status1_phase; - ULONG Ent_command_phase; - ULONG Ent_jump_table0; - ULONG Ent_din_phaseB; - ULONG Ent_dout_phaseB; - ULONG Ent_din_pad_0; - ULONG Ent_dout_pad_0; - ULONG Ent_jump_tablew; - ULONG Ent_din_pad_1; - ULONG Ent_dout_pad_1; - ULONG Ent_mout_phase; - ULONG Ent_status_phase; - ULONG Ent_min_phase; - ULONG Ent_jump_msgok; - ULONG Ent_msg__1; - ULONG Ent_msg___3; - ULONG Ent_msg___2; - ULONG Ent_set_atn; - ULONG Ent_msg__a; - ULONG Ent_msg__23; - ULONG Ent_msg__3; - ULONG Ent_msg__4; - ULONG Ent_clr_atn; - ULONG Ent_din_phaseW; - ULONG Ent_dout_phaseW; - ULONG Ent_din_pad_addrB; - ULONG Ent_dout_pad_addrB; - ULONG Ent_din_pad_addrW; - ULONG Ent_dout_pad_addrW; - - - pACB = (PACB) host->hostdata; - ioport = pACB->IOPortBase; - bval = SCRATCHAB_AS_BASE; /* set scratchB contains 4K RAM base address */ - outb(bval,ioport+CTEST2); - - wlval = inl((ioport+SCRATCHB)); /* get starting address of 4K RAM */ -/* wlval += 0x800; */ /* point to Upper 2K RAM */ - DesPhysAddr[0] = wlval; /* destination address */ - -#ifdef DC390W_DEBUG0 - printk("DesAddr=%8x,",(UINT) wlval); -#endif - bval = 0; /* set Scratch_A and Scratch_B to normal mode */ - outb(bval,ioport+CTEST2); - - /*------------------------------------------------------------------- - * patch the label in jump instruction: using offset relative - * to start_script - *------------------------------------------------------------------*/ - - Ent_reselected = (ULONG) reselected - (ULONG) start_script; - Ent_reselecttag = (ULONG) reselecttag - (ULONG) start_script; - Ent_select0 = (ULONG) select0 - (ULONG) start_script; - Ent_select1 = (ULONG) select1 - (ULONG) start_script; - Ent_check_phase = (ULONG) check_phase - (ULONG) start_script; - Ent_status1_phase = (ULONG) status1_phase - (ULONG) start_script; - Ent_command_phase = (ULONG) command_phase - (ULONG) start_script; - Ent_din_phaseB = (ULONG) din_phaseB - (ULONG) start_script; - Ent_dout_phaseB = (ULONG) dout_phaseB - (ULONG) start_script; - Ent_din_phaseW = (ULONG) din_phaseW - (ULONG) start_script; - Ent_dout_phaseW = (ULONG) dout_phaseW - (ULONG) start_script; - Ent_jump_table0 = (ULONG) jump_table0 - (ULONG) start_script; - Ent_din_pad_0 = (ULONG) din_pad_0 - (ULONG) start_script; - Ent_din_pad_addrB = (ULONG) din_pad_addrB - (ULONG) start_script; - Ent_dout_pad_0 = (ULONG) dout_pad_0 - (ULONG) start_script; - Ent_dout_pad_addrB = (ULONG) dout_pad_addrB - (ULONG) start_script; - Ent_jump_tablew = (ULONG) jump_tablew - (ULONG) start_script; - Ent_din_pad_1 = (ULONG) din_pad_1 - (ULONG) start_script; - Ent_din_pad_addrW = (ULONG) din_pad_addrW - (ULONG) start_script; - Ent_dout_pad_1 = (ULONG) dout_pad_1 - (ULONG) start_script; - Ent_dout_pad_addrW = (ULONG) dout_pad_addrW - (ULONG) start_script; - Ent_mout_phase = (ULONG) mout_phase - (ULONG) start_script; - Ent_status_phase = (ULONG) status_phase - (ULONG) start_script; - Ent_min_phase = (ULONG) min_phase - (ULONG) start_script; - Ent_jump_msgok = (ULONG) jump_msgok - (ULONG) start_script; - Ent_msg__1 = (ULONG) msg__1 - (ULONG) start_script; - Ent_msg___3 = (ULONG) msg___3 - (ULONG) start_script; - Ent_msg___2 = (ULONG) msg___2 - (ULONG) start_script; - Ent_set_atn = (ULONG) set_atn - (ULONG) start_script; - Ent_msg__a = (ULONG) msg__a - (ULONG) start_script; - Ent_msg__23 = (ULONG) msg__23 - (ULONG) start_script; - Ent_msg__3 = (ULONG) msg__3 - (ULONG) start_script; - Ent_msg__4 = (ULONG) msg__4 - (ULONG) start_script; - Ent_clr_atn = (ULONG) clr_atn - (ULONG) start_script; - - jmp_select0[0] = Ent_select0 + wlval; - jmp_reselected[0] = Ent_reselected + wlval; - jmp_check_phase[0] = Ent_check_phase + wlval; - jmp_check_phase1[0] = Ent_check_phase + wlval; - jmp_check_phase2[0] = Ent_check_phase + wlval; - jmp_check_phase3[0] = Ent_check_phase + wlval; - jmp_check_phase4[0] = Ent_check_phase + wlval; - jmp_check_phase5[0] = Ent_check_phase + wlval; - jmp_check_phase6[0] = Ent_check_phase + wlval; - jmp_status1_phase[0] = Ent_status1_phase + wlval; - jmp_status1_phase1[0] = Ent_status1_phase + wlval; - jmp_status1_phase2[0] = Ent_status1_phase + wlval; - jmp_status1_phase3[0] = Ent_status1_phase + wlval; - jmp_command_phase[0] = Ent_command_phase + wlval; - for(j=0,k=1,m=0; j< (MAX_SG_LIST_BUF+1); j++) - { - jmp_dio_phaseB[k] = Ent_din_phaseB + m + wlval; - jmp_dio_phaseW[k] = Ent_din_phaseW + m + wlval; - k += 2; - jmp_dio_phaseB[k] = Ent_dout_phaseB + m + wlval; - jmp_dio_phaseW[k] = Ent_dout_phaseW + m + wlval; - k += 2; - m += 8; - } - jmp_din_pad_0[0] = Ent_din_pad_0 + wlval; - jmp_dout_pad_0[0] = Ent_dout_pad_0 + wlval; - jmp_din_pad_addrB[0] = Ent_din_pad_addrB + wlval; - jmp_dout_pad_addrB[0] = Ent_dout_pad_addrB + wlval; - jmp_din_pad_addrW[0] = Ent_din_pad_addrW + wlval; - jmp_dout_pad_addrW[0] = Ent_dout_pad_addrW + wlval; - jmp_din_pad_1[0] = Ent_din_pad_1 + wlval; - jmp_dout_pad_1[0] = Ent_dout_pad_1 + wlval; - jmp_status_phase[0] = Ent_status_phase + wlval; - jmp_min_phase[0] = Ent_min_phase + wlval; - jmp_mout_phase[0] = Ent_mout_phase + wlval; - jmp_jump_msgok[0] = Ent_jump_msgok + wlval; - jmp_msg__1[0] = Ent_msg__1 + wlval; - jmp_msg___3[0] = Ent_msg___3 + wlval; - jmp_msg___2[0] = Ent_msg___2 + wlval; - jmp_msg__a[0] = Ent_msg__a + wlval; - jmp_msg__a1[0] = Ent_msg__a + wlval; - jmp_msg__a2[0] = Ent_msg__a + wlval; - jmp_msg__23[0] = Ent_msg__23 + wlval; - jmp_msg__3[0] = Ent_msg__3 + wlval; - jmp_msg__4[0] = Ent_msg__4 + wlval; - - /*-------------------------------------------------------------------- - // patch the element in ACB struct: using Physical address - //-------------------------------------------------------------------*/ - -#ifndef VERSION_ELF_1_2_13 - wlval1 = virt_to_phys( pACB->msgin123 ); -#else - wlval1 = (ULONG) pACB->msgin123; -#endif - ACB_msgin123_1[0] = wlval1; - ACB_msgin123_2[0] = wlval1; - ACB_msgin123_3[0] = wlval1; - ACB_msgin123_4[0] = wlval1; - ACB_msgin123_5[0] = wlval1; - ACB_msgin123_6[0] = wlval1; - ACB_msgin123_7[0] = wlval1; - -#ifndef VERSION_ELF_1_2_13 - ACB_status[0] = virt_to_phys( &pACB->status ); -#else - ACB_status[0] = (ULONG) &pACB->status; -#endif - /*-------------------------------------------------------------------- - // patch the element in SRB struct: using offset in struct - //-------------------------------------------------------------------*/ - - pSRB = (PSRB) pACB->SRB_array; - select1[0] = (select1[0] & 0xffff0000) + ((ULONG) &pSRB->__select - (ULONG) &pSRB->CmdBlock); - SRB_msgout0[0] = (ULONG) &pSRB->__msgout0 - (ULONG) &pSRB->CmdBlock; - SRB_msgout01[0] = (ULONG) &pSRB->__msgout0 - (ULONG) &pSRB->CmdBlock; - SRB_command[0] = (ULONG) &pSRB->__command - (ULONG) &pSRB->CmdBlock; - SRB_SegmentPad[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock; - SRB_SegmentPad1[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock; - SRB_SegmentPad2[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock; - SRB_SegmentPad3[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock; - wlval = (ULONG) &pSRB->Segment0 - (ULONG) &pSRB->CmdBlock; - for(j=0,k=1; j<(MAX_SG_LIST_BUF+1); j++) - { - din_phaseB[k] = wlval; - dout_phaseB[k] = wlval; - din_phaseW[k] = wlval; - dout_phaseW[k] = wlval; - k += 2; - wlval += 8; - } - - - bval = inb(ioport+DCNTL); - bval |= IRQ_DISABLE; - outb(bval,ioport+DCNTL); /* disable interrupt */ - -/* pSrc = scsi_init_malloc( 2048, GFP_ATOMIC); */ - pSrc = scsi_init_malloc( 4096, GFP_ATOMIC); /* 1.11 */ -#ifdef DC390W_DEBUG0 - printk("SrcAlloc=%8x,",(UINT) pSrc); -#endif - alignm = 4 - (((ULONG) pSrc) & 3); - pSrc1 = (void *)(((ULONG) pSrc) + alignm); - length = (ULONG) end_script - (ULONG) start_script; - memcpy( pSrc1, (void *) start_script, length); - pStart = (ULONG *) ((ULONG) start_mov - (ULONG) start_script); - pStart =(ULONG *) (((ULONG) pStart) + ((ULONG) pSrc1)); - -#ifdef DC390W_DEBUG0 - printk("SrcAddr=%8x,\n",(UINT) pSrc1); -#endif -#ifndef VERSION_ELF_1_2_13 - (ULONG *)pStart[1] = virt_to_phys( pSrc1 ); -#else - (ULONG *)pStart[1] = (ULONG) pSrc1; -#endif - -/* wlval = virt_to_phys( start_script ); */ /* physical address of start_script */ -/* SrcPhysAddr[0] = wlval; */ /* sources address */ - -/* start to download SCRIPT instruction to the RAM of NCR53c825A,875 */ - -/* wlval = virt_to_phys( start_mov ); */ - -#ifndef VERSION_ELF_1_2_13 - wlval = virt_to_phys( pStart ); -#else - wlval = (ULONG) pStart; -#endif - - outl(wlval,ioport+DSP); - - bval = inb(ioport+ISTAT); - while(!(bval & DMA_INT_PENDING)) /* check load start_script is finished? */ - bval = inb(ioport+ISTAT); - - bval = inb(ioport+DSTAT); /* clear interrupt */ - - bval = inb(ioport+DCNTL); - bval &= ~IRQ_DISABLE; - outb(bval,ioport+DCNTL); /* re-enable interrupt */ - - scsi_init_free((char *) pSrc, 4096); - - wlval = DesPhysAddr[0]; /* starting addr of RAM */ - wlval -= (ULONG) start_script; - - pACB->jmp_reselect = wlval + (ULONG) start_script; - pACB->jmp_select = wlval + (ULONG) select1; - pACB->jmp_table8 = wlval + (ULONG) jump_table0; - pACB->jmp_set_atn = wlval + (ULONG) set_atn; - pACB->jmp_clear_ack = wlval + (ULONG) msg__a; - pACB->jmp_next = wlval + (ULONG) check_phase; - pACB->jmp_din8 = wlval + (ULONG) din_phaseB+8; - pACB->jmp_dout8 = wlval + (ULONG) dout_phaseB+8; - pACB->jmp_clear_atn = wlval + (ULONG) clr_atn; - pACB->jmp_reselecttag = wlval + (ULONG) reselecttag; - - wlval = pACB->jmp_reselect; - outl(wlval,(ioport+DSP)); - return; -} - - -/*********************************************************************** - * Function : int DC390W_detect(Scsi_Host_Template *psht) - * - * Purpose : detects and initializes NCR53c825A,875 SCSI chips - * that were autoprobed, overridden on the LILO command line, - * or specified at compile time. - * - * Inputs : psht - template for this SCSI adapter - * - * Returns : number of host adapters detected - * - ***********************************************************************/ - -int -DC390W_detect(Scsi_Host_Template *psht) -{ - UCHAR pci_bus, pci_device_fn, irq; -#ifndef VERSION_ELF_1_2_13 - UINT io_port, ram_base; -#else - ULONG io_port, ram_base; -#endif - USHORT i; - int error = 0; - USHORT adaptCnt = 0; /* Number of boards detected */ - USHORT pci_index = 0; /* Device index to PCI BIOS calls */ - USHORT pci_index2 = 0; /* Device index to PCI BIOS calls */ - USHORT chipType = 0; - - -#ifndef VERSION_ELF_1_2_13 - psht->proc_dir = &proc_scsi_tmscsiw; -#endif - - InitialTime = 1; - pSHT_start = psht; - jmp_table16 = (ULONG) jump_tablew - (ULONG) jump_table0; - jmp_din16 = (ULONG) din_phaseW - (ULONG) din_phaseB; - jmp_dout16 = (ULONG) dout_phaseW - (ULONG) dout_phaseB; - pACB_start = NULL; - - if ( pcibios_present() ) - { - for (i = 0; i < MAX_ADAPTER_NUM; ++i) - { - if( !pcibios_find_device( PCI_VENDOR_ID_NCR, - PCI_DEVICE_ID_NCR53C825A, - pci_index, &pci_bus, &pci_device_fn) ) - { - chipType = PCI_DEVICE_ID_NCR53C825A; - pci_index++; - } - else if( !pcibios_find_device( PCI_VENDOR_ID_NCR, - PCI_DEVICE_ID_NCR53C875, - pci_index2, &pci_bus, &pci_device_fn) ) - { - chipType = PCI_DEVICE_ID_NCR53C875; - pci_index2++; - } - - if( chipType ) - { - error = pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &io_port); - error |= pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_2, &ram_base); - error |= pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &irq); - if( error ) - { - printk("DC390W_detect: reading configuration registers error!\n"); - InitialTime = 0; - return( 0 ); - } - - (USHORT) io_port = (USHORT) io_port & 0xFFFE; -#ifdef DC390W_DEBUG0 - printk("DC390W : IO_PORT=%4x,RAM_BASE=%8x,IRQ=%x,CHIPID=%x,\n", - (UINT) io_port, (UINT) ram_base, irq, (UCHAR)chipType); -#endif - - if( !DC390W_init(psht, chipType, io_port, irq, i) ) - adaptCnt++; - chipType = 0; - } - else - break; - } - } - InitialTime = 0; - adapterCnt = adaptCnt; - return( adaptCnt ); -} - -#ifndef VERSION_ELF_1_2_13 - -/******************************************************************** - * Function: tmscsiw_set_info() - * - * Purpose: Set adapter info (!) - * - * Not yet implemented - * - *******************************************************************/ - -int tmscsiw_set_info(char *buffer, int length, struct Scsi_Host *shpnt) -{ - return(-ENOSYS); /* Currently this is a no-op */ -} - -/******************************************************************** - * Function: tmscsiw_proc_info(char* buffer, char **start, - * off_t offset, int length, int hostno, int inout) - * - * Purpose: return SCSI Adapter/Device Info - * - * Input: buffer: Pointer to a buffer where to write info - * start : - * offset: - * hostno: Host adapter index - * inout : Read (=0) or set(!=0) info - * - * Output: buffer: contains info - * length; length of info in buffer - * - * return value: length - * - ********************************************************************/ - -/* KG: proc_info taken from driver aha152x.c */ - -#undef SPRINTF -#define SPRINTF(args...) pos += sprintf(pos, ## args) - -#define YESNO(YN)\ -if (YN) SPRINTF(" Yes ");\ -else SPRINTF(" No ") - -int tmscsiw_proc_info(char *buffer, char **start, - off_t offset, int length, int hostno, int inout) -{ - int dev, spd, spd1; - char *pos = buffer; - PSH shpnt; - PACB acbpnt; - PDCB dcbpnt; - unsigned long flags; -/* Scsi_Cmnd *ptr; */ - - acbpnt = pACB_start; - - while(acbpnt != (PACB)-1) - { - shpnt = acbpnt->pScsiHost; - if (shpnt->host_no == hostno) break; - acbpnt = acbpnt->pNextACB; - } - - if (acbpnt == (PACB)-1) return(-ESRCH); - if (!shpnt) return(-ESRCH); - - if(inout) /* Has data been written to the file ? */ - return(tmscsiw_set_info(buffer, length, shpnt)); - - SPRINTF("Tekram DC390W/U/F (T) PCI SCSI Host Adadpter, "); - SPRINTF("Driver Version 1.12, 1997/02/17\n"); - - save_flags(flags); - cli(); - - SPRINTF("SCSI Host Nr %i, ", hostno); - SPRINTF("DC390WUF Adapter Nr %i\n", acbpnt->AdapterIndex); - SPRINTF("IOPortBase 0x%04x, ", acbpnt -> IOPortBase); - SPRINTF("IRQLevel 0x%02x\n",acbpnt -> IRQLevel); - - SPRINTF("Adapter Type: "); - switch(acbpnt->AdaptType) - { - case DC390W: SPRINTF("DC390W, Fast Wide SCSI \n"); break; - case DC390U: SPRINTF("DC390U, Ultra SCSI\n"); break; - case DC390F: SPRINTF("DC390F, Ultra Wide SCSI\n"); break; - default: SPRINTF("Unknown !\n"); - } - - SPRINTF("MaxID %i, MaxLUN %i, ", acbpnt->max_id, acbpnt->max_lun); - SPRINTF("AdapterID %i, AdapterLUN %i\n", acbpnt->AdaptSCSIID, acbpnt->AdaptSCSILUN); - - SPRINTF("TagMaxNum %i, Status %i\n", acbpnt->TagMaxNum, acbpnt->status); - - SPRINTF("Nr of attached devices: %i\n", acbpnt->DeviceCnt); - - SPRINTF("Un ID LUN Prty Sync DsCn SndS TagQ Wide NegoPeriod SyncSpeed SyncOffs\n"); - dcbpnt = acbpnt->pLinkDCB; - - for (dev = 0; dev < acbpnt->DeviceCnt; dev++) - { - SPRINTF("%02i %02i %02i ", dev, dcbpnt->UnitSCSIID, dcbpnt->UnitSCSILUN); - YESNO(dcbpnt->DevMode & PARITY_CHK_); - YESNO(dcbpnt->DCBsxfer & OFFSET_MASK); - YESNO(dcbpnt->DevMode & EN_DISCONNECT_); - YESNO(dcbpnt->DevMode & SEND_START_); - YESNO(dcbpnt->MaxCommand > 1); - YESNO(dcbpnt->DCBscntl3 & EN_WIDE_SCSI); - SPRINTF(" %03i ns ", (dcbpnt->NegoPeriod) << 2); - if (dcbpnt->DCBsxfer & OFFSET_MASK) - { - spd = 1000/(dcbpnt->SyncPeriod <<2); - spd1 = 1000%(dcbpnt->SyncPeriod <<2); - spd1 = (spd1 * 10)/(dcbpnt->SyncPeriod <<2); - SPRINTF(" %2i.%1i M %02i\n", spd, spd1, dcbpnt->DCBsxfer & OFFSET_MASK); - } - else SPRINTF("\n"); - /* Add more info ...*/ - dcbpnt = dcbpnt->pNextDCB; - } - - restore_flags(flags); - *start = buffer + offset; - - if (pos - buffer < offset) - return 0; - else if (pos - buffer - offset < length) - return pos - buffer - offset; - else - return length; -} -#endif /* VERSION_ELF_1_2_13 */ - -#ifdef MODULE - -/*********************************************************************** - * Function : static int DC390W_shutdown (struct Scsi_Host *host) - * - * Purpose : does a clean (we hope) shutdown of the NCR SCSI chip. - * Use prior to dumping core, unloading the NCR driver, etc. - * - * Returns : 0 on success - ***********************************************************************/ -static int -DC390W_shutdown (struct Scsi_Host *host) -{ - USHORT ioport; - unsigned long flags; - PACB pACB = (PACB) host->hostdata; - - ioport = (unsigned int) pACB->IOPortBase; - - save_flags (flags); - cli(); - -/* pACB->soft_reset(host); */ -/* - * For now, we take the simplest solution : reset the SCSI bus. Eventually, - * - If a command is connected, kill it with an ABORT message - * - If commands are disconnected, connect to each target/LUN and - * do a ABORT, followed by a SOFT reset, followed by a hard - * reset. - */ - -#ifdef DC390W_DEBUG0 - printk("DC390W: shutdown,"); -#endif - outb(ASSERT_RST, ioport+SCNTL1); - udelay(25); /* Minimum amount of time to assert RST */ - outb(0, ioport+SCNTL1); - restore_flags (flags); - return( 0 ); -} - - -int DC390W_release(struct Scsi_Host *host) -{ - int irq_count; - struct Scsi_Host *tmp; - - DC390W_shutdown (host); - - if (host->irq != IRQ_NONE) - { - for (irq_count = 0, tmp = pSH_start; tmp; tmp = tmp->next) - { - if ( tmp->irq == host->irq ) - ++irq_count; - } - if (irq_count == 1) - { -#ifdef DC390W_DEBUG0 - printk("DC390W: Free IRQ %i.",host->irq); -#endif -#ifndef VERSION_ELF_1_2_13 - free_irq(host->irq,NULL); -#else - free_irq(host->irq); -#endif - } - } - - release_region(host->io_port,host->n_io_port); - - return( 1 ); -} - -Scsi_Host_Template driver_template = DC390WUF; -#include "scsi_module.c" -#endif /* def MODULE */ - |