]>
git.saurik.com Git - apple/boot.git/blob - gen/libsaio/disk.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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
22 * @APPLE_LICENSE_HEADER_END@
25 * Mach Operating System
26 * Copyright (c) 1990 Carnegie-Mellon University
27 * Copyright (c) 1989 Carnegie-Mellon University
28 * All rights reserved. The CMU software License Agreement specifies
29 * the terms and conditions for use and redistribution.
33 * INTEL CORPORATION PROPRIETARY INFORMATION
35 * This software is supplied under the terms of a license agreement or
36 * nondisclosure agreement with Intel Corporation and may not be copied
37 * nor disclosed except in accordance with the terms of that agreement.
39 * Copyright 1988, 1989 Intel Corporation
43 * Copyright 1993 NeXT Computer, Inc.
44 * All rights reserved.
47 #define DRIVER_PRIVATE
51 #import <dev/i386/disk.h>
55 static Biosread(int biosdev
, int secno
);
56 static read_label(char *name
, int biosdev
, daddr_t
*boff
, int partition
);
57 void diskActivityHook(void);
58 extern void spinActivityIndicator(void);
60 /* diskinfo unpacking */
61 #define SPT(di) ((di)&0xff)
62 #define HEADS(di) ((((di)>>8)&0xff)+1)
63 #define SPC(di) (SPT(di)*HEADS(di))
64 #define BPS 512 /* sector size of the device */
65 #define N_CACHE_SECS (BIOS_LEN / BPS)
68 #define DISKLABEL 15 /* sector num of disk label */
78 int spt
; /* sectors per track */
79 int spc
; /* sectors per cylinder */
83 daddr_t blknos
[NBUFS
];
84 struct iob iob
[NFILES
];
86 static int label_cached
;
88 // intbuf is the whole buffer, biosbuf is the current cached sector
89 static char * const intbuf
= (char *)ptov(BIOS_ADDR
);
99 di
= get_diskinfo(io
->biosdev
);
101 /* initialize disk parameters -- spt and spc */
103 io
->dirbuf_blkno
= -1;
105 diskinfo
.spt
= SPT(di
);
106 diskinfo
.spc
= diskinfo
.spt
* HEADS(di
);
107 if (read_label(name
, io
->biosdev
, &io
->i_boff
, io
->partition
) < 0)
126 io
->i_flgs
|= F_RDDATA
;
128 /* assume the best */
131 dev
= io
->i_ino
.i_dev
;
133 sector
= io
->i_bn
* (label_secsize
/DOS_BSIZE
);
135 for (offset
= 0; offset
< io
->i_cc
; offset
+= BPS
) {
137 io
->i_error
= Biosread(io
->biosdev
, sector
);
142 /* copy 1 sector from the internal buffer biosbuf into buf */
143 bcopy(biosbuf
, &io
->i_ma
[offset
], BPS
);
148 io
->i_flgs
&= ~F_TYPEMASK
;
152 /* A haque: Biosread(0,-1) means flush the sector cache.
155 Biosread(int biosdev
, int secno
)
157 static int xbiosdev
, xcyl
=-1, xhead
, xsec
, xnsecs
;
164 if (biosdev
== 0 && secno
== -1) {
173 head
= (secno
% spc
) / spt
;
176 if (biosdev
== xbiosdev
&& cyl
== xcyl
&& head
== xhead
&&
177 sec
>= xsec
&& sec
< (xsec
+ xnsecs
))
178 { // this sector is in intbuf cache
179 biosbuf
= intbuf
+ (BPS
* (sec
-xsec
));
188 xnsecs
= ((sec
+ N_CACHE_SECS
) > spt
) ? (spt
- sec
) : N_CACHE_SECS
;
191 while ((rc
= biosread(biosdev
,cyl
,head
,sec
, xnsecs
)) && (++tries
< 5))
194 error(" biosread error 0x%x @ %d, C:%d H:%d S:%d\n",
195 rc
, secno
, cyl
, head
, sec
);
197 sleep(1); // on disk errors, bleh!
203 // extern char name[];
214 struct disk_label
*dlp
;
215 struct fdisk_part
*fd
;
216 struct disk_blk0
*blk0
;
220 static int cached_boff
;
227 // read sector 0 into the internal buffer "biosbuf"
228 if ( rc
= Biosread(biosdev
, 0) )
231 // Check for a valid boot block.
232 blk0
= (struct disk_blk0
*)biosbuf
;
233 if (blk0
->signature
== DISK_SIGNATURE
) {
234 // Check to see if the disk has been partitioned with FDISK
235 // to allow DOS and ufs filesystems to exist on the same spindle.
236 fd
= (struct fdisk_part
*)blk0
->parts
;
237 for ( n
= 0; n
< FDISK_NPART
; n
++, fd
++)
238 if (fd
->systid
== FDISK_NEXTNAME
)
240 part_offset
= fd
->relsect
;
244 /* It's not an error if there is not a valid boot block. */
246 /* Read the NeXT disk label.
247 * Since we can't count on it fitting in the sector cache,
248 * we'll put it elsewhere.
250 dlp
= (struct disk_label
*)malloc(sizeof(*dlp
) + BPS
);
251 for(n
= 0, cp
= (char *)dlp
;
252 n
< ((sizeof(*dlp
) + BPS
- 1) / BPS
);
254 if (rc
= Biosread(biosdev
, DISKLABEL
+ part_offset
+ n
))
256 bcopy(biosbuf
, cp
, BPS
);
259 byte_swap_disklabel_in(dlp
);
263 if (dlp
->dl_version
!= DL_V3
) {
264 error("bad disk label magic\n");
268 label_secsize
= dlp
->dl_secsize
;
270 if ((dlp
->dl_part
[partition
].p_base
) < 0) {
271 error("no such partition\n");
275 *boff
= cached_boff
= dlp
->dl_front
+ dlp
->dl_part
[partition
].p_base
;
277 if (!strcmp(name
,"$LBL")) strcpy(name
, dlp
->dl_bootfile
);
289 /* replace this function if you want to change
290 * the way disk activity is indicated to the user.
294 diskActivityHook(void)
296 spinActivityIndicator();