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 + -
显示快捷键?