From 47bf2e3878ab3088df684fe379a034ee01245f52 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sun, 23 Dec 2018 11:33:10 +0100 Subject: [PATCH] sdhci: detect Ricoh SDHCI controllers They don't advertise themselves as standard SDHCI, but are mostly compatible. Only check for the one in my machine for now. Also improve tracing in the probe function. Change-Id: Ia47238fb25b783790fa8caaedf2a71aeb6e29d89 Reviewed-on: https://review.haiku-os.org/c/haiku/+/806 Reviewed-by: Adrien Destugues --- src/add-ons/kernel/busses/mmc/sdhci_pci.cpp | 35 +++++++++++++++---- .../kernel/device_manager/device_manager.cpp | 8 ++++- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp b/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp index cb6ec3324b..907e57583d 100644 --- a/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp +++ b/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp @@ -616,22 +616,45 @@ supports_device(device_node* parent) const char* bus; uint16 type, subType; uint8 pciSubDeviceId; + uint16 vendorId, deviceId; // make sure parent is a PCI SDHCI device node if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) - != B_OK || gDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, - &subType, false) < B_OK || gDeviceManager->get_attr_uint16(parent, - B_DEVICE_TYPE, &type, false) < B_OK) { - ERROR("Could not find required attribute device/bus\n"); + != B_OK) { + TRACE("Could not find required attribute device/bus\n"); return -1; } if (strcmp(bus, "pci") != 0) return 0.0f; + if (gDeviceManager->get_attr_uint16(parent, B_DEVICE_VENDOR_ID, &vendorId, + false) != B_OK + || gDeviceManager->get_attr_uint16(parent, B_DEVICE_ID, &deviceId, + false) != B_OK) { + TRACE("No vendor or device id attribute\n"); + return 0.0f; + } + + TRACE("Probe device %p (%04x:%04x)\n", parent, vendorId, deviceId); + + if (gDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, &subType, + false) < B_OK + || gDeviceManager->get_attr_uint16(parent, B_DEVICE_TYPE, &type, + false) < B_OK) { + TRACE("Could not find type/subtype attributes\n"); + return -1; + } + if (type == PCI_base_peripheral) { - if (subType != PCI_sd_host) - return 0.0f; + if (subType != PCI_sd_host) { + // Also accept some compliant devices that do not advertise + // themselves as such. + if (vendorId != 0x1180 && deviceId != 0xe823) { + TRACE("Not the right subclass, and not a Ricoh device\n"); + return 0.0f; + } + } pci_device_module_info* pci; pci_device* device; diff --git a/src/system/kernel/device_manager/device_manager.cpp b/src/system/kernel/device_manager/device_manager.cpp index 2f3713221b..00d035a41d 100644 --- a/src/system/kernel/device_manager/device_manager.cpp +++ b/src/system/kernel/device_manager/device_manager.cpp @@ -1661,6 +1661,10 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path) case PCI_sd_host: _AddPath(*stack, "busses", "mmc"); break; + case PCI_system_peripheral_other: + _AddPath(*stack, "busses", "mmc"); + _AddPath(*stack, "drivers"); + break; default: _AddPath(*stack, "drivers"); break; @@ -1964,7 +1968,9 @@ device_node::Probe(const char* devicePath, uint32 updateCycle) // TODO: maybe make this extendible via settings file? if (!strcmp(devicePath, "disk")) { matches = type == PCI_mass_storage - || (type == PCI_base_peripheral && subType == PCI_sd_host); + || (type == PCI_base_peripheral + && (subType == PCI_sd_host + || subType == PCI_system_peripheral_other)); } else if (!strcmp(devicePath, "audio")) { matches = type == PCI_multimedia && (subType == PCI_audio || subType == PCI_hd_audio);