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
mmc_bus_init(device_node * node,void ** _device)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
mmc_bus_uninit(void * _device)41 mmc_bus_uninit(void* _device)
42 {
43 CALLED();
44 MMCBus* device = (MMCBus*)_device;
45 delete device;
46 }
47
48
49 static status_t
mmc_bus_register_child(void * _device)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
mmc_bus_removed(void * _device)58 mmc_bus_removed(void* _device)
59 {
60 CALLED();
61 }
62
63
64 status_t
mmc_bus_added_device(device_node * parent)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
mmc_bus_execute_command(device_node * node,void * cookie,uint16_t rca,uint8_t command,uint32_t argument,uint32_t * result)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
mmc_bus_do_io(device_node * node,void * cookie,uint16_t rca,uint8_t command,IOOperation * operation,bool offsetAsSectors)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
mmc_bus_set_width(device_node * node,void * cookie,int width)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
std_ops(int32 op,...)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