[haiku-commits] haiku: hrev52171 - in src/add-ons/kernel: busses/mmc bus_managers/mmc drivers/disk/mmc

  • From: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 5 Aug 2018 16:56:58 -0400 (EDT)

hrev52171 adds 1 changeset to branch 'master'
old head: 42cc463169541d13948b6a9d43231f7343c995f7
new head: 25b6a6f19b13680a759cffecebf60d0b7e76d3d3
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=25b6a6f19b13+%5E42cc46316954

----------------------------------------------------------------------------

25b6a6f19b13: SDHCI MMC Driver
  
  1. SDHCI PCI Bus: Discovering SDHC device from the PCI bus
        and registers a child node(MMC bus) to which slots
        are attached. SDHC registers are mapped by MMUIO,
        they are binded in a structure(struct* registers).
        A pin based interrupt handler is also installed,
        which triggers the handler function and interrupts
        are being taken care of. Added API's to set-up and
        the clock for SD/MMC card, change frequency and
        reset the registers.
  
  2. Device Manager: Currently, busses subdir lists are har-
        dcoded and in order to load the driver. We hard
        coded the bus dir under PCI devices.
  
  3. MMC Disk Driver: In order to register the slots under
        /dev/disk/mmc and hence data transfer and other
        operations can be done.
  
  4. MMC Bus Manager: Setted up a bus manager to create an object
        to do a particular for eg certain data transfer and
        get freed until another operation is requested.
  
  Change-Id: I369354da6b79adc6b6dfb08fe160334af1392a34
  Reviewed-on: https://review.haiku-os.org/318
  Reviewed-by: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>

                                   [ krish_iyer <krishnaniyer97@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev52171
Commit:      25b6a6f19b13680a759cffecebf60d0b7e76d3d3
URL:         https://git.haiku-os.org/haiku/commit/?id=25b6a6f19b13
Author:      krish_iyer <krishnaniyer97@xxxxxxxxx>
Date:        Sat Apr 28 13:54:09 2018 UTC
Committer:   Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Commit-Date: Sun Aug  5 20:56:54 2018 UTC

----------------------------------------------------------------------------

14 files changed, 1118 insertions(+), 3 deletions(-)
src/add-ons/kernel/bus_managers/Jamfile          |   1 +
src/add-ons/kernel/bus_managers/mmc/Jamfile      |   8 +
src/add-ons/kernel/bus_managers/mmc/mmc_bus.cpp  |  43 ++
src/add-ons/kernel/bus_managers/mmc/mmc_bus.h    |  53 ++
.../kernel/bus_managers/mmc/mmc_module.cpp       | 137 +++++
src/add-ons/kernel/busses/Jamfile                |   1 +
src/add-ons/kernel/busses/mmc/Jamfile            |   7 +
src/add-ons/kernel/busses/mmc/sdhci_pci.cpp      | 534 +++++++++++++++++++
src/add-ons/kernel/busses/mmc/sdhci_pci.h        | 129 +++++
src/add-ons/kernel/drivers/disk/Jamfile          |   3 +-
src/add-ons/kernel/drivers/disk/mmc/Jamfile      |   8 +
src/add-ons/kernel/drivers/disk/mmc/mmc_disk.cpp | 157 ++++++
src/add-ons/kernel/drivers/disk/mmc/mmc_disk.h   |  24 +
.../kernel/device_manager/device_manager.cpp     |  16 +-

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/bus_managers/Jamfile 
b/src/add-ons/kernel/bus_managers/Jamfile
index e997c36156..386b887d09 100644
--- a/src/add-ons/kernel/bus_managers/Jamfile
+++ b/src/add-ons/kernel/bus_managers/Jamfile
@@ -7,6 +7,7 @@ SubInclude HAIKU_TOP src add-ons kernel bus_managers fdt ;
 SubInclude HAIKU_TOP src add-ons kernel bus_managers firewire ;
 SubInclude HAIKU_TOP src add-ons kernel bus_managers ata ;
 SubInclude HAIKU_TOP src add-ons kernel bus_managers isa ;
+SubInclude HAIKU_TOP src add-ons kernel bus_managers mmc ;
 SubInclude HAIKU_TOP src add-ons kernel bus_managers pci ;
 SubInclude HAIKU_TOP src add-ons kernel bus_managers ps2 ;
 SubInclude HAIKU_TOP src add-ons kernel bus_managers random ;
diff --git a/src/add-ons/kernel/bus_managers/mmc/Jamfile 
b/src/add-ons/kernel/bus_managers/mmc/Jamfile
new file mode 100644
index 0000000000..fbf3722826
--- /dev/null
+++ b/src/add-ons/kernel/bus_managers/mmc/Jamfile
@@ -0,0 +1,8 @@
+SubDir HAIKU_TOP src add-ons kernel bus_managers mmc ;
+
+UsePrivateKernelHeaders ;
+
+KernelAddon mmc_bus :
+       mmc_module.cpp
+       mmc_bus.cpp
+       ;
diff --git a/src/add-ons/kernel/bus_managers/mmc/mmc_bus.cpp 
b/src/add-ons/kernel/bus_managers/mmc/mmc_bus.cpp
new file mode 100644
index 0000000000..ffdc09cdb8
--- /dev/null
+++ b/src/add-ons/kernel/bus_managers/mmc/mmc_bus.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018 Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             B Krishnan Iyer, krishnaniyer97@xxxxxxxxx
+ */
+#include "mmc_bus.h"
+
+
+MMCBus::MMCBus(device_node* node)
+       :
+       fNode(node),
+       fController(NULL),
+       fCookie(NULL),
+       fStatus(B_OK),
+       fDriverCookie(NULL)
+{
+       CALLED();
+       device_node* parent = gDeviceManager->get_parent_node(node);
+       fStatus = gDeviceManager->get_driver(parent,
+               (driver_module_info**)&fController, &fCookie);
+       gDeviceManager->put_node(parent);
+
+       if (fStatus != B_OK) {
+               ERROR("Not able to establish the bus %s\n",
+                       strerror(fStatus));
+               return;
+       }
+}
+
+
+MMCBus::~MMCBus()
+{
+       CALLED();
+}
+
+
+status_t
+MMCBus::InitCheck()
+{
+       return fStatus;
+}
diff --git a/src/add-ons/kernel/bus_managers/mmc/mmc_bus.h 
b/src/add-ons/kernel/bus_managers/mmc/mmc_bus.h
new file mode 100644
index 0000000000..efdc97efec
--- /dev/null
+++ b/src/add-ons/kernel/bus_managers/mmc/mmc_bus.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2018 Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             B Krishnan Iyer, krishnaniyer97@xxxxxxxxx
+ */
+#ifndef MMC_BUS_H
+#define MMC_BUS_H
+
+
+#include <new>
+#include <stdio.h>
+#include <string.h>
+
+#include <lock.h>
+#include <util/AutoLock.h>
+#include "../../busses/mmc/sdhci_pci.h"
+
+
+#define MMCBUS_TRACE
+#ifdef MMCBUS_TRACE
+#      define TRACE(x...)              dprintf("\33[33mmmc_bus:\33[0m " x)
+#else
+#      define TRACE(x...)
+#endif
+#define TRACE_ALWAYS(x...)     dprintf("\33[33mmmc_bus:\33[0m " x)
+#define ERROR(x...)                    dprintf("\33[33mmmc_bus:\33[0m " x)
+#define CALLED()                       TRACE("CALLED %s\n", 
__PRETTY_FUNCTION__)
+
+extern device_manager_info *gDeviceManager;
+
+
+class MMCBus;
+
+class MMCBus {
+public:
+
+                       MMCBus(device_node *node);
+                       ~MMCBus();
+                       status_t InitCheck();
+
+private:
+
+               device_node*                            fNode;
+               sdhci_mmc_bus_interface*        fController;
+               void*                                           fCookie;
+               status_t                                        fStatus;
+               void*                                           fDriverCookie;
+};
+
+
+#endif /*MMC_BUS_H*/
\ No newline at end of file
diff --git a/src/add-ons/kernel/bus_managers/mmc/mmc_module.cpp 
b/src/add-ons/kernel/bus_managers/mmc/mmc_module.cpp
new file mode 100644
index 0000000000..7ada05ce64
--- /dev/null
+++ b/src/add-ons/kernel/bus_managers/mmc/mmc_module.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2018 Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             B Krishnan Iyer, krishnaniyer97@xxxxxxxxx
+ */
+#include "mmc_bus.h"
+
+
+device_manager_info* gDeviceManager = NULL;
+
+
+static status_t
+mmc_bus_init(device_node* node, void** _device)
+{
+       CALLED();
+       MMCBus* device = new(std::nothrow) MMCBus(node);
+       if (device == NULL) {
+               ERROR("Unable to allocate MMC bus\n");
+               return B_NO_MEMORY;
+       }
+
+       status_t result = device->InitCheck();
+       if (result != B_OK) {
+               TRACE("failed to set up mmc bus device object\n");
+               return result;
+       }
+       TRACE("MMC bus object created\n");
+
+       *_device = device;
+       return B_OK;
+}
+
+
+static void
+mmc_bus_uninit(void* _device)
+{
+       CALLED();
+       MMCBus* device = (MMCBus*)_device;
+       delete device;
+}
+
+
+static void
+mmc_bus_removed(void* _device)
+{
+       CALLED();
+}
+
+
+status_t
+mmc_bus_added_device(device_node* parent)
+{
+       CALLED();
+       uint16 deviceType;
+       if (gDeviceManager->get_attr_uint16(parent,
+                       SDHCI_DEVICE_TYPE_ITEM, &deviceType, true) != B_OK) {
+               TRACE("device is missing\n");
+               return B_ERROR;
+       }
+
+       TRACE("MMC bus device added\n");
+
+       device_attr attributes[] = {
+               { B_DEVICE_BUS, B_STRING_TYPE, { string: "mmc bus"}},
+               { SDHCI_DEVICE_TYPE_ITEM, B_UINT16_TYPE,
+                       { ui16: deviceType }},
+               { NULL }
+       };
+
+       return gDeviceManager->register_node(parent, MMC_BUS_MODULE_NAME,
+               attributes, NULL, NULL);
+}
+
+
+static status_t
+std_ops(int32 op, ...)
+{
+       switch (op) {
+               case B_MODULE_INIT:
+                       // Nothing to do
+               case B_MODULE_UNINIT:
+                       return B_OK;
+
+               default:
+                       break;
+       }
+
+       return B_ERROR;
+}
+
+
+driver_module_info mmc_bus_device_module = {
+       {
+               MMC_BUS_MODULE_NAME,
+               0,
+               std_ops
+       },
+       NULL, // supported devices
+       NULL, // register node
+       mmc_bus_init,
+       mmc_bus_uninit,
+       NULL, // register child devices
+       NULL, // rescan
+       mmc_bus_removed,
+       NULL, // suspend
+       NULL // resume
+};
+
+
+driver_module_info mmc_bus_controller_module = {
+       {
+               SDHCI_BUS_CONTROLLER_MODULE_NAME,
+               0,
+               &std_ops
+       },
+
+       NULL, // supported devices
+       mmc_bus_added_device,
+       NULL,
+       NULL,
+       NULL
+};
+
+
+module_dependency module_dependencies[] = {
+       { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
+       {}
+};
+
+
+module_info* modules[] = {
+       (module_info*)&mmc_bus_controller_module,
+       (module_info*)&mmc_bus_device_module,
+       NULL
+};
diff --git a/src/add-ons/kernel/busses/Jamfile 
b/src/add-ons/kernel/busses/Jamfile
index 402cbec5f8..7b549f0e04 100644
--- a/src/add-ons/kernel/busses/Jamfile
+++ b/src/add-ons/kernel/busses/Jamfile
@@ -2,6 +2,7 @@ SubDir HAIKU_TOP src add-ons kernel busses ;
 
 SubInclude HAIKU_TOP src add-ons kernel busses ata ;
 SubInclude HAIKU_TOP src add-ons kernel busses agp_gart ;
+SubInclude HAIKU_TOP src add-ons kernel busses mmc ;
 SubInclude HAIKU_TOP src add-ons kernel busses random ;
 SubInclude HAIKU_TOP src add-ons kernel busses scsi ;
 SubInclude HAIKU_TOP src add-ons kernel busses usb ;
diff --git a/src/add-ons/kernel/busses/mmc/Jamfile 
b/src/add-ons/kernel/busses/mmc/Jamfile
new file mode 100644
index 0000000000..ef5298fb2f
--- /dev/null
+++ b/src/add-ons/kernel/busses/mmc/Jamfile
@@ -0,0 +1,7 @@
+SubDir HAIKU_TOP src add-ons kernel busses mmc ;
+
+SubDirC++Flags -fno-rtti ;
+
+KernelAddon sdhci_pci :
+       sdhci_pci.cpp
+;
diff --git a/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp 
b/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp
new file mode 100644
index 0000000000..35f31d3557
--- /dev/null
+++ b/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp
@@ -0,0 +1,534 @@
+/*
+ * Copyright 2018 Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             B Krishnan Iyer, krishnaniyer97@xxxxxxxxx
+ */
+#include <new>
+#include <stdio.h>
+#include <string.h>
+
+#include <bus/PCI.h>
+#include <PCI_x86.h>
+
+#include <KernelExport.h>
+
+#include "sdhci_pci.h"
+
+
+#define TRACE_SDHCI
+#ifdef TRACE_SDHCI
+#      define TRACE(x...) dprintf("\33[33msdhci_pci:\33[0m " x)
+#else
+#      define TRACE(x...) ;
+#endif
+#define TRACE_ALWAYS(x...)     dprintf("\33[33msdhci_pci:\33[0m " x)
+#define ERROR(x...)                    dprintf("\33[33msdhci_pci:\33[0m " x)
+#define CALLED(x...)           TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
+
+
+#define SDHCI_PCI_DEVICE_MODULE_NAME "busses/mmc/sdhci_pci/driver_v1"
+#define SDHCI_PCI_MMC_BUS_MODULE_NAME "busses/mmc/sdhci_pci/device/v1"
+
+#define SDHCI_PCI_CONTROLLER_TYPE_NAME "sdhci pci controller"
+
+#define SLOTS_COUNT                            "device/slots_count"
+#define SLOT_NUMBER                            "device/slot"
+#define BAR_INDEX                              "device/bar"
+
+typedef struct {
+       pci_device_module_info* pci;
+       pci_device* device;
+       addr_t base_addr;
+       uint8 irq;
+       sdhci_mmc_bus mmc_bus;
+       area_id regs_area;
+       device_node* node;
+       pci_info info;
+       struct registers* _regs;
+
+} sdhci_pci_mmc_bus_info;
+
+
+device_manager_info* gDeviceManager;
+device_module_info* gSDHCIDeviceController;
+static pci_x86_module_info* sPCIx86Module;
+
+
+static void
+sdhci_register_dump(uint8_t slot, struct registers* regs)
+{
+       TRACE("Register values for slot: %d\n", slot);
+       TRACE("system_address: %d\n", regs->system_address);
+       TRACE("block_size: %d\n", regs->block_size);
+       TRACE("block_count: %d\n", regs->block_count);
+       TRACE("argument: %d\n", regs->argument);
+       TRACE("transfer_mode: %d\n", regs->transfer_mode);
+       TRACE("command: %d\n", regs->command);
+       TRACE("response0: %d\n", regs->response0);
+       TRACE("response2: %d\n", regs->response2);
+       TRACE("response4: %d\n", regs->response4);
+       TRACE("response6: %d\n", regs->response6);
+       TRACE("buffer_data_port: %d\n", regs->buffer_data_port);
+       TRACE("present_state: %d\n", regs->present_state);
+       TRACE("power_control: %d\n", regs->power_control);
+       TRACE("host_control: %d\n", regs->host_control);
+       TRACE("wakeup_control: %d\n", regs->wakeup_control);
+       TRACE("block_gap_control: %d\n", regs->block_gap_control);
+       TRACE("clock_control: %d\n", regs->clock_control);
+       TRACE("software_reset: %d\n", regs->software_reset);
+       TRACE("timeout_control: %d\n", regs->timeout_control);
+       TRACE("interrupt_status: %d\n", regs->interrupt_status);
+       TRACE("interrupt_status_enable: %d\n", regs->interrupt_status_enable);
+       TRACE("interrupt_signal_enable: %d\n", regs->interrupt_signal_enable);
+       TRACE("auto_cmd12_error_status: %d\n", regs->auto_cmd12_error_status);
+       TRACE("capabilities: %d\n", regs->capabilities);
+       TRACE("capabilities_rsvd: %d\n", regs->capabilities_rsvd);
+       TRACE("max_current_capabilities: %d\n",
+               regs->max_current_capabilities);
+       TRACE("max_current_capabilities_rsvd: %d\n",
+               regs->max_current_capabilities_rsvd);
+       TRACE("slot_interrupt_status: %d\n", regs->slot_interrupt_status);
+       TRACE("host_control_version %d\n", regs->host_control_version);
+}
+
+
+static void
+sdhci_reset(struct registers* regs)
+{
+       // if card is not present then no point of reseting the registers
+       if (!(regs->present_state & SDHCI_CARD_DETECT))
+               return;
+
+       // enabling software reset all
+       regs->software_reset |= SDHCI_SOFTWARE_RESET_ALL;
+
+       // waiting for clock and power to get off
+       while (regs->clock_control != 0 && regs->power_control != 0);
+}
+
+
+static void
+sdhci_set_clock(struct registers* regs, uint16_t base_clock_div)
+{
+       uint32_t clock_control = regs->clock_control;
+       int base_clock = SDHCI_BASE_CLOCK_FREQ(regs->capabilities);
+
+       TRACE("SDCLK frequency: %dMHz\n", base_clock);
+
+       // clearing previous frequency
+       clock_control &= SDHCI_CLR_FREQ_SEL;
+       clock_control |= base_clock_div;
+
+       // enabling internal clock
+       clock_control |= SDHCI_INTERNAL_CLOCK_ENABLE;
+       regs->clock_control = clock_control;
+
+       // waiting till internal clock gets stable
+       while (!(regs->clock_control & SDHCI_INTERNAL_CLOCK_STABLE));
+
+       regs->clock_control |= SDHCI_SD_CLOCK_ENABLE; // enabling the SD clock
+}
+
+
+static void
+sdhci_stop_clock(struct registers* regs)
+{
+       regs->clock_control &= SDHCI_SD_CLOCK_DISABLE;
+}
+
+
+static void
+sdhci_set_power(struct registers* _regs)
+{
+       uint16_t command = _regs->command;
+
+       if (SDHCI_VOLTAGE_SUPPORTED(_regs->capabilities))
+               if (SDHCI_VOLTAGE_SUPPORTED_33(_regs->capabilities))
+                       _regs->power_control |= SDHCI_VOLTAGE_SUPPORT_33;
+               else if (SDHCI_VOLTAGE_SUPPORTED_30(_regs->capabilities))
+                       _regs->power_control |= SDHCI_VOLTAGE_SUPPORT_30;
+               else
+                       _regs->power_control |= SDHCI_VOLTAGE_SUPPORT_18;
+       else
+               TRACE("No voltage is supported\n");
+
+       if (SDHCI_CARD_INSERTED(_regs->present_state) == 0) {
+               TRACE("Card not inserted\n");
+               return;
+       }
+
+       _regs->power_control |= SDHCI_BUS_POWER_ON;
+       TRACE("Executed CMD0\n");
+
+       command = SDHCI_RESPONSE_R1 | SDHCI_CMD_CRC_EN
+               | SDHCI_CMD_INDEX_EN | SDHCI_CMD_0;
+       _regs->command |= command;
+
+       DELAY(1000);
+}
+
+
+static status_t
+init_bus(device_node* node, void** bus_cookie)
+{
+       CALLED();
+       status_t status = B_OK;
+       area_id regs_area;
+       volatile uint32_t* regs;
+       uint8_t bar, slot;
+
+       sdhci_pci_mmc_bus_info* bus = new(std::nothrow) sdhci_pci_mmc_bus_info;
+       if (bus == NULL)
+               return B_NO_MEMORY;
+
+       pci_info* pciInfo = &bus->info;
+       pci_device_module_info* pci;
+       pci_device* device;
+
+       device_node* parent = gDeviceManager->get_parent_node(node);
+       device_node* pciParent = gDeviceManager->get_parent_node(parent);
+       gDeviceManager->get_driver(pciParent, (driver_module_info**)&pci,
+               (void**)&device);
+       gDeviceManager->put_node(pciParent);
+       gDeviceManager->put_node(parent);
+
+       if (get_module(B_PCI_X86_MODULE_NAME, (module_info**)&sPCIx86Module)
+           != B_OK) {
+           sPCIx86Module = NULL;
+               TRACE("PCIx86Module not loaded\n");
+       }
+
+       int msiCount = sPCIx86Module->get_msi_count(pciInfo->bus,
+               pciInfo->device, pciInfo->function);
+
+       TRACE("interrupts count: %d\n",msiCount);
+
+       if (gDeviceManager->get_attr_uint8(node, SLOT_NUMBER, &slot, false) < 
B_OK
+               || gDeviceManager->get_attr_uint8(node, BAR_INDEX, &bar, false) 
< B_OK)
+               return -1;
+
+       bus->node = node;
+       bus->pci = pci;
+       bus->device = device;
+
+       pci->get_pci_info(device, pciInfo);
+
+       // legacy interrupt
+       bus->base_addr = pciInfo->u.h0.base_registers[bar];
+
+       // enable bus master and io
+       uint16 pcicmd = pci->read_pci_config(device, PCI_command, 2);
+       pcicmd &= ~(PCI_command_int_disable | PCI_command_io);
+       pcicmd |= PCI_command_master | PCI_command_memory;
+       pci->write_pci_config(device, PCI_command, 2, pcicmd);
+
+       TRACE("init_bus() %p node %p pci %p device %p\n", bus, node,
+               bus->pci, bus->device);
+
+       // mapping the registers by MMUIO method
+       int bar_size = pciInfo->u.h0.base_register_sizes[bar];
+
+       regs_area = map_physical_memory("sdhc_regs_map",
+               pciInfo->u.h0.base_registers[bar],
+               pciInfo->u.h0.base_register_sizes[bar], 
B_ANY_KERNEL_BLOCK_ADDRESS,
+               B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void**)&regs);
+
+       if (regs_area < B_OK) {
+               TRACE("mapping failed");
+               return B_BAD_VALUE;
+       }
+
+       bus->regs_area = regs_area;
+       struct registers* _regs = (struct registers*)regs;
+       bus->_regs = _regs;
+       sdhci_reset(_regs);
+       bus->irq = pciInfo->u.h0.interrupt_line;
+
+       TRACE("irq interrupt line: %d\n",bus->irq);
+
+       if (bus->irq == 0 || bus->irq == 0xff) {
+               TRACE("PCI IRQ not assigned\n");
+               if (sPCIx86Module != NULL) {
+                       put_module(B_PCI_X86_MODULE_NAME);
+                       sPCIx86Module = NULL;
+               }
+               delete bus;
+               return B_ERROR;
+       }
+
+       status = install_io_interrupt_handler(bus->irq,
+               sdhci_generic_interrupt, bus, 0);
+
+       if (status != B_OK) {
+               TRACE("can't install interrupt handler\n");
+               return status;
+       }
+       TRACE("interrupt handler installed\n");
+
+       _regs->interrupt_status_enable = SDHCI_INT_CMD_CMP
+               | SDHCI_INT_TRANS_CMP | SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM
+               | SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | SDHCI_INT_INDEX
+               | SDHCI_INT_BUS_POWER | SDHCI_INT_END_BIT;
+       _regs->interrupt_signal_enable =  SDHCI_INT_CMD_CMP
+               | SDHCI_INT_TRANS_CMP | SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM
+               | SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | SDHCI_INT_INDEX
+               | SDHCI_INT_BUS_POWER | SDHCI_INT_END_BIT;
+
+       sdhci_register_dump(slot, _regs);
+       sdhci_set_clock(_regs, SDHCI_BASE_CLOCK_DIV_128);
+       sdhci_set_power(_regs);
+       sdhci_register_dump(slot, _regs);
+
+       *bus_cookie = bus;
+       return status;
+}
+
+
+void
+sdhci_error_interrupt_recovery(struct registers* _regs)
+{
+       _regs->interrupt_signal_enable &= ~(SDHCI_INT_CMD_CMP
+               | SDHCI_INT_TRANS_CMP | SDHCI_INT_CARD_INS | 
SDHCI_INT_CARD_REM);
+
+       if (_regs->interrupt_status & 7) {
+               _regs->software_reset |= 1 << 1;
+               while (_regs->command);
+       }
+
+       int16_t erorr_status = _regs->interrupt_status;
+       _regs->interrupt_status &= ~(erorr_status);
+}
+
+
+int32
+sdhci_generic_interrupt(void* data)
+{
+       TRACE("interrupt function called\n");
+       sdhci_pci_mmc_bus_info* bus = (sdhci_pci_mmc_bus_info*)data;
+
+       uint16_t intmask, card_present;
+
+       intmask = bus->_regs->slot_interrupt_status;
+
+       if (intmask == 0 || intmask == 0xffffffff) {
+               TRACE("invalid command interrupt\n");
+
+               return B_UNHANDLED_INTERRUPT;
+       }
+
+       // handling card presence interrupt
+       if (intmask & (SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM)) {
+               card_present = ((intmask & SDHCI_INT_CARD_INS) != 0);
+               bus->_regs->interrupt_status_enable &= ~(SDHCI_INT_CARD_INS
+                       | SDHCI_INT_CARD_REM);
+               bus->_regs->interrupt_signal_enable &= ~(SDHCI_INT_CARD_INS
+                       | SDHCI_INT_CARD_REM);
+
+               bus->_regs->interrupt_status_enable |= card_present
+                       ? SDHCI_INT_CARD_REM : SDHCI_INT_CARD_INS;
+               bus->_regs->interrupt_signal_enable |= card_present
+                       ? SDHCI_INT_CARD_REM : SDHCI_INT_CARD_INS;
+
+               bus->_regs->interrupt_status |= (intmask &
+                       (SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM));
+               TRACE("Card presence interrupt handled\n");
+
+               return B_HANDLED_INTERRUPT;
+       }
+
+       // handling command interrupt
+       if (intmask & SDHCI_INT_CMD_MASK) {
+               TRACE("interrupt status error: %d\n", 
bus->_regs->interrupt_status);
+               bus->_regs->interrupt_status |= (intmask & SDHCI_INT_CMD_MASK);
+               TRACE("Command interrupt handled\n");
+
+               return B_HANDLED_INTERRUPT;
+       }
+
+       // handling bus power interrupt
+       if (intmask & SDHCI_INT_BUS_POWER) {
+               bus->_regs->interrupt_status |= SDHCI_INT_BUS_POWER;
+               TRACE("card is consuming too much power\n");
+
+               return B_HANDLED_INTERRUPT;
+       }
+
+       intmask &= ~(SDHCI_INT_BUS_POWER | SDHCI_INT_CARD_INS
+               |SDHCI_INT_CARD_REM | SDHCI_INT_CMD_MASK);
+
+}
+
+
+static void
+uninit_bus(void* bus_cookie)
+{
+       sdhci_pci_mmc_bus_info* bus = (sdhci_pci_mmc_bus_info*)bus_cookie;
+       delete bus;
+}
+
+
+static void
+bus_removed(void* bus_cookie)
+{
+       return;
+}
+
+
+static status_t
+register_child_devices(void* cookie)
+{
+       CALLED();
+       device_node* node = (device_node*)cookie;
+       device_node* parent = gDeviceManager->get_parent_node(node);
+       pci_device_module_info* pci;
+       pci_device* device;
+       uint8 slots_count, bar, slotsInfo;
+
+       gDeviceManager->get_driver(parent, (driver_module_info**)&pci,
+               (void**)&device);
+       uint16 pciSubDeviceId = pci->read_pci_config(device, PCI_subsystem_id, 
2);
+       slotsInfo = pci->read_pci_config(device, SDHCI_PCI_SLOT_INFO, 1);
+       bar = SDHCI_PCI_SLOT_INFO_FIRST_BASE_INDEX(slotsInfo);
+       slots_count = SDHCI_PCI_SLOTS(slotsInfo);
+
+       char prettyName[25];
+
+       if (slots_count > 6 || bar > 5) {
+               TRACE("Invalid slots count: %d or BAR count: %d \n", 
slots_count, bar);
+               return B_BAD_VALUE;
+       }
+
+       for (uint8_t slot = 0; slot <= slots_count; slot++) {
+
+               bar = bar + slot;
+               sprintf(prettyName, "SDHC bus %" B_PRIu16 " slot %"
+                       B_PRIu8, pciSubDeviceId, slot);
+               device_attr attrs[] = {
+                       // properties of this controller for SDHCI bus manager
+                       { B_DEVICE_PRETTY_NAME, B_STRING_TYPE,
+                               { string: prettyName }},
+                       { B_DEVICE_FIXED_CHILD, B_STRING_TYPE,
+                               {string: SDHCI_BUS_CONTROLLER_MODULE_NAME}},
+                       {SDHCI_DEVICE_TYPE_ITEM, B_UINT16_TYPE,
+                               { ui16: pciSubDeviceId}},
+                       {B_DEVICE_BUS, B_STRING_TYPE,{string: "mmc"}},
+                       {SLOT_NUMBER, B_UINT8_TYPE,
+                               { ui8: slot}},
+                       {BAR_INDEX, B_UINT8_TYPE,
+                               { ui8: bar}},
+                       { NULL }
+               };
+               if (gDeviceManager->register_node(node, 
SDHCI_PCI_MMC_BUS_MODULE_NAME,
+                               attrs, NULL, &node) != B_OK)
+                       return B_BAD_VALUE;
+       }
+       return B_OK;
+}
+
+
+static status_t
+init_device(device_node* node, void** device_cookie)
+{
+       CALLED();
+       *device_cookie = node;
+       return B_OK;
+}
+
+
+static status_t
+register_device(device_node* parent)
+{
+       device_attr attrs[] = {
+               {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "SDHC PCI 
controller"}},
+               {}
+       };
+
+       return gDeviceManager->register_node(parent, 
SDHCI_PCI_DEVICE_MODULE_NAME,
+               attrs, NULL, NULL);
+}
+
+
+static float
+supports_device(device_node* parent)
+{
+       CALLED();
+       const char* bus;
+       uint16 type, subType;
+       uint8 pciSubDeviceId;
+
+       // 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)
+               return -1;
+
+       if (strcmp(bus, "pci") != 0)
+               return 0.0f;
+
+       if (type == PCI_base_peripheral) {
+               if (subType != PCI_sd_host)
+                       return 0.0f;
+
+               pci_device_module_info* pci;
+               pci_device* device;
+               gDeviceManager->get_driver(parent, (driver_module_info**)&pci,
+                       (void**)&device);
+               pciSubDeviceId = pci->read_pci_config(device, PCI_revision, 1);
+               TRACE("SDHCI Device found! Subtype: 0x%04x, type: 0x%04x\n",
+                       subType, type);
+               return 0.8f;
+       }
+
+       return 0.0f;
+}
+
+
+module_dependency module_dependencies[] = {
+       { SDHCI_BUS_CONTROLLER_MODULE_NAME, 
(module_info**)&gSDHCIDeviceController},
+       { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager },
+       {}
+};
+
+
+static sdhci_mmc_bus_interface gSDHCIPCIDeviceModule = {
+       {
+               {
+                       SDHCI_PCI_MMC_BUS_MODULE_NAME,
+                       0,
+                       NULL
+               },
+               NULL,   // supports device
+               NULL,   // register device
+               init_bus,
+               uninit_bus,
+               NULL,   // register child devices
+               NULL,   // rescan
+               bus_removed,
+       }
+};
+
+
+static driver_module_info sSDHCIDevice = {
+       {
+               SDHCI_PCI_DEVICE_MODULE_NAME,
+               0,
+               NULL
+       },
+       supports_device,
+       register_device,
+       init_device,
+       NULL,   // uninit
+       register_child_devices,
+       NULL,   // rescan
+       NULL,   // device removed
+};
+
+
+module_info* modules[] = {
+       (module_info* )&sSDHCIDevice,
+       (module_info* )&gSDHCIPCIDeviceModule,
+       NULL
+};
diff --git a/src/add-ons/kernel/busses/mmc/sdhci_pci.h 
b/src/add-ons/kernel/busses/mmc/sdhci_pci.h
new file mode 100644
index 0000000000..1d493f3906
--- /dev/null
+++ b/src/add-ons/kernel/busses/mmc/sdhci_pci.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2018 Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             B Krishnan Iyer, krishnaniyer97@xxxxxxxxx
+ */
+#ifndef _SDHCI_PCI_H
+#define _SDHCI_PCI_H
+
+
+#include <device_manager.h>
+#include <KernelExport.h>
+
+
+#define SDHCI_PCI_SLOT_INFO                                                    
0x40
+#define SDHCI_PCI_SLOTS(x)                                                     
        ((( x >> 4) & 7))
+#define SDHCI_PCI_SLOT_INFO_FIRST_BASE_INDEX(x)                        (( x ) 
& 7)
+
+#define SDHCI_DEVICE_TYPE_ITEM                                                 
        "sdhci/type"
+#define SDHCI_BUS_TYPE_NAME                                                    
"bus/sdhci/v1"
+
+#define SDHCI_CARD_DETECT                                                      
        1 << 16
+
+#define SDHCI_SOFTWARE_RESET_ALL                                               
1 << 0
+
+#define SDHCI_BASE_CLOCK_FREQ(x)                                               
((x >> 8) & 63)
+#define SDHCI_VOLTAGE_SUPPORTED(x)                      ((x >> 24) & 7)
+#define SDHCI_VOLTAGE_SUPPORTED_33(x)                   ((x >> 24) & 1)
+#define SDHCI_VOLTAGE_SUPPORTED_30(x)                          ((x >> 24) & 3)
+#define SDHCI_VOLTAGE_SUPPORT_33                                               
7 << 1
+#define SDHCI_VOLTAGE_SUPPORT_30                                               
6 << 1
+#define SDHCI_VOLTAGE_SUPPORT_18                                               
5 << 1
+#define SDHCI_CARD_INSERTED(x)                                                 
((x >> 16) & 1)
+#define SDHCI_BASE_CLOCK_DIV_1                                                 
0 << 8
+#define SDHCI_BASE_CLOCK_DIV_2                                                 
1 << 8
+#define SDHCI_BASE_CLOCK_DIV_4                                                 
2 << 8
+#define SDHCI_BASE_CLOCK_DIV_8                                                 
4 << 8
+#define SDHCI_BASE_CLOCK_DIV_16                                                
        8 << 8
+#define SDHCI_BASE_CLOCK_DIV_32                                                
        16 << 8
+#define SDHCI_BASE_CLOCK_DIV_64                                                
        32 << 8
+#define SDHCI_BASE_CLOCK_DIV_128                                               
64 << 8
+#define SDHCI_BASE_CLOCK_DIV_256                                               
128 << 8
+#define SDHCI_INTERNAL_CLOCK_ENABLE                                            
1 << 0
+#define SDHCI_INTERNAL_CLOCK_STABLE                                            
1 << 1
+#define SDHCI_SD_CLOCK_ENABLE                                                  
1 << 2
+#define SDHCI_SD_CLOCK_DISABLE                                                 
~(1 << 2)
+#define SDHCI_CLR_FREQ_SEL                                                     
    ~(255 << 8)
+#define SDHCI_BUS_POWER_ON                                                     
    1
+#define SDHCI_RESPONSE_R1                               2
+#define SDHCI_CMD_CRC_EN                                1 << 3
+#define SDHCI_CMD_INDEX_EN                              1 << 4
+#define SDHCI_CMD_0                                     ~(63 << 8)
+/* Interrupt registers */
+#define SDHCI_INT_CMD_CMP              0x00000001              // command 
complete enable
+#define SDHCI_INT_TRANS_CMP            0x00000002              // transfer 
complete enable
+#define SDHCI_INT_CARD_INS             0x00000040              // card 
insertion enable
+#define SDHCI_INT_CARD_REM             0x00000080              // card removal 
enable
+#define SDHCI_INT_TIMEOUT              0x00010000              // Timeout error
+#define SDHCI_INT_CRC                  0x00020000              // CRC error
+#define SDHCI_INT_END_BIT              0x00040000              // end bit error
+#define SDHCI_INT_INDEX                0x00080000              // index error
+#define SDHCI_INT_BUS_POWER            0x00800000              // power fail
+
+#define         SDHCI_INT_CMD_ERROR_MASK       (SDHCI_INT_TIMEOUT | \
+               SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX)
+
+#define SDHCI_INT_CMD_MASK     (SDHCI_INT_CMD_CMP | SDHCI_INT_CMD_ERROR_MASK)
+
+
+struct registers {
+       volatile uint32_t system_address;
+       volatile uint16_t block_size;
+       volatile uint16_t block_count;
+       volatile uint32_t argument;
+       volatile uint16_t transfer_mode;
+       volatile uint16_t command;
+       volatile uint32_t response0;
+       volatile uint32_t response2;
+       volatile uint32_t response4;
+       volatile uint32_t response6;
+       volatile uint32_t buffer_data_port;
+       volatile uint32_t present_state;
+       volatile uint8_t host_control;
+       volatile uint8_t power_control;
+       volatile uint8_t block_gap_control;
+       volatile uint8_t wakeup_control;
+       volatile uint16_t clock_control;
+       volatile uint8_t timeout_control;
+       volatile uint8_t software_reset;
+       volatile uint32_t interrupt_status;
+       volatile uint32_t interrupt_status_enable;
+       volatile uint32_t interrupt_signal_enable;
+       volatile uint16_t auto_cmd12_error_status;
+       volatile uint16_t : 16;
+       volatile uint32_t capabilities;
+       volatile uint32_t capabilities_rsvd;
+       volatile uint32_t max_current_capabilities;
+       volatile uint32_t max_current_capabilities_rsvd;
+       volatile uint64_t padding[21];
+       volatile uint32_t : 32;
+       volatile uint16_t slot_interrupt_status;
+       volatile uint16_t host_control_version;
+} __attribute__((packed));
+
+typedef void* sdhci_mmc_bus;
+
+#define DELAY(n)       snooze(n)
+
+#define SDHCI_BUS_CONTROLLER_MODULE_NAME "bus_managers/mmc_bus/driver_v1"
+
+#define        MMC_BUS_MODULE_NAME "bus_managers/mmc_bus/device/v1"
+
+static void sdhci_register_dump(uint8_t, struct registers*);
+static void sdhci_reset(struct registers*);
+static void sdhci_set_clock(struct registers*, uint16_t);
+static void sdhci_set_power(struct registers*);
+static void sdhci_stop_clock(struct registers*);
+void sdhci_error_interrupt_recovery(struct registers*);
+
+status_t sdhci_generic_interrupt(void*);
+
+typedef struct {
+       driver_module_info info;
+
+} sdhci_mmc_bus_interface;
+
+
+#endif /*_SDHCI_PCI_H*/
diff --git a/src/add-ons/kernel/drivers/disk/Jamfile 
b/src/add-ons/kernel/drivers/disk/Jamfile
index d6ce88a04a..9dfc9029e1 100644
--- a/src/add-ons/kernel/drivers/disk/Jamfile
+++ b/src/add-ons/kernel/drivers/disk/Jamfile
@@ -2,6 +2,7 @@ SubDir HAIKU_TOP src add-ons kernel drivers disk ;
 
 SubInclude HAIKU_TOP src add-ons kernel drivers disk floppy ;
 SubInclude HAIKU_TOP src add-ons kernel drivers disk norflash ;
+SubInclude HAIKU_TOP src add-ons kernel drivers disk mmc ;
 SubInclude HAIKU_TOP src add-ons kernel drivers disk scsi ;
 SubInclude HAIKU_TOP src add-ons kernel drivers disk usb ;
-SubInclude HAIKU_TOP src add-ons kernel drivers disk virtual ;
+SubInclude HAIKU_TOP src add-ons kernel drivers disk virtual ;
\ No newline at end of file
diff --git a/src/add-ons/kernel/drivers/disk/mmc/Jamfile 
b/src/add-ons/kernel/drivers/disk/mmc/Jamfile
new file mode 100644
index 0000000000..bb603575c9
--- /dev/null
+++ b/src/add-ons/kernel/drivers/disk/mmc/Jamfile
@@ -0,0 +1,8 @@
+SubDir HAIKU_TOP src add-ons kernel drivers disk mmc ;
+
+UsePrivateKernelHeaders ;
+SubDirHdrs $(HAIKU_TOP) src system kernel device_manager ;
+
+KernelAddon mmc_disk :
+       mmc_disk.cpp
+;
diff --git a/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.cpp 
b/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.cpp
new file mode 100644
index 0000000000..ccccc3550a
--- /dev/null
+++ b/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2018 Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             B Krishnan Iyer, krishnaniyer97@xxxxxxxxx
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "mmc_disk.h"
+
+#include <drivers/device_manager.h>
+#include <drivers/KernelExport.h>
+#include <drivers/Drivers.h>
+#include <kernel/OS.h>
+
+// #include <fs/devfs.h>
+
+#define TRACE_MMC_DISK
+#ifdef TRACE_MMC_DISK
+#      define TRACE(x...) dprintf("mmc_disk: " x)
+#else
+#      define TRACE(x...) ;
+#endif
+#define ERROR(x...)                    dprintf("\33[33mmc_disk:\33[0m " x)
+#define CALLED()                       TRACE("CALLED %s\n", 
__PRETTY_FUNCTION__)
+
+#define MMC_DISK_DRIVER_MODULE_NAME "drivers/disk/mmc/mmc_disk/driver_v1"
+#define MMC_DISK_DEVICE_MODULE_NAME "drivers/disk/mmc/mmc_disk/device_v1"
+#define MMC_DEVICE_ID_GENERATOR "mmc/device_id"
+
+static device_manager_info* sDeviceManager;
+
+
+static float
+mmc_disk_supports_device(device_node* parent)
+{
+       CALLED();
+       const char* bus;
+       // uint16 deviceType;
+
+       if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus,
+                       true) != B_OK)
+               return -1;
+
+       if (strcmp(bus, "mmc") != 0) {
+               TRACE("bus value %s, parent: %p\n",bus, parent);
+               return 0.0;
+       }
+       // Used to check the device type but later we have attached an
+       // attribute(mmc) to the bus. Not a compulsion to use this condition
+       #if 0
+       if (sDeviceManager->get_attr_uint16(parent, SDHCI_DEVICE_TYPE_ITEM,
+                       &deviceType, true) != B_OK)
+       {
+               TRACE(" Inavlid device type, bus found: %s and attr val %d\n",
+                               bus, deviceType);
+               return 0.0;
+       }
+       #endif
+       TRACE("sdhci device found, parent: %p\n", parent);
+
+       return 0.8;
+}
+
+
+static status_t
+mmc_disk_register_device(device_node* node)
+{
+       CALLED();
+
+       device_attr attrs[] = {
+               { NULL }
+       };
+
+       return sDeviceManager->register_node(node
+               , MMC_DISK_DRIVER_MODULE_NAME, attrs, NULL, NULL);
+}
+
+
+static status_t
+mmc_disk_init_driver(device_node* node, void** cookie)
+{
+       CALLED();
+       mmc_disk_driver_info* info = (mmc_disk_driver_info*)malloc(
+               sizeof(mmc_disk_driver_info));
+
+       if (info == NULL)
+               return B_NO_MEMORY;
+
+       memset(info, 0, sizeof(*info));
+
+       info->node = node;
+
+       *cookie = info;
+       return B_OK;
+}
+
+
+static void
+mmc_disk_uninit_driver(void* _cookie)
+{
+       CALLED();
+       mmc_disk_driver_info* info = (mmc_disk_driver_info*)_cookie;
+       free(info);
+}
+
+
+static status_t
+mmc_disk_register_child_devices(void* _cookie)
+{
+       CALLED();
+       mmc_disk_driver_info* info = (mmc_disk_driver_info*)_cookie;
+       status_t status;
+
+       int32 id = sDeviceManager->create_id(MMC_DEVICE_ID_GENERATOR);
+       if (id < 0)
+               return id;
+
+       char name[64];
+       snprintf(name, sizeof(name), "disk/mmc/%" B_PRId32 "/raw", id);
+
+       status = sDeviceManager->publish_device(info->node, name,
+               MMC_DISK_DEVICE_MODULE_NAME);
+
+       return status;
+}
+
+
+module_dependency module_dependencies[] = {
+       {B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager},
+       {}
+};
+
+
+struct driver_module_info sMMCDiskDriver = {
+       {
+               MMC_DISK_DRIVER_MODULE_NAME,
+               0,
+               NULL
+       },
+       mmc_disk_supports_device,
+       mmc_disk_register_device,
+       mmc_disk_init_driver,
+       mmc_disk_uninit_driver,
+       mmc_disk_register_child_devices,
+       NULL, // mmc_disk_rescan_child_devices,
+       NULL,
+};
+
+
+module_info* modules[] = {
+       (module_info*)&sMMCDiskDriver,
+       NULL
+};
diff --git a/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.h 
b/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.h
new file mode 100644
index 0000000000..990e104aff
--- /dev/null
+++ b/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2018 Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             B Krishnan Iyer, krishnaniyer97@xxxxxxxxx
+ */
+#ifndef _MMC_DISK_H
+#define _MMC_DISK_H
+
+
+#include <device_manager.h>
+#include <KernelExport.h>
+
+
+#define SDHCI_DEVICE_TYPE_ITEM "sdhci/type"
+
+typedef struct {
+       device_node*    node;
+       status_t                media_status;
+} mmc_disk_driver_info;
+
+
+#endif /*_MMC_DISK_H*/
\ No newline at end of file
diff --git a/src/system/kernel/device_manager/device_manager.cpp 
b/src/system/kernel/device_manager/device_manager.cpp
index f42a03094d..233f9b6fd4 100644
--- a/src/system/kernel/device_manager/device_manager.cpp
+++ b/src/system/kernel/device_manager/device_manager.cpp
@@ -42,7 +42,6 @@
 #      define TRACE(a) ;
 #endif
 
-
 #define DEVICE_MANAGER_ROOT_NAME "system/devices_root/driver_v1"
 #define DEVICE_MANAGER_GENERIC_NAME "system/devices_generic/driver_v1"
 
@@ -1538,7 +1537,9 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& 
_path)
                if (get_attr_uint16(this, B_DEVICE_TYPE, &type, false) != B_OK
                        || get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, 
false)
                                        != B_OK)
+               {
                        generic = true;
+               }
 
                get_attr_uint16(this, B_DEVICE_INTERFACE, &interface, false);
 
@@ -1599,6 +1600,16 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& 
_path)
                                                break;
                                }
                                break;
+                       case PCI_base_peripheral:
+                               switch (subType) {
+                                       case PCI_sd_host:
+                                               _AddPath(*stack, "busses", 
"mmc");
+                                               break;
+                                       default:
+                                               _AddPath(*stack, "drivers");
+                                               break;
+                               }
+                               break;
                        default:
                                if (sRootNode == this) {
                                        _AddPath(*stack, "busses/pci");
@@ -1885,7 +1896,8 @@ device_node::Probe(const char* devicePath, uint32 
updateCycle)
                        // Check if this node matches the device path
                        // TODO: maybe make this extendible via settings file?
                        if (!strcmp(devicePath, "disk")) {
-                               matches = type == PCI_mass_storage;
+                               matches = type == PCI_mass_storage
+                                       && (type == PCI_base_peripheral || 
subType == PCI_sd_host);
                        } else if (!strcmp(devicePath, "audio")) {
                                matches = type == PCI_multimedia
                                        && (subType == PCI_audio || subType == 
PCI_hd_audio);


Other related posts:

  • » [haiku-commits] haiku: hrev52171 - in src/add-ons/kernel: busses/mmc bus_managers/mmc drivers/disk/mmc - Alexander von Gluck IV