Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / boot / pc98 / boot2 / disk.c
1 /*
2  * Mach Operating System
3  * Copyright (c) 1992, 1991 Carnegie Mellon University
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation is hereby granted, provided that both the copyright
8  * notice and this permission notice appear in all copies of the
9  * software, derivative works or modified versions, and any portions
10  * thereof, and that both notices appear in supporting documentation.
11  *
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15  *
16  * Carnegie Mellon requests users of this software to return to
17  *
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19  *  School of Computer Science
20  *  Carnegie Mellon University
21  *  Pittsburgh PA 15213-3890
22  *
23  * any improvements or extensions that they make and grant Carnegie Mellon
24  * the rights to redistribute these changes.
25  *
26  *      from: Mach, Revision 2.2  92/04/04  11:35:49  rpd
27  * $FreeBSD: src/sys/boot/pc98/boot2/disk.c,v 1.4.2.1 2003/01/13 08:52:53 nyan Exp $
28  * $DragonFly: src/sys/boot/pc98/boot2/Attic/disk.c,v 1.2 2003/06/17 04:28:18 dillon Exp $
29  */
30
31 /*
32  * Ported to PC-9801 by Yoshio Kimura
33  */
34
35 /*
36  * 93/10/08  bde
37  *      If there is no 386BSD partition, initialize the label sector with
38  *      LABELSECTOR instead of with garbage.
39  *
40  * 93/08/22  bde
41  *      Fixed reading of bad sector table.  It is at the end of the 'c'
42  *      partition, which is not always at the end of the disk.
43  */
44
45 #include "boot.h"
46 #include <sys/disklabel.h>
47 #include <sys/diskslice.h>
48
49 #define BIOS_DEV_FLOPPY 0x0
50 #define BIOS_DEV_WIN    0x80
51
52 #define BPS             512
53 #define SPT(di)         ((di)&0xff)
54 #define HEADS(di)       (((di)>>8)&0xff)
55
56
57 static int spt, spc;
58
59 struct fs *fs;
60 struct inode inode;
61 int dosdev, unit, slice, part, maj, boff;
62
63 /*#define EMBEDDED_DISKLABEL 1*/
64
65 /* Read ahead buffer large enough for one track on a 1440K floppy.  For
66  * reading from floppies, the bootstrap has to be loaded on a 64K boundary
67  * to ensure that this buffer doesn't cross a 64K DMA boundary.
68  */
69 #define RA_SECTORS      18
70 static char ra_buf[RA_SECTORS * BPS];
71 static int ra_dev;
72 static int ra_end;
73 static int ra_first;
74
75 static char *Bread(int dosdev, int sector);
76
77 int
78 devopen(void)
79 {
80         struct dos_partition *dptr;
81         struct disklabel *dl;
82         char *p;
83         int i, sector = 0, di, dosdev_copy;
84
85         dosdev_copy = dosdev;
86         di = get_diskinfo(dosdev_copy);
87         spc = (spt = SPT(di)) * HEADS(di);
88
89 #ifndef RAWBOOT
90         if ((dosdev_copy & 0xf0) == 0x90)
91         {
92                 boff = 0;
93                 part = (spt == 15 ? 0 : 1);
94         }
95         else
96         {
97 #ifdef  EMBEDDED_DISKLABEL
98                 dl = &disklabel;
99 #else   EMBEDDED_DISKLABEL
100 #ifdef PC98
101                 p = Bread(dosdev_copy, 1);
102                 dptr = (struct dos_partition *)p;
103                 slice = WHOLE_DISK_SLICE;
104                 for (i = 0; i < NDOSPART; i++, dptr++)
105                         if (dptr->dp_mid == DOSPTYP_386BSD) {
106                                 slice = BASE_SLICE + i;
107                                 sector = dptr->dp_scyl * spc;
108                                 break;
109                         }
110                 p = Bread(dosdev, sector + LABELSECTOR);
111                 dl=((struct disklabel *)p);
112                 disklabel = *dl;        /* structure copy (maybe useful later)*/
113 #else
114                 p = Bread(dosdev_copy, 0);
115                 dptr = (struct dos_partition *)(p+DOSPARTOFF);
116                 slice = WHOLE_DISK_SLICE;
117                 for (i = 0; i < NDOSPART; i++, dptr++)
118                         if (dptr->dp_typ == DOSPTYP_386BSD) {
119                                 slice = BASE_SLICE + i;
120                                 sector = dptr->dp_start;
121                                 break;
122                         }
123                 p = Bread(dosdev_copy, sector + LABELSECTOR);
124                 dl=((struct disklabel *)p);
125                 disklabel = *dl;        /* structure copy (maybe useful later)*/
126 #endif /* PC98 */
127 #endif  EMBEDDED_DISKLABEL
128                 if (dl->d_magic != DISKMAGIC) {
129                         printf("bad disklabel\n");
130                         return 1;
131                 }
132                 /* This little trick is for OnTrack DiskManager disks */
133                 boff = dl->d_partitions[part].p_offset -
134                         dl->d_partitions[2].p_offset + sector;
135
136 #ifndef PC98
137                 bsize = dl->d_partitions[part].p_size;
138                 if (bsize == 0) {
139                         printf("empty partition\n");
140                         return 1;
141                 }
142
143 #endif
144
145         }
146 #endif /* RAWBOOT */
147         return 0;
148 }
149
150
151 /*
152  * Be aware that cnt is rounded up to N*BPS
153  */
154 void
155 devread(char *iodest, int sector, int cnt)
156 {
157         int offset;
158         char *p;
159         int dosdev_copy;
160
161         for (offset = 0; offset < cnt; offset += BPS)
162         {
163                 dosdev_copy = dosdev;
164                 p = Bread(dosdev_copy, sector++);
165                 bcopy(p, iodest+offset, BPS);
166         }
167 }
168
169
170 static char *
171 Bread(int dosdev, int sector)
172 {
173         if (dosdev != ra_dev || sector < ra_first || sector >= ra_end)
174         {
175                 int cyl, head, sec, nsec;
176
177                 cyl = sector/spc;
178 #ifndef PC98
179                 if (cyl > 1023) {
180                         printf("Error: C:%d > 1023 (BIOS limit)\n", cyl);
181                         for(;;);        /* loop forever */
182                 }
183 #endif
184                 head = (sector % spc) / spt;
185                 sec = sector % spt;
186                 nsec = spt - sec;
187                 if (nsec > RA_SECTORS)
188                         nsec = RA_SECTORS;
189                 twiddle();
190                 if (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)
191                 {
192                     nsec = 1;
193                     twiddle();
194                     while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0) {
195                         printf("Error: D:0x%x C:%d H:%d S:%d\n",
196                                dosdev, cyl, head, sec);
197                         twiddle();
198                     }
199                 }
200                 ra_dev = dosdev;
201                 ra_first = sector;
202                 ra_end = sector + nsec;
203         }
204         return (ra_buf + (sector - ra_first) * BPS);
205 }