[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] qemu-system-ppc -m g3beige -hda is setting /dev/hdc on Linu
From: |
Rob Landley |
Subject: |
[Qemu-devel] qemu-system-ppc -m g3beige -hda is setting /dev/hdc on Linux. |
Date: |
Sat, 13 Feb 2010 02:02:00 -0600 |
User-agent: |
KMail/1.11.2 (Linux/2.6.28-17-generic; KDE/4.2.2; x86_64; ; ) |
The -hda, -hdb, -hdc, and -hdd command line options for g3beige don't match
the order the kernel assigns the drives.
The reason is that the Linux kernel always initializes the cmd646 driver
before the pmac driver, thus if there's a cmd646 it gets /dev/hda and
/dev/hdb, and the pmac gets /dev/hdc and /dev/hdb.
If you only supply an -hda (and/or -hdb) with no -hdc or -hdd, then the cmd646
driver never attaches to anything and only the pmac controller shows up, thus
-hda and -hdb set /dev/hda and /dev/hdb. But if you specify a -hdc it shows
up as /dev/hda every time, and kicks the -hda entry to /dev/hdc.
Note that neither the kernel's CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST nor
CONFIG_IDEPCI_PCIBUS_ORDER made any difference, because those affect multiple
devices handled by the same driver, and this is a static driver initialization
order issue. When you statically link in both drivers, cmd64x always probes
before pmac due to the above hardwired device order in the kernel, 100%
reliable and deterministic. It's hardwired, and you have to patch the kernel
to change it.
Here's a patch to the Linux kernel that changes the device probe order so the
kernel behaves like g3beige is expecting it to:
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -39,6 +39,7 @@
obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o
obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o
obj-$(CONFIG_BLK_DEV_CELLEB) += scc_pata.o
+obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o
obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
@@ -76,8 +77,6 @@
obj-$(CONFIG_BLK_DEV_CMD640) += cmd640.o
-obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o
-
obj-$(CONFIG_IDE_H8300) += ide-h8300.o
obj-$(CONFIG_IDE_GENERIC) += ide-generic.o
The problem is, the kernel guys will never take that patch upstream because
what they're currently doing isn't actually wrong. Their behavior is
consistent, the kernel's been probing the same devices in the same order since
the 90's, and they don't really care what order things go in.
The problem is that the association between qemu's command line arguments and
the devices they refer to is somewhat arbitrary. On the other targets I've
used (arm, mips, x86, and so on), the device QEMU initializes in response to
"-hda" is the one the Linux kernel makes /dev/hda (or /dev/sda), and the one
it intializes in response to "-hdc" is the one Linux makes /dev/hdc. But in
this case, they don't match up, and that's screwing up my same init/build
script that works fine on all the other tarets.
Here's a patch to QEMU that makes those arguments intialize the devices the
kernel expects them to. This doesn't change where any of the hardware is on
the board, just which command line arguments associate with which drives:
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -346,16 +346,16 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
exit(1);
}
- /* First IDE channel is a MAC IDE on the MacIO bus */
- hd[0] = drive_get(IF_IDE, 0, 0);
- hd[1] = drive_get(IF_IDE, 0, 1);
+ /* Second IDE channel is a MAC IDE on the MacIO bus */
+ hd[0] = drive_get(IF_IDE, 1, 0);
+ hd[1] = drive_get(IF_IDE, 1, 1);
dbdma = DBDMA_init(&dbdma_mem_index);
ide_mem_index[0] = -1;
ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
- /* Second IDE channel is a CMD646 on the PCI bus */
- hd[0] = drive_get(IF_IDE, 1, 0);
- hd[1] = drive_get(IF_IDE, 1, 1);
+ /* First IDE channel is a CMD646 on the PCI bus */
+ hd[0] = drive_get(IF_IDE, 0, 0);
+ hd[1] = drive_get(IF_IDE, 0, 1);
hd[3] = hd[2] = NULL;
pci_cmd646_ide_init(pci_bus, hd, 0);
Rob
--
Latency is more important than throughput. It's that simple. - Linus Torvalds