Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / platform / pc32 / boot / dosboot / disk.c
1 /*\r
2  * Mach Operating System\r
3  * Copyright (c) 1992, 1991 Carnegie Mellon University\r
4  * All Rights Reserved.\r
5  * \r
6  * Permission to use, copy, modify and distribute this software and its\r
7  * documentation is hereby granted, provided that both the copyright\r
8  * notice and this permission notice appear in all copies of the\r
9  * software, derivative works or modified versions, and any portions\r
10  * thereof, and that both notices appear in supporting documentation.\r
11  * \r
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"\r
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR\r
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.\r
15  * \r
16  * Carnegie Mellon requests users of this software to return to\r
17  * \r
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU\r
19  *  School of Computer Science\r
20  *  Carnegie Mellon University\r
21  *  Pittsburgh PA 15213-3890\r
22  * \r
23  * any improvements or extensions that they make and grant Carnegie Mellon\r
24  * the rights to redistribute these changes.\r
25  *\r
26  *      from: Mach, Revision 2.2  92/04/04  11:35:49  rpd\r
27  * $FreeBSD: src/sys/i386/boot/dosboot/disk.c,v 1.6 1999/12/08 09:32:49 phk Exp $\r
28  * $DragonFly: src/sys/platform/pc32/boot/dosboot/Attic/disk.c,v 1.2 2003/06/17 04:28:34 dillon Exp $\r
29  */\r
30 #include <stdio.h>\r
31 #include <memory.h>\r
32 \r
33 #define bcopy(a,b,c)    memcpy(b,a,c)\r
34 \r
35 #include "boot.h"\r
36 #include "disklabe.h"\r
37 #include "diskslic.h"\r
38 \r
39 #define BIOS_DEV_FLOPPY 0x0\r
40 #define BIOS_DEV_WIN    0x80\r
41 \r
42 #define BPS                     512\r
43 #define SPT(di)         ((di)&0xff)\r
44 #define HEADS(di)       ((((di)>>8)&0xff)+1)\r
45 \r
46 static char i_buf[BPS];\r
47 #define I_ADDR          ((void *) i_buf)        /* XXX where all reads go */\r
48 \r
49 \r
50 static int spt, spc;\r
51 \r
52 char *iodest;\r
53 struct fs *fs;\r
54 struct inode inode;\r
55 long dosdev, slice, unit, part, maj, boff, poff, bnum, cnt;\r
56 \r
57 extern int biosread(int dev, int track, int head, int sector, int cnt, unsigned char far *buffer);\r
58 \r
59 struct  disklabel disklabel;\r
60 \r
61 static void Bread(int dosdev, long sector);\r
62 \r
63 unsigned long get_diskinfo(int drive)\r
64 {\r
65         char dr = (char) drive;\r
66         unsigned long rt;\r
67 \r
68         _asm {\r
69                 mov ah,8                ; get diskinfo\r
70                 mov dl,dr               ; drive\r
71                 int 13h\r
72                 cmp ah,0\r
73                 je ok\r
74                 ;\r
75                 ; Failure! We assume it's a floppy!\r
76                 ;\r
77                 sub ax,ax\r
78                 mov bh,ah\r
79                 mov bl,2\r
80                 mov ch,79\r
81                 mov cl,15\r
82                 mov dh,1\r
83                 mov dl,1\r
84         ok:\r
85                 mov ah,dh\r
86                 mov al,cl\r
87                 and al,3fh\r
88                 mov word ptr rt,ax\r
89 \r
90                 xor bx,bx\r
91                 mov bl,cl\r
92                 and bl,0c0h\r
93                 shl bx,2\r
94                 mov bl,ch\r
95                 mov word ptr rt+2,bx\r
96         }\r
97         return rt;\r
98 }\r
99 \r
100 int devopen(void)\r
101 {\r
102         struct dos_partition *dptr;\r
103         struct disklabel *dl;\r
104         int dosdev = (int) inode.i_dev;\r
105         int i;\r
106         long di, sector;\r
107         \r
108         di = get_diskinfo(dosdev);\r
109         spc = (spt = (int)SPT(di)) * (int)HEADS(di);\r
110         if (dosdev == 2)\r
111         {\r
112                 boff = 0;\r
113                 part = (spt == 15 ? 3 : 1);\r
114         }\r
115         else\r
116         {\r
117 #ifdef  EMBEDDED_DISKLABEL\r
118                 dl = &disklabel;\r
119 #else   EMBEDDED_DISKLABEL\r
120                 Bread(dosdev, 0);\r
121                 dptr = (struct dos_partition *)(((char *)I_ADDR)+DOSPARTOFF);\r
122                 sector = LABELSECTOR;\r
123                 slice = WHOLE_DISK_SLICE;\r
124                 for (i = 0; i < NDOSPART; i++, dptr++)\r
125                         if (dptr->dp_typ == DOSPTYP_386BSD) {\r
126                                 slice = BASE_SLICE + i;\r
127                                 sector = dptr->dp_start + LABELSECTOR;\r
128                                 break;\r
129                         }\r
130                 Bread(dosdev, sector++);\r
131                 dl=((struct disklabel *)I_ADDR);\r
132                 disklabel = *dl;        /* structure copy (maybe useful later)*/\r
133 #endif  EMBEDDED_DISKLABEL\r
134                 if (dl->d_magic != DISKMAGIC) {\r
135                         printf("bad disklabel");\r
136                         return 1;\r
137                 }\r
138 \r
139                 if( (maj == 4) || (maj == 0) || (maj == 1)) {\r
140                         if (dl->d_type == DTYPE_SCSI)\r
141                                 maj = 4; /* use scsi as boot dev */\r
142                         else\r
143                                 maj = 0; /* must be ESDI/IDE */\r
144                 }\r
145 \r
146                 boff = dl->d_partitions[part].p_offset;\r
147         }\r
148         return 0;\r
149 }\r
150 \r
151 void devread(void)\r
152 {\r
153         long offset, sector = bnum;\r
154         int dosdev = (int) inode.i_dev;\r
155         for (offset = 0; offset < cnt; offset += BPS)\r
156         {\r
157                 Bread(dosdev, sector++);\r
158                 bcopy(I_ADDR, iodest+offset, BPS);\r
159         }\r
160 }\r
161 \r
162 /* Read ahead buffer large enough for one track on a 1440K floppy.  For\r
163  * reading from floppies, the bootstrap has to be loaded on a 64K boundary\r
164  * to ensure that this buffer doesn't cross a 64K DMA boundary.\r
165  */\r
166 #define RA_SECTORS      18\r
167 static char ra_buf[RA_SECTORS * BPS];\r
168 static int ra_dev;\r
169 static long ra_end;\r
170 static long ra_first;\r
171 \r
172 static void Bread(int dosdev, long sector)\r
173 {\r
174         if (dosdev != ra_dev || sector < ra_first || sector >= ra_end)\r
175         {\r
176                 int cyl, head, sec, nsec;\r
177 \r
178                 cyl = (int) (sector/(long)spc);\r
179                 head = (int) ((sector % (long) spc) / (long) spt);\r
180                 sec = (int) (sector % (long) spt);\r
181                 nsec = spt - sec;\r
182                 if (nsec > RA_SECTORS)\r
183                         nsec = RA_SECTORS;\r
184                 if (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)\r
185                 {\r
186                     nsec = 1;\r
187                     while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)\r
188                                 printf("Error: C:%d H:%d S:%d\n", cyl, head, sec);\r
189                 }\r
190                 ra_dev = dosdev;\r
191                 ra_first = sector;\r
192                 ra_end = sector + nsec;\r
193         }\r
194         bcopy(ra_buf + (sector - ra_first) * BPS, I_ADDR, BPS);\r
195 }\r