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 15 device_manager_info* gDeviceManager = NULL; 16 17 18 static status_t 19 mmc_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 40 static void 41 mmc_bus_uninit(void* _device) 42 { 43 CALLED(); 44 MMCBus* device = (MMCBus*)_device; 45 delete device; 46 } 47 48 49 static status_t 50 mmc_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 57 static void 58 mmc_bus_removed(void* _device) 59 { 60 CALLED(); 61 } 62 63 64 status_t 65 mmc_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 80 static status_t 81 mmc_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 96 static status_t 97 mmc_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 111 static void 112 mmc_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 122 static status_t 123 std_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 139 driver_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 157 mmc_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 177 module_dependency module_dependencies[] = { 178 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager }, 179 {} 180 }; 181 182 183 module_info* modules[] = { 184 (module_info*)&mmc_bus_controller_module, 185 (module_info*)&mmc_bus_device_module, 186 NULL 187 }; 188