|
|
1.1 ! root 1: /* $Header: /y/i386/RCS/dmalock.c,v 1.1 93/04/14 10:26:34 root Exp $ ! 2: * ! 3: * The information contained herein is a trade secret of INETCO ! 4: * Systems, Ltd, and is confidential information. It is provided ! 5: * under a license agreement, and may be copied or disclosed only ! 6: * under the terms of that agreement. Any reproduction or ! 7: * disclosure of this material without the express written ! 8: * authorization of INETCO Systems, Ltd. or persuant to the license ! 9: * agreement is unlawful. ! 10: * ! 11: * Copyright (c) 1989 ! 12: * An unpublished work by INETCO Systems, Ltd. ! 13: * All rights reserved. ! 14: * ! 15: * $Description: $ ! 16: * Routines to lock/unlock the DMA controller chip. ! 17: * ! 18: * $Author: root $ ! 19: * ! 20: * $Creation: June 21, 1989 $ ! 21: * ! 22: * $Log: dmalock.c,v $ ! 23: * Revision 1.1 93/04/14 10:26:34 root ! 24: * r75 ! 25: * ! 26: * Revision 1.1 89/06/30 16:21:26 src ! 27: * Initial revision ! 28: * ! 29: */ ! 30: ! 31: #include <sys/timeout.h> ! 32: ! 33: typedef void (* vfp_t)(); /* Void function pointer type. */ ! 34: ! 35: /* ! 36: * If the following variable is non-zero, DMA controller locking is enabled, ! 37: * allowing at access to only one DMA channel at a time. ! 38: */ ! 39: int DMALCK = 1; ! 40: ! 41: static TIM * dmatail = (TIM *)0; /* DMA deferred function queue tail. */ ! 42: static TIM * dmahead = (TIM *)0; /* DMA deferred function queue head. */ ! 43: ! 44: /* ! 45: * int ! 46: * dmalock( dfp, fun, arg ) ! 47: * TIM * dfp; ! 48: * vfp_t fun; ! 49: * int arg; ! 50: * ! 51: * Inputs: dfp = Deferred function structure pointer. ! 52: * fun = Function to call if request is deferred. ! 53: * arg = Argument to pass to function. ! 54: * ! 55: * Action: Either locks DMA controller immediately or defers function ! 56: * call until lock can be granted. ! 57: * ! 58: * Return: 0 = Lock granted or -1 = Lock deferred. ! 59: * ! 60: * Notes: DMA controller locking was introduced to cure a bug on the ! 61: * NCR DMA controller, where overlapped DMA caused problems. ! 62: * No action is taken if DMA locking is disabled. ! 63: */ ! 64: ! 65: int ! 66: dmalock( dfp, fun, arg ) ! 67: register TIM * dfp; ! 68: vfp_t fun; ! 69: int arg; ! 70: { ! 71: register int s; /* Interrupt mask state. */ ! 72: ! 73: /* ! 74: * If DMA locking is disabled, allow functions to proceed. ! 75: */ ! 76: if ( DMALCK == 0 ) ! 77: return( 0 ); ! 78: ! 79: /* ! 80: * Record function and argument to be invoked upon dmaunlock. ! 81: */ ! 82: dfp->t_func = fun; ! 83: dfp->t_farg = arg; ! 84: dfp->t_next = (TIM *)0; ! 85: ! 86: s = sphi(); ! 87: ! 88: /* ! 89: * If the queue is empty, put our structure at the head. ! 90: */ ! 91: if ( dmahead == (TIM *)0 ) { ! 92: dmahead = dfp; ! 93: dmatail = dfp; ! 94: spl( s ); ! 95: return( 0 ); ! 96: } ! 97: ! 98: /* ! 99: * PARANOIA: If our structure is already at the head of the queue, ! 100: * print a message and return. ! 101: */ ! 102: if ( dmahead == dfp ) { ! 103: spl( s ); ! 104: printf( "dmalock: driver attempting to doubly lock DMA controller.\n" ); ! 105: return( 0 ); ! 106: } ! 107: ! 108: /* ! 109: * Append to tail of DMA deferred function queue. ! 110: */ ! 111: dmatail->t_next = dfp; ! 112: dmatail = dfp; ! 113: spl( s ); ! 114: return( -1 ); ! 115: } ! 116: ! 117: /* ! 118: * void ! 119: * dmaunlock( dfp ) ! 120: * TIM * dfp; ! 121: * ! 122: * Inputs: dfp = Deferred function structure pointer. ! 123: * ! 124: * Action: Unlocks the DMA controller and calls the next deferred ! 125: * function, if any. ! 126: * ! 127: * Notes: No action is taken if the deferred function structure pointer ! 128: * is not the same as the one used to lock the DMA controller. ! 129: */ ! 130: ! 131: void ! 132: dmaunlock( dfp ) ! 133: register TIM * dfp; ! 134: { ! 135: register TIM * qp; /* Temporary function queue pointer. */ ! 136: register int s; /* Interrupt mask state. */ ! 137: ! 138: s = sphi(); ! 139: ! 140: /* ! 141: * If the DMA controller is not locked, return. ! 142: */ ! 143: if ( dmahead == (TIM *)0 ) { ! 144: spl( s ); ! 145: return; ! 146: } ! 147: ! 148: /* ! 149: * If our lock is not the one holding the DMA controller: ! 150: */ ! 151: if ( dmahead != dfp ) { ! 152: ! 153: /* ! 154: * Look for us in queue. ! 155: */ ! 156: for ( qp = dmahead; qp != dmatail; qp = qp->t_next ) ! 157: ! 158: /* ! 159: * If found, remove us. ! 160: */ ! 161: if ( qp->t_next == dfp ) { ! 162: qp->t_next = dfp->t_next; ! 163: ! 164: if ( dmatail == dfp ) ! 165: dmatail = qp; ! 166: ! 167: break; ! 168: } ! 169: ! 170: spl( s ); ! 171: return; ! 172: } ! 173: ! 174: /* ! 175: * If there are no functions waiting for us, empty queue and return. ! 176: */ ! 177: if ( dmahead == dmatail ) { ! 178: dmahead = (TIM *)0; ! 179: spl( s ); ! 180: return; ! 181: } ! 182: ! 183: /* ! 184: * Remove us and execute next deferred function. ! 185: */ ! 186: dmahead = dmahead->t_next; ! 187: spl( s ); ! 188: (*dmahead->t_func)( dmahead->t_farg, dmahead ); ! 189: } ! 190:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.