static grub_err_t grub_biosdisk_open (const char *name, grub_disk_t disk) { int drive; struct grub_biosdisk_data *data; drive = (! grub_strcmp (name, "boot")) ? grub_boot_drive : grub_biosdisk_get_drive (name); if (drive < 0) return grub_errno; data = get_drive_geom (drive); if (! data) return grub_error (GRUB_ERR_BAD_DEVICE, "invalid drive"); disk->has_partitions = (drive != cd_drive); disk->id = drive; disk->total_sectors = data->total_sectors; disk->data = data; return GRUB_ERR_NONE; }
static grub_err_t grub_biosdisk_open (const char *name, grub_disk_t disk) { grub_uint64_t total_sectors = 0; int drive; struct grub_biosdisk_data *data; drive = grub_biosdisk_get_drive (name); if (drive < 0) return grub_errno; disk->has_partitions = ((drive & 0x80) && (drive != cd_drive)); disk->id = drive; data = (struct grub_biosdisk_data *) grub_zalloc (sizeof (*data)); if (! data) return grub_errno; data->drive = drive; if ((cd_drive) && (drive == cd_drive)) { data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM; data->sectors = 32; total_sectors = GRUB_ULONG_MAX; /* TODO: get the correct size. */ } else if (drive & 0x80) { /* HDD */ int version; version = grub_biosdisk_check_int13_extensions (drive); if (version) { struct grub_biosdisk_drp *drp = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; /* Clear out the DRP. */ grub_memset (drp, 0, sizeof (*drp)); drp->size = sizeof (*drp); if (! grub_biosdisk_get_diskinfo_int13_extensions (drive, drp)) { data->flags = GRUB_BIOSDISK_FLAG_LBA; if (drp->total_sectors) total_sectors = drp->total_sectors; else /* Some buggy BIOSes doesn't return the total sectors correctly but returns zero. So if it is zero, compute it by C/H/S returned by the LBA BIOS call. */ total_sectors = drp->cylinders * drp->heads * drp->sectors; } } } if (! (data->flags & GRUB_BIOSDISK_FLAG_CDROM)) { if (grub_biosdisk_get_diskinfo_standard (drive, &data->cylinders, &data->heads, &data->sectors) != 0) { if (total_sectors && (data->flags & GRUB_BIOSDISK_FLAG_LBA)) { data->sectors = 63; data->heads = 255; data->cylinders = grub_divmod64 (total_sectors + data->heads * data->sectors - 1, data->heads * data->sectors, 0); } else { grub_free (data); return grub_error (GRUB_ERR_BAD_DEVICE, "%s cannot get C/H/S values", disk->name); } } if (! total_sectors) total_sectors = data->cylinders * data->heads * data->sectors; } disk->total_sectors = total_sectors; disk->data = data; return GRUB_ERR_NONE; }