From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1M7yON-0007cv-Hn for mharc-grub-devel@gnu.org; Sat, 23 May 2009 17:04:31 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1M7yOL-0007c4-08 for grub-devel@gnu.org; Sat, 23 May 2009 17:04:29 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1M7yOF-0007WO-Oq for grub-devel@gnu.org; Sat, 23 May 2009 17:04:28 -0400 Received: from [199.232.76.173] (port=50983 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1M7yOF-0007WH-H4 for grub-devel@gnu.org; Sat, 23 May 2009 17:04:23 -0400 Received: from mailout10.t-online.de ([194.25.134.21]:55432) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1M7yOE-00063C-5U for grub-devel@gnu.org; Sat, 23 May 2009 17:04:22 -0400 Received: from fwd04.aul.t-online.de by mailout10.sul.t-online.de with smtp id 1M7yOC-0003qK-00; Sat, 23 May 2009 23:04:20 +0200 Received: from [10.3.2.2] (ThshHMZlwh9CqBN112qWE8f2TKfU8ezkw1hAa4y+797TKSS2XfnIeIYT0LtH1LIwYK@[217.235.188.140]) by fwd04.aul.t-online.de with esmtp id 1M7yNy-1lDiOO0; Sat, 23 May 2009 23:04:06 +0200 Message-ID: <4A1864C7.9060606@t-online.de> Date: Sat, 23 May 2009 23:04:07 +0200 From: Christian Franke User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.21) Gecko/20090403 SeaMonkey/1.1.16 MIME-Version: 1.0 To: The development of GRUB 2 References: <1242689772.16522.1.camel@mj> <1242692278.26306.3.camel@mj> <1M6P7a-0SfD5U0@fwd04.aul.t-online.de> <4A1478C1.5000906@t-online.de> <1242857580.2555.2.camel@mj> <4A15C0C5.6070708@t-online.de> In-Reply-To: <4A15C0C5.6070708@t-online.de> Content-Type: multipart/mixed; boundary="------------000002030905000005010001" X-ID: ThshHMZlwh9CqBN112qWE8f2TKfU8ezkw1hAa4y+797TKSS2XfnIeIYT0LtH1LIwYK X-TOI-MSGID: f84ef1c1-dad1-4e31-9259-6585c806bb69 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Subject: Re: [PATCH] ata.mod under qemu X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 23 May 2009 21:04:29 -0000 This is a multi-part message in MIME format. --------------000002030905000005010001 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Christian Franke wrote: > Pavel Roskin wrote: >>> >> It helps detect CD-ROM under qemu. But on the real hardware, it >> introduces ghost drives. >> >> Without the patch, I have (ata7) for the SATA hard drive. With the >> patch, I have (ata7) for the SATA hard drive, (ata6) for the SATA DVD-RW >> and two bogus unreadable drives (ata0) and (ata1). >> >> New patch attached. Please test on the above hardware if possible. -- Regards, Christian Franke --------------000002030905000005010001 Content-Type: text/x-diff; name="grub2-ata-status-fix-2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="grub2-ata-status-fix-2.patch" diff --git a/disk/ata.c b/disk/ata.c index ea42d59..5fa0ef5 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -41,11 +41,14 @@ grub_ata_wait_not_busy (struct grub_ata_device *dev, int milliseconds) grub_millisleep (1); int i = 1; - while (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY) + grub_uint8_t sts; + while ((sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS)) + & GRUB_ATA_STATUS_BUSY) { if (i >= milliseconds) { - grub_dprintf ("ata", "timeout: %dms\n", milliseconds); + grub_dprintf ("ata", "timeout: %dms, status=0x%x\n", + milliseconds, sts); return grub_error (GRUB_ERR_TIMEOUT, "ATA timeout"); } @@ -151,6 +154,7 @@ grub_atapi_identify (struct grub_ata_device *dev) return grub_errno; grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4); + grub_ata_wait (); if (grub_ata_check_ready (dev)) { grub_free (info); @@ -248,6 +252,7 @@ grub_ata_identify (struct grub_ata_device *dev) info16 = (grub_uint16_t *) info; grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4); + grub_ata_wait (); if (grub_ata_check_ready (dev)) { grub_free (info); @@ -259,24 +264,38 @@ grub_ata_identify (struct grub_ata_device *dev) if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD)) { - if (grub_ata_regget (dev, GRUB_ATA_REG_ERROR) & 0x04) /* ABRT */ - { - /* Device without ATA IDENTIFY, try ATAPI. */ - grub_free(info); - grub_errno = GRUB_ERR_NONE; - return grub_atapi_identify (dev); - } + grub_free(info); + grub_errno = GRUB_ERR_NONE; + grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); + + if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ + | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR + && (grub_ata_regget (dev, GRUB_ATA_REG_ERROR) & 0x04 /* ABRT */)) + /* Device without ATA IDENTIFY, try ATAPI. */ + return grub_atapi_identify (dev); + + else if (sts == 0x00) + /* No device, return error but don't print message. */ + return GRUB_ERR_UNKNOWN_DEVICE; + else - { - /* Error. */ - grub_free(info); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "device can not be identified"); - } + /* Other Error. */ + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "device can not be identified"); } grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE); + /* Re-check status to avoid bogus identify data due to stuck DRQ. */ + grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); + if (sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) + { + grub_dprintf("ata", "bad status=0x%x", sts); + grub_free(info); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "error reading ATA IDENTIFY data"); + } + /* Now it is certain that this is not an ATAPI device. */ dev->atapi = 0; @@ -334,26 +353,12 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); grub_ata_wait (); - /* If status is 0x00, it is safe to assume that there - is no device (or only a !READY) device connected. */ - grub_int8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); - grub_dprintf ("ata", "status=0x%x\n", sts); - if (sts == 0x00) - { - grub_free(dev); - return 0; - } - /* 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. - But this tests often detects a second (slave) device - connected to a SATA controller which supports only one - (master) device. In this case, the status register - check above usually works. */ + was preserved, there is a device connected. */ grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A); grub_ata_wait (); - grub_int8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS); + grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS); grub_dprintf ("ata", "sectors=0x%x\n", sec); if (sec != 0x5A) { @@ -361,6 +366,12 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) 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)) { --------------000002030905000005010001--