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,22 +1826,21 @@ struct partition {
1826 uint32_t nr_sects; /* nr of sectors in partition */ 1826 uint32_t nr_sects; /* nr of sectors in partition */
1827 } __attribute__((packed)); 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 uint8_t buf[512]; 1833 uint8_t buf[512];
1833 int ret, i, heads, sectors, cylinders; 1834 int ret, i, heads, sectors, cylinders;
1834 struct partition *p; 1835 struct partition *p;
1835 uint32_t nr_sects; 1836 uint32_t nr_sects;
1836 1837
1837 - if (s->cylinders != 0)  
1838 - return;  
1839 ret = bdrv_read(s->bs, 0, buf, 1); 1838 ret = bdrv_read(s->bs, 0, buf, 1);
1840 if (ret < 0) 1839 if (ret < 0)
1841 - return; 1840 + return -1;
1842 /* test msdos magic */ 1841 /* test msdos magic */
1843 if (buf[510] != 0x55 || buf[511] != 0xaa) 1842 if (buf[510] != 0x55 || buf[511] != 0xaa)
1844 - return; 1843 + return -1;
1845 for(i = 0; i < 4; i++) { 1844 for(i = 0; i < 4; i++) {
1846 p = ((struct partition *)(buf + 0x1be)) + i; 1845 p = ((struct partition *)(buf + 0x1be)) + i;
1847 nr_sects = le32_to_cpu(p->nr_sects); 1846 nr_sects = le32_to_cpu(p->nr_sects);
@@ -1849,23 +1848,23 @@ static void ide_guess_geometry(IDEState *s) @@ -1849,23 +1848,23 @@ static void ide_guess_geometry(IDEState *s)
1849 /* We make the assumption that the partition terminates on 1848 /* We make the assumption that the partition terminates on
1850 a cylinder boundary */ 1849 a cylinder boundary */
1851 heads = p->end_head + 1; 1850 heads = p->end_head + 1;
1852 - if (heads < 1 || heads > 16)  
1853 - continue;  
1854 sectors = p->end_sector & 63; 1851 sectors = p->end_sector & 63;
1855 if (sectors == 0) 1852 if (sectors == 0)
1856 continue; 1853 continue;
1857 cylinders = s->nb_sectors / (heads * sectors); 1854 cylinders = s->nb_sectors / (heads * sectors);
1858 if (cylinders < 1 || cylinders > 16383) 1855 if (cylinders < 1 || cylinders > 16383)
1859 continue; 1856 continue;
1860 - s->heads = heads;  
1861 - s->sectors = sectors;  
1862 - s->cylinders = cylinders; 1857 + *pheads = heads;
  1858 + *psectors = sectors;
  1859 + *pcylinders = cylinders;
1863 #if 0 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 #endif 1863 #endif
  1864 + return 0;
1867 } 1865 }
1868 } 1866 }
  1867 + return -1;
1869 } 1868 }
1870 1869
1871 static void ide_init2(IDEState *ide_state, int irq, 1870 static void ide_init2(IDEState *ide_state, int irq,
@@ -1873,7 +1872,7 @@ 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 IDEState *s; 1873 IDEState *s;
1875 static int drive_serial = 1; 1874 static int drive_serial = 1;
1876 - int i, cylinders, heads, secs; 1875 + int i, cylinders, heads, secs, translation;
1877 int64_t nb_sectors; 1876 int64_t nb_sectors;
1878 1877
1879 for(i = 0; i < 2; i++) { 1878 for(i = 0; i < 2; i++) {
@@ -1892,8 +1891,26 @@ static void ide_init2(IDEState *ide_state, int irq, @@ -1892,8 +1891,26 @@ static void ide_init2(IDEState *ide_state, int irq,
1892 s->heads = heads; 1891 s->heads = heads;
1893 s->sectors = secs; 1892 s->sectors = secs;
1894 } else { 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 /* if no geometry, use a standard physical disk geometry */ 1914 /* if no geometry, use a standard physical disk geometry */
1898 cylinders = nb_sectors / (16 * 63); 1915 cylinders = nb_sectors / (16 * 63);
1899 if (cylinders > 16383) 1916 if (cylinders > 16383)