Commit bf1b938fce39c8837899d11d074e2df983592a5b

Authored by bellard
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)
... ...