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