xref: /illumos-gate/usr/src/grub/grub-0.97/stage2/bios.c (revision 1b8adde7ba7d5e04395c141c5400dc2cffd7d809)
1*1b8adde7SWilliam Kucharski /* bios.c - implement C part of low-level BIOS disk input and output */
2*1b8adde7SWilliam Kucharski /*
3*1b8adde7SWilliam Kucharski  *  GRUB  --  GRand Unified Bootloader
4*1b8adde7SWilliam Kucharski  *  Copyright (C) 1999,2000,2003,2004  Free Software Foundation, Inc.
5*1b8adde7SWilliam Kucharski  *
6*1b8adde7SWilliam Kucharski  *  This program is free software; you can redistribute it and/or modify
7*1b8adde7SWilliam Kucharski  *  it under the terms of the GNU General Public License as published by
8*1b8adde7SWilliam Kucharski  *  the Free Software Foundation; either version 2 of the License, or
9*1b8adde7SWilliam Kucharski  *  (at your option) any later version.
10*1b8adde7SWilliam Kucharski  *
11*1b8adde7SWilliam Kucharski  *  This program is distributed in the hope that it will be useful,
12*1b8adde7SWilliam Kucharski  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13*1b8adde7SWilliam Kucharski  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*1b8adde7SWilliam Kucharski  *  GNU General Public License for more details.
15*1b8adde7SWilliam Kucharski  *
16*1b8adde7SWilliam Kucharski  *  You should have received a copy of the GNU General Public License
17*1b8adde7SWilliam Kucharski  *  along with this program; if not, write to the Free Software
18*1b8adde7SWilliam Kucharski  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*1b8adde7SWilliam Kucharski  */
20*1b8adde7SWilliam Kucharski 
21*1b8adde7SWilliam Kucharski #include "shared.h"
22*1b8adde7SWilliam Kucharski 
23*1b8adde7SWilliam Kucharski 
24*1b8adde7SWilliam Kucharski /* These are defined in asm.S, and never be used elsewhere, so declare the
25*1b8adde7SWilliam Kucharski    prototypes here.  */
26*1b8adde7SWilliam Kucharski extern int biosdisk_int13_extensions (int ax, int drive, void *dap);
27*1b8adde7SWilliam Kucharski extern int biosdisk_standard (int ah, int drive,
28*1b8adde7SWilliam Kucharski 			      int coff, int hoff, int soff,
29*1b8adde7SWilliam Kucharski 			      int nsec, int segment);
30*1b8adde7SWilliam Kucharski extern int check_int13_extensions (int drive);
31*1b8adde7SWilliam Kucharski extern int get_diskinfo_standard (int drive,
32*1b8adde7SWilliam Kucharski 				  unsigned long *cylinders,
33*1b8adde7SWilliam Kucharski 				  unsigned long *heads,
34*1b8adde7SWilliam Kucharski 				  unsigned long *sectors);
35*1b8adde7SWilliam Kucharski #if 0
36*1b8adde7SWilliam Kucharski extern int get_diskinfo_floppy (int drive,
37*1b8adde7SWilliam Kucharski 				unsigned long *cylinders,
38*1b8adde7SWilliam Kucharski 				unsigned long *heads,
39*1b8adde7SWilliam Kucharski 				unsigned long *sectors);
40*1b8adde7SWilliam Kucharski #endif
41*1b8adde7SWilliam Kucharski 
42*1b8adde7SWilliam Kucharski 
43*1b8adde7SWilliam Kucharski /* Read/write NSEC sectors starting from SECTOR in DRIVE disk with GEOMETRY
44*1b8adde7SWilliam Kucharski    from/into SEGMENT segment. If READ is BIOSDISK_READ, then read it,
45*1b8adde7SWilliam Kucharski    else if READ is BIOSDISK_WRITE, then write it. If an geometry error
46*1b8adde7SWilliam Kucharski    occurs, return BIOSDISK_ERROR_GEOMETRY, and if other error occurs, then
47*1b8adde7SWilliam Kucharski    return the error number. Otherwise, return 0.  */
48*1b8adde7SWilliam Kucharski int
49*1b8adde7SWilliam Kucharski biosdisk (int read, int drive, struct geometry *geometry,
50*1b8adde7SWilliam Kucharski 	  unsigned int sector, int nsec, int segment)
51*1b8adde7SWilliam Kucharski {
52*1b8adde7SWilliam Kucharski 
53*1b8adde7SWilliam Kucharski   int err;
54*1b8adde7SWilliam Kucharski 
55*1b8adde7SWilliam Kucharski   if (geometry->flags & BIOSDISK_FLAG_LBA_EXTENSION)
56*1b8adde7SWilliam Kucharski     {
57*1b8adde7SWilliam Kucharski       struct disk_address_packet
58*1b8adde7SWilliam Kucharski       {
59*1b8adde7SWilliam Kucharski 	unsigned char length;
60*1b8adde7SWilliam Kucharski 	unsigned char reserved;
61*1b8adde7SWilliam Kucharski 	unsigned short blocks;
62*1b8adde7SWilliam Kucharski 	unsigned long buffer;
63*1b8adde7SWilliam Kucharski 	unsigned long long block;
64*1b8adde7SWilliam Kucharski       } __attribute__ ((packed)) dap;
65*1b8adde7SWilliam Kucharski 
66*1b8adde7SWilliam Kucharski       /* XXX: Don't check the geometry by default, because some buggy
67*1b8adde7SWilliam Kucharski 	 BIOSes don't return the number of total sectors correctly,
68*1b8adde7SWilliam Kucharski 	 even if they have working LBA support. Hell.  */
69*1b8adde7SWilliam Kucharski #ifdef NO_BUGGY_BIOS_IN_THE_WORLD
70*1b8adde7SWilliam Kucharski       if (sector >= geometry->total_sectors)
71*1b8adde7SWilliam Kucharski 	return BIOSDISK_ERROR_GEOMETRY;
72*1b8adde7SWilliam Kucharski #endif /* NO_BUGGY_BIOS_IN_THE_WORLD */
73*1b8adde7SWilliam Kucharski 
74*1b8adde7SWilliam Kucharski       /* FIXME: sizeof (DAP) must be 0x10. Should assert that the compiler
75*1b8adde7SWilliam Kucharski 	 can't add any padding.  */
76*1b8adde7SWilliam Kucharski       dap.length = sizeof (dap);
77*1b8adde7SWilliam Kucharski       dap.block = sector;
78*1b8adde7SWilliam Kucharski       dap.blocks = nsec;
79*1b8adde7SWilliam Kucharski       dap.reserved = 0;
80*1b8adde7SWilliam Kucharski       /* This is undocumented part. The address is formated in
81*1b8adde7SWilliam Kucharski 	 SEGMENT:ADDRESS.  */
82*1b8adde7SWilliam Kucharski       dap.buffer = segment << 16;
83*1b8adde7SWilliam Kucharski       err = biosdisk_int13_extensions ((read + 0x42) << 8, drive, &dap);
84*1b8adde7SWilliam Kucharski       /*
85*1b8adde7SWilliam Kucharski        * Try to report errors upwards when the bios has read only part of
86*1b8adde7SWilliam Kucharski        * the requested buffer, but didn't return an error code.
87*1b8adde7SWilliam Kucharski        */
88*1b8adde7SWilliam Kucharski       if (err == 0 && dap.blocks != nsec)
89*1b8adde7SWilliam Kucharski 	err = BIOSDISK_ERROR_SHORT_IO;
90*1b8adde7SWilliam Kucharski 
91*1b8adde7SWilliam Kucharski /* #undef NO_INT13_FALLBACK */
92*1b8adde7SWilliam Kucharski #ifndef NO_INT13_FALLBACK
93*1b8adde7SWilliam Kucharski       if (err)
94*1b8adde7SWilliam Kucharski 	{
95*1b8adde7SWilliam Kucharski 	  if (geometry->flags & BIOSDISK_FLAG_CDROM)
96*1b8adde7SWilliam Kucharski 	    return err;
97*1b8adde7SWilliam Kucharski 
98*1b8adde7SWilliam Kucharski 	  geometry->flags &= ~BIOSDISK_FLAG_LBA_EXTENSION;
99*1b8adde7SWilliam Kucharski 	  geometry->total_sectors = (geometry->cylinders
100*1b8adde7SWilliam Kucharski 				     * geometry->heads
101*1b8adde7SWilliam Kucharski 				     * geometry->sectors);
102*1b8adde7SWilliam Kucharski 	  return biosdisk (read, drive, geometry, sector, nsec, segment);
103*1b8adde7SWilliam Kucharski 	}
104*1b8adde7SWilliam Kucharski #endif /* ! NO_INT13_FALLBACK */
105*1b8adde7SWilliam Kucharski 
106*1b8adde7SWilliam Kucharski     }
107*1b8adde7SWilliam Kucharski   else
108*1b8adde7SWilliam Kucharski     {
109*1b8adde7SWilliam Kucharski       int cylinder_offset, head_offset, sector_offset;
110*1b8adde7SWilliam Kucharski       int head;
111*1b8adde7SWilliam Kucharski       /* SECTOR_OFFSET is counted from one, while HEAD_OFFSET and
112*1b8adde7SWilliam Kucharski 	 CYLINDER_OFFSET are counted from zero.  */
113*1b8adde7SWilliam Kucharski       sector_offset = sector % geometry->sectors + 1;
114*1b8adde7SWilliam Kucharski       head = sector / geometry->sectors;
115*1b8adde7SWilliam Kucharski       head_offset = head % geometry->heads;
116*1b8adde7SWilliam Kucharski       cylinder_offset = head / geometry->heads;
117*1b8adde7SWilliam Kucharski 
118*1b8adde7SWilliam Kucharski       if (cylinder_offset >= geometry->cylinders)
119*1b8adde7SWilliam Kucharski 	return BIOSDISK_ERROR_GEOMETRY;
120*1b8adde7SWilliam Kucharski 
121*1b8adde7SWilliam Kucharski       err = biosdisk_standard (read + 0x02, drive,
122*1b8adde7SWilliam Kucharski 			       cylinder_offset, head_offset, sector_offset,
123*1b8adde7SWilliam Kucharski 			       nsec, segment);
124*1b8adde7SWilliam Kucharski     }
125*1b8adde7SWilliam Kucharski 
126*1b8adde7SWilliam Kucharski   return err;
127*1b8adde7SWilliam Kucharski }
128*1b8adde7SWilliam Kucharski 
129*1b8adde7SWilliam Kucharski /* Check bootable CD-ROM emulation status.  */
130*1b8adde7SWilliam Kucharski static int
131*1b8adde7SWilliam Kucharski get_cdinfo (int drive, struct geometry *geometry)
132*1b8adde7SWilliam Kucharski {
133*1b8adde7SWilliam Kucharski   int err;
134*1b8adde7SWilliam Kucharski   struct iso_spec_packet
135*1b8adde7SWilliam Kucharski   {
136*1b8adde7SWilliam Kucharski     unsigned char size;
137*1b8adde7SWilliam Kucharski     unsigned char media_type;
138*1b8adde7SWilliam Kucharski     unsigned char drive_no;
139*1b8adde7SWilliam Kucharski     unsigned char controller_no;
140*1b8adde7SWilliam Kucharski     unsigned long image_lba;
141*1b8adde7SWilliam Kucharski     unsigned short device_spec;
142*1b8adde7SWilliam Kucharski     unsigned short cache_seg;
143*1b8adde7SWilliam Kucharski     unsigned short load_seg;
144*1b8adde7SWilliam Kucharski     unsigned short length_sec512;
145*1b8adde7SWilliam Kucharski     unsigned char cylinders;
146*1b8adde7SWilliam Kucharski     unsigned char sectors;
147*1b8adde7SWilliam Kucharski     unsigned char heads;
148*1b8adde7SWilliam Kucharski 
149*1b8adde7SWilliam Kucharski     unsigned char dummy[16];
150*1b8adde7SWilliam Kucharski   } __attribute__ ((packed)) cdrp;
151*1b8adde7SWilliam Kucharski 
152*1b8adde7SWilliam Kucharski   grub_memset (&cdrp, 0, sizeof (cdrp));
153*1b8adde7SWilliam Kucharski   cdrp.size = sizeof (cdrp) - sizeof (cdrp.dummy);
154*1b8adde7SWilliam Kucharski   err = biosdisk_int13_extensions (0x4B01, drive, &cdrp);
155*1b8adde7SWilliam Kucharski   if (! err && cdrp.drive_no == drive)
156*1b8adde7SWilliam Kucharski     {
157*1b8adde7SWilliam Kucharski       if ((cdrp.media_type & 0x0F) == 0)
158*1b8adde7SWilliam Kucharski         {
159*1b8adde7SWilliam Kucharski           /* No emulation bootable CD-ROM */
160*1b8adde7SWilliam Kucharski           geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION | BIOSDISK_FLAG_CDROM;
161*1b8adde7SWilliam Kucharski           geometry->cylinders = 0;
162*1b8adde7SWilliam Kucharski           geometry->heads = 1;
163*1b8adde7SWilliam Kucharski           geometry->sectors = 15;
164*1b8adde7SWilliam Kucharski           geometry->sector_size = 2048;
165*1b8adde7SWilliam Kucharski           geometry->total_sectors = MAXINT;
166*1b8adde7SWilliam Kucharski           return 1;
167*1b8adde7SWilliam Kucharski         }
168*1b8adde7SWilliam Kucharski       else
169*1b8adde7SWilliam Kucharski         {
170*1b8adde7SWilliam Kucharski 	  /* Floppy or hard-disk emulation */
171*1b8adde7SWilliam Kucharski           geometry->cylinders
172*1b8adde7SWilliam Kucharski 	    = ((unsigned int) cdrp.cylinders
173*1b8adde7SWilliam Kucharski 	       + (((unsigned int) (cdrp.sectors & 0xC0)) << 2));
174*1b8adde7SWilliam Kucharski           geometry->heads = cdrp.heads;
175*1b8adde7SWilliam Kucharski           geometry->sectors = cdrp.sectors & 0x3F;
176*1b8adde7SWilliam Kucharski           geometry->sector_size = SECTOR_SIZE;
177*1b8adde7SWilliam Kucharski           geometry->total_sectors = (geometry->cylinders
178*1b8adde7SWilliam Kucharski 				     * geometry->heads
179*1b8adde7SWilliam Kucharski 				     * geometry->sectors);
180*1b8adde7SWilliam Kucharski           return -1;
181*1b8adde7SWilliam Kucharski         }
182*1b8adde7SWilliam Kucharski     }
183*1b8adde7SWilliam Kucharski 
184*1b8adde7SWilliam Kucharski   /*
185*1b8adde7SWilliam Kucharski    * If this is the boot_drive, default to non-emulation bootable CD-ROM.
186*1b8adde7SWilliam Kucharski    *
187*1b8adde7SWilliam Kucharski    * Some BIOS (Tecra S1) fails the int13 call above. If we return
188*1b8adde7SWilliam Kucharski    * failure here, GRUB will run, but cannot see the boot drive,
189*1b8adde7SWilliam Kucharski    * not a very good situation. Defaulting to non-emulation mode
190*1b8adde7SWilliam Kucharski    * is a last-ditch effort.
191*1b8adde7SWilliam Kucharski    */
192*1b8adde7SWilliam Kucharski   if (drive >= 0x88 && drive == boot_drive)
193*1b8adde7SWilliam Kucharski     {
194*1b8adde7SWilliam Kucharski       geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION | BIOSDISK_FLAG_CDROM;
195*1b8adde7SWilliam Kucharski       geometry->cylinders = 0;
196*1b8adde7SWilliam Kucharski       geometry->heads = 1;
197*1b8adde7SWilliam Kucharski       geometry->sectors = 15;
198*1b8adde7SWilliam Kucharski       geometry->sector_size = 2048;
199*1b8adde7SWilliam Kucharski       geometry->total_sectors = MAXINT;
200*1b8adde7SWilliam Kucharski       return 1;
201*1b8adde7SWilliam Kucharski     }
202*1b8adde7SWilliam Kucharski   return 0;
203*1b8adde7SWilliam Kucharski }
204*1b8adde7SWilliam Kucharski 
205*1b8adde7SWilliam Kucharski /* Return the geometry of DRIVE in GEOMETRY. If an error occurs, return
206*1b8adde7SWilliam Kucharski    non-zero, otherwise zero.  */
207*1b8adde7SWilliam Kucharski int
208*1b8adde7SWilliam Kucharski get_diskinfo (int drive, struct geometry *geometry)
209*1b8adde7SWilliam Kucharski {
210*1b8adde7SWilliam Kucharski   int err;
211*1b8adde7SWilliam Kucharski 
212*1b8adde7SWilliam Kucharski   /* Clear the flags.  */
213*1b8adde7SWilliam Kucharski   geometry->flags = 0;
214*1b8adde7SWilliam Kucharski 
215*1b8adde7SWilliam Kucharski   if (drive & 0x80)
216*1b8adde7SWilliam Kucharski     {
217*1b8adde7SWilliam Kucharski       /* hard disk or CD-ROM */
218*1b8adde7SWilliam Kucharski       int version;
219*1b8adde7SWilliam Kucharski       unsigned long total_sectors = 0;
220*1b8adde7SWilliam Kucharski 
221*1b8adde7SWilliam Kucharski       version = check_int13_extensions (drive);
222*1b8adde7SWilliam Kucharski 
223*1b8adde7SWilliam Kucharski       if (drive >= 0x88 || version)
224*1b8adde7SWilliam Kucharski 	{
225*1b8adde7SWilliam Kucharski 	  /* Possible CD-ROM - check the status.  */
226*1b8adde7SWilliam Kucharski 	  if (get_cdinfo (drive, geometry))
227*1b8adde7SWilliam Kucharski 	    return 0;
228*1b8adde7SWilliam Kucharski 	}
229*1b8adde7SWilliam Kucharski 
230*1b8adde7SWilliam Kucharski       if (version)
231*1b8adde7SWilliam Kucharski 	{
232*1b8adde7SWilliam Kucharski 	  struct drive_parameters
233*1b8adde7SWilliam Kucharski 	  {
234*1b8adde7SWilliam Kucharski 	    unsigned short size;
235*1b8adde7SWilliam Kucharski 	    unsigned short flags;
236*1b8adde7SWilliam Kucharski 	    unsigned long cylinders;
237*1b8adde7SWilliam Kucharski 	    unsigned long heads;
238*1b8adde7SWilliam Kucharski 	    unsigned long sectors;
239*1b8adde7SWilliam Kucharski 	    unsigned long long total_sectors;
240*1b8adde7SWilliam Kucharski 	    unsigned short bytes_per_sector;
241*1b8adde7SWilliam Kucharski 	    /* ver 2.0 or higher */
242*1b8adde7SWilliam Kucharski 	    unsigned long EDD_configuration_parameters;
243*1b8adde7SWilliam Kucharski 	    /* ver 3.0 or higher */
244*1b8adde7SWilliam Kucharski 	    unsigned short signature_dpi;
245*1b8adde7SWilliam Kucharski 	    unsigned char length_dpi;
246*1b8adde7SWilliam Kucharski 	    unsigned char reserved[3];
247*1b8adde7SWilliam Kucharski 	    unsigned char name_of_host_bus[4];
248*1b8adde7SWilliam Kucharski 	    unsigned char name_of_interface_type[8];
249*1b8adde7SWilliam Kucharski 	    unsigned char interface_path[8];
250*1b8adde7SWilliam Kucharski 	    unsigned char device_path[8];
251*1b8adde7SWilliam Kucharski 	    unsigned char reserved2;
252*1b8adde7SWilliam Kucharski 	    unsigned char checksum;
253*1b8adde7SWilliam Kucharski 
254*1b8adde7SWilliam Kucharski 	    /* XXX: This is necessary, because the BIOS of Thinkpad X20
255*1b8adde7SWilliam Kucharski 	       writes a garbage to the tail of drive parameters,
256*1b8adde7SWilliam Kucharski 	       regardless of a size specified in a caller.  */
257*1b8adde7SWilliam Kucharski 	    unsigned char dummy[16];
258*1b8adde7SWilliam Kucharski 	  } __attribute__ ((packed)) drp;
259*1b8adde7SWilliam Kucharski 
260*1b8adde7SWilliam Kucharski 	  /* It is safe to clear out DRP.  */
261*1b8adde7SWilliam Kucharski 	  grub_memset (&drp, 0, sizeof (drp));
262*1b8adde7SWilliam Kucharski 
263*1b8adde7SWilliam Kucharski 	  /* PhoenixBIOS 4.0 Revision 6.0 for ZF Micro might understand
264*1b8adde7SWilliam Kucharski 	     the greater buffer size for the "get drive parameters" int
265*1b8adde7SWilliam Kucharski 	     0x13 call in its own way.  Supposedly the BIOS assumes even
266*1b8adde7SWilliam Kucharski 	     bigger space is available and thus corrupts the stack.
267*1b8adde7SWilliam Kucharski 	     This is why we specify the exactly necessary size of 0x42
268*1b8adde7SWilliam Kucharski 	     bytes. */
269*1b8adde7SWilliam Kucharski 	  drp.size = sizeof (drp) - sizeof (drp.dummy);
270*1b8adde7SWilliam Kucharski 
271*1b8adde7SWilliam Kucharski 	  err = biosdisk_int13_extensions (0x4800, drive, &drp);
272*1b8adde7SWilliam Kucharski 	  if (! err)
273*1b8adde7SWilliam Kucharski 	    {
274*1b8adde7SWilliam Kucharski 	      /* Set the LBA flag.  */
275*1b8adde7SWilliam Kucharski 	      geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION;
276*1b8adde7SWilliam Kucharski 
277*1b8adde7SWilliam Kucharski 	      /* I'm not sure if GRUB should check the bit 1 of DRP.FLAGS,
278*1b8adde7SWilliam Kucharski 		 so I omit the check for now. - okuji  */
279*1b8adde7SWilliam Kucharski 	      /* if (drp.flags & (1 << 1)) */
280*1b8adde7SWilliam Kucharski 
281*1b8adde7SWilliam Kucharski 	      /* FIXME: when the 2TB limit becomes critical, we must
282*1b8adde7SWilliam Kucharski 		 change the type of TOTAL_SECTORS to unsigned long
283*1b8adde7SWilliam Kucharski 		 long.  */
284*1b8adde7SWilliam Kucharski 	      if (drp.total_sectors)
285*1b8adde7SWilliam Kucharski 		total_sectors = drp.total_sectors & ~0L;
286*1b8adde7SWilliam Kucharski 	      else
287*1b8adde7SWilliam Kucharski 		/* Some buggy BIOSes doesn't return the total sectors
288*1b8adde7SWilliam Kucharski 		   correctly but returns zero. So if it is zero, compute
289*1b8adde7SWilliam Kucharski 		   it by C/H/S returned by the LBA BIOS call.  */
290*1b8adde7SWilliam Kucharski 		total_sectors = drp.cylinders * drp.heads * drp.sectors;
291*1b8adde7SWilliam Kucharski 	    }
292*1b8adde7SWilliam Kucharski 	}
293*1b8adde7SWilliam Kucharski 
294*1b8adde7SWilliam Kucharski       /* Don't pass GEOMETRY directly, but pass each element instead,
295*1b8adde7SWilliam Kucharski 	 so that we can change the structure easily.  */
296*1b8adde7SWilliam Kucharski       err = get_diskinfo_standard (drive,
297*1b8adde7SWilliam Kucharski 				   &geometry->cylinders,
298*1b8adde7SWilliam Kucharski 				   &geometry->heads,
299*1b8adde7SWilliam Kucharski 				   &geometry->sectors);
300*1b8adde7SWilliam Kucharski       if (err)
301*1b8adde7SWilliam Kucharski 	return err;
302*1b8adde7SWilliam Kucharski 
303*1b8adde7SWilliam Kucharski       if (! total_sectors)
304*1b8adde7SWilliam Kucharski 	{
305*1b8adde7SWilliam Kucharski 	  total_sectors = (geometry->cylinders
306*1b8adde7SWilliam Kucharski 			   * geometry->heads
307*1b8adde7SWilliam Kucharski 			   * geometry->sectors);
308*1b8adde7SWilliam Kucharski 	}
309*1b8adde7SWilliam Kucharski       geometry->total_sectors = total_sectors;
310*1b8adde7SWilliam Kucharski       geometry->sector_size = SECTOR_SIZE;
311*1b8adde7SWilliam Kucharski     }
312*1b8adde7SWilliam Kucharski   else
313*1b8adde7SWilliam Kucharski     {
314*1b8adde7SWilliam Kucharski       /* floppy disk */
315*1b8adde7SWilliam Kucharski 
316*1b8adde7SWilliam Kucharski       /* First, try INT 13 AH=8h call.  */
317*1b8adde7SWilliam Kucharski       err = get_diskinfo_standard (drive,
318*1b8adde7SWilliam Kucharski 				   &geometry->cylinders,
319*1b8adde7SWilliam Kucharski 				   &geometry->heads,
320*1b8adde7SWilliam Kucharski 				   &geometry->sectors);
321*1b8adde7SWilliam Kucharski 
322*1b8adde7SWilliam Kucharski #if 0
323*1b8adde7SWilliam Kucharski       /* If fails, then try floppy-specific probe routine.  */
324*1b8adde7SWilliam Kucharski       if (err)
325*1b8adde7SWilliam Kucharski 	err = get_diskinfo_floppy (drive,
326*1b8adde7SWilliam Kucharski 				   &geometry->cylinders,
327*1b8adde7SWilliam Kucharski 				   &geometry->heads,
328*1b8adde7SWilliam Kucharski 				   &geometry->sectors);
329*1b8adde7SWilliam Kucharski #endif
330*1b8adde7SWilliam Kucharski 
331*1b8adde7SWilliam Kucharski       if (err)
332*1b8adde7SWilliam Kucharski 	return err;
333*1b8adde7SWilliam Kucharski 
334*1b8adde7SWilliam Kucharski       geometry->total_sectors = (geometry->cylinders
335*1b8adde7SWilliam Kucharski 				 * geometry->heads
336*1b8adde7SWilliam Kucharski 				 * geometry->sectors);
337*1b8adde7SWilliam Kucharski       geometry->sector_size = SECTOR_SIZE;
338*1b8adde7SWilliam Kucharski     }
339*1b8adde7SWilliam Kucharski 
340*1b8adde7SWilliam Kucharski   return 0;
341*1b8adde7SWilliam Kucharski }
342