1/* 2 * Copyright 2018-2021 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * B Krishnan Iyer, krishnaniyer97@gmail.com 7 * Adrien Destugues, pulkomandy@pulkomandy.tk 8 */ 9#include "mmc_bus.h" 10 11 12#define MMC_BUS_DEVICE_NAME "bus_managers/mmc_bus/device/v1" 13 14 15device_manager_info* gDeviceManager = NULL; 16 17 18static status_t 19mmc_bus_init(device_node* node, void** _device) 20{ 21 CALLED(); 22 MMCBus* device = new(std::nothrow) MMCBus(node); 23 if (device == NULL) { 24 ERROR("Unable to allocate MMC bus\n"); 25 return B_NO_MEMORY; 26 } 27 28 status_t result = device->InitCheck(); 29 if (result != B_OK) { 30 TRACE("failed to set up mmc bus device object\n"); 31 return result; 32 } 33 TRACE("MMC bus object created\n"); 34 35 *_device = device; 36 return B_OK; 37} 38 39 40static void 41mmc_bus_uninit(void* _device) 42{ 43 CALLED(); 44 MMCBus* device = (MMCBus*)_device; 45 delete device; 46} 47 48 49static status_t 50mmc_bus_register_child(void* _device) 51{ 52 // Nothing to do, child devices are registered by the scanning thread 53 return B_OK; 54} 55 56 57static void 58mmc_bus_removed(void* _device) 59{ 60 CALLED(); 61} 62 63 64status_t 65mmc_bus_added_device(device_node* parent) 66{ 67 CALLED(); 68 69 device_attr attributes[] = { 70 { B_DEVICE_BUS, B_STRING_TYPE, { .string = "mmc"}}, 71 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { .string = "MMC bus root"}}, 72 { NULL } 73 }; 74 75 return gDeviceManager->register_node(parent, MMC_BUS_DEVICE_NAME, 76 attributes, NULL, NULL); 77} 78 79 80static status_t 81mmc_bus_execute_command(device_node* node, void* cookie, uint16_t rca, 82 uint8_t command, uint32_t argument, uint32_t* result) 83{ 84 TRACE("In mmc_bus_execute_command\n"); 85 86 MMCBus* bus = (MMCBus*)cookie; 87 88 bus->AcquireBus(); 89 status_t error = bus->ExecuteCommand(rca, command, argument, result); 90 bus->ReleaseBus(); 91 92 return error; 93} 94 95 96static status_t 97mmc_bus_do_io(device_node* node, void* cookie, uint16_t rca, uint8_t command, 98 IOOperation* operation, bool offsetAsSectors) 99{ 100 MMCBus* bus = (MMCBus*)cookie; 101 status_t result = B_OK; 102 103 bus->AcquireBus(); 104 result = bus->DoIO(rca, command, operation, offsetAsSectors); 105 bus->ReleaseBus(); 106 107 return result; 108} 109 110 111static void 112mmc_bus_set_width(device_node* node, void* cookie, int width) 113{ 114 MMCBus* bus = (MMCBus*)cookie; 115 116 bus->AcquireBus(); 117 bus->SetBusWidth(width); 118 bus->ReleaseBus(); 119} 120 121 122static status_t 123std_ops(int32 op, ...) 124{ 125 switch (op) { 126 case B_MODULE_INIT: 127 // Nothing to do 128 case B_MODULE_UNINIT: 129 return B_OK; 130 131 default: 132 break; 133 } 134 135 return B_ERROR; 136} 137 138 139driver_module_info mmc_bus_device_module = { 140 { 141 MMC_BUS_DEVICE_NAME, 142 0, 143 std_ops 144 }, 145 NULL, // supported devices 146 NULL, // register node 147 mmc_bus_init, 148 mmc_bus_uninit, 149 mmc_bus_register_child, 150 NULL, // rescan 151 mmc_bus_removed, 152 NULL, // suspend 153 NULL // resume 154}; 155 156 157mmc_device_interface mmc_bus_controller_module = { 158 { 159 { 160 MMC_BUS_MODULE_NAME, 161 0, 162 &std_ops 163 }, 164 165 NULL, // supported devices 166 mmc_bus_added_device, 167 NULL, 168 NULL, 169 NULL 170 }, 171 mmc_bus_execute_command, 172 mmc_bus_do_io, 173 mmc_bus_set_width 174}; 175 176 177module_dependency module_dependencies[] = { 178 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager }, 179 {} 180}; 181 182 183module_info* modules[] = { 184 (module_info*)&mmc_bus_controller_module, 185 (module_info*)&mmc_bus_device_module, 186 NULL 187}; 188