📄 sysscsi.c
字号:
/* sysScsi.c - Motorola MVME2600 series SCSI-2 initialization for sysLib.c *//* Copyright 1984-1999 Wind River Systems, Inc. *//* Copyright 1996,1997,1998,1999 Motorola, Inc., All Rights Reserved */#include "copyright_wrs.h"/*modification history--------------------01n,10jun99,tm Fixed SYS_REG_SIOP typo and PMC int numbers for PCI_CFG_FORCE01m,03may99,srr updated with new WRS naming conventions.01l,14apr98,ms_ merged Motorola mv2700 support01k,13jan98,srr updated copyright dates to 1998.01j,09jul97,tb added support for ncr875 and secondary SCSI.01i,18sep97,dds added feature to enable wide SCSI.01h,09jul97,mas added support for SCSI I/O routines sysScsiInByte() and sysScsiOutByte(); ncr810DelayCount now set to NCR810_DELAY_MULT (SPR 8842).01g,09may97,mas added extended VME support, secondary SCSI and use of global ncr810PciMemOffset and PCI2DRAM_BASE_ADRS define (SPR 8410). added NCR810_DELAY_MULT (SPR 8430).01f,11apr97,mas changed sysScsiInit() to use pciIomapLib.c functions(SPR 8226).01e,06mar97,dds SPR 7996/8091: made fixes to configure scsi devices.01d,03jan97,wlf doc: cleanup.01c,02jan97,dat added sysScsiConfig sample code, fixed mod history01b,17dec96,mas renamed INSTRUCTIONS -> NCR810_INSTRUCTIONS (SPR 7649).01a,29nov95,mot written (ver 01d, mv1600/sysScsi.c)*//* DescriptionThis file contains the sysScsiInit() and related routines necessary forinitializing the SCSI subsystem. It also contains BSP-specific SCSI I/O routines required by the ncr810 driver.The constant PCI2DRAM_BASE_ADRS must be defined in the BSP.*/#ifdef INCLUDE_SCSI/* includes */#ifdef INCLUDE_SCSI2#include "drv/scsi/ncr810.h"#else#error INCLUDE_SCSI2 must be defined for use with this driver.#endif /* INCLUDE_SCSI2 */#include "tapeFsLib.h"/* external declarations */extern int ncr810PciMemOffset;extern int ncr810DelayCount;extern ULONG NCR810_INSTRUCTIONS;extern ULONG ncr810Wait[];extern BOOL scsiDebug;extern void eieioExecute();extern void vxEieio ();extern UCHAR sysInByte (ULONG);extern void sysOutByte (ULONG,UCHAR);#ifdef INCLUDE_SECONDARY_SCSI/* global declarations */SCSI_CTRL * pSysScsiCtrl2;#endif /* INCLUDE_SECONDARY_SCSI *//* function declarations */LOCAL void swapScript (UINT32 * start, UINT32 * end);/********************************************************************************* sysScsiInit - initialize an on-board SCSI port** This routine creates and initializes an NCR 53C8\f2xx\f1 SCSI I/O* processor (SIOP) structure, enabling use of the on-board SCSI port. It* connects the proper interrupt service routine to the desired vector, and* enables the interrupt at the desired level.** RETURNS: OK, or ERROR if the SIOP structure cannot be created, the* controller cannot be initialized, valid values cannot be set up in the* SIOP registers, or the interrupt service routine cannot be connected.*/ STATUS sysScsiInit () { int pciBusNo; int pciDevNo; int pciFuncNo; UINT16 devType;#ifdef INCLUDE_SECONDARY_SCSI UINT16 devType2;#endif /* INCLUDE_SECONDARY_SCSI */ static BOOL firstTime = TRUE; UINT32 iobaseCsr; /* base address 0 */ char irq; /* IRQ level */ /* Local structure(s) with a prefill for ncr825SetHwRegister */ static NCR810_HW_REGS hwRegs = SYS_REG_SIOP_HW_REGS;#ifdef INCLUDE_SECONDARY_SCSI static NCR810_HW_REGS hwRegs2 = SYS_REG_SIOP_HW_REGS;#endif /* INCLUDE_SECONDARY_SCSI */ /* Set CPU <-> PCI address offset */ ncr810PciMemOffset = PCI2DRAM_BASE_ADRS; /* * Since the PCI bus is little endian, and the PPC CPU's are big endian, * the ncr8xx scripts need to be byte swapped in memory. However, they * should only be swapped the first time that sysScsiInit() is invoked. */ if (firstTime) { swapScript ((UINT32 *) &ncr810Wait, (UINT32 *) ((UINT32) &ncr810Wait + (UINT32)(NCR810_INSTRUCTIONS * 8))); firstTime = FALSE; } /* Try to automatically configure the correct type of NCR8XX controller. */ if (pciFindDevice ((PCI_ID_SCSI & 0xFFFF), ((PCI_ID_SCSI >> 16) & 0xFFFF), 0, &pciBusNo, &pciDevNo, &pciFuncNo) != ERROR) { /* Get Device ID */ pciConfigInWord (pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_DEVICE_ID, &devType); SCSI_DEBUG_MSG ("Found Primary SCSI Controller - Dev/Ven ID = 0x%x\n", PCI_ID_SCSI,0,0,0,0,0); } else { logMsg ("SCSI controller not found\n", 0, 0, 0, 0, 0, 0); return (ERROR); }#ifndef SCSI_WIDE_ENABLE devType = NCR810_DEVICE_ID;#endif ncr810DelayCount = NCR810_DELAY_MULT; /* * NOTE: * * If PCI_CFG_TYPE is PCI_CFG_FORCE, and an mcpn750 is being used, two * PMC slots are available. The SCSI PMC card could be inserted into * either, so the best guess of PMC1A has been used here (int num 0x09). * To use the other slot, change PMC1A_INT_LVL to PMC1D_INT_LVL. * * This is not an issue when either autoconfig is being used * (PCI_CFG_TYPE == PCI_CFG_AUTO) or an mcp750 (only one PMC slot) * is being used. */ if (PCI_CFG_TYPE == PCI_CFG_FORCE) { pciConfigOutLong(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_BASE_ADDRESS_0, SCSI_BASE_ADRS);#ifdef CONFIG1_PLANAR_PCI /* e.g. MCP750 */ pciConfigOutByte(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_DEV_INT_LINE, (PMC_INT_LVL - EXT_INTERRUPT_BASE));#endif#ifdef CONFIG2_PLANAR_PCI /* e.g. MCPN750 */ pciConfigOutByte(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_DEV_INT_LINE, (PMC1A_INT_LVL - EXT_INTERRUPT_BASE));#endif } /* read the configuration parameters */ pciConfigInLong(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_BASE_ADDRESS_0, &iobaseCsr); pciConfigInByte(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_DEV_INT_LINE, &irq); iobaseCsr &= PCI_IOBASE_MASK; iobaseCsr |= ISA_MSTR_IO_LOCAL; irq += EXT_INTERRUPT_BASE; /* Create the SCSI controller */ if ((pSysScsiCtrl = (SCSI_CTRL *) ncr810CtrlCreate ( (UINT8 *) iobaseCsr, (UINT) NCR810_40MHZ, devType )) == NULL) { return (ERROR); } /* connect the SCSI controller's interrupt service routine */ if (intConnect (INUM_TO_IVEC ((int)irq), ncr810Intr, (int) pSysScsiCtrl) == ERROR) { return (ERROR); } /* Enable SCSI interrupts */ intEnable (irq); /* initialise SCSI controller with default parameters (user tuneable) */ if (ncr810CtrlInit ((NCR_810_SCSI_CTRL *)pSysScsiCtrl, SCSI_DEF_CTRL_BUS_ID) == ERROR) return (ERROR);#if (USER_D_CACHE_MODE & CACHE_SNOOP_ENABLE) scsiCacheSnoopEnable ((SCSI_CTRL *) pSysScsiCtrl);#else scsiCacheSnoopDisable ((SCSI_CTRL *) pSysScsiCtrl);#endif /* * Set the good value in the registers of the SIOP coupled * with the hardware implementation */ if (ncr810SetHwRegister ((NCR_810_SCSI_CTRL *)pSysScsiCtrl, &hwRegs) == ERROR) return(ERROR);#ifdef INCLUDE_SECONDARY_SCSI if (pciFindDevice ((PCI_ID_SEC_SCSI & 0xFFFF), ((PCI_ID_SEC_SCSI >> 16) & 0xFFFF), 0, &pciBusNo, &pciDevNo, &pciFuncNo) != ERROR) { /* Get Device ID */ pciConfigInWord (pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_DEVICE_ID, &devType2); SCSI_DEBUG_MSG ("Found Secondary SCSI Controller - Dev/Ven ID = 0x%x\n", PCI_ID_SCSI,0,0,0,0,0); } else { logMsg ("Secondary SCSI controller not found\n", 0, 0, 0, 0, 0, 0); return (ERROR); }#ifndef SCSI_WIDE_ENABLE devType2 = NCR810_DEVICE_ID;#endif ncr810DelayCount = (sysGetBusSpd () * NCR810_DELAY_MULT); /* Create the SCSI controller */ if ((pSysScsiCtrl2 = (SCSI_CTRL *) ncr810CtrlCreate ( (UINT8 *) SCSI_BASE_ADRS2, (UINT) NCR810_40MHZ, devType2 )) == NULL) { return (ERROR); } /* connect the SCSI controller's interrupt service routine */ if (intConnect (INUM_TO_IVEC (SCSI_INT_VEC2), ncr810Intr, (int) pSysScsiCtrl2) == ERROR) { return (ERROR); } /* Enable SCSI interrupts */ intEnable (PMC_INT_LVL3); /* initialise SCSI controller with default parameters (user tuneable) */ if (ncr810CtrlInit ((NCR_810_SCSI_CTRL *)pSysScsiCtrl2, SCSI_DEF_CTRL_BUS_ID) == ERROR) return (ERROR); #if (USER_D_CACHE_MODE & CACHE_SNOOP_ENABLE) scsiCacheSnoopEnable ((SCSI_CTRL *) pSysScsiCtrl2); #else scsiCacheSnoopDisable ((SCSI_CTRL *) pSysScsiCtrl2); #endif /* * Set the good value in the registers of the SIOP coupled * with the hardware implementation */ if (ncr810SetHwRegister ((NCR_810_SCSI_CTRL *)pSysScsiCtrl2, &hwRegs2) == ERROR) return(ERROR); #endif /* INCLUDE_SECONDARY_SCSI */ /* Include tape support if configured in config.h */ #ifdef INCLUDE_TAPEFS tapeFsInit (); /* initialise tapeFs */#endif /* INCLUDE_TAPEFS */ return (OK); }/********************************************************************************* swapScript - byte swaps the 32 bit NCR8XX scripts** This routine byte swaps 4 byte (32 bit) long scripts instructions due to* the fact that the PPC processor is big endian and the PCI SCSI device is* little endian. ** The two parameters supplied <start> and <end> denote the start of scripts* in memory and the end of the scripts in memory. Note that both these* values are assumed to be on 4 byte boundaries. It is further assumed that* the instructions are located in a writable area of memory.** RETURNS: N/A*/LOCAL void swapScript ( UINT32 * start, UINT32 * end ) { int size; UINT32 i; UINT32 val; /* determine the size (length) of the scripts */ size = (int) end - (int) start; if (size % 4) printf ("Incorrect length (start - end) mod 4 != 0 size: %d\n", size); /* swap each 4 byte word in memory */ for (i=0; i < (size/4); i ++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -