xref: /haiku/src/add-ons/kernel/bus_managers/mmc/mmc_module.cpp (revision d1fee57deec586903e32d05712a78c093323335f)
125b6a6f1Skrish_iyer /*
27a160a86SAdrien Destugues  * Copyright 2018-2021 Haiku, Inc. All rights reserved.
325b6a6f1Skrish_iyer  * Distributed under the terms of the MIT License.
425b6a6f1Skrish_iyer  *
525b6a6f1Skrish_iyer  * Authors:
625b6a6f1Skrish_iyer  *		B Krishnan Iyer, krishnaniyer97@gmail.com
77a160a86SAdrien Destugues  *		Adrien Destugues, pulkomandy@pulkomandy.tk
825b6a6f1Skrish_iyer  */
925b6a6f1Skrish_iyer #include "mmc_bus.h"
1025b6a6f1Skrish_iyer 
1125b6a6f1Skrish_iyer 
12ff76d2dfSAdrien Destugues #define	MMC_BUS_DEVICE_NAME "bus_managers/mmc_bus/device/v1"
13ff76d2dfSAdrien Destugues 
14ff76d2dfSAdrien Destugues 
1525b6a6f1Skrish_iyer device_manager_info* gDeviceManager = NULL;
1625b6a6f1Skrish_iyer 
1725b6a6f1Skrish_iyer 
1825b6a6f1Skrish_iyer static status_t
1925b6a6f1Skrish_iyer mmc_bus_init(device_node* node, void** _device)
2025b6a6f1Skrish_iyer {
2125b6a6f1Skrish_iyer 	CALLED();
2225b6a6f1Skrish_iyer 	MMCBus* device = new(std::nothrow) MMCBus(node);
2325b6a6f1Skrish_iyer 	if (device == NULL) {
2425b6a6f1Skrish_iyer 		ERROR("Unable to allocate MMC bus\n");
2525b6a6f1Skrish_iyer 		return B_NO_MEMORY;
2625b6a6f1Skrish_iyer 	}
2725b6a6f1Skrish_iyer 
2825b6a6f1Skrish_iyer 	status_t result = device->InitCheck();
2925b6a6f1Skrish_iyer 	if (result != B_OK) {
3025b6a6f1Skrish_iyer 		TRACE("failed to set up mmc bus device object\n");
3125b6a6f1Skrish_iyer 		return result;
3225b6a6f1Skrish_iyer 	}
3325b6a6f1Skrish_iyer 	TRACE("MMC bus object created\n");
3425b6a6f1Skrish_iyer 
3525b6a6f1Skrish_iyer 	*_device = device;
3625b6a6f1Skrish_iyer 	return B_OK;
3725b6a6f1Skrish_iyer }
3825b6a6f1Skrish_iyer 
3925b6a6f1Skrish_iyer 
4025b6a6f1Skrish_iyer static void
4125b6a6f1Skrish_iyer mmc_bus_uninit(void* _device)
4225b6a6f1Skrish_iyer {
4325b6a6f1Skrish_iyer 	CALLED();
4425b6a6f1Skrish_iyer 	MMCBus* device = (MMCBus*)_device;
4525b6a6f1Skrish_iyer 	delete device;
4625b6a6f1Skrish_iyer }
4725b6a6f1Skrish_iyer 
4825b6a6f1Skrish_iyer 
49dedbe94eSAdrien Destugues static status_t
50dedbe94eSAdrien Destugues mmc_bus_register_child(void* _device)
51dedbe94eSAdrien Destugues {
52dedbe94eSAdrien Destugues 	CALLED();
53dedbe94eSAdrien Destugues 	MMCBus* device = (MMCBus*)_device;
54dedbe94eSAdrien Destugues 	device->Rescan();
55dedbe94eSAdrien Destugues 	return B_OK;
56dedbe94eSAdrien Destugues }
57dedbe94eSAdrien Destugues 
58dedbe94eSAdrien Destugues 
5925b6a6f1Skrish_iyer static void
6025b6a6f1Skrish_iyer mmc_bus_removed(void* _device)
6125b6a6f1Skrish_iyer {
6225b6a6f1Skrish_iyer 	CALLED();
6325b6a6f1Skrish_iyer }
6425b6a6f1Skrish_iyer 
6525b6a6f1Skrish_iyer 
6625b6a6f1Skrish_iyer status_t
6725b6a6f1Skrish_iyer mmc_bus_added_device(device_node* parent)
6825b6a6f1Skrish_iyer {
6925b6a6f1Skrish_iyer 	CALLED();
7025b6a6f1Skrish_iyer 
7125b6a6f1Skrish_iyer 	device_attr attributes[] = {
72dedbe94eSAdrien Destugues 		{ B_DEVICE_BUS, B_STRING_TYPE, { string: "mmc"}},
73dedbe94eSAdrien Destugues 		{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "MMC bus root"}},
7425b6a6f1Skrish_iyer 		{ NULL }
7525b6a6f1Skrish_iyer 	};
7625b6a6f1Skrish_iyer 
77ff76d2dfSAdrien Destugues 	return gDeviceManager->register_node(parent, MMC_BUS_DEVICE_NAME,
7825b6a6f1Skrish_iyer 		attributes, NULL, NULL);
7925b6a6f1Skrish_iyer }
8025b6a6f1Skrish_iyer 
8125b6a6f1Skrish_iyer 
8225b6a6f1Skrish_iyer static status_t
8362eaf4c0SAdrien Destugues mmc_bus_execute_command(device_node* node, uint8_t command, uint32_t argument,
8462eaf4c0SAdrien Destugues 	uint32_t* result)
8562eaf4c0SAdrien Destugues {
8674b60970SAnarchos 	// FIXME store the parent cookie in the bus cookie or something instead of
8774b60970SAnarchos 	// getting/putting the parent each time.
8874b60970SAnarchos 	driver_module_info* mmc;
8962eaf4c0SAdrien Destugues 	void* cookie;
9062eaf4c0SAdrien Destugues 
9162eaf4c0SAdrien Destugues 	TRACE("In mmc_bus_execute_command\n");
9262eaf4c0SAdrien Destugues 	device_node* parent = gDeviceManager->get_parent_node(node);
9374b60970SAnarchos 	gDeviceManager->get_driver(parent, &mmc, &cookie);
9462eaf4c0SAdrien Destugues 	gDeviceManager->put_node(parent);
9562eaf4c0SAdrien Destugues 
9674b60970SAnarchos 	MMCBus* bus = (MMCBus*)cookie;
9774b60970SAnarchos 
9874b60970SAnarchos 	bus->AcquireBus();
9974b60970SAnarchos 	status_t error = bus->ExecuteCommand(command, argument, result);
10074b60970SAnarchos 	bus->ReleaseBus();
10174b60970SAnarchos 	return error;
10274b60970SAnarchos }
10374b60970SAnarchos 
10474b60970SAnarchos 
10574b60970SAnarchos static status_t
1069a37366bSAdrien Destugues mmc_bus_do_io(device_node* node, uint16_t rca, uint8_t command,
107*d1fee57dSAdrien Destugues 	IOOperation* operation, bool offsetAsSectors)
10874b60970SAnarchos {
10974b60970SAnarchos 	driver_module_info* mmc;
11074b60970SAnarchos 	void* cookie;
11174b60970SAnarchos 
1127a160a86SAdrien Destugues 	// FIXME store the parent cookie in the bus cookie or something instead of
1137a160a86SAdrien Destugues 	// getting/putting the parent each time.
11474b60970SAnarchos 	device_node* parent = gDeviceManager->get_parent_node(node);
11574b60970SAnarchos 	gDeviceManager->get_driver(parent, &mmc, &cookie);
11674b60970SAnarchos 	gDeviceManager->put_node(parent);
11774b60970SAnarchos 
11874b60970SAnarchos 	MMCBus* bus = (MMCBus*)cookie;
11974b60970SAnarchos 	bus->AcquireBus();
1207a160a86SAdrien Destugues 	status_t result = B_OK;
1217a160a86SAdrien Destugues 
122*d1fee57dSAdrien Destugues 	result = bus->DoIO(rca, command, operation, offsetAsSectors);
1237a160a86SAdrien Destugues 
12474b60970SAnarchos 	bus->ReleaseBus();
12574b60970SAnarchos 	return result;
12662eaf4c0SAdrien Destugues }
12762eaf4c0SAdrien Destugues 
12862eaf4c0SAdrien Destugues 
12962eaf4c0SAdrien Destugues static status_t
13025b6a6f1Skrish_iyer std_ops(int32 op, ...)
13125b6a6f1Skrish_iyer {
13225b6a6f1Skrish_iyer 	switch (op) {
13325b6a6f1Skrish_iyer 		case B_MODULE_INIT:
13425b6a6f1Skrish_iyer 			// Nothing to do
13525b6a6f1Skrish_iyer 		case B_MODULE_UNINIT:
13625b6a6f1Skrish_iyer 			return B_OK;
13725b6a6f1Skrish_iyer 
13825b6a6f1Skrish_iyer 		default:
13925b6a6f1Skrish_iyer 			break;
14025b6a6f1Skrish_iyer 	}
14125b6a6f1Skrish_iyer 
14225b6a6f1Skrish_iyer 	return B_ERROR;
14325b6a6f1Skrish_iyer }
14425b6a6f1Skrish_iyer 
14525b6a6f1Skrish_iyer 
14625b6a6f1Skrish_iyer driver_module_info mmc_bus_device_module = {
14725b6a6f1Skrish_iyer 	{
148ff76d2dfSAdrien Destugues 		MMC_BUS_DEVICE_NAME,
14925b6a6f1Skrish_iyer 		0,
15025b6a6f1Skrish_iyer 		std_ops
15125b6a6f1Skrish_iyer 	},
15225b6a6f1Skrish_iyer 	NULL, // supported devices
15325b6a6f1Skrish_iyer 	NULL, // register node
15425b6a6f1Skrish_iyer 	mmc_bus_init,
15525b6a6f1Skrish_iyer 	mmc_bus_uninit,
156dedbe94eSAdrien Destugues 	mmc_bus_register_child,
15725b6a6f1Skrish_iyer 	NULL, // rescan
15825b6a6f1Skrish_iyer 	mmc_bus_removed,
15925b6a6f1Skrish_iyer 	NULL, // suspend
16025b6a6f1Skrish_iyer 	NULL // resume
16125b6a6f1Skrish_iyer };
16225b6a6f1Skrish_iyer 
16325b6a6f1Skrish_iyer 
16462eaf4c0SAdrien Destugues mmc_device_interface mmc_bus_controller_module = {
16562eaf4c0SAdrien Destugues 	{
16625b6a6f1Skrish_iyer 		{
167ff76d2dfSAdrien Destugues 			MMC_BUS_MODULE_NAME,
16825b6a6f1Skrish_iyer 			0,
16925b6a6f1Skrish_iyer 			&std_ops
17025b6a6f1Skrish_iyer 		},
17125b6a6f1Skrish_iyer 
17225b6a6f1Skrish_iyer 		NULL, // supported devices
17325b6a6f1Skrish_iyer 		mmc_bus_added_device,
17425b6a6f1Skrish_iyer 		NULL,
17525b6a6f1Skrish_iyer 		NULL,
17625b6a6f1Skrish_iyer 		NULL
17762eaf4c0SAdrien Destugues 	},
17874b60970SAnarchos 	mmc_bus_execute_command,
1797a160a86SAdrien Destugues 	mmc_bus_do_io
18025b6a6f1Skrish_iyer };
18125b6a6f1Skrish_iyer 
18225b6a6f1Skrish_iyer 
18325b6a6f1Skrish_iyer module_dependency module_dependencies[] = {
18425b6a6f1Skrish_iyer 	{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
18525b6a6f1Skrish_iyer 	{}
18625b6a6f1Skrish_iyer };
18725b6a6f1Skrish_iyer 
18825b6a6f1Skrish_iyer 
18925b6a6f1Skrish_iyer module_info* modules[] = {
19025b6a6f1Skrish_iyer 	(module_info*)&mmc_bus_controller_module,
19125b6a6f1Skrish_iyer 	(module_info*)&mmc_bus_device_module,
19225b6a6f1Skrish_iyer 	NULL
19325b6a6f1Skrish_iyer };
194