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