xref: /haiku/src/add-ons/kernel/drivers/disk/mmc/mmc_disk.cpp (revision 21258e2674226d6aa732321b6f8494841895af5f)
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 <string.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <ctype.h>
12 #include "mmc_disk.h"
13 
14 #include <drivers/device_manager.h>
15 #include <drivers/KernelExport.h>
16 #include <drivers/Drivers.h>
17 #include <kernel/OS.h>
18 
19 // #include <fs/devfs.h>
20 
21 #define TRACE_MMC_DISK
22 #ifdef TRACE_MMC_DISK
23 #	define TRACE(x...) dprintf("mmc_disk: " x)
24 #else
25 #	define TRACE(x...) ;
26 #endif
27 #define ERROR(x...)			dprintf("\33[33mmc_disk:\33[0m " x)
28 #define CALLED() 			TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
29 
30 #define MMC_DISK_DRIVER_MODULE_NAME "drivers/disk/mmc/mmc_disk/driver_v1"
31 #define MMC_DISK_DEVICE_MODULE_NAME "drivers/disk/mmc/mmc_disk/device_v1"
32 #define MMC_DEVICE_ID_GENERATOR "mmc/device_id"
33 
34 static device_manager_info* sDeviceManager;
35 
36 
37 static float
38 mmc_disk_supports_device(device_node* parent)
39 {
40 	CALLED();
41 	const char* bus;
42 	// uint16 deviceType;
43 
44 	if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus,
45 			true) != B_OK)
46 		return -1;
47 
48 	if (strcmp(bus, "mmc") != 0) {
49 		TRACE("bus value %s, parent: %p\n",bus, parent);
50 		return 0.0;
51 	}
52 	// Used to check the device type but later we have attached an
53 	// attribute(mmc) to the bus. Not a compulsion to use this condition
54 	#if 0
55 	if (sDeviceManager->get_attr_uint16(parent, SDHCI_DEVICE_TYPE_ITEM,
56 			&deviceType, true) != B_OK)
57 	{
58 		TRACE(" Inavlid device type, bus found: %s and attr val %d\n",
59 				bus, deviceType);
60 		return 0.0;
61 	}
62 	#endif
63 	TRACE("sdhci device found, parent: %p\n", parent);
64 
65 	return 0.8;
66 }
67 
68 
69 static status_t
70 mmc_disk_register_device(device_node* node)
71 {
72 	CALLED();
73 
74 	device_attr attrs[] = {
75 		{ NULL }
76 	};
77 
78 	return sDeviceManager->register_node(node
79 		, MMC_DISK_DRIVER_MODULE_NAME, attrs, NULL, NULL);
80 }
81 
82 
83 static status_t
84 mmc_disk_init_driver(device_node* node, void** cookie)
85 {
86 	CALLED();
87 	mmc_disk_driver_info* info = (mmc_disk_driver_info*)malloc(
88 		sizeof(mmc_disk_driver_info));
89 
90 	if (info == NULL)
91 		return B_NO_MEMORY;
92 
93 	memset(info, 0, sizeof(*info));
94 
95 	info->node = node;
96 
97 	*cookie = info;
98 	return B_OK;
99 }
100 
101 
102 static void
103 mmc_disk_uninit_driver(void* _cookie)
104 {
105 	CALLED();
106 	mmc_disk_driver_info* info = (mmc_disk_driver_info*)_cookie;
107 	free(info);
108 }
109 
110 
111 static status_t
112 mmc_disk_register_child_devices(void* _cookie)
113 {
114 	CALLED();
115 	mmc_disk_driver_info* info = (mmc_disk_driver_info*)_cookie;
116 	status_t status;
117 
118 	int32 id = sDeviceManager->create_id(MMC_DEVICE_ID_GENERATOR);
119 	if (id < 0)
120 		return id;
121 
122 	char name[64];
123 	snprintf(name, sizeof(name), "disk/mmc/%" B_PRId32 "/raw", id);
124 
125 	status = sDeviceManager->publish_device(info->node, name,
126 		MMC_DISK_DEVICE_MODULE_NAME);
127 
128 	return status;
129 }
130 
131 
132 module_dependency module_dependencies[] = {
133 	{B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager},
134 	{}
135 };
136 
137 
138 struct driver_module_info sMMCDiskDriver = {
139 	{
140 		MMC_DISK_DRIVER_MODULE_NAME,
141 		0,
142 		NULL
143 	},
144 	mmc_disk_supports_device,
145 	mmc_disk_register_device,
146 	mmc_disk_init_driver,
147 	mmc_disk_uninit_driver,
148 	mmc_disk_register_child_devices,
149 	NULL, // mmc_disk_rescan_child_devices,
150 	NULL,
151 };
152 
153 
154 module_info* modules[] = {
155 	(module_info*)&sMMCDiskDriver,
156 	NULL
157 };
158