11b8adde7SWilliam Kucharski /* bios.c - implement C part of low-level BIOS disk input and output */
21b8adde7SWilliam Kucharski /*
31b8adde7SWilliam Kucharski * GRUB -- GRand Unified Bootloader
41b8adde7SWilliam Kucharski * Copyright (C) 1999,2000,2003,2004 Free Software Foundation, Inc.
51b8adde7SWilliam Kucharski *
61b8adde7SWilliam Kucharski * This program is free software; you can redistribute it and/or modify
71b8adde7SWilliam Kucharski * it under the terms of the GNU General Public License as published by
81b8adde7SWilliam Kucharski * the Free Software Foundation; either version 2 of the License, or
91b8adde7SWilliam Kucharski * (at your option) any later version.
101b8adde7SWilliam Kucharski *
111b8adde7SWilliam Kucharski * This program is distributed in the hope that it will be useful,
121b8adde7SWilliam Kucharski * but WITHOUT ANY WARRANTY; without even the implied warranty of
131b8adde7SWilliam Kucharski * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
141b8adde7SWilliam Kucharski * GNU General Public License for more details.
151b8adde7SWilliam Kucharski *
161b8adde7SWilliam Kucharski * You should have received a copy of the GNU General Public License
171b8adde7SWilliam Kucharski * along with this program; if not, write to the Free Software
181b8adde7SWilliam Kucharski * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
191b8adde7SWilliam Kucharski */
209890706eSHans Rosenfeld /*
219890706eSHans Rosenfeld * Copyright 2016 Nexenta Systems, Inc.
229890706eSHans Rosenfeld */
231b8adde7SWilliam Kucharski
241b8adde7SWilliam Kucharski #include "shared.h"
251b8adde7SWilliam Kucharski
261b8adde7SWilliam Kucharski
271b8adde7SWilliam Kucharski /* These are defined in asm.S, and never be used elsewhere, so declare the
281b8adde7SWilliam Kucharski prototypes here. */
291b8adde7SWilliam Kucharski extern int biosdisk_int13_extensions (int ax, int drive, void *dap);
301b8adde7SWilliam Kucharski extern int biosdisk_standard (int ah, int drive,
311b8adde7SWilliam Kucharski int coff, int hoff, int soff,
321b8adde7SWilliam Kucharski int nsec, int segment);
331b8adde7SWilliam Kucharski extern int check_int13_extensions (int drive);
341b8adde7SWilliam Kucharski extern int get_diskinfo_standard (int drive,
351b8adde7SWilliam Kucharski unsigned long *cylinders,
361b8adde7SWilliam Kucharski unsigned long *heads,
371b8adde7SWilliam Kucharski unsigned long *sectors);
381b8adde7SWilliam Kucharski #if 0
391b8adde7SWilliam Kucharski extern int get_diskinfo_floppy (int drive,
401b8adde7SWilliam Kucharski unsigned long *cylinders,
411b8adde7SWilliam Kucharski unsigned long *heads,
421b8adde7SWilliam Kucharski unsigned long *sectors);
431b8adde7SWilliam Kucharski #endif
441b8adde7SWilliam Kucharski
451b8adde7SWilliam Kucharski
461b8adde7SWilliam Kucharski /* Read/write NSEC sectors starting from SECTOR in DRIVE disk with GEOMETRY
471b8adde7SWilliam Kucharski from/into SEGMENT segment. If READ is BIOSDISK_READ, then read it,
481b8adde7SWilliam Kucharski else if READ is BIOSDISK_WRITE, then write it. If an geometry error
491b8adde7SWilliam Kucharski occurs, return BIOSDISK_ERROR_GEOMETRY, and if other error occurs, then
501b8adde7SWilliam Kucharski return the error number. Otherwise, return 0. */
511b8adde7SWilliam Kucharski int
biosdisk(int read,int drive,struct geometry * geometry,unsigned long long sector,int nsec,int segment)521b8adde7SWilliam Kucharski biosdisk (int read, int drive, struct geometry *geometry,
539890706eSHans Rosenfeld unsigned long long sector, int nsec, int segment)
541b8adde7SWilliam Kucharski {
551b8adde7SWilliam Kucharski
561b8adde7SWilliam Kucharski int err;
571b8adde7SWilliam Kucharski
581b8adde7SWilliam Kucharski if (geometry->flags & BIOSDISK_FLAG_LBA_EXTENSION)
591b8adde7SWilliam Kucharski {
601b8adde7SWilliam Kucharski struct disk_address_packet
611b8adde7SWilliam Kucharski {
621b8adde7SWilliam Kucharski unsigned char length;
631b8adde7SWilliam Kucharski unsigned char reserved;
641b8adde7SWilliam Kucharski unsigned short blocks;
651b8adde7SWilliam Kucharski unsigned long buffer;
661b8adde7SWilliam Kucharski unsigned long long block;
671b8adde7SWilliam Kucharski } __attribute__ ((packed)) dap;
681b8adde7SWilliam Kucharski
691b8adde7SWilliam Kucharski /* XXX: Don't check the geometry by default, because some buggy
701b8adde7SWilliam Kucharski BIOSes don't return the number of total sectors correctly,
711b8adde7SWilliam Kucharski even if they have working LBA support. Hell. */
721b8adde7SWilliam Kucharski #ifdef NO_BUGGY_BIOS_IN_THE_WORLD
731b8adde7SWilliam Kucharski if (sector >= geometry->total_sectors)
741b8adde7SWilliam Kucharski return BIOSDISK_ERROR_GEOMETRY;
751b8adde7SWilliam Kucharski #endif /* NO_BUGGY_BIOS_IN_THE_WORLD */
761b8adde7SWilliam Kucharski
771b8adde7SWilliam Kucharski /* FIXME: sizeof (DAP) must be 0x10. Should assert that the compiler
781b8adde7SWilliam Kucharski can't add any padding. */
791b8adde7SWilliam Kucharski dap.length = sizeof (dap);
801b8adde7SWilliam Kucharski dap.block = sector;
811b8adde7SWilliam Kucharski dap.blocks = nsec;
821b8adde7SWilliam Kucharski dap.reserved = 0;
831b8adde7SWilliam Kucharski /* This is undocumented part. The address is formated in
841b8adde7SWilliam Kucharski SEGMENT:ADDRESS. */
851b8adde7SWilliam Kucharski dap.buffer = segment << 16;
861b8adde7SWilliam Kucharski err = biosdisk_int13_extensions ((read + 0x42) << 8, drive, &dap);
871b8adde7SWilliam Kucharski /*
881b8adde7SWilliam Kucharski * Try to report errors upwards when the bios has read only part of
891b8adde7SWilliam Kucharski * the requested buffer, but didn't return an error code.
901b8adde7SWilliam Kucharski */
911b8adde7SWilliam Kucharski if (err == 0 && dap.blocks != nsec)
921b8adde7SWilliam Kucharski err = BIOSDISK_ERROR_SHORT_IO;
931b8adde7SWilliam Kucharski
941b8adde7SWilliam Kucharski /* #undef NO_INT13_FALLBACK */
951b8adde7SWilliam Kucharski #ifndef NO_INT13_FALLBACK
961b8adde7SWilliam Kucharski if (err)
971b8adde7SWilliam Kucharski {
981b8adde7SWilliam Kucharski if (geometry->flags & BIOSDISK_FLAG_CDROM)
991b8adde7SWilliam Kucharski return err;
1001b8adde7SWilliam Kucharski
1011b8adde7SWilliam Kucharski geometry->flags &= ~BIOSDISK_FLAG_LBA_EXTENSION;
102828d47c1SShidokht Yadegari geometry->total_sectors = ((unsigned long long)geometry->cylinders
1031b8adde7SWilliam Kucharski * geometry->heads
1041b8adde7SWilliam Kucharski * geometry->sectors);
1051b8adde7SWilliam Kucharski return biosdisk (read, drive, geometry, sector, nsec, segment);
1061b8adde7SWilliam Kucharski }
1071b8adde7SWilliam Kucharski #endif /* ! NO_INT13_FALLBACK */
1081b8adde7SWilliam Kucharski
1091b8adde7SWilliam Kucharski }
1101b8adde7SWilliam Kucharski else
1111b8adde7SWilliam Kucharski {
1121b8adde7SWilliam Kucharski int cylinder_offset, head_offset, sector_offset;
1131b8adde7SWilliam Kucharski int head;
1141b8adde7SWilliam Kucharski /* SECTOR_OFFSET is counted from one, while HEAD_OFFSET and
1151b8adde7SWilliam Kucharski CYLINDER_OFFSET are counted from zero. */
1161b8adde7SWilliam Kucharski sector_offset = sector % geometry->sectors + 1;
1171b8adde7SWilliam Kucharski head = sector / geometry->sectors;
1181b8adde7SWilliam Kucharski head_offset = head % geometry->heads;
1191b8adde7SWilliam Kucharski cylinder_offset = head / geometry->heads;
1201b8adde7SWilliam Kucharski
1211b8adde7SWilliam Kucharski if (cylinder_offset >= geometry->cylinders)
1221b8adde7SWilliam Kucharski return BIOSDISK_ERROR_GEOMETRY;
1231b8adde7SWilliam Kucharski
1241b8adde7SWilliam Kucharski err = biosdisk_standard (read + 0x02, drive,
1251b8adde7SWilliam Kucharski cylinder_offset, head_offset, sector_offset,
1261b8adde7SWilliam Kucharski nsec, segment);
1271b8adde7SWilliam Kucharski }
1281b8adde7SWilliam Kucharski
1291b8adde7SWilliam Kucharski return err;
1301b8adde7SWilliam Kucharski }
1311b8adde7SWilliam Kucharski
1321b8adde7SWilliam Kucharski /* Check bootable CD-ROM emulation status. */
1331b8adde7SWilliam Kucharski static int
get_cdinfo(int drive,struct geometry * geometry)1341b8adde7SWilliam Kucharski get_cdinfo (int drive, struct geometry *geometry)
1351b8adde7SWilliam Kucharski {
1361b8adde7SWilliam Kucharski int err;
1371b8adde7SWilliam Kucharski struct iso_spec_packet
1381b8adde7SWilliam Kucharski {
1391b8adde7SWilliam Kucharski unsigned char size;
1401b8adde7SWilliam Kucharski unsigned char media_type;
1411b8adde7SWilliam Kucharski unsigned char drive_no;
1421b8adde7SWilliam Kucharski unsigned char controller_no;
1431b8adde7SWilliam Kucharski unsigned long image_lba;
1441b8adde7SWilliam Kucharski unsigned short device_spec;
1451b8adde7SWilliam Kucharski unsigned short cache_seg;
1461b8adde7SWilliam Kucharski unsigned short load_seg;
1471b8adde7SWilliam Kucharski unsigned short length_sec512;
1481b8adde7SWilliam Kucharski unsigned char cylinders;
1491b8adde7SWilliam Kucharski unsigned char sectors;
1501b8adde7SWilliam Kucharski unsigned char heads;
1511b8adde7SWilliam Kucharski
1521b8adde7SWilliam Kucharski unsigned char dummy[16];
1531b8adde7SWilliam Kucharski } __attribute__ ((packed)) cdrp;
1541b8adde7SWilliam Kucharski
1551b8adde7SWilliam Kucharski grub_memset (&cdrp, 0, sizeof (cdrp));
1561b8adde7SWilliam Kucharski cdrp.size = sizeof (cdrp) - sizeof (cdrp.dummy);
1571b8adde7SWilliam Kucharski err = biosdisk_int13_extensions (0x4B01, drive, &cdrp);
1581b8adde7SWilliam Kucharski if (! err && cdrp.drive_no == drive)
1591b8adde7SWilliam Kucharski {
1601b8adde7SWilliam Kucharski if ((cdrp.media_type & 0x0F) == 0)
1611b8adde7SWilliam Kucharski {
1621b8adde7SWilliam Kucharski /* No emulation bootable CD-ROM */
1631b8adde7SWilliam Kucharski geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION | BIOSDISK_FLAG_CDROM;
1641b8adde7SWilliam Kucharski geometry->cylinders = 0;
1651b8adde7SWilliam Kucharski geometry->heads = 1;
1661b8adde7SWilliam Kucharski geometry->sectors = 15;
1671b8adde7SWilliam Kucharski geometry->sector_size = 2048;
16898c507c4SJan Setje-Eilers geometry->total_sectors = MAXUINT;
1691b8adde7SWilliam Kucharski return 1;
1701b8adde7SWilliam Kucharski }
1711b8adde7SWilliam Kucharski else
1721b8adde7SWilliam Kucharski {
1731b8adde7SWilliam Kucharski /* Floppy or hard-disk emulation */
1741b8adde7SWilliam Kucharski geometry->cylinders
1751b8adde7SWilliam Kucharski = ((unsigned int) cdrp.cylinders
1761b8adde7SWilliam Kucharski + (((unsigned int) (cdrp.sectors & 0xC0)) << 2));
1771b8adde7SWilliam Kucharski geometry->heads = cdrp.heads;
1781b8adde7SWilliam Kucharski geometry->sectors = cdrp.sectors & 0x3F;
1791b8adde7SWilliam Kucharski geometry->sector_size = SECTOR_SIZE;
180828d47c1SShidokht Yadegari geometry->total_sectors = ((unsigned long long)geometry->cylinders
1811b8adde7SWilliam Kucharski * geometry->heads
1821b8adde7SWilliam Kucharski * geometry->sectors);
1831b8adde7SWilliam Kucharski return -1;
1841b8adde7SWilliam Kucharski }
1851b8adde7SWilliam Kucharski }
1861b8adde7SWilliam Kucharski
1871b8adde7SWilliam Kucharski /*
1881b8adde7SWilliam Kucharski * If this is the boot_drive, default to non-emulation bootable CD-ROM.
1891b8adde7SWilliam Kucharski *
1901b8adde7SWilliam Kucharski * Some BIOS (Tecra S1) fails the int13 call above. If we return
1911b8adde7SWilliam Kucharski * failure here, GRUB will run, but cannot see the boot drive,
1921b8adde7SWilliam Kucharski * not a very good situation. Defaulting to non-emulation mode
1931b8adde7SWilliam Kucharski * is a last-ditch effort.
1941b8adde7SWilliam Kucharski */
1951b8adde7SWilliam Kucharski if (drive >= 0x88 && drive == boot_drive)
1961b8adde7SWilliam Kucharski {
1971b8adde7SWilliam Kucharski geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION | BIOSDISK_FLAG_CDROM;
1981b8adde7SWilliam Kucharski geometry->cylinders = 0;
1991b8adde7SWilliam Kucharski geometry->heads = 1;
2001b8adde7SWilliam Kucharski geometry->sectors = 15;
2011b8adde7SWilliam Kucharski geometry->sector_size = 2048;
20298c507c4SJan Setje-Eilers geometry->total_sectors = MAXUINT;
2031b8adde7SWilliam Kucharski return 1;
2041b8adde7SWilliam Kucharski }
2051b8adde7SWilliam Kucharski return 0;
2061b8adde7SWilliam Kucharski }
2071b8adde7SWilliam Kucharski
2081b8adde7SWilliam Kucharski /* Return the geometry of DRIVE in GEOMETRY. If an error occurs, return
2091b8adde7SWilliam Kucharski non-zero, otherwise zero. */
2101b8adde7SWilliam Kucharski int
get_diskinfo(int drive,struct geometry * geometry)2111b8adde7SWilliam Kucharski get_diskinfo (int drive, struct geometry *geometry)
2121b8adde7SWilliam Kucharski {
2131b8adde7SWilliam Kucharski int err;
214*2f7f7a62SAlex Wilson int gotchs = 0;
2151b8adde7SWilliam Kucharski
2161b8adde7SWilliam Kucharski /* Clear the flags. */
2171b8adde7SWilliam Kucharski geometry->flags = 0;
2181b8adde7SWilliam Kucharski
2191b8adde7SWilliam Kucharski if (drive & 0x80)
2201b8adde7SWilliam Kucharski {
2211b8adde7SWilliam Kucharski /* hard disk or CD-ROM */
2221b8adde7SWilliam Kucharski int version;
223828d47c1SShidokht Yadegari unsigned long long total_sectors = 0;
2241b8adde7SWilliam Kucharski
2251b8adde7SWilliam Kucharski version = check_int13_extensions (drive);
2261b8adde7SWilliam Kucharski
2271b8adde7SWilliam Kucharski if (drive >= 0x88 || version)
2281b8adde7SWilliam Kucharski {
2291b8adde7SWilliam Kucharski /* Possible CD-ROM - check the status. */
2301b8adde7SWilliam Kucharski if (get_cdinfo (drive, geometry))
2311b8adde7SWilliam Kucharski return 0;
2321b8adde7SWilliam Kucharski }
2331b8adde7SWilliam Kucharski
234*2f7f7a62SAlex Wilson /* Don't pass GEOMETRY directly, but pass each element instead,
235*2f7f7a62SAlex Wilson so that we can change the structure easily. */
236*2f7f7a62SAlex Wilson err = get_diskinfo_standard (drive,
237*2f7f7a62SAlex Wilson &geometry->cylinders,
238*2f7f7a62SAlex Wilson &geometry->heads,
239*2f7f7a62SAlex Wilson &geometry->sectors);
240*2f7f7a62SAlex Wilson if (err == 0)
241*2f7f7a62SAlex Wilson gotchs = 1;
242*2f7f7a62SAlex Wilson /* get_diskinfo_standard returns 0x60 if the BIOS call actually
243*2f7f7a62SAlex Wilson succeeded but returned 0 sectors -- in this case don't
244*2f7f7a62SAlex Wilson return yet but continue to check the LBA geom */
245*2f7f7a62SAlex Wilson else if (err != 0x60)
246*2f7f7a62SAlex Wilson return err;
247*2f7f7a62SAlex Wilson
2481b8adde7SWilliam Kucharski if (version)
2491b8adde7SWilliam Kucharski {
2501b8adde7SWilliam Kucharski struct drive_parameters
2511b8adde7SWilliam Kucharski {
2521b8adde7SWilliam Kucharski unsigned short size;
2531b8adde7SWilliam Kucharski unsigned short flags;
2541b8adde7SWilliam Kucharski unsigned long cylinders;
2551b8adde7SWilliam Kucharski unsigned long heads;
2561b8adde7SWilliam Kucharski unsigned long sectors;
2571b8adde7SWilliam Kucharski unsigned long long total_sectors;
2581b8adde7SWilliam Kucharski unsigned short bytes_per_sector;
2591b8adde7SWilliam Kucharski /* ver 2.0 or higher */
2601b8adde7SWilliam Kucharski unsigned long EDD_configuration_parameters;
2611b8adde7SWilliam Kucharski /* ver 3.0 or higher */
2621b8adde7SWilliam Kucharski unsigned short signature_dpi;
2631b8adde7SWilliam Kucharski unsigned char length_dpi;
2641b8adde7SWilliam Kucharski unsigned char reserved[3];
2651b8adde7SWilliam Kucharski unsigned char name_of_host_bus[4];
2661b8adde7SWilliam Kucharski unsigned char name_of_interface_type[8];
2671b8adde7SWilliam Kucharski unsigned char interface_path[8];
2681b8adde7SWilliam Kucharski unsigned char device_path[8];
2691b8adde7SWilliam Kucharski unsigned char reserved2;
2701b8adde7SWilliam Kucharski unsigned char checksum;
2711b8adde7SWilliam Kucharski
2721b8adde7SWilliam Kucharski /* XXX: This is necessary, because the BIOS of Thinkpad X20
2731b8adde7SWilliam Kucharski writes a garbage to the tail of drive parameters,
2741b8adde7SWilliam Kucharski regardless of a size specified in a caller. */
2751b8adde7SWilliam Kucharski unsigned char dummy[16];
2761b8adde7SWilliam Kucharski } __attribute__ ((packed)) drp;
2771b8adde7SWilliam Kucharski
2781b8adde7SWilliam Kucharski /* It is safe to clear out DRP. */
2791b8adde7SWilliam Kucharski grub_memset (&drp, 0, sizeof (drp));
2801b8adde7SWilliam Kucharski
2811b8adde7SWilliam Kucharski /* PhoenixBIOS 4.0 Revision 6.0 for ZF Micro might understand
2821b8adde7SWilliam Kucharski the greater buffer size for the "get drive parameters" int
2831b8adde7SWilliam Kucharski 0x13 call in its own way. Supposedly the BIOS assumes even
2841b8adde7SWilliam Kucharski bigger space is available and thus corrupts the stack.
2851b8adde7SWilliam Kucharski This is why we specify the exactly necessary size of 0x42
2861b8adde7SWilliam Kucharski bytes. */
2871b8adde7SWilliam Kucharski drp.size = sizeof (drp) - sizeof (drp.dummy);
2881b8adde7SWilliam Kucharski
2891b8adde7SWilliam Kucharski err = biosdisk_int13_extensions (0x4800, drive, &drp);
2901b8adde7SWilliam Kucharski if (! err)
2911b8adde7SWilliam Kucharski {
2921b8adde7SWilliam Kucharski /* Set the LBA flag. */
2931b8adde7SWilliam Kucharski geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION;
2941b8adde7SWilliam Kucharski
2951b8adde7SWilliam Kucharski /* I'm not sure if GRUB should check the bit 1 of DRP.FLAGS,
2961b8adde7SWilliam Kucharski so I omit the check for now. - okuji */
2971b8adde7SWilliam Kucharski /* if (drp.flags & (1 << 1)) */
2981b8adde7SWilliam Kucharski
299*2f7f7a62SAlex Wilson /* If we didn't get valid CHS info from the standard call,
300*2f7f7a62SAlex Wilson then we should fill it out here */
301*2f7f7a62SAlex Wilson if (! gotchs)
302*2f7f7a62SAlex Wilson {
303*2f7f7a62SAlex Wilson geometry->cylinders = drp.cylinders;
304*2f7f7a62SAlex Wilson
305*2f7f7a62SAlex Wilson if (drp.sectors > 0 && drp.heads > 0)
306*2f7f7a62SAlex Wilson {
307*2f7f7a62SAlex Wilson geometry->heads = drp.heads;
308*2f7f7a62SAlex Wilson geometry->sectors = drp.sectors;
309*2f7f7a62SAlex Wilson }
310*2f7f7a62SAlex Wilson else
311*2f7f7a62SAlex Wilson {
312*2f7f7a62SAlex Wilson /* Return fake geometry. This disk reports that it
313*2f7f7a62SAlex Wilson supports LBA, so all the other routines will use LBA
314*2f7f7a62SAlex Wilson to talk to it and not look at this geometry. However,
315*2f7f7a62SAlex Wilson some of the partition-finding routines still need
316*2f7f7a62SAlex Wilson non-zero values in these fields. */
317*2f7f7a62SAlex Wilson geometry->heads = 16;
318*2f7f7a62SAlex Wilson geometry->sectors = 63;
319*2f7f7a62SAlex Wilson }
320*2f7f7a62SAlex Wilson gotchs = 1;
321*2f7f7a62SAlex Wilson }
322*2f7f7a62SAlex Wilson
3231b8adde7SWilliam Kucharski if (drp.total_sectors)
324828d47c1SShidokht Yadegari total_sectors = drp.total_sectors;
3251b8adde7SWilliam Kucharski else
3261b8adde7SWilliam Kucharski /* Some buggy BIOSes doesn't return the total sectors
3271b8adde7SWilliam Kucharski correctly but returns zero. So if it is zero, compute
3281b8adde7SWilliam Kucharski it by C/H/S returned by the LBA BIOS call. */
329828d47c1SShidokht Yadegari total_sectors = (unsigned long long)drp.cylinders *
330828d47c1SShidokht Yadegari drp.heads * drp.sectors;
3311b8adde7SWilliam Kucharski }
3321b8adde7SWilliam Kucharski }
3331b8adde7SWilliam Kucharski
334*2f7f7a62SAlex Wilson /* In case we got the 0x60 return code from _standard on a disk that
335*2f7f7a62SAlex Wilson didn't support LBA (or was somehow invalid), return that error now */
336*2f7f7a62SAlex Wilson if (! gotchs)
337*2f7f7a62SAlex Wilson return 0x60;
3381b8adde7SWilliam Kucharski
3391b8adde7SWilliam Kucharski if (! total_sectors)
3401b8adde7SWilliam Kucharski {
341828d47c1SShidokht Yadegari total_sectors = ((unsigned long long)geometry->cylinders
3421b8adde7SWilliam Kucharski * geometry->heads
3431b8adde7SWilliam Kucharski * geometry->sectors);
3441b8adde7SWilliam Kucharski }
3451b8adde7SWilliam Kucharski geometry->total_sectors = total_sectors;
3461b8adde7SWilliam Kucharski geometry->sector_size = SECTOR_SIZE;
3471b8adde7SWilliam Kucharski }
3481b8adde7SWilliam Kucharski else
3491b8adde7SWilliam Kucharski {
3501b8adde7SWilliam Kucharski /* floppy disk */
3511b8adde7SWilliam Kucharski
3521b8adde7SWilliam Kucharski /* First, try INT 13 AH=8h call. */
3531b8adde7SWilliam Kucharski err = get_diskinfo_standard (drive,
3541b8adde7SWilliam Kucharski &geometry->cylinders,
3551b8adde7SWilliam Kucharski &geometry->heads,
3561b8adde7SWilliam Kucharski &geometry->sectors);
3571b8adde7SWilliam Kucharski
3581b8adde7SWilliam Kucharski #if 0
3591b8adde7SWilliam Kucharski /* If fails, then try floppy-specific probe routine. */
3601b8adde7SWilliam Kucharski if (err)
3611b8adde7SWilliam Kucharski err = get_diskinfo_floppy (drive,
3621b8adde7SWilliam Kucharski &geometry->cylinders,
3631b8adde7SWilliam Kucharski &geometry->heads,
3641b8adde7SWilliam Kucharski &geometry->sectors);
3651b8adde7SWilliam Kucharski #endif
3661b8adde7SWilliam Kucharski
3671b8adde7SWilliam Kucharski if (err)
3681b8adde7SWilliam Kucharski return err;
3691b8adde7SWilliam Kucharski
370828d47c1SShidokht Yadegari geometry->total_sectors = ((unsigned long long)geometry->cylinders
3711b8adde7SWilliam Kucharski * geometry->heads
3721b8adde7SWilliam Kucharski * geometry->sectors);
3731b8adde7SWilliam Kucharski geometry->sector_size = SECTOR_SIZE;
3741b8adde7SWilliam Kucharski }
3751b8adde7SWilliam Kucharski
3761b8adde7SWilliam Kucharski return 0;
3771b8adde7SWilliam Kucharski }
378