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