From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Mar 2010 22:18:13 +0000 (+0100) Subject: Handle defered device registration X-Git-Tag: 1.99~780^2~34 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9b6e10bbbfc52a2a5f121e3b999e836114fa5417;p=thirdparty%2Fgrub.git Handle defered device registration --- diff --git a/disk/ata.c b/disk/ata.c index 662fe71a7..b2291cd53 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -333,25 +333,8 @@ grub_ata_identify (struct grub_ata_device *dev) } static grub_err_t -grub_ata_device_initialize (int port, int device, int addr, int addr2) +check_device (struct grub_ata_device *dev) { - struct grub_ata_device *dev; - struct grub_ata_device **devp; - - grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n", - port, device, addr, addr2); - - dev = grub_malloc (sizeof(*dev)); - if (! dev) - return grub_errno; - - /* Setup the device information. */ - dev->port = port; - dev->device = device; - dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE; - 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 (); @@ -363,10 +346,7 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) 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; - } + 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 @@ -375,16 +355,38 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) 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; - } + 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); + + dev = grub_malloc (sizeof(*dev)); + if (! dev) + return grub_errno; + + /* Setup the device information. */ + dev->port = port; + dev->device = device; + dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE; + dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE; + dev->next = NULL; /* 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; } @@ -667,6 +669,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; @@ -685,6 +695,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) { @@ -701,6 +712,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; @@ -757,6 +773,16 @@ grub_atapi_iterate (int (*hook) (const char *name, int luns)) 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; + } + grub_snprintf (devname, sizeof (devname), "ata%d", dev->port * 2 + dev->device); @@ -827,6 +853,7 @@ grub_atapi_open (const char *name, 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) { @@ -846,6 +873,13 @@ grub_atapi_open (const char *name, struct grub_scsi *scsi) 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;