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