summaryrefslogtreecommitdiffstats
path: root/include/driver.h
blob: e1b344cfe335fc9181121fa7181e37db97a6976f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef DRIVER_H
#define DRIVER_H

#include <list.h>

#define MAX_DRIVER_NAME 16

#define DEVICE_TYPE_UNKNOWN     0
#define DEVICE_TYPE_ETHER       1
#define DEVICE_TYPE_CONSOLE     2
#define DEVICE_TYPE_DRAM	3
#define DEVICE_TYPE_BLOCK	4
#define DEVICE_TYPE_FS		5
#define DEVICE_TYPE_MIIPHY	6
#define MAX_DEVICE_TYPE         6

#include <param.h>

struct device_d {
	char name[MAX_DRIVER_NAME]; /* The name of this device. Used to match
				     * to the corresponding driver.
				     */
	char id[MAX_DRIVER_NAME];

	unsigned long size;

	/* For devices which are directly mapped into memory, i.e. NOR Flash or
	 * SDRAM.
	 */
	unsigned long map_base;

	void *platform_data; /* board specific information about this device */
	void *priv;          /* data private to the driver */
	void *type_data;     /* In case this device is a specific device, this pointer
			      * points to the type specific device, i.e. eth_device
			      */

	struct driver_d *driver; /* The driver for this device */

	struct list_head list;

	unsigned long type;

	struct param_d *param;
};

struct driver_d {
	char name[MAX_DRIVER_NAME]; /* The name of this driver. Used to match to
				     * the corresponding device.
				     */
	struct list_head list;

	int     (*probe) (struct device_d *);
	int     (*remove)(struct device_d *);
	ssize_t (*read)  (struct device_d*, void* buf, size_t count, ulong offset, ulong flags);
	ssize_t (*write) (struct device_d*, const void* buf, size_t count, ulong offset, ulong flags);
	ssize_t (*erase) (struct device_d*, size_t count, unsigned long offset);
	int     (*protect)(struct device_d*, size_t count, unsigned long offset, int prot);
	int     (*memmap)(struct device_d*, void **map, int flags);

	void    (*info) (struct device_d *);
	void    (*shortinfo) (struct device_d *);

	unsigned long type;
	void *type_data; /* In case this driver is of a specific type, i.e. a filesystem
			  * driver, this pointer points to the corresponding data struct
			  */
};

#define RW_SIZE(x)      (x)
#define RW_SIZE_MASK    0x7

/* Register/unregister devices and drivers. Since we don't have modules
 * we do not need a driver_unregister function.
 */
int register_driver(struct driver_d *);
int register_device(struct device_d *);
void unregister_device(struct device_d *);

/* Iterate through the devices of a given type. if last is NULL, the
 * first device of this type is returned. Put this pointer in as
 * 'last' to get the next device. This functions returns NULL if no
 * more devices are found.
 */
struct device_d *get_device_by_type(ulong type, struct device_d *last);
struct device_d *get_device_by_id(const char *id);
struct device_d *get_first_device(void);

/* Find a free device id from the given template. This is archieved by
 * appending a number to the template. Dynamically created devices should
 * use this function rather than filling the id field themselves.
 */
int get_free_deviceid(char *id, char *id_template);

struct device_d *device_from_spec_str(const char *str, char **endp);
char *deviceid_from_spec_str(const char *str, char **endp);

extern struct list_head device_list;
#define for_each_device(dev) list_for_each_entry(dev, &device_list, list)

extern struct list_head driver_list;
#define for_each_driver(drv) list_for_each_entry(drv, &driver_list, list)

/* Find a driver with the given name. Currently the filesystem implementation
 * uses this to get the driver from the name the user specifies with the
 * mount command
 */
struct driver_d *get_driver_by_name(const char *name);

ssize_t dev_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t dev_write(struct device_d *dev, const void *buf, size_t count, ulong offset, ulong flags);
ssize_t dev_erase(struct device_d *dev, size_t count, unsigned long offset);
ssize_t dev_protect(struct device_d *dev, size_t count, unsigned long offset, int prot);
int     dev_memmap(struct device_d *dev, void **map, int flags);

/* These are used by drivers which work with direct memory accesses */
ssize_t mem_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
ssize_t mem_write(struct device_d *dev, const void *buf, size_t count, ulong offset, ulong flags);

/* Use this if you have nothing to do in your drivers probe function */
int dummy_probe(struct device_d *);

int generic_memmap_ro(struct device_d *dev, void **map, int flags);
int generic_memmap_rw(struct device_d *dev, void **map, int flags);

#endif /* DRIVER_H */