]>
git.saurik.com Git - apple/boot.git/blob - gen/libsaio/disk.c
41f0f3976aa640d0475774b822b14bf0baec4d84
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1990 Carnegie-Mellon University
28 * Copyright (c) 1989 Carnegie-Mellon University
29 * All rights reserved. The CMU software License Agreement specifies
30 * the terms and conditions for use and redistribution.
34 * INTEL CORPORATION PROPRIETARY INFORMATION
36 * This software is supplied under the terms of a license agreement or
37 * nondisclosure agreement with Intel Corporation and may not be copied
38 * nor disclosed except in accordance with the terms of that agreement.
40 * Copyright 1988, 1989 Intel Corporation
44 * Copyright 1993 NeXT Computer, Inc.
45 * All rights reserved.
48 #define DRIVER_PRIVATE
52 #import <dev/i386/disk.h>
56 static Biosread(int biosdev
, int secno
);
57 static read_label(char *name
, int biosdev
, daddr_t
*boff
, int partition
);
58 void diskActivityHook(void);
59 extern void spinActivityIndicator(void);
61 /* diskinfo unpacking */
62 #define SPT(di) ((di)&0xff)
63 #define HEADS(di) ((((di)>>8)&0xff)+1)
64 #define SPC(di) (SPT(di)*HEADS(di))
65 #define BPS 512 /* sector size of the device */
66 #define N_CACHE_SECS (BIOS_LEN / BPS)
69 #define DISKLABEL 15 /* sector num of disk label */
79 int spt
; /* sectors per track */
80 int spc
; /* sectors per cylinder */
84 daddr_t blknos
[NBUFS
];
85 struct iob iob
[NFILES
];
87 static int label_cached
;
89 // intbuf is the whole buffer, biosbuf is the current cached sector
90 static char * const intbuf
= (char *)ptov(BIOS_ADDR
);
100 di
= get_diskinfo(io
->biosdev
);
102 /* initialize disk parameters -- spt and spc */
104 io
->dirbuf_blkno
= -1;
106 diskinfo
.spt
= SPT(di
);
107 diskinfo
.spc
= diskinfo
.spt
* HEADS(di
);
108 if (read_label(name
, io
->biosdev
, &io
->i_boff
, io
->partition
) < 0)
127 io
->i_flgs
|= F_RDDATA
;
129 /* assume the best */
132 dev
= io
->i_ino
.i_dev
;
134 sector
= io
->i_bn
* (label_secsize
/DOS_BSIZE
);
136 for (offset
= 0; offset
< io
->i_cc
; offset
+= BPS
) {
138 io
->i_error
= Biosread(io
->biosdev
, sector
);
143 /* copy 1 sector from the internal buffer biosbuf into buf */
144 bcopy(biosbuf
, &io
->i_ma
[offset
], BPS
);
149 io
->i_flgs
&= ~F_TYPEMASK
;
153 /* A haque: Biosread(0,-1) means flush the sector cache.
156 Biosread(int biosdev
, int secno
)
158 static int xbiosdev
, xcyl
=-1, xhead
, xsec
, xnsecs
;
165 if (biosdev
== 0 && secno
== -1) {
174 head
= (secno
% spc
) / spt
;
177 if (biosdev
== xbiosdev
&& cyl
== xcyl
&& head
== xhead
&&
178 sec
>= xsec
&& sec
< (xsec
+ xnsecs
))
179 { // this sector is in intbuf cache
180 biosbuf
= intbuf
+ (BPS
* (sec
-xsec
));
189 xnsecs
= ((sec
+ N_CACHE_SECS
) > spt
) ? (spt
- sec
) : N_CACHE_SECS
;
192 while ((rc
= biosread(biosdev
,cyl
,head
,sec
, xnsecs
)) && (++tries
< 5))
195 error(" biosread error 0x%x @ %d, C:%d H:%d S:%d\n",
196 rc
, secno
, cyl
, head
, sec
);
198 sleep(1); // on disk errors, bleh!
204 // extern char name[];
215 struct disk_label
*dlp
;
216 struct fdisk_part
*fd
;
217 struct disk_blk0
*blk0
;
221 static int cached_boff
;
228 // read sector 0 into the internal buffer "biosbuf"
229 if ( rc
= Biosread(biosdev
, 0) )
232 // Check for a valid boot block.
233 blk0
= (struct disk_blk0
*)biosbuf
;
234 if (blk0
->signature
== DISK_SIGNATURE
) {
235 // Check to see if the disk has been partitioned with FDISK
236 // to allow DOS and ufs filesystems to exist on the same spindle.
237 fd
= (struct fdisk_part
*)blk0
->parts
;
238 for ( n
= 0; n
< FDISK_NPART
; n
++, fd
++)
239 if (fd
->systid
== FDISK_NEXTNAME
)
241 part_offset
= fd
->relsect
;
245 /* It's not an error if there is not a valid boot block. */
247 /* Read the NeXT disk label.
248 * Since we can't count on it fitting in the sector cache,
249 * we'll put it elsewhere.
251 dlp
= (struct disk_label
*)malloc(sizeof(*dlp
) + BPS
);
252 for(n
= 0, cp
= (char *)dlp
;
253 n
< ((sizeof(*dlp
) + BPS
- 1) / BPS
);
255 if (rc
= Biosread(biosdev
, DISKLABEL
+ part_offset
+ n
))
257 bcopy(biosbuf
, cp
, BPS
);
260 byte_swap_disklabel_in(dlp
);
264 if (dlp
->dl_version
!= DL_V3
) {
265 error("bad disk label magic\n");
269 label_secsize
= dlp
->dl_secsize
;
271 if ((dlp
->dl_part
[partition
].p_base
) < 0) {
272 error("no such partition\n");
276 *boff
= cached_boff
= dlp
->dl_front
+ dlp
->dl_part
[partition
].p_base
;
278 if (!strcmp(name
,"$LBL")) strcpy(name
, dlp
->dl_bootfile
);
290 /* replace this function if you want to change
291 * the way disk activity is indicated to the user.
295 diskActivityHook(void)
297 spinActivityIndicator();