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