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