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