If we are running on an Apple PPC platform, enable bus mastering for this card. This is because it seems that Apple's OF implementation enables bus mastering for rtl8139 cards by default with the result that several drivers forget to explicitly enable it, causing them to fail under QEMU.
This has been reported necessary for various rtl8139 drivers under OS 9, OS X and MorphOS.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/pci.c | 15 +++++++++++++++ drivers/pci_database.c | 2 +- drivers/pci_database.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/pci.c b/drivers/pci.c index 8ceb9c1..3abd5bf 100644 --- a/drivers/pci.c +++ b/drivers/pci.c @@ -567,6 +567,21 @@ int eth_config_cb (const pci_config_t *config) return 0; }
+int rtl8139_config_cb(const pci_config_t *config) +{ +#ifdef CONFIG_PPC + /* Apple's OF seemingly enables bus mastering on some cards by + * default, which means that some buggy drivers forget to + * explicitly set it (OS X, MorphOS). Mimic this behaviour so + * that these buggy drivers work under emulation. */ + if (is_apple()) { + ob_pci_enable_bus_master(config); + } +#endif + + return eth_config_cb(config); +} + static inline void pci_decode_pci_addr(pci_addr addr, int *flags, int *space_code, uint32_t *mask) { diff --git a/drivers/pci_database.c b/drivers/pci_database.c index 65cff27..b220586 100644 --- a/drivers/pci_database.c +++ b/drivers/pci_database.c @@ -132,7 +132,7 @@ static const pci_dev_t eth_devices[] = { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_RTL8139, NULL, "rtl8139", "RTL8139 PCI", "pci10ec,8139\0", 0, 0, 0, - NULL, "ethernet", + rtl8139_config_cb, "ethernet", }, { /* Virtio-network controller */ diff --git a/drivers/pci_database.h b/drivers/pci_database.h index 9e8dc05..1cc1e56 100644 --- a/drivers/pci_database.h +++ b/drivers/pci_database.h @@ -39,6 +39,7 @@ extern int bridge_config_cb(const pci_config_t *config); extern int ebus_config_cb(const pci_config_t *config); extern int i82378_config_cb(const pci_config_t *config); extern int usb_ohci_config_cb(const pci_config_t *config); +extern int rtl8139_config_cb(const pci_config_t *config);
static inline int pci_compat_len(const pci_dev_t *dev) {