tcmmap.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 291 行
C
291 行
#ifndef lintstatic char *sccsid = "@(#)tcmmap.c 4.1 (ULTRIX) 2/21/91";#endif lint/************************************************************************ * * * Copyright (c) 1990 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. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * 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. * * * ************************************************************************//********************************************************//* sk.c - Memory mapped device driver for the *//* TURBOchannel *//* *//* Abstract: *//* *//* This driver provides a memory map mechanism for a *//* generic memory mapped device. *//* *//* Author: Digital Equipment Corporation *//* *//********************************************************//* INCLUDE FILES *//* *//********************************************************//* Header files required by memory mapped device driver */#include "sk.h" /* Driver header file generated by config */ #include "../h/types.h"#include "../h/errno.h"#include "../h/uio.h"#include "../../machine/common/cpuconf.h" /* Include for BADADDR */ #include "../machine/param.h"#include "../h/ioctl.h"#include "../h/param.h"#include "../h/buf.h"#include "../h/vmmac.h"#include "../io/uba/ubavar.h"#include "../io/tc/tc.h" /* TURBOchannel definitions */ /**********************************************************//* DECLARATIONS *//* *//**********************************************************/#define SKREGSIZE 256 /* First csr area size */ #define SKUNIT(dev) (minor(dev)) /* Device minor number */ /* Driver routines declarations */int skprobe(),skattach(),skintr(),skmmap(); /* Array of pointers to uba_device structures */ struct uba_device *skdinfo[NSK]; /* Declare and initialize uba_driver structure */ struct uba_driver skdriver = { skprobe,0,skattach,0,0, "sk",skdinfo,0,0,0};/* Device register structure */ struct sk_reg_t { volatile char stub_0; /* Base address */ volatile char T; /* First readable, always T */ volatile char stub_1; /* Data is only on every other word */ volatile char C; /* Second readable */ volatile char nonused[124]; volatile short status; volatile unsigned short intvec; volatile unsigned short reset; volatile char unused[2]; volatile unsigned short start; volatile char nevused[2]; volatile unsigned short skdata; volatile char pads[92]; /* Fills out the remainder of */ /* the 256 byte block */}; /* Define a softc structure for use by the interrupt service *//* routines, the error log routines, etc. */ struct sk_softc{ int sk_time; /* Timeout value*/ int sk_expint; /* Expecting interrupt*/ int sk_timeout; /* Timeout situation : true or false */ int sk_data; /* Value read after interrupt*/ int intcnt; /* Number of times interrupts may happen */ struct sk_reg_t *sk_base; /* Pointer to sk_reg_t structure */} sksoftc[NSK]; /* Define debug constants */ #define SK_DEBUG#ifdef SK_DEBUGint sk_debug = 0;#endif SK_DEBUG/**********************************************************//* AUTOCONFIGURATION *//* *//**********************************************************//********* Probe Routine **********************************//* *//* The skprobe routine calls the BADADDR macro to *//* determine that there is indeed a board at the *//* specified address. If the board is present, *//* skprobe returns the size of the register space that *//* the board occupies. If the device is not present, *//* skprobe returns 0. *//* *//**********************************************************/skprobe(addr1,unit)caddr_t addr1; /* System Virtual Address for the sk device */ int unit; /* Unit number associated with the sk device */ { /* Pointer to device register structure */ register struct sk_reg_t *sk_reg; /* Pointer to sk_softc structure */ register struct sk_softc *sksc; /* Kernel was properly configured */ #ifdef SK_DEBUG if (sk_debug) cprintf("SK probe routine entered\\n"); #endif SK_DEBUG sk_reg = (struct sk_reg_t *)addr1; /* Point to device registers */ /* Call the BADADDR macro to determine if */ /* the device is present */ if (BADADDR ((char *) &sk_reg->T,sizeof(char)) !=0) { return (0); } /* Check the first location */ if (sk_reg->T != 'T') return(0); /* Call the BADADDR macro a second time to determine */ /* if the device is present */ if (BADADDR ((char *) &sk_reg->C,sizeof(char)) !=0) { return (0); } /* Check the second location */ if (sk_reg->C != 'C') return(0); /* Set the pointer to the address of the sk_softc */ /* structure array */ sksc = &sksoftc[unit]; /* Store the base address */ sksc->sk_base = (struct sk_reg_t *)addr1; /* Device found */ #ifdef SK_DEBUG if (sk_debug) cprintf("SK driver found\\n"); #endif SK_DEBUG /* Return size of register space */ return (SKREGSIZE); }/*********** Attach Routine *******************************//* *//* The skattach routine initializes the device and its *//* software state. *//**********************************************************/skattach(ui)struct uba_device *ui; /* Pointer to uba_device structure */ {/* Attach routine code goes here */}/********** Interrupt Routine *****************************//* *//**********************************************************/skintr(unit)int unit; /* Logical unit number of device */ { /* Pointer to device register structure */ register struct sk_reg_t *sk_reg; /* Pointer to sk_softc structure */ register struct sk_softc *sksc; /* Set the device's softc structure */ sksc = &sksoftc[unit]; /* Store the base address */ sk_reg = sksc->sk_base; /* Check some status word and then set it */ if (sk_reg->status < 0) { sk_reg->status = 5; /* Read in some data */ sksc->sk_data = sk_reg->skdata; }}/**********************************************************//* OPEN AND CLOSE *//* *//**********************************************************//********* Open Routine ***********************************//* *//**********************************************************/skopen(dev,flag)dev_t dev; /* Major/minor device number */ int flag; /* Flags from /usr/sys/h/file.h */ { /* Return to the open system call */ return (0); }/********* Close Routine **********************************//* *//**********************************************************/skclose(dev,flag)dev_t dev; /* Major/minor device number */ int flag; /* Flags from /usr/sys/h/file.h */ { /* Return to the close system call */ return (0); }/**********************************************************//* MEMORY MAPPING *//* *//**********************************************************//********* Memory Mapping Routine *************************//* *//* The skmmap routine is invoked by the kernel as a *//* result of an application calling the mmap(2) system *//* call. The skmmap routine makes sure that the *//* specified offset into the memory mapped device's *//* memory is valid. If the offset is not valid, skmmap *//* returns -1. If the offset is valid, skmmap returns *//* the page frame number corresponding to the page at *//* the specified offset. *//* *//**********************************************************/skmmap(dev, off, prot)dev_t dev; /* Device whose memory is to be mapped */ off_t off; /* Byte offset into device memory */ int prot; /* Protection flag: PROT_READ or PROT_WRITE */ { /* Pointer to device register structure */ register struct sk_reg_t *sk_reg; /* Pointer to sk_softc structure */ register struct sk_softc *sksc; /* Page frame number */ int kpfnum; /* Make sure that the offset into the device registers */ /* is less than the size of the device register space. */ if ((u_int) off >= SKREGSIZE) return (-1); /* Otherwise, set the device's sk_softc structure */ sksc = &sksoftc [SKUNIT(dev)]; /* and store the base address */ sk_reg = sksc->sk_base; /* Find the register space of the device */ kpfnum = vtokpfnum(sk_reg+off); return (kpfnum); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?