/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
GRUB_MOD_LICENSE ("GPLv3+");
static int cd_drive = 0;
static int grub_biosdisk_get_num_floppies (void)
{
int drive;
/* reset the disk system first */
{
/* call GET DISK TYPE */
break;
/* check if this drive exists */
break;
}
return drive;
}
/*
* is passed for disk address packet. If an error occurs, return
* non-zero, otherwise zero.
*/
static int
{
/* compute the address of disk_address_packet */
}
/*
* return non-zero, otherwise zero.
*/
static int
{
int ret, i;
/* Try 3 times. */
for (i = 0; i < 3; i++)
{
/* set up CHS information */
/* set %ch to low eight bits of cylinder */
/* set bits 6-7 of %cl to high two bits of cylinder */
/* set bits 0-5 of %cl to sector */
/* set %dh to head and %dl to drive */
/* set %ah to AH */
/* set %al to NSEC */
/* check if successful */
return 0;
/* save return value */
/* if fail, reset the disk system */
}
return ret;
}
/*
* Check if LBA is supported for DRIVE. If it is supported, then return
* the major version of extensions, otherwise zero.
*/
static int
{
return 0;
return 0;
/* check if AH=0x42 is supported */
return 0;
}
/*
* Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an
* error occurs, then return non-zero, otherwise zero.
*/
static int
unsigned long *cylinders,
unsigned long *heads,
unsigned long *sectors)
{
/* Check if unsuccessful. Ignore return value if carry isn't set to
workaround some buggy BIOSes. */
/* bogus BIOSes may not return an error number */
/* 0 sectors means no disk */
/* XXX 0x60 is one of the unused error numbers */
return 0x60;
/* the number of heads is counted from zero */
return 0;
}
static int
{
/* compute the address of drive parameters */
/* Check if unsuccessful. Ignore return value if carry isn't set to
workaround some buggy BIOSes. */
return 0;
}
/*
* Return the cdrom information of DRIVE in CDRP. If an error occurs,
* then return non-zero, otherwise zero.
*/
static int
{
}
/*
* Return the geometry of DRIVE in a drive parameters, DRP. If an error
* occurs, then return non-zero, otherwise zero.
*/
static int
{
}
static int
{
unsigned long drive;
return cd_drive;
goto fail;
if (grub_errno != GRUB_ERR_NONE)
goto fail;
if (name[0] == 'h')
drive += 0x80;
return (int) drive ;
fail:
return -1;
}
static int
{
return hook ("cd");
}
static int
{
int num_floppies;
int drive;
/* For hard disks, attempt to read the MBR. */
switch (pull)
{
case GRUB_DISK_PULL_NONE:
{
{
break;
}
return 1;
}
return 0;
case GRUB_DISK_PULL_REMOVABLE:
if (cd_drive)
{
return 1;
}
/* For floppy disks, we can get the number safely. */
return 1;
return 0;
default:
return 0;
}
return 0;
}
static grub_err_t
{
int drive;
if (drive < 0)
return grub_errno;
if (! data)
return grub_errno;
{
/* TODO: get the correct size. */
}
else
{
/* HDD */
int version;
if (version)
{
= (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
/* Clear out the DRP. */
{
if (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. */
if (drp->bytes_per_sector
{
for (disk->log_sector_size = 0;
disk->log_sector_size++);
}
}
}
}
{
{
{
}
else
{
}
}
if (! total_sectors)
}
return GRUB_ERR_NONE;
}
static void
{
}
/* For readability. */
#define GRUB_BIOSDISK_READ 0
static grub_err_t
unsigned segment)
{
{
<< disk->log_sector_size));
{
int i;
if (cmd)
for (i = 0; i < GRUB_BIOSDISK_CDROM_RETRY_COUNT; i++)
break;
if (i == GRUB_BIOSDISK_CDROM_RETRY_COUNT)
}
else
{
/* Fall back to the CHS mode. */
}
}
else
{
unsigned head;
/* It is impossible to reach over 8064 MiB (a bit less than LBA24) with
the traditional CHS access. */
if (sector >
1024 /* cylinders */ *
256 /* heads */ *
63 /* spt */)
{
switch (cmd)
{
case GRUB_BIOSDISK_READ:
case GRUB_BIOSDISK_WRITE:
}
}
}
return GRUB_ERR_NONE;
}
/* Return the number of sectors which can be read safely at a time. */
static grub_size_t
{
/* OFFSET = SECTOR % SECTORS */
/* Limit the max to 0x7f because of Phoenix EDD. */
return size;
}
static grub_err_t
{
while (size)
{
return grub_errno;
}
return grub_errno;
}
static grub_err_t
{
while (size)
{
return grub_errno;
}
return grub_errno;
}
{
.name = "biosdisk",
.next = 0
};
static void
grub_disk_biosdisk_fini (void)
{
}
{
= (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
{
return;
}
/* Since diskboot.S rejects devices over 0x90 it must be a CD booted with
cdboot.S
*/
if (boot_drive >= 0x90)
}
{
}