getfloat.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 431 行
C
431 行
#ifndef lintstatic char *sccsid = "@(#)getfloat.c 4.1 (ULTRIX) 7/2/90";#endif lint/************************************************************************ * * * Copyright(c) 1987 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * Name: getfloat.c * * Modification History * * Oct 11, 1989 - Alan Frechette * Fixed sizer to assume no drives attached to a disk controller * in floating address space. Previously sizer would assume that * there are 4 drives attached which is wrong in most cases. * * July 6, 1989 - Alan Frechette * Added check for a VAXSTAR cputype. * * May 02, 1989 - Alan Frechette * Changes to deal with new unique "cpu" handling for both * vax and mips architectures. * * Feb 12, 1989 - Alan Frechette * New sizer code which supports multiple architectures. * Restructured this code and cleaned it up considerably. * Based on the original V3.0 sizer by Tungning Cherng. * ***********************************************************************/#include "sizer.h"#define QB_IO_OFFSET 0x400000/***************************************************************** Name: getfloat ** ** Abstract: Search all the UNIBUS ADAPTERS for devices that ** exist in floating address space. Add all found ** devices to the alive device table "adltbl[]". ** ** Inputs: ** ubas The number of UNIBUS ADAPTERS for the system. ** ** Outputs: None. ** ** Return Values: None. ** ** Side Effects:This routine uses an algorithm which guesses ** where certain devices can exist in floating ** address space. The algorithm goes through the ** floating devices table "floattbl[]" and gets ** the offset of where this device may exist in ** floating space. It then pokes at that address ** to see if that device exists there. If it does ** exist there then it will add the device to the ** alive device table "adltbl[]". The following ** routines are called: * * ** match_device_name() Search device name in device table. ** foundit() Find if device is in alive device table.** float_ctlr() Handle a floating controller device. ** getunit() Get unit number for the device. *****************************************************************/getfloat(ubas)int ubas;{ char tconname[10]; int unit, addr, retval, i, x, index; int tcsr, kumem, umem_start, tconnum, tdevtype; short shortint; struct stat stbuf; struct float_devices *fadptr; /* No UNIBUS/QBUS virtual memory interface */ if(CPUSUB == ST_VAXSTAR || CPU == VAXSTAR) return; /* No UNIBUS/QBUS virtual memory interface */ if(stat("/dev/kUmem", &stbuf) != 0) return; /* Open up UNIBUS/QBUS virtual memory interface */ if((kumem = open("/dev/kUmem", 0)) < 0) quitonerror(-9); /* Get start of UNIBUS/QBUS memory based on CPU type */ switch(CPU) { case MVAX_I: case MVAX_II: case VAX_3400: case VAX_3600: case VAX_3900: case VAX_60: case DS_5400: case DS_5500: case DS_5800: umem_start = nl[NL_qmem].n_value;/* Get start of qmem */ break; default: umem_start = nl[NL_umem].n_value;/* Get start of umem */ break; } /* Search all UBA's for floating address devices */ for(i=0;i<ubas;i++) { /* Get start of floating address space */ switch(CPU) { case MVAX_I: case MVAX_II: case VAX_3400: case VAX_3600: case VAX_3900: case VAX_60: case DS_5400: case DS_5500: case DS_5800: addr = umem_start + QB_IO_OFFSET; break; default: addr = umem_start + (i * 01000000) + 0760000; break; } /* Point to floating address devices table */ fadptr = floattbl; addr += fadptr->gap * 2; while(strcmp(fadptr->name,"\0") != 0) { /* Poke to see if device exists at this address */ lseek(kumem,addr,0); retval = read(kumem,&shortint,sizeof(shortint)); unit = 0; while(retval > 0) { /* Find device in configuration device table */ index = match_device_name(fadptr->name); strcpy(tconname,"uba"); tconnum = i; tdevtype = (index == -1) ? UNKNOWN : devtbl[index].devtype; /* Figure out this device's CSR address */ switch(CPU) { case MVAX_I: case MVAX_II: case VAX_3400: case VAX_3600: case VAX_3900: case VAX_60: case DS_5400: case DS_5500: case DS_5800: tcsr = (u_short) (addr - umem_start - QB_IO_OFFSET); break; default: tcsr = (u_short) (addr - umem_start - 0600000 - (i * 01000000)); break; } /* * Check if this device is already in * the alive device table "adltbl[]". */ if(!foundit(tcsr,tconname,tconnum,tdevtype)) { init_adl_entry(ADLINDEX); adltbl[ADLINDEX].device_index = index; strcpy(adltbl[ADLINDEX].conn_name,tconname); adltbl[ADLINDEX].conn_number = i; if(index == -1) { strcpy(adltbl[ADLINDEX].unsupp_devname, fadptr->name); adltbl[ADLINDEX].csr = tcsr; ADLINDEX++; } else { if(devtbl[index].devtype != CONTROLLER) adltbl[ADLINDEX].csr = tcsr; if(devtbl[index].supportedflag) { unit = getunit(fadptr->name); adltbl[ADLINDEX].device_unit = unit; } ADLINDEX++; if(devtbl[index].devtype == CONTROLLER) float_ctlr(addr,umem_start, unit,devtbl[index].devname); } unit++; } addr += fadptr->gap * 2; x = (addr - umem_start) % (fadptr->gap * 2); if(x > 0) addr += fadptr->gap * 2 - x; lseek(kumem,addr,0); retval = read(kumem,&shortint,sizeof(shortint)); } fadptr++; if(fadptr->gap == 0) continue; x = (addr - umem_start) % (fadptr->gap * 2); if(x > 0) addr += (fadptr->gap * 2) - x; else addr += fadptr->gap * 2; } }}/***************************************************************** Name: foundit ** ** Abstract: Check alive device table to see if this device ** has already been added. Devices are straight ** forward, but controllers are tricky. For the ** controllers we must first find a device with ** the same CSR as ours and then check the device ** before it (i - 1) to see if it is on the same ** bus as we are. This depends on the fact that ** the order of things in the alive device table ** are as follows: ** ** (1) uda on uba (2) uq on uda at csr (3) ra on uq ** ** Inputs: ** csr The csr of the device to look for. ** connectname The device connection point name to look for. ** connectnum The device connection point number to look for. ** devtype The device type from device table "devtbl[]". ** ** Outputs: None. ** ** Return Values: ** 1 Device is in the alive device table. ** 0 Device is not in the alive device table. *****************************************************************/foundit(csr,connectname,connectnum,devtype)int csr;char *connectname;int connectnum;int devtype;{ int i, found; found = 0; for(i=0;i<ADLINDEX;i++) { if(adltbl[i].csr == csr) { if(strcmp(adltbl[i].conn_name,connectname) == 0 && adltbl[i].conn_number == connectnum) { found = 1; break; } else if(devtype == CONTROLLER) { if(strcmp(adltbl[i - 1].conn_name, connectname) == 0 && adltbl[i - 1].conn_number == connectnum) { found = 1; break; } } } } return(found);}/***************************************************************** Name: float_ctlr ** ** Abstract: We found a controller in floating address space.** Figure out the type of controller and how many ** devices are attached to this controller. Add ** the devices to the alive device table. This ** code assumes that a default number of devices ** are attached to the controller. ** ** Inputs: ** addr The address of the device in floating space. ** umem_start The start of UNIBUS/QBUS floating address space.** unit The controller device unit number. ** name The controller device name. ** ** Outputs: None. ** ** Return Values: None. *****************************************************************/float_ctlr(addr,umem_start,unit,name)int addr,umem_start,unit;char name[20];{ int ctlrunit, j, devunit, index; init_adl_entry(ADLINDEX); if(strncmp(name,"uda",3) == 0) { ctlrunit = getunit("uq"); index = match_device_name("uq"); adltbl[ADLINDEX].device_index = index; adltbl[ADLINDEX].device_unit = ctlrunit; adltbl[ADLINDEX].csr =(u_short)(addr - 0600000 - umem_start); strcpy(adltbl[ADLINDEX].conn_name, "uda"); adltbl[ADLINDEX].conn_number = unit; ADLINDEX++;#ifdef notdef devunit = getunit("ra"); for(j=0;j<4;j++) { init_adl_entry(ADLINDEX); index = match_device_name("ra"); adltbl[ADLINDEX].device_index = index; adltbl[ADLINDEX].device_unit = devunit; adltbl[ADLINDEX].device_drive = j; strcpy(adltbl[ADLINDEX].conn_name, "uq"); adltbl[ADLINDEX].conn_number = ctlrunit; devunit++; ADLINDEX++; }#endif notdef } if(strncmp(name,"klesiu",6) == 0) { ctlrunit = getunit("uq"); index = match_device_name("uq"); adltbl[ADLINDEX].device_index = index; adltbl[ADLINDEX].device_unit = ctlrunit; adltbl[ADLINDEX].csr =(u_short)(addr - 0600000 - umem_start); strcpy(adltbl[ADLINDEX].conn_name, "klesiu"); adltbl[ADLINDEX].conn_number = unit; ADLINDEX++; init_adl_entry(ADLINDEX); devunit = getunit("tms"); index = match_device_name("tms"); adltbl[ADLINDEX].device_index = index; adltbl[ADLINDEX].device_unit = devunit; adltbl[ADLINDEX].device_drive = 0; strcpy(adltbl[ADLINDEX].conn_name, "uq"); adltbl[ADLINDEX].conn_number = ctlrunit; ADLINDEX++; } if(strncmp(name,"hl",2) == 0) { devunit = getunit("rl"); for(j=0;j<4;j++) { init_adl_entry(ADLINDEX); index = match_device_name("rl"); adltbl[ADLINDEX].device_index = index; adltbl[ADLINDEX].device_unit = devunit; adltbl[ADLINDEX].device_drive = j; strcpy(adltbl[ADLINDEX].conn_name, "hl"); adltbl[ADLINDEX].conn_number = unit; ADLINDEX++; devunit++; } } if(strncmp(name,"fx",2) == 0) { devunit = getunit("rx"); for(j=0;j<2;j++) { init_adl_entry(ADLINDEX); index = match_device_name("rx"); adltbl[ADLINDEX].device_index = index; adltbl[ADLINDEX].device_unit = devunit; adltbl[ADLINDEX].device_drive = j; strcpy(adltbl[ADLINDEX].conn_name, "fx"); adltbl[ADLINDEX].conn_number = unit; ADLINDEX++; devunit++; } }}/***************************************************************** Name: getunit ** ** Abstract: Find the next available unit number for the ** given device name. We seach through the alive ** device table to find out if any devices match ** the device name. If so we keep track of the ** highest unit number for that device name and ** use the next available one for our floating ** device. ** ** Inputs: ** name The name of the device to search for. ** ** Outputs: None. ** ** Return Values: ** unit The next available unit number for the device. *****************************************************************/getunit(name)char *name;{ int i, index, newunit, unit, len, found; newunit = unit = found = 0; len = strlen(name); for(i=0;i<ADLINDEX;i++) { index = adltbl[i].device_index; if((strncmp(name,devtbl[index].devname,len) == 0) && adltbl[i].device_unit != -1) { found = 1; newunit = adltbl[i].device_unit; if(newunit > unit) unit = newunit; } } if(found > 0) unit++; return(unit);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?