Commit bf1b938fce39c8837899d11d074e2df983592a5b
1 parent
46d4767d
disable automatic BIOS translation if the logical disk geometry implies it
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1154 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
33 additions
and
16 deletions
hw/ide.c
... | ... | @@ -1826,22 +1826,21 @@ struct partition { |
1826 | 1826 | uint32_t nr_sects; /* nr of sectors in partition */ |
1827 | 1827 | } __attribute__((packed)); |
1828 | 1828 | |
1829 | -/* try to guess the IDE physical geometry from the MSDOS partition table */ | |
1830 | -static void ide_guess_geometry(IDEState *s) | |
1829 | +/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */ | |
1830 | +static int guess_disk_lchs(IDEState *s, | |
1831 | + int *pcylinders, int *pheads, int *psectors) | |
1831 | 1832 | { |
1832 | 1833 | uint8_t buf[512]; |
1833 | 1834 | int ret, i, heads, sectors, cylinders; |
1834 | 1835 | struct partition *p; |
1835 | 1836 | uint32_t nr_sects; |
1836 | 1837 | |
1837 | - if (s->cylinders != 0) | |
1838 | - return; | |
1839 | 1838 | ret = bdrv_read(s->bs, 0, buf, 1); |
1840 | 1839 | if (ret < 0) |
1841 | - return; | |
1840 | + return -1; | |
1842 | 1841 | /* test msdos magic */ |
1843 | 1842 | if (buf[510] != 0x55 || buf[511] != 0xaa) |
1844 | - return; | |
1843 | + return -1; | |
1845 | 1844 | for(i = 0; i < 4; i++) { |
1846 | 1845 | p = ((struct partition *)(buf + 0x1be)) + i; |
1847 | 1846 | nr_sects = le32_to_cpu(p->nr_sects); |
... | ... | @@ -1849,23 +1848,23 @@ static void ide_guess_geometry(IDEState *s) |
1849 | 1848 | /* We make the assumption that the partition terminates on |
1850 | 1849 | a cylinder boundary */ |
1851 | 1850 | heads = p->end_head + 1; |
1852 | - if (heads < 1 || heads > 16) | |
1853 | - continue; | |
1854 | 1851 | sectors = p->end_sector & 63; |
1855 | 1852 | if (sectors == 0) |
1856 | 1853 | continue; |
1857 | 1854 | cylinders = s->nb_sectors / (heads * sectors); |
1858 | 1855 | if (cylinders < 1 || cylinders > 16383) |
1859 | 1856 | continue; |
1860 | - s->heads = heads; | |
1861 | - s->sectors = sectors; | |
1862 | - s->cylinders = cylinders; | |
1857 | + *pheads = heads; | |
1858 | + *psectors = sectors; | |
1859 | + *pcylinders = cylinders; | |
1863 | 1860 | #if 0 |
1864 | - printf("guessed partition: CHS=%d %d %d\n", | |
1865 | - s->cylinders, s->heads, s->sectors); | |
1861 | + printf("guessed geometry: LCHS=%d %d %d\n", | |
1862 | + cylinders, heads, sectors); | |
1866 | 1863 | #endif |
1864 | + return 0; | |
1867 | 1865 | } |
1868 | 1866 | } |
1867 | + return -1; | |
1869 | 1868 | } |
1870 | 1869 | |
1871 | 1870 | static void ide_init2(IDEState *ide_state, int irq, |
... | ... | @@ -1873,7 +1872,7 @@ static void ide_init2(IDEState *ide_state, int irq, |
1873 | 1872 | { |
1874 | 1873 | IDEState *s; |
1875 | 1874 | static int drive_serial = 1; |
1876 | - int i, cylinders, heads, secs; | |
1875 | + int i, cylinders, heads, secs, translation; | |
1877 | 1876 | int64_t nb_sectors; |
1878 | 1877 | |
1879 | 1878 | for(i = 0; i < 2; i++) { |
... | ... | @@ -1892,8 +1891,26 @@ static void ide_init2(IDEState *ide_state, int irq, |
1892 | 1891 | s->heads = heads; |
1893 | 1892 | s->sectors = secs; |
1894 | 1893 | } else { |
1895 | - ide_guess_geometry(s); | |
1896 | - if (s->cylinders == 0) { | |
1894 | + if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0) { | |
1895 | + if (heads > 16) { | |
1896 | + /* if heads > 16, it means that a BIOS LBA | |
1897 | + translation was active, so the default | |
1898 | + hardware geometry is OK */ | |
1899 | + goto default_geometry; | |
1900 | + } else { | |
1901 | + s->cylinders = cylinders; | |
1902 | + s->heads = heads; | |
1903 | + s->sectors = secs; | |
1904 | + /* disable any translation to be in sync with | |
1905 | + the logical geometry */ | |
1906 | + translation = bdrv_get_translation_hint(s->bs); | |
1907 | + if (translation == BIOS_ATA_TRANSLATION_AUTO) { | |
1908 | + bdrv_set_translation_hint(s->bs, | |
1909 | + BIOS_ATA_TRANSLATION_NONE); | |
1910 | + } | |
1911 | + } | |
1912 | + } else { | |
1913 | + default_geometry: | |
1897 | 1914 | /* if no geometry, use a standard physical disk geometry */ |
1898 | 1915 | cylinders = nb_sectors / (16 * 63); |
1899 | 1916 | if (cylinders > 16383) | ... | ... |