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