xref: /haiku/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp (revision 204dee708a999d5a71d0cb9497650ee7cef85d0a)
1 /*
2  * Copyright 2012, Haiku, Inc.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ithamar R. Adema <ithamar@upgrade-android.com>
7  */
8 
9 
10 #include <string.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <ctype.h>
14 
15 #include <drivers/device_manager.h>
16 #include <drivers/KernelExport.h>
17 #include <drivers/Drivers.h>
18 #include <kernel/OS.h>
19 
20 
21 //#define TRACE_NORFLASH
22 #ifdef TRACE_NORFLASH
23 #define TRACE(x...)	dprintf("nor: " x)
24 #else
25 #define TRACE(x...)
26 #endif
27 
28 
29 #define NORFLASH_DEVICE_MODULE_NAME	"drivers/disk/norflash/device_v1"
30 #define NORFLASH_DRIVER_MODULE_NAME	"drivers/disk/norflash/driver_v1"
31 
32 
33 #define NORFLASH_ADDR	0x00000000
34 
35 
36 struct nor_driver_info {
37 	device_node *node;
38 	size_t blocksize;
39 	size_t totalsize;
40 
41 	area_id id;
42 	void *mapped;
43 };
44 
45 
46 static device_manager_info *sDeviceManager;
47 
48 
49 static status_t
50 nor_init_device(void *_info, void **_cookie)
51 {
52 	TRACE("init_device\n");
53 	nor_driver_info *info = (nor_driver_info*)_info;
54 
55 	info->mapped = NULL;
56 	info->blocksize = 128 * 1024;
57 	info->totalsize = info->blocksize * 256;
58 
59 	info->id = map_physical_memory("NORFlash", NORFLASH_ADDR, info->totalsize, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &info->mapped);
60 	if (info->id < 0)
61 		return info->id;
62 
63 	*_cookie = info;
64 	return B_OK;
65 }
66 
67 
68 static void
69 nor_uninit_device(void *_cookie)
70 {
71 	TRACE("uninit_device\n");
72 	nor_driver_info *info = (nor_driver_info*)_cookie;
73 	if (info)
74 		delete_area(info->id);
75 }
76 
77 
78 static status_t
79 nor_open(void *deviceCookie, const char *path, int openMode,
80 	void **_cookie)
81 {
82 	TRACE("open(%s)\n", path);
83 	*_cookie = deviceCookie;
84 	return B_OK;
85 }
86 
87 
88 static status_t
89 nor_close(void *_cookie)
90 {
91 	TRACE("close()\n");
92 	return B_OK;
93 }
94 
95 
96 static status_t
97 nor_free(void *_cookie)
98 {
99 	TRACE("free()\n");
100 	return B_OK;
101 }
102 
103 
104 static status_t
105 nor_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
106 {
107 	nor_driver_info *info = (nor_driver_info*)cookie;
108 	TRACE("ioctl(%ld,%lu)\n", op, length);
109 
110 	switch (op) {
111 		case B_GET_GEOMETRY:
112 		{
113 			device_geometry *deviceGeometry = (device_geometry*)buffer;
114 			deviceGeometry->removable = false;
115 			deviceGeometry->bytes_per_sector = info->blocksize;
116 			deviceGeometry->sectors_per_track = info->totalsize / info->blocksize;
117 			deviceGeometry->cylinder_count = 1;
118 			deviceGeometry->head_count = 1;
119 			deviceGeometry->device_type = B_DISK;
120 			deviceGeometry->removable = false;
121 			deviceGeometry->read_only = true;
122 			deviceGeometry->write_once = false;
123 			return B_OK;
124 		}
125 		break;
126 
127 		case B_GET_DEVICE_NAME:
128 			strlcpy((char*)buffer, "NORFlash", length);
129 			break;
130 	}
131 
132 	return B_ERROR;
133 }
134 
135 
136 static status_t
137 nor_read(void *_cookie, off_t position, void *data, size_t *numbytes)
138 {
139 	nor_driver_info *info = (nor_driver_info*)_cookie;
140 	TRACE("read(%Ld,%lu)\n", position, *numbytes);
141 
142 	if (position + *numbytes > info->totalsize)
143 		*numbytes = info->totalsize - (position + *numbytes);
144 
145 	memcpy(data, info->mapped + position, *numbytes);
146 
147 	return B_OK;
148 }
149 
150 
151 static status_t
152 nor_write(void *_cookie, off_t position, const void *data, size_t *numbytes)
153 {
154 	TRACE("write(%Ld,%lu)\n", position, *numbytes);
155 	*numbytes = 0;
156 	return B_ERROR;
157 }
158 
159 
160 static float
161 nor_supports_device(device_node *parent)
162 {
163 	TRACE("supports_device\n");
164 	return 0.6;
165 }
166 
167 
168 static status_t
169 nor_register_device(device_node *node)
170 {
171 	TRACE("register_device\n");
172 	// ready to register
173 	device_attr attrs[] = {
174 		{ NULL }
175 	};
176 
177 	return sDeviceManager->register_node(node, NORFLASH_DRIVER_MODULE_NAME,
178 		attrs, NULL, NULL);
179 }
180 
181 
182 static status_t
183 nor_init_driver(device_node *node, void **cookie)
184 {
185 	TRACE("init_driver\n");
186 
187 	nor_driver_info *info = (nor_driver_info*)malloc(sizeof(nor_driver_info));
188 	if (info == NULL)
189 		return B_NO_MEMORY;
190 
191 	memset(info, 0, sizeof(*info));
192 
193 	info->node = node;
194 
195 	*cookie = info;
196 	return B_OK;
197 }
198 
199 
200 static void
201 nor_uninit_driver(void *_cookie)
202 {
203 	TRACE("uninit_driver\n");
204 	nor_driver_info *info = (nor_driver_info*)_cookie;
205 	free(info);
206 }
207 
208 
209 static status_t
210 nor_register_child_devices(void *_cookie)
211 {
212 	TRACE("register_child_devices\n");
213 	nor_driver_info *info = (nor_driver_info*)_cookie;
214 	status_t status;
215 
216 	status = sDeviceManager->publish_device(info->node, "disk/nor/0/raw",
217 		NORFLASH_DEVICE_MODULE_NAME);
218 
219 	return status;
220 }
221 
222 
223 struct device_module_info sNORFlashDiskDevice = {
224 	{
225 		NORFLASH_DEVICE_MODULE_NAME,
226 		0,
227 		NULL
228 	},
229 
230 	nor_init_device,
231 	nor_uninit_device,
232 	NULL, //nor_remove,
233 
234 	nor_open,
235 	nor_close,
236 	nor_free,
237 	nor_read,
238 	nor_write,
239 	NULL,	// nor_io,
240 	nor_ioctl,
241 
242 	NULL,	// select
243 	NULL,	// deselect
244 };
245 
246 
247 
248 struct driver_module_info sNORFlashDiskDriver = {
249 	{
250 		NORFLASH_DRIVER_MODULE_NAME,
251 		0,
252 		NULL
253 	},
254 
255 	nor_supports_device,
256 	nor_register_device,
257 	nor_init_driver,
258 	nor_uninit_driver,
259 	nor_register_child_devices,
260 	NULL,	// rescan
261 	NULL,	// removed
262 };
263 
264 
265 module_dependency module_dependencies[] = {
266 	{ B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager },
267 	{ }
268 };
269 
270 
271 module_info *modules[] = {
272 	(module_info*)&sNORFlashDiskDriver,
273 	(module_info*)&sNORFlashDiskDevice,
274 	NULL
275 };
276