|
|
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.0 (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 1997-1998 by Apple Computer, Inc., All rights reserved. ! 26: * Copyright 1994-1997 NeXT Software, Inc., All rights reserved. ! 27: * ! 28: * IdeCntInline.h - included by IdeCnt.m -- misc functions ! 29: * ! 30: * HISTORY ! 31: * 07-Jul-1994 Rakesh Dubey at NeXT ! 32: * Created from original driver written by David Somayajulu. ! 33: */ ! 34: ! 35: /* ! 36: * FIXME: must get rid of this. ! 37: */ ! 38: extern vm_offset_t ! 39: pmap_resident_extract( ! 40: pmap_t pmap, ! 41: vm_offset_t va ! 42: ); ! 43: ! 44: ! 45: static __inline__ ! 46: void ! 47: outw_fast( ! 48: io_addr_t port, ! 49: unsigned short data ! 50: ) ! 51: { ! 52: asm volatile( ! 53: "outw %1,%0" ! 54: : ! 55: : "d" (port), "a" (data) ! 56: : "cc"); ! 57: } ! 58: ! 59: /* ! 60: * This is same as one in standard header files except that the header file ! 61: * that gets pulled in has wrong code for this function. FIXME. 10/5/94. ! 62: */ ! 63: static __inline__ ! 64: unsigned long ! 65: inl_mine( ! 66: IOEISAPortAddress port ! 67: ) ! 68: { ! 69: unsigned long data; ! 70: ! 71: asm volatile( ! 72: "inl %1,%0" ! 73: : "=a" (data) ! 74: : "d" (port)); ! 75: ! 76: return (data); ! 77: } ! 78: ! 79: static __inline__ ! 80: void ! 81: outl_fast( ! 82: IOEISAPortAddress port, ! 83: unsigned long data ! 84: ) ! 85: { ! 86: asm volatile( ! 87: "outl %1,%0" ! 88: : ! 89: : "d" (port), "a" (data) ! 90: : "cc"); ! 91: } ! 92: ! 93: static __inline__ ! 94: void ! 95: rwBuffer_16(caddr_t addr, BOOL read, unsigned length, ! 96: unsigned ideDataRegister) ! 97: { ! 98: unsigned int len = length; ! 99: unsigned short *dst; ! 100: ! 101: dst = (unsigned short *)addr; ! 102: length /= 2; ! 103: ! 104: if (read) { ! 105: while (length-- > 0) ! 106: *dst++ = inw(ideDataRegister); ! 107: } else { ! 108: while (length-- > 0) ! 109: outw_fast(ideDataRegister, *dst++); ! 110: } ! 111: ! 112: if (len % 2 == 0) ! 113: return; ! 114: ! 115: /* ! 116: * Extra byte. This can happen for ATAPI I/O requests. ! 117: */ ! 118: if (read) { ! 119: * (unsigned char *)dst = inw(ideDataRegister); ! 120: } else { ! 121: outw(ideDataRegister, * (unsigned char *)dst); ! 122: } ! 123: } ! 124: ! 125: /* ! 126: * Using 32-bit access. ! 127: */ ! 128: static __inline__ ! 129: void ! 130: rwBuffer_32(caddr_t addr, BOOL read, unsigned length, ! 131: unsigned ideDataRegister) ! 132: { ! 133: unsigned int len = length; ! 134: unsigned int *dst; ! 135: ! 136: dst = (unsigned int *)addr; ! 137: length /= 4; ! 138: ! 139: if (read) { ! 140: while (length-- > 0) ! 141: *dst++ = inl_mine(ideDataRegister); ! 142: } else { ! 143: while (length-- > 0) ! 144: outl_fast(ideDataRegister, *dst++); ! 145: } ! 146: ! 147: if (len % 4 == 0) ! 148: return; ! 149: ! 150: /* ! 151: * Hand off the remainder to the standard routine. ! 152: */ ! 153: rwBuffer_16((caddr_t) dst, read, len % 4, ideDataRegister); ! 154: } ! 155: ! 156: static __inline__ ! 157: void ! 158: rwBuffer(caddr_t addr, BOOL read, unsigned length, ! 159: unsigned ideDataRegister, ideTransferWidth_t transferWidth) ! 160: { ! 161: if (transferWidth == IDE_TRANSFER_32_BIT) { ! 162: rwBuffer_32(addr, read, length, ideDataRegister); ! 163: } else { ! 164: rwBuffer_16(addr, read, length, ideDataRegister); ! 165: } ! 166: } ! 167: ! 168: /* ! 169: * Note: length is <= PAGE_SIZE while calling this function. If a request is ! 170: * of odd size and is split over two pages then we always make the second one ! 171: * odd sized. ! 172: */ ! 173: ! 174: static __inline__ ! 175: void ! 176: ideXferData(caddr_t addr, BOOL read, struct vm_map *client, ! 177: unsigned length, ideRegsAddrs_t ideRegs, ! 178: ideTransferWidth_t transferWidth) ! 179: { ! 180: unsigned count, offset; ! 181: unsigned short sw; ! 182: extern struct vm_map *kernel_map; ! 183: caddr_t maddr0, maddr1; ! 184: ! 185: /* ! 186: * Simple case, no mapping required. ! 187: */ ! 188: if (client == kernel_map) { ! 189: rwBuffer(addr, read, length, ideRegs.data, transferWidth); ! 190: return; ! 191: } ! 192: ! 193: /* ! 194: * Get the physical address here. ! 195: */ ! 196: offset = (unsigned)addr & (PAGE_SIZE - 1); ! 197: maddr0 = (caddr_t) pmap_resident_extract( ! 198: vm_map_pmap_EXTERNAL((struct vm_map *) client), ! 199: (vm_offset_t) addr); ! 200: ! 201: if ((PAGE_SIZE - offset) < length) { /* this is a pain */ ! 202: count = PAGE_SIZE - offset; ! 203: maddr1 = (caddr_t) pmap_resident_extract( ! 204: vm_map_pmap_EXTERNAL((struct vm_map *) client), ! 205: (vm_offset_t) addr + count); ! 206: if (count % 2) { ! 207: rwBuffer((unsigned char *)pmap_phys_to_kern(maddr0), ! 208: read, (count - 1), ideRegs.data, transferWidth); ! 209: ! 210: if (read) { ! 211: sw = inw(ideRegs.data); ! 212: *((unsigned char *)pmap_phys_to_kern(maddr0 + count - 1)) = ! 213: (unsigned char)(sw & 0xff); ! 214: *((unsigned char *)pmap_phys_to_kern(maddr1)) = ! 215: (unsigned char)((sw & 0xff) >> 8); ! 216: } else { ! 217: sw = *((unsigned char *)pmap_phys_to_kern(maddr0+count - 1)); ! 218: sw |= *((unsigned char *)pmap_phys_to_kern(maddr1)) << 8; ! 219: outw_fast(ideRegs.data, sw); ! 220: } ! 221: maddr1++; ! 222: rwBuffer((unsigned char *)pmap_phys_to_kern(maddr1), ! 223: read, (length - count - 1), ! 224: ideRegs.data, transferWidth); ! 225: } else { ! 226: rwBuffer((unsigned char *)pmap_phys_to_kern(maddr0), ! 227: read, count, ideRegs.data, transferWidth); ! 228: rwBuffer((unsigned char *)pmap_phys_to_kern(maddr1), ! 229: read, (length - count), ! 230: ideRegs.data, transferWidth); ! 231: } ! 232: } else { ! 233: rwBuffer((unsigned char *) pmap_phys_to_kern(maddr0), ! 234: read, length, ideRegs.data, transferWidth); ! 235: } ! 236: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.