merge with mainline

This commit is contained in:
BVK Chaitanya 2010-07-13 00:43:28 +05:30
commit 297f0c2b6e
218 changed files with 35637 additions and 4957 deletions

View file

@ -24,10 +24,13 @@
#include <grub/time.h>
#include <grub/pci.h>
#include <grub/scsi.h>
#include <grub/cs5536.h>
/* At the moment, only two IDE ports are supported. */
static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 };
static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 };
static const grub_port_t grub_ata_ioaddress[] = { GRUB_ATA_CH0_PORT1,
GRUB_ATA_CH1_PORT1 };
static const grub_port_t grub_ata_ioaddress2[] = { GRUB_ATA_CH0_PORT2,
GRUB_ATA_CH1_PORT2 };
static struct grub_ata_device *grub_ata_devices;
@ -331,11 +334,38 @@ grub_ata_identify (struct grub_ata_device *dev)
return 0;
}
static grub_err_t
check_device (struct grub_ata_device *dev)
{
grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
grub_ata_wait ();
/* Try to detect if the port is in use by writing to it,
waiting for a while and reading it again. If the value
was preserved, there is a device connected. */
grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
grub_ata_wait ();
grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
grub_dprintf ("ata", "sectors=0x%x\n", sec);
if (sec != 0x5A)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no device connected");
/* The above test may detect a second (slave) device
connected to a SATA controller which supports only one
(master) device. It is not safe to use the status register
READY bit to check for controller channel existence. Some
ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */
/* Use the IDENTIFY DEVICE command to query the device. */
return grub_ata_identify (dev);
}
static grub_err_t
grub_ata_device_initialize (int port, int device, int addr, int addr2)
{
struct grub_ata_device *dev;
struct grub_ata_device **devp;
grub_err_t err;
grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n",
port, device, addr, addr2);
@ -351,39 +381,14 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2)
dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE;
dev->next = NULL;
grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
grub_ata_wait ();
/* Try to detect if the port is in use by writing to it,
waiting for a while and reading it again. If the value
was preserved, there is a device connected. */
grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
grub_ata_wait ();
grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
grub_dprintf ("ata", "sectors=0x%x\n", sec);
if (sec != 0x5A)
{
grub_free(dev);
return 0;
}
/* The above test may detect a second (slave) device
connected to a SATA controller which supports only one
(master) device. It is not safe to use the status register
READY bit to check for controller channel existence. Some
ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */
/* Use the IDENTIFY DEVICE command to query the device. */
if (grub_ata_identify (dev))
{
grub_free (dev);
return 0;
}
/* Register the device. */
for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
*devp = dev;
err = check_device (dev);
if (err)
grub_print_error ();
return 0;
}
@ -408,7 +413,7 @@ grub_ata_pciinit (grub_pci_device_t dev,
class = grub_pci_read (addr);
/* AMD CS5536 Southbridge. */
if (pciid == 0x208f1022)
if (pciid == GRUB_CS5536_PCIID)
{
cs5536 = 1;
nports = 1;
@ -666,6 +671,14 @@ grub_ata_iterate (int (*hook) (const char *name))
for (dev = grub_ata_devices; dev; dev = dev->next)
{
char devname[10];
grub_err_t err;
err = check_device (dev);
if (err)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
if (dev->atapi)
continue;
@ -684,6 +697,7 @@ static grub_err_t
grub_ata_open (const char *name, grub_disk_t disk)
{
struct grub_ata_device *dev;
grub_err_t err;
for (dev = grub_ata_devices; dev; dev = dev->next)
{
@ -700,6 +714,11 @@ grub_ata_open (const char *name, grub_disk_t disk)
if (dev->atapi)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
err = check_device (dev);
if (err)
return err;
disk->total_sectors = dev->size;
disk->id = (unsigned long) dev;
@ -749,20 +768,25 @@ static struct grub_disk_dev grub_atadisk_dev =
/* ATAPI code. */
static int
grub_atapi_iterate (int (*hook) (const char *name, int luns))
grub_atapi_iterate (int (*hook) (int bus, int luns))
{
struct grub_ata_device *dev;
for (dev = grub_ata_devices; dev; dev = dev->next)
{
char devname[10];
grub_snprintf (devname, sizeof (devname),
"ata%d", dev->port * 2 + dev->device);
grub_err_t err;
err = check_device (dev);
if (err)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
if (! dev->atapi)
continue;
if (hook (devname, 1))
if (hook (dev->port * 2 + dev->device, 1))
return 1;
}
@ -822,46 +846,45 @@ grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)),
}
static grub_err_t
grub_atapi_open (const char *name, struct grub_scsi *scsi)
grub_atapi_open (int devnum, struct grub_scsi *scsi)
{
struct grub_ata_device *dev;
struct grub_ata_device *devfnd = 0;
grub_err_t err;
for (dev = grub_ata_devices; dev; dev = dev->next)
{
char devname[10];
grub_snprintf (devname, sizeof (devname),
"ata%d", dev->port * 2 + dev->device);
if (!grub_strcmp (devname, name))
if (dev->port * 2 + dev->device == devnum)
{
devfnd = dev;
break;
}
}
grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name);
grub_dprintf ("ata", "opening ATAPI dev `ata%d'\n", devnum);
if (! devfnd)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device");
err = check_device (devfnd);
if (err)
return err;
if (! devfnd->atapi)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device");
scsi->data = devfnd;
return GRUB_ERR_NONE;
}
static void
grub_atapi_close (struct grub_scsi *scsi)
{
grub_free (scsi->name);
}
static struct grub_scsi_dev grub_atapi_dev =
{
.name = "ATAPI",
.name = "ata",
.id = GRUB_SCSI_SUBSYSTEM_ATAPI,
.iterate = grub_atapi_iterate,
.open = grub_atapi_open,
.close = grub_atapi_close,
.read = grub_atapi_read,
.write = grub_atapi_write
};