vmemmap.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 284 行
C
284 行
#ifndef lintstatic char *sccsid = "@(#)vmemmap.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 *//* *//* 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 "../io/uba/ubavar.h"#include "../io/vme/vbareg.h" /* VMEbus definitions */ #include "../h/vmmac.h"/**********************************************************//* 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,SKREGSIZE,VMEA16D16,0,0 };/* Device register structure */struct sk_reg_t { volatile char stub_0; /* Base address */ volatile char V; /* First readable, always V */ volatile char stub_1; /* Data is only on every other byte */ volatile char M; /* 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 *//* routine, the error log routine, 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(unit,addr1)int unit; /* Unit number associated with the sk device */caddr_t addr1; /* System Virtual Address for 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 /* Point to device registers */ sk_reg = (struct sk_reg_t *)addr1; /* Call the BADADDR macro to determine if */ /* the device is present */ if (BADADDR ((char *) &sk_reg->V,sizeof(char)) !=0) { return (0); } /* Check the first location */ if (sk_reg->V != 'V') return(0); /* Call the BADADDR macro a second time to determine */ /* if the device is present */ if (BADADDR ((char *) &sk_reg->M,sizeof(char)) !=0) { return (0); } /* Check the second location */ if (sk_reg->M != 'M') 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; sksc = &sksoftc[unit]; /* Set the device's softc structure */ sk_reg = sksc->sk_base; /* Store the base address */ /* 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 */ { register struct sk_reg_t *sk_reg; /* Ptr to device register structure */ register struct sk_softc *sksc; /* Pointer to sk_softc structure */ int kpfnum; /* Page frame number */ /* 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)]; sk_reg = sksc->sk_base; /* and store the base address */ /* Find the register space of the device */ kpfnum = vtokpfnum(sk_reg+off); return (kpfnum); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?