Root/
Source at commit 2381 created 10 years 21 days ago. By ifabio, Apply patch: (Credits to Thomas Jansen aka tja) - Reading options from all devices during boot. The options for the boot menu are only read from the devices rd(0,0) or bt(0,0). Consequently, boot menu options (e.g. "Quiet Boot", "Timeout", etc.) in plists on other devices (like most users have) are ignored. This patch extends the list of paths to search for the options plist on all devices that can be found. | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * The contents of this file constitute Original Code as defined in and␊ |
7 | * are subject to the Apple Public Source License Version 2.0 (the␊ |
8 | * "License"). You may not use this file except in compliance with the␊ |
9 | * License. Please obtain a copy of the License at␊ |
10 | * http://www.apple.com/publicsource and read it before using this file.␊ |
11 | * ␊ |
12 | * This Original Code and all software distributed under the License are␊ |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the␊ |
17 | * License for the specific language governing rights and limitations␊ |
18 | * under the License.␊ |
19 | * ␊ |
20 | * @APPLE_LICENSE_HEADER_END@␊ |
21 | */␊ |
22 | /*␊ |
23 | * cache.c - A simple cache for file systems meta-data.␊ |
24 | *␊ |
25 | * Copyright (c) 2000 Apple Computer, Inc.␊ |
26 | *␊ |
27 | * DRI: Josh de Cesare␊ |
28 | */␊ |
29 | ␊ |
30 | #include <sl.h>␊ |
31 | // #include <fs.h>␊ |
32 | ␊ |
33 | struct CacheEntry {␊ |
34 | CICell ih;␊ |
35 | long time;␊ |
36 | long long offset;␊ |
37 | };␊ |
38 | typedef struct CacheEntry CacheEntry;␊ |
39 | ␊ |
40 | #define kCacheSize (0x100000)␊ |
41 | #define kCacheMinBlockSize (0x200)␊ |
42 | #define kCacheMaxBlockSize (0x8000)␊ |
43 | #define kCacheMaxEntries (kCacheSize / kCacheMinBlockSize)␊ |
44 | ␊ |
45 | static CICell gCacheIH;␊ |
46 | static long gCacheBlockSize;␊ |
47 | static long gCacheNumEntries;␊ |
48 | static long gCacheTime;␊ |
49 | ␊ |
50 | #ifdef __i386__␊ |
51 | static CacheEntry *gCacheEntries;␊ |
52 | static char *gCacheBuffer;␊ |
53 | #else␊ |
54 | static CacheEntry gCacheEntries[kCacheMaxEntries];␊ |
55 | static char gCacheBuffer[kCacheSize];␊ |
56 | #endif␊ |
57 | ␊ |
58 | #if CACHE_STATS␊ |
59 | unsigned long gCacheHits;␊ |
60 | unsigned long gCacheMisses;␊ |
61 | unsigned long gCacheEvicts;␊ |
62 | #endif␊ |
63 | ␊ |
64 | void CacheReset()␊ |
65 | {␊ |
66 | gCacheIH = NULL;␊ |
67 | }␊ |
68 | ␊ |
69 | void CacheInit( CICell ih, long blockSize )␊ |
70 | {␊ |
71 | #ifdef __i386__␊ |
72 | if ((ih == gCacheIH) && (blockSize == gCacheBlockSize))␊ |
73 | return;␊ |
74 | #endif␊ |
75 | ␊ |
76 | if ((blockSize < kCacheMinBlockSize) ||␊ |
77 | (blockSize > kCacheMaxBlockSize))␊ |
78 | return;␊ |
79 | ␊ |
80 | gCacheBlockSize = blockSize;␊ |
81 | gCacheNumEntries = kCacheSize / gCacheBlockSize;␊ |
82 | gCacheTime = 0;␊ |
83 | ␊ |
84 | #if CACHE_STATS␊ |
85 | gCacheHits = 0;␊ |
86 | gCacheMisses = 0;␊ |
87 | gCacheEvicts = 0;␊ |
88 | #endif␊ |
89 | ␊ |
90 | gCacheIH = ih;␊ |
91 | ␊ |
92 | #ifdef __i386__␊ |
93 | if (!gCacheBuffer) gCacheBuffer = (char *) malloc(kCacheSize);␊ |
94 | if (!gCacheEntries) gCacheEntries = (CacheEntry *) malloc(kCacheMaxEntries * sizeof(CacheEntry));␊ |
95 | if ( !gCacheBuffer || !gCacheEntries )␊ |
96 | {␊ |
97 | gCacheIH = 0; // invalidate cache␊ |
98 | return;␊ |
99 | }␊ |
100 | #endif␊ |
101 | ␊ |
102 | bzero(gCacheEntries, kCacheMaxEntries * sizeof(CacheEntry));␊ |
103 | }␊ |
104 | ␊ |
105 | long CacheRead( CICell ih, char * buffer, long long offset,␊ |
106 | ␉ long length, long cache )␊ |
107 | {␊ |
108 | long cnt, oldestEntry = 0, oldestTime, loadCache = 0;␊ |
109 | CacheEntry *entry;␊ |
110 | ␊ |
111 | // See if the data can be cached.␊ |
112 | if (cache && (gCacheIH == ih) && (length == gCacheBlockSize)) {␊ |
113 | // Look for the data in the cache.␊ |
114 | for (cnt = 0; cnt < gCacheNumEntries; cnt++) {␊ |
115 | entry = &gCacheEntries[cnt];␊ |
116 | if ((entry->ih == ih) && (entry->offset == offset)) {␊ |
117 | entry->time = ++gCacheTime;␊ |
118 | break;␊ |
119 | }␊ |
120 | }␊ |
121 | ␊ |
122 | // If the data was found copy it to the caller.␊ |
123 | if (cnt != gCacheNumEntries) {␊ |
124 | bcopy(gCacheBuffer + cnt * gCacheBlockSize, buffer, gCacheBlockSize);␊ |
125 | #if CACHE_STATS␊ |
126 | gCacheHits++;␊ |
127 | #endif␊ |
128 | return gCacheBlockSize;␊ |
129 | }␊ |
130 | ␊ |
131 | // Could not find the data in the cache.␊ |
132 | loadCache = 1;␊ |
133 | }␊ |
134 | ␊ |
135 | // Read the data from the disk.␊ |
136 | Seek(ih, offset);␊ |
137 | Read(ih, (long)buffer, length);␊ |
138 | #if CACHE_STATS␊ |
139 | if (cache) gCacheMisses++;␊ |
140 | #endif␊ |
141 | ␊ |
142 | // Put the data from the disk in the cache if needed.␊ |
143 | if (loadCache) {␊ |
144 | // Find a free entry.␊ |
145 | oldestTime = gCacheTime;␊ |
146 | for (cnt = 0; cnt < gCacheNumEntries; cnt++) {␊ |
147 | entry = &gCacheEntries[cnt];␊ |
148 | ␊ |
149 | // Found a free entry.␊ |
150 | if (entry->ih == 0) break;␊ |
151 | ␊ |
152 | if (entry->time < oldestTime) {␊ |
153 | oldestTime = entry->time;␊ |
154 | oldestEntry = cnt;␊ |
155 | }␊ |
156 | }␊ |
157 | ␊ |
158 | // If no free entry was found, use the oldest.␊ |
159 | if (cnt == gCacheNumEntries) {␊ |
160 | cnt = oldestEntry;␊ |
161 | #if CACHE_STATS␊ |
162 | gCacheEvicts++;␊ |
163 | #endif␊ |
164 | }␊ |
165 | ␊ |
166 | // Copy the data from disk to the new entry.␊ |
167 | entry = &gCacheEntries[cnt];␊ |
168 | entry->ih = ih;␊ |
169 | entry->time = ++gCacheTime;␊ |
170 | entry->offset = offset;␊ |
171 | bcopy(buffer, gCacheBuffer + cnt * gCacheBlockSize, gCacheBlockSize);␊ |
172 | }␊ |
173 | ␊ |
174 | return length;␊ |
175 | }␊ |
176 |