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