|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: /*
25: * Copyright 1994 NeXT Computer, Inc.
26: * All rights reserved.
27: *
28: */
29:
30: #if NOTYET
31:
32: #import <driverkit/i386/IOEISADMATransferBuffer.h>
33: #import <driverkit/IODeviceDescriptionPrivate.h>
34: #import <machdep/i386/dma.h>
35: #import <machdep/i386/dma_inline.h>
36: #import <machdep/i386/dma_exported.h>
37:
38: #define MIN(a,b) ((a) < (b) ? (a) : (b))
39:
40: @implementation IOEISADMATransferBuffer
41:
42:
43: -setChannel:(unsigned int)newChannel
44: forDevice:device
45: {
46: unsigned int *list;
47:
48: localChannel = newChannel;
49: directDevice = device;
50: deviceDescription = [device deviceDescription];
51: if (deviceDescription == nil) {
52: return nil;
53: }
54: if ((list = [deviceDescription channelList])) {
55: realChannel = list[newChannel];
56: } else {
57: return nil;
58: }
59: return self;
60: }
61:
62: -(IODMADirection)transferDirection
63: {
64: return transferDirection;
65: }
66:
67: -(void)setTransferDirection:(IODMADirection)dir
68: {
69: transferDirection = dir;
70: }
71:
72: -(IOReturn)startTransfer
73: {
74: IORange range;
75:
76: range.start = 0;
77: range.size = [self size];
78: return [self startTransferAt:range];
79: }
80:
81: -(IOReturn)startTransferAt:(IORange)range
82: {
83: int Size;
84: IOPhysicalRange prange;
85:
86: Size = [self size];
87: if (range.start > Size || (range.start + range.size) > Size)
88: return IO_R_INVALID;
89:
90: if ([self getPhysicalAddress:&prange at:range.start]
91: == NO) {
92: return IO_R_INVALID;
93: }
94: prange.size = MIN(range.size, prange.size);
95:
96: (void) dma_mask_chan(realChannel);
97: if (transferDirection == IO_DMARead) {
98: /* DMA write to memory */
99: dma_chan_xfer_dir(realChannel, DMA_XFER_WRITE);
100: } else {
101: /* DMA read from memory */
102: dma_chan_xfer_dir(realChannel, DMA_XFER_READ);
103: }
104:
105: dma_set_chan_addr(realChannel, prange.start);
106:
107: dma_set_chan_count(realChannel, prange.size);
108:
109: currentTransfer = prange;
110:
111: (void) dma_unmask_chan(realChannel);
112:
113: return (IO_R_SUCCESS);
114: }
115:
116: -(IOReturn)abortTransfer
117: {
118: // XXX
119: return (IO_R_SUCCESS);
120: }
121:
122: -(BOOL)transferIsComplete
123: {
124: return is_dma_done(realChannel);
125: }
126:
127: -(unsigned)currentTransferLocation
128: {
129: return get_dma_addr(realChannel) - currentTransfer.start;
130: }
131:
132: -(unsigned)currentTransferCount
133: {
134: return get_dma_count(realChannel);
135: }
136:
137:
138: -(IOReturn)enableChannel
139: {
140: dma_unmask_chan(realChannel);
141: return IO_R_SUCCESS;
142: }
143: -(void)disableChannel
144: {
145: dma_mask_chan(realChannel);
146: }
147:
148:
149: /*
150: * Reserve and release exclusive DMA lock. Use is optional; provides
151: * exclusion between mutually incompatible DMA devices.
152: */
153: - (void)reserveDMALock
154: {
155: [directDevice reserveDMALock];
156: }
157: - (void)releaseDMALock
158: {
159: [directDevice releaseDMALock];
160: }
161:
162: /*
163: * FIXME -- the kernel dma code should provide a way
164: * to get the current transfer mode.
165: */
166:
167: static IODMATransferMode currentMode;
168:
169: -(IODMATransferMode)transferMode
170: {
171: return currentMode;
172: }
173:
174: -(IOReturn)setTransferMode:(IODMATransferMode)mode
175: {
176: unsigned real_mode;
177:
178: switch(mode) {
179: case IO_Demand:
180: real_mode = DMA_MODE_DEMAND;
181: break;
182: case IO_Single:
183: default:
184: real_mode = DMA_MODE_SINGLE;
185: break;
186: case IO_Block:
187: real_mode = DMA_MODE_BLOCK;
188: break;
189: case IO_Cascade:
190: real_mode = DMA_MODE_CASCADE;
191: break;
192: }
193: dma_chan_xfer_mode(realChannel, real_mode);
194: currentMode = mode;
195: return IO_R_SUCCESS;
196: }
197:
198: -(IOEISADMATransferWidth)transferWidth
199: {
200: int width;
201: IOEISADMATransferWidth ret;
202:
203: width = get_dma_xfer_width(realChannel);
204: switch(width) {
205: case DMA_XFR_8_BIT:
206: default: /* should never be reached */
207: ret = IO_8Bit;
208: break;
209: case DMA_XFR_16_BIT_WORD:
210: ret = IO_16BitWordCount;
211: break;
212: case DMA_XFR_16_BIT_BYTE:
213: ret = IO_16BitByteCount;
214: break;
215: case DMA_XFR_32_BIT:
216: ret = IO_32Bit;
217: break;
218: }
219: return ret;
220: }
221:
222: -(IOReturn)setTransferWidth:(IOEISADMATransferWidth)width
223: {
224: int dmaWidth;
225:
226: switch(width) {
227: case IO_8Bit:
228: dmaWidth = DMA_XFR_8_BIT;
229: break;
230: case IO_16BitWordCount:
231: dmaWidth = DMA_XFR_16_BIT_WORD;
232: break;
233: case IO_16BitByteCount:
234: dmaWidth = DMA_XFR_16_BIT_BYTE;
235: break;
236: case IO_32Bit:
237: dmaWidth = DMA_XFR_32_BIT;
238: break;
239: default:
240: return IO_R_INVALID_ARG;
241: }
242: dma_xfer_width(realChannel, dmaWidth);
243: return IO_R_SUCCESS;
244: }
245:
246: -(IOEISADMATiming)transferTiming
247: {
248: return 0; //XXX
249: }
250:
251: -(IOReturn)setTransferTiming:(IOEISADMATiming)timing
252: {
253: int dmaTiming;
254:
255: switch(timing) {
256: case IO_Compatible:
257: dmaTiming = DMA_TIMING_COMPAT;
258: break;
259: case IO_TypeA:
260: dmaTiming = DMA_TIMING_A;
261: break;
262: case IO_TypeB:
263: dmaTiming = DMA_TIMING_B;
264: break;
265: case IO_Burst:
266: dmaTiming = DMA_TIMING_BURST;
267: break;
268: }
269: dma_timing(realChannel, dmaTiming);
270: return IO_R_SUCCESS;
271: }
272:
273: -(IOEISAStopRegisterMode)stopRegisterMode
274: {
275: return 0; //XXX
276: }
277:
278: -(IOReturn)setStopRegisterMode:(IOEISAStopRegisterMode)mode
279: {
280: unsigned dmaFlag;
281:
282: if(mode == IO_StopRegisterEnable) {
283: dmaFlag = DMA_STOP_ENABLE;
284: }
285: else {
286: dmaFlag = DMA_STOP_DISABLE;
287: }
288: dma_stop_enable(realChannel, dmaFlag);
289: return IO_R_SUCCESS;
290: }
291:
292: -(IOIncrementMode)transferIncrementMode
293: {
294: return 0; //XXX
295: }
296: -(IOReturn)setTransferIncrementMode:(IOIncrementMode)mode
297: {
298: int dir = (mode == IO_Decrement ? DMA_ADRS_DECR : DMA_ADRS_INCR);
299:
300: dma_chan_adrs_dir(realChannel, dir);
301: return IO_R_SUCCESS;
302: }
303:
304: -(BOOL)autoinitializeMode
305: {
306: return 0; //XXX
307: }
308:
309: -(IOReturn)setAutoinitializeMode:(BOOL)mode
310: {
311: dma_chan_autoinit(realChannel, (mode ? 1 : 0));
312: return IO_R_SUCCESS;
313: }
314:
315: -(BOOL)isValidForDMA
316: {
317: int offset, total;
318: IOPhysicalRange prange;
319:
320: if (eisa_present())
321: return YES;
322:
323: for (total = [self size], offset = 0; total > 0; ) {
324: if ([self getPhysicalAddress:&prange at:offset] == NO) {
325: return NO;
326: }
327: if (prange.start >= 16 * 1024 * 1024) // XXX use symbolic constant
328: return NO;
329: total -= prange.size;
330: offset += prange.size;
331: }
332: return YES;
333: }
334:
335:
336: /*
337: * Returns the maximum number of bytes that can be transferred in one
338: * operation from the specified offset in the buffer.
339: */
340: -(unsigned int)maximumTransferLengthAtOffset:(unsigned int)offset
341: {
342: int len = 0;
343: IOPhysicalRange prange;
344:
345: if ([self getPhysicalAddress:&prange at:offset] == NO)
346: return 0;
347: if (eisa_present())
348: return prange.size;
349: else
350: return MIN(prange.size, 64 * 1024);
351: }
352:
353: +(BOOL)allocMemoryWithSize:(int)memSize
354: attributes:(IOBufferAttributes)attr
355: alignment:(IOAlignment)align
356: allocedAddress:(IOVirtualAddress *)allocPtr
357: dataAddress:(IOVirtualAddress *)dataPtr
358: allocedSize:(int *)sizePtr
359: newAttributes:(IOBufferAttributes *)newAttrPtr
360: newMap:(IOAddressMap *)mapPtr
361: {
362: IOVirtualAddress vaddr;
363: int alignSize, newSize;
364:
365: alignSize = IOAlignmentToSize(align);
366: newSize = memSize + 2 * alignSize;
367:
368: /* an optimization that relies on IOMalloc returning aligned pages. */
369: if (newSize > PAGE_SIZE && memSize <= PAGE_SIZE)
370: newSize = PAGE_SIZE;
371:
372: if (eisa_present())
373: vaddr = (IOVirtualAddress)IOMalloc(newSize);
374: else
375: vaddr = (IOVirtualAddress)IOMallocLow(newSize);
376: if (vaddr == 0)
377: return FALSE;
378:
379: *allocPtr = vaddr;
380: if (newSize != memSize)
381: *dataPtr = (vaddr + alignSize - 1) & ~(alignSize - 1);
382: else
383: *dataPtr = vaddr;
384: *sizePtr = newSize;
385: *newAttrPtr = IOBuf_Wired | IOBuf_WiredStatic | IOBuf_Contiguous;
386: *mapPtr = (IOAddressMap)IOVmTaskSelf();
387: return TRUE;
388: }
389:
390:
391: +(BOOL)freeMemory:(IOVirtualAddress)addr
392: size:(int)memsize
393: map:(IOAddressMap)memmap
394: attributes:(IOBufferAttributes)attr
395: {
396: if (eisa_present())
397: IOFree((void *)addr, memsize);
398: else
399: IOFreeLow((void *)addr, memsize);
400: return TRUE;
401: }
402:
403: @end
404:
405: #endif NOTYET
406:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.