|
|
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.