📄 sysscsi.c
字号:
/* sysScsi.c - Template SCSI-2 initialization for sysLib.c *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01c,17jul02,dat remove obsolete information01b,08apr99,dat spr 26491, changed PCI macro names01a,02feb99,tm dervied from ncr810 sysScsi.c / AutoConfig support (SPR 24733)*//* 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.*/#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 UCHAR sysInByte (ULONG);extern void sysOutByte (ULONG,UCHAR);/* 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; 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 = TEMPLATE_SIOP_HW_REGS; /* Set virtual <-> PCI address offset */ ncr810PciMemOffset = LOCAL2PCI_MEM(0); /* * Given the PCI bus is little endian, if the CPU architecture is big * endian, then 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) { if (_BYTE_ORDER == _BIG_ENDIAN) { 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; if (PCI_CFG_TYPE == PCI_CFG_FORCE) { pciConfigOutLong(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_BASE_ADDRESS_0, SCSI_BASE_ADRS); pciConfigOutByte(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_DEV_INT_LINE, (SCSI_INT_LVL - EXT_INTERRUPT_BASE)); } /* read the configuration parameters */ pciConfigInLong(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_BASE_ADDRESS_0, &iobaseCsr); pciConfigInByte(pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_DEV_INT_LINE, &irq); /* TODO - Perform any necessary PCI to CPU address translations here */ /* TODO - Perform any necessary interrupt number calculations here */ /* Create the SCSI controller */ SCSI_DEBUG_MSG("sysScsiInit: ncr810CtrlCreate w/ io[0x%08x] irq[0x%02X]\n", iobaseCsr, irq, 0, 0, 0, 0 ); 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 (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); ncr810DelayCount = (sysGetBusSpd () * NCR810_DELAY_MULT); /* 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 ++) { val = BYTE_SWAP_32_BIT ( (UINT32) *((UINT32 *) (start + i)) ); *((UINT32 *) start + i) = val; } }/* Data for example code in sysScsiConfig, modify as needed */SCSI_PHYS_DEV * pSpd20;SCSI_PHYS_DEV * pSpd31; /* SCSI_PHYS_DEV ptrs (suffix == ID, LUN) */SCSI_PHYS_DEV * pSpd40;BLK_DEV * pSbd0;BLK_DEV * pSbd1;BLK_DEV * pSbd2; /* SCSI_BLK_DEV ptrs for Winchester */BLK_DEV * pSbdFloppy; /* ptr to SCSI floppy block device */#ifdef INCLUDE_SCSI2SEQ_DEV * pSd0;TAPE_CONFIG * pTapeConfig;#endif /* INCLUDE_SCSI2 *//********************************************************************************* sysScsiConfig - system SCSI configuration** This routine is an example SCSI configuration routine.** Most of the code for this routine shows how to declare a SCSI peripheral* configuration. This routine must be edited to reflect the actual* configuration of the user's SCSI bus. This example can also be found in* src/config/usrScsi.c.** For users just getting started, hardware configurations can be tested* by defining SCSI_AUTO_CONFIG in config.h, which probes the bus and* displays all devices found. No device should have the same SCSI bus ID as* the VxWorks SCSI port (default = 7), or the same ID as any other device.* Check for proper bus termination.** This routine includes three configuration examples that demonstrate* configuration of a SCSI hard disk (any type), of an OMTI 3500 floppy disk,* and of a tape drive (any type).** The hard disk is divided into two 32-megabyte partitions and a third* partition with the remainder of the disk. The first partition is* initialized as a dosFs device. The second and third partitions are* initialized as rt11Fs devices, each with 256 directory entries.** It is recommended that the first partition on a block device (BLK_DEV) be* a dosFs device, if the intention is eventually to boot VxWorks from the* device. This will simplify the task considerably.*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -