|
|
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 1997 by Apple Computer, Inc., all rights reserved. ! 26: /* ! 27: * Copyright (c) 1991-1997 NeXT Software, Inc. All rights reserved. ! 28: * ! 29: * IdeCntInline.h - included by IdeCnt.m -- misc functions ! 30: * ! 31: * HISTORY ! 32: */ ! 33: ! 34: ! 35: #import <driverkit/kernelDriver.h> ! 36: #import "io_inline.h" ! 37: ! 38: ! 39: static __inline__ ! 40: void ! 41: rwBuffer(caddr_t addr, BOOL read, unsigned length, unsigned ideDataRegister) ! 42: { ! 43: unsigned int len = length; ! 44: unsigned short *dst; ! 45: ! 46: dst = (unsigned short *)addr; ! 47: length /= 2; ! 48: ! 49: if (read) ! 50: { ! 51: while (length-- > 0) ! 52: *dst++ = inw(ideDataRegister); ! 53: } ! 54: else ! 55: { ! 56: while (length-- > 0) ! 57: outw(ideDataRegister, *dst++); ! 58: } ! 59: ! 60: if (len % 2 == 0) ! 61: return; ! 62: ! 63: /* ! 64: * Extra byte. This can happen for ATAPI I/O requests. ! 65: */ ! 66: if (read) ! 67: { ! 68: *(unsigned char *)dst = inw(ideDataRegister); ! 69: } ! 70: else ! 71: { ! 72: outw(ideDataRegister, * (unsigned char *)dst); ! 73: } ! 74: } ! 75: ! 76: /* ! 77: * Note: length is <= PAGE_SIZE while calling this function. If a request is ! 78: * of odd size and is split over two pages then we always make the second one ! 79: * odd sized. ! 80: */ ! 81: ! 82: static __inline__ ! 83: void ! 84: ideXferData(caddr_t addr, BOOL read, struct vm_map *client, ! 85: unsigned length, ideRegsAddrs_t ideRegs ) ! 86: { ! 87: unsigned count, offset; ! 88: unsigned short sw; ! 89: extern struct vm_map *kernel_map; ! 90: u_int32_t maddr0, maddr1; ! 91: vm_address_t xaddr0, xaddr1; ! 92: ! 93: /* ! 94: * Simple case, no mapping required. ! 95: */ ! 96: if (client == kernel_map) ! 97: { ! 98: rwBuffer(addr, read, length, ideRegs.data); ! 99: return; ! 100: } ! 101: ! 102: offset = (unsigned)addr & (PAGE_SIZE - 1); ! 103: ! 104: IOPhysicalFromVirtual( (vm_task_t)client, (vm_address_t)addr, &maddr0 ); ! 105: maddr0 = trunc_page(maddr0); ! 106: ! 107: if ((PAGE_SIZE - offset) < length) /* this is a pain */ ! 108: { ! 109: count = PAGE_SIZE - offset; ! 110: ! 111: IOPhysicalFromVirtual( (vm_task_t)client, (vm_address_t)round_page(addr), &maddr1 ); ! 112: maddr1 = trunc_page(maddr1); ! 113: ! 114: IOMapPhysicalIntoIOTask( maddr0, PAGE_SIZE, &xaddr0 ); ! 115: IOMapPhysicalIntoIOTask( maddr1, PAGE_SIZE, &xaddr1 ); ! 116: ! 117: xaddr0 = trunc_page(xaddr0) + offset; ! 118: xaddr1 = trunc_page(xaddr1); ! 119: ! 120: if (count % 2) ! 121: { ! 122: rwBuffer((unsigned char *)xaddr0, read, (count - 1), ideRegs.data); ! 123: ! 124: if (read) ! 125: { ! 126: sw = inw(ideRegs.data); ! 127: ((unsigned char *)xaddr0)[count-1] = (unsigned char)((sw & 0xff00) >> 8); ! 128: ((unsigned char *)xaddr1)[0] = (unsigned char) (sw & 0x00ff); ! 129: } ! 130: else ! 131: { ! 132: sw = ((unsigned char *)xaddr0)[count - 1] << 8; ! 133: sw |= ((unsigned char *)xaddr1)[0]; ! 134: outw(ideRegs.data, sw); ! 135: } ! 136: xaddr1++; ! 137: rwBuffer((unsigned char *)xaddr1, read, (length - count - 1), ideRegs.data); ! 138: } ! 139: else ! 140: { ! 141: rwBuffer((unsigned char *)xaddr0, read, count, ideRegs.data ); ! 142: rwBuffer((unsigned char *)xaddr1, read, (length - count), ideRegs.data ); ! 143: } ! 144: ! 145: xaddr0 = trunc_page(xaddr0); ! 146: xaddr1 = trunc_page(xaddr1); ! 147: IOUnmapPhysicalFromIOTask( xaddr0, PAGE_SIZE ); ! 148: IOUnmapPhysicalFromIOTask( xaddr1, PAGE_SIZE ); ! 149: } ! 150: else ! 151: { ! 152: IOMapPhysicalIntoIOTask( maddr0, PAGE_SIZE, &xaddr0 ); ! 153: xaddr0 = trunc_page(xaddr0) + offset; ! 154: ! 155: rwBuffer((unsigned char *) xaddr0, read, length, ideRegs.data ); ! 156: ! 157: xaddr0 = trunc_page(xaddr0); ! 158: IOUnmapPhysicalFromIOTask( xaddr0, length ); ! 159: } ! 160: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.