Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / platform / pc32 / boot / biosboot / 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/i386/boot/biosboot/disk.c,v 1.28 1999/12/08 09:32:48 phk Exp $
28  * $DragonFly: src/sys/platform/pc32/boot/biosboot/Attic/disk.c,v 1.2 2003/06/17 04:28:34 dillon Exp $
29  */
30
31 /*
32  * 93/10/08  bde
33  *      If there is no 386BSD partition, initialize the label sector with
34  *      LABELSECTOR instead of with garbage.
35  *
36  * 93/08/22  bde
37  *      Fixed reading of bad sector table.  It is at the end of the 'c'
38  *      partition, which is not always at the end of the disk.
39  */
40
41 #include "boot.h"
42 #include <sys/disklabel.h>
43 #include <sys/diskslice.h>
44
45 #define BIOS_DEV_FLOPPY 0x0
46 #define BIOS_DEV_WIN    0x80
47
48 #define BPS             512
49 #define SPT(di)         ((di)&0xff)
50 #define HEADS(di)       ((((di)>>8)&0xff)+1)
51
52 static int bsize;
53
54 static int spt, spc;
55
56 struct fs *fs;
57 struct inode inode;
58 int dosdev, unit, slice, part, maj, boff;
59
60 /*#define EMBEDDED_DISKLABEL 1*/
61
62 /* Read ahead buffer large enough for one track on a 1440K floppy.  For
63  * reading from floppies, the bootstrap has to be loaded on a 64K boundary
64  * to ensure that this buffer doesn't cross a 64K DMA boundary.
65  */
66 #define RA_SECTORS      18
67 static char ra_buf[RA_SECTORS * BPS];
68 static int ra_dev;
69 static int ra_end;
70 static int ra_first;
71
72 static char *Bread(int dosdev, int sector);
73
74 int
75 devopen(void)
76 {
77         struct dos_partition *dptr;
78         struct disklabel *dl;
79         char *p;
80         int i, sector = 0, di, dosdev_copy;
81
82         dosdev_copy = dosdev;
83         di = get_diskinfo(dosdev_copy);
84         spt = SPT(di);
85
86         /* Hack for 2.88MB floppy drives. */
87         if (!(dosdev_copy & 0x80) && spt == 36)
88                 spt = 18;
89
90         spc = spt * HEADS(di);
91
92 #ifndef RAWBOOT
93         {
94 #ifdef  EMBEDDED_DISKLABEL
95                 dl = &disklabel;
96 #else   EMBEDDED_DISKLABEL
97                 p = Bread(dosdev_copy, 0);
98                 dptr = (struct dos_partition *)(p+DOSPARTOFF);
99                 slice = WHOLE_DISK_SLICE;
100                 for (i = 0; i < NDOSPART; i++, dptr++)
101                         if (dptr->dp_typ == DOSPTYP_386BSD) {
102                                 slice = BASE_SLICE + i;
103                                 sector = dptr->dp_start;
104                                 break;
105                         }
106                 p = Bread(dosdev_copy, sector + LABELSECTOR);
107                 dl=((struct disklabel *)p);
108                 disklabel = *dl;        /* structure copy (maybe useful later)*/
109 #endif  EMBEDDED_DISKLABEL
110                 if (dl->d_magic != DISKMAGIC) {
111                         printf("bad disklabel\n");
112                         return 1;
113                 }
114                 if( (maj == 4) || (maj == 0) || (maj == 1))
115                 {
116                         if (dl->d_type == DTYPE_SCSI)
117                         {
118                                 maj = 4; /* use scsi as boot dev */
119                         }
120                         else
121                         {
122                                 maj = 0; /* must be ESDI/IDE */
123                         }
124                 }
125                 /* This little trick is for OnTrack DiskManager disks */
126                 boff = dl->d_partitions[part].p_offset -
127                         dl->d_partitions[2].p_offset + sector;
128
129                 bsize = dl->d_partitions[part].p_size;
130                 if (bsize == 0) {
131                         printf("empty partition\n");
132                         return 1;
133                 }
134
135         }
136 #endif /* RAWBOOT */
137         return 0;
138 }
139
140
141 /*
142  * Be aware that cnt is rounded up to N*BPS
143  */
144 void
145 devread(char *iodest, int sector, int cnt)
146 {
147         int offset;
148         char *p;
149         int dosdev_copy;
150
151         for (offset = 0; offset < cnt; offset += BPS)
152         {
153                 dosdev_copy = dosdev;
154                 p = Bread(dosdev_copy, sector++);
155                 bcopy(p, iodest+offset, BPS);
156         }
157 }
158
159
160 static char *
161 Bread(int dosdev, int sector)
162 {
163         if (dosdev != ra_dev || sector < ra_first || sector >= ra_end)
164         {
165                 int cyl, head, sec, nsec;
166
167                 cyl = sector/spc;
168                 if (cyl > 1023) {
169                         printf("Error: C:%d > 1023 (BIOS limit)\n", cyl);
170                         for(;;);        /* loop forever */
171                 }
172                 head = (sector % spc) / spt;
173                 sec = sector % spt;
174                 nsec = spt - sec;
175                 if (nsec > RA_SECTORS)
176                         nsec = RA_SECTORS;
177                 twiddle();
178                 if (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)
179                 {
180                     nsec = 1;
181                     twiddle();
182                     while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0) {
183                         printf("Error: D:0x%x C:%d H:%d S:%d\n",
184                                dosdev, cyl, head, sec);
185                         twiddle();
186                     }
187                 }
188                 ra_dev = dosdev;
189                 ra_first = sector;
190                 ra_end = sector + nsec;
191         }
192         return (ra_buf + (sector - ra_first) * BPS);
193 }