qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [5797] Abstract out geometry detection code from IDE for re


From: Anthony Liguori
Subject: [Qemu-devel] [5797] Abstract out geometry detection code from IDE for reuse
Date: Tue, 25 Nov 2008 21:50:25 +0000

Revision: 5797
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5797
Author:   aliguori
Date:     2008-11-25 21:50:24 +0000 (Tue, 25 Nov 2008)

Log Message:
-----------
Abstract out geometry detection code from IDE for reuse

Virtio will want to use the geometry detection code.  It doesn't belong 
in ide.c anyway.

Signed-off-by: Anthony Liguori <address@hidden>

Modified Paths:
--------------
    trunk/block.c
    trunk/block.h
    trunk/hw/ide.c

Modified: trunk/block.c
===================================================================
--- trunk/block.c       2008-11-25 17:26:09 UTC (rev 5796)
+++ trunk/block.c       2008-11-25 21:50:24 UTC (rev 5797)
@@ -739,6 +739,122 @@
     *nb_sectors_ptr = length;
 }
 
+struct partition {
+        uint8_t boot_ind;           /* 0x80 - active */
+        uint8_t head;               /* starting head */
+        uint8_t sector;             /* starting sector */
+        uint8_t cyl;                /* starting cylinder */
+        uint8_t sys_ind;            /* What partition type */
+        uint8_t end_head;           /* end head */
+        uint8_t end_sector;         /* end sector */
+        uint8_t end_cyl;            /* end cylinder */
+        uint32_t start_sect;        /* starting sector counting from 0 */
+        uint32_t nr_sects;          /* nr of sectors in partition */
+} __attribute__((packed));
+
+/* try to guess the disk logical geometry from the MSDOS partition table. 
Return 0 if OK, -1 if could not guess */
+static int guess_disk_lchs(BlockDriverState *bs,
+                           int *pcylinders, int *pheads, int *psectors)
+{
+    uint8_t buf[512];
+    int ret, i, heads, sectors, cylinders;
+    struct partition *p;
+    uint32_t nr_sects;
+    int64_t nb_sectors;
+
+    bdrv_get_geometry(bs, &nb_sectors);
+
+    ret = bdrv_read(bs, 0, buf, 1);
+    if (ret < 0)
+        return -1;
+    /* test msdos magic */
+    if (buf[510] != 0x55 || buf[511] != 0xaa)
+        return -1;
+    for(i = 0; i < 4; i++) {
+        p = ((struct partition *)(buf + 0x1be)) + i;
+        nr_sects = le32_to_cpu(p->nr_sects);
+        if (nr_sects && p->end_head) {
+            /* We make the assumption that the partition terminates on
+               a cylinder boundary */
+            heads = p->end_head + 1;
+            sectors = p->end_sector & 63;
+            if (sectors == 0)
+                continue;
+            cylinders = nb_sectors / (heads * sectors);
+            if (cylinders < 1 || cylinders > 16383)
+                continue;
+            *pheads = heads;
+            *psectors = sectors;
+            *pcylinders = cylinders;
+#if 0
+            printf("guessed geometry: LCHS=%d %d %d\n",
+                   cylinders, heads, sectors);
+#endif
+            return 0;
+        }
+    }
+    return -1;
+}
+
+void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int 
*psecs)
+{
+    int translation, lba_detected = 0;
+    int cylinders, heads, secs;
+    int64_t nb_sectors;
+
+    /* if a geometry hint is available, use it */
+    bdrv_get_geometry(bs, &nb_sectors);
+    bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
+    translation = bdrv_get_translation_hint(bs);
+    if (cylinders != 0) {
+        *pcyls = cylinders;
+        *pheads = heads;
+        *psecs = secs;
+    } else {
+        if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
+            if (heads > 16) {
+                /* if heads > 16, it means that a BIOS LBA
+                   translation was active, so the default
+                   hardware geometry is OK */
+                lba_detected = 1;
+                goto default_geometry;
+            } else {
+                *pcyls = cylinders;
+                *pheads = heads;
+                *psecs = secs;
+                /* disable any translation to be in sync with
+                   the logical geometry */
+                if (translation == BIOS_ATA_TRANSLATION_AUTO) {
+                    bdrv_set_translation_hint(bs,
+                                              BIOS_ATA_TRANSLATION_NONE);
+                }
+            }
+        } else {
+        default_geometry:
+            /* if no geometry, use a standard physical disk geometry */
+            cylinders = nb_sectors / (16 * 63);
+
+            if (cylinders > 16383)
+                cylinders = 16383;
+            else if (cylinders < 2)
+                cylinders = 2;
+            *pcyls = cylinders;
+            *pheads = 16;
+            *psecs = 63;
+            if ((lba_detected == 1) && (translation == 
BIOS_ATA_TRANSLATION_AUTO)) {
+                if ((*pcyls * *pheads) <= 131072) {
+                    bdrv_set_translation_hint(bs,
+                                              BIOS_ATA_TRANSLATION_LARGE);
+                } else {
+                    bdrv_set_translation_hint(bs,
+                                              BIOS_ATA_TRANSLATION_LBA);
+                }
+            }
+        }
+        bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
+    }
+}
+
 void bdrv_set_geometry_hint(BlockDriverState *bs,
                             int cyls, int heads, int secs)
 {

Modified: trunk/block.h
===================================================================
--- trunk/block.h       2008-11-25 17:26:09 UTC (rev 5796)
+++ trunk/block.h       2008-11-25 21:50:24 UTC (rev 5797)
@@ -78,6 +78,7 @@
 int bdrv_truncate(BlockDriverState *bs, int64_t offset);
 int64_t bdrv_getlength(BlockDriverState *bs);
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
+void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int 
*psecs);
 int bdrv_commit(BlockDriverState *bs);
 /* async block I/O */
 typedef struct BlockDriverAIOCB BlockDriverAIOCB;

Modified: trunk/hw/ide.c
===================================================================
--- trunk/hw/ide.c      2008-11-25 17:26:09 UTC (rev 5796)
+++ trunk/hw/ide.c      2008-11-25 21:50:24 UTC (rev 5797)
@@ -2676,69 +2676,13 @@
     s->media_changed = 0;
 }
 
-struct partition {
-       uint8_t boot_ind;               /* 0x80 - active */
-       uint8_t head;           /* starting head */
-       uint8_t sector;         /* starting sector */
-       uint8_t cyl;            /* starting cylinder */
-       uint8_t sys_ind;                /* What partition type */
-       uint8_t end_head;               /* end head */
-       uint8_t end_sector;     /* end sector */
-       uint8_t end_cyl;                /* end cylinder */
-       uint32_t start_sect;    /* starting sector counting from 0 */
-       uint32_t nr_sects;              /* nr of sectors in partition */
-} __attribute__((packed));
-
-/* try to guess the disk logical geometry from the MSDOS partition table. 
Return 0 if OK, -1 if could not guess */
-static int guess_disk_lchs(IDEState *s,
-                           int *pcylinders, int *pheads, int *psectors)
-{
-    uint8_t *buf = s->io_buffer;
-    int ret, i, heads, sectors, cylinders;
-    struct partition *p;
-    uint32_t nr_sects;
-
-    ret = bdrv_read(s->bs, 0, buf, 1);
-    if (ret < 0) {
-        return -1;
-    }
-    /* test msdos magic */
-    if (buf[510] != 0x55 || buf[511] != 0xaa) {
-        return -1;
-    }
-    for(i = 0; i < 4; i++) {
-        p = ((struct partition *)(buf + 0x1be)) + i;
-        nr_sects = le32_to_cpu(p->nr_sects);
-        if (nr_sects && p->end_head) {
-            /* We make the assumption that the partition terminates on
-               a cylinder boundary */
-            heads = p->end_head + 1;
-            sectors = p->end_sector & 63;
-            if (sectors == 0)
-                continue;
-            cylinders = s->nb_sectors / (heads * sectors);
-            if (cylinders < 1 || cylinders > 16383)
-                continue;
-            *pheads = heads;
-            *psectors = sectors;
-            *pcylinders = cylinders;
-#if 0
-            printf("guessed geometry: LCHS=%d %d %d\n",
-                   cylinders, heads, sectors);
-#endif
-            return 0;
-        }
-    }
-    return -1;
-}
-
 static void ide_init2(IDEState *ide_state,
                       BlockDriverState *hd0, BlockDriverState *hd1,
                       qemu_irq irq)
 {
     IDEState *s;
     static int drive_serial = 1;
-    int i, cylinders, heads, secs, translation, lba_detected = 0;
+    int i, cylinders, heads, secs;
     uint64_t nb_sectors;
 
     for(i = 0; i < 2; i++) {
@@ -2750,56 +2694,12 @@
             s->bs = hd1;
         if (s->bs) {
             bdrv_get_geometry(s->bs, &nb_sectors);
+            bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
+            s->cylinders = cylinders;
+            s->heads = heads;
+            s->sectors = secs;
             s->nb_sectors = nb_sectors;
-            /* if a geometry hint is available, use it */
-            bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
-            translation = bdrv_get_translation_hint(s->bs);
-            if (cylinders != 0) {
-                s->cylinders = cylinders;
-                s->heads = heads;
-                s->sectors = secs;
-            } else {
-                if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0) {
-                    if (heads > 16) {
-                        /* if heads > 16, it means that a BIOS LBA
-                           translation was active, so the default
-                           hardware geometry is OK */
-                        lba_detected = 1;
-                        goto default_geometry;
-                    } else {
-                        s->cylinders = cylinders;
-                        s->heads = heads;
-                        s->sectors = secs;
-                        /* disable any translation to be in sync with
-                           the logical geometry */
-                        if (translation == BIOS_ATA_TRANSLATION_AUTO) {
-                            bdrv_set_translation_hint(s->bs,
-                                                      
BIOS_ATA_TRANSLATION_NONE);
-                        }
-                    }
-                } else {
-                default_geometry:
-                    /* if no geometry, use a standard physical disk geometry */
-                    cylinders = nb_sectors / (16 * 63);
-                    if (cylinders > 16383)
-                        cylinders = 16383;
-                    else if (cylinders < 2)
-                        cylinders = 2;
-                    s->cylinders = cylinders;
-                    s->heads = 16;
-                    s->sectors = 63;
-                    if ((lba_detected == 1) && (translation == 
BIOS_ATA_TRANSLATION_AUTO)) {
-                      if ((s->cylinders * s->heads) <= 131072) {
-                        bdrv_set_translation_hint(s->bs,
-                                                  BIOS_ATA_TRANSLATION_LARGE);
-                      } else {
-                        bdrv_set_translation_hint(s->bs,
-                                                  BIOS_ATA_TRANSLATION_LBA);
-                      }
-                    }
-                }
-                bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, 
s->sectors);
-            }
+
             if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
                 s->is_cdrom = 1;
                bdrv_set_change_cb(s->bs, cdrom_change_cb, s);






reply via email to

[Prev in Thread] Current Thread [Next in Thread]