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