summaryrefslogtreecommitdiff
path: root/src/include/device/device.h
blob: aff5616a880ef8f781e7c380f82f054539fb05b4 (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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef DEVICE_H
#define DEVICE_H

#include <stdint.h>
#include <device/resource.h>
#include <device/path.h>


struct device;
typedef struct device * device_t;
struct pci_operations;
struct pci_bus_operations;
struct smbus_bus_operations;

/* Chip operations */
struct chip_operations {
	void (*enable_dev)(struct device *dev);
#if CONFIG_CHIP_NAME == 1
	char *name;
#endif
};

#if CONFIG_CHIP_NAME == 1
#define CHIP_NAME(X) .name = X,
#else
#define CHIP_NAME(X)
#endif

struct bus;

struct device_operations {
	void (*read_resources)(device_t dev);
	void (*set_resources)(device_t dev);
	void (*enable_resources)(device_t dev);
	void (*init)(device_t dev);
	unsigned int (*scan_bus)(device_t bus, unsigned int max);
	void (*enable)(device_t dev);
	void (*set_link)(device_t dev, unsigned int link);
	void (*reset_bus)(struct bus *bus);
	const struct pci_operations *ops_pci;
	const struct smbus_bus_operations *ops_smbus_bus;
	const struct pci_bus_operations *ops_pci_bus;
};


struct bus {
	device_t 	dev;		/* This bridge device */
	device_t 	children;	/* devices behind this bridge */
	unsigned	bridge_ctrl;	/* Bridge control register */
	unsigned char	link;		/* The index of this link */
	unsigned char	secondary; 	/* secondary bus number */
	unsigned char	subordinate;	/* max subordinate bus number */
	unsigned char   cap;		/* PCi capability offset */
	unsigned	reset_needed : 1;
	unsigned	disable_relaxed_ordering : 1;
};

#define MAX_RESOURCES 12
#define MAX_LINKS    8 
/*
 * There is one device structure for each slot-number/function-number
 * combination:
 */

struct device {
	struct bus *	bus;		/* bus this device is on, for bridge
					 * devices, it is the up stream bus */
	device_t	sibling;	/* next device on this bus */
	device_t	next;		/* chain of all devices */

	struct device_path path;
	unsigned 	vendor;
	unsigned 	device;
	unsigned int	class;		/* 3 bytes: (base,sub,prog-if) */
	unsigned int	hdr_type;	/* PCI header type */
	unsigned int    enabled : 1;	/* set if we should enable the device */
	unsigned int    initialized : 1; /* set if we have initialized the device */
	unsigned int    have_resources : 1; /* Set if we have read the devices resources */
	unsigned int    on_mainboard : 1;
	unsigned long   rom_address;

	uint8_t command;

	/* Base registers for this device. I/O, MEM and Expansion ROM */
	struct resource resource[MAX_RESOURCES];
	unsigned int resources;

	/* link are (down sream) buses attached to the device, usually a leaf
	 * device with no children have 0 buses attached and a bridge has 1 bus 
	 */
	struct bus link[MAX_LINKS];
	/* number of buses attached to the device */
	unsigned int links;

	struct device_operations *ops;
	struct chip_operations *chip_ops;
	void *chip_info;
};

extern struct device	dev_root;	/* root bus */
extern struct device	*all_devices;	/* list of all devices */


/* Generic device interface functions */
extern device_t alloc_dev(struct bus *parent, struct device_path *path);
extern void dev_enumerate(void);
extern void dev_configure(void);
extern void dev_enable(void);
extern void dev_initialize(void);
extern void dev_optimize(void);

/* Generic device helper functions */
extern int reset_bus(struct bus *bus);
extern unsigned int scan_bus(struct device *bus, unsigned int max);
extern void compute_allocate_resource(struct bus *bus, struct resource *bridge,
	unsigned long type_mask, unsigned long type);
extern void assign_resources(struct bus *bus);
extern void enable_resources(struct device *dev);
extern void enumerate_static_device(void);
extern void enumerate_static_devices(void);
extern const char *dev_path(device_t dev);
const char *bus_path(struct bus *bus);
extern void dev_set_enabled(device_t dev, int enable);
extern void disable_children(struct bus *bus);

/* Helper functions */
device_t find_dev_path(struct bus *parent, struct device_path *path);
device_t alloc_find_dev(struct bus *parent, struct device_path *path);
device_t dev_find_device (unsigned int vendor, unsigned int device, device_t from);
device_t dev_find_class (unsigned int class, device_t from);
device_t dev_find_slot (unsigned int bus, unsigned int devfn);
device_t dev_find_slot_on_smbus (unsigned int bus, unsigned int addr);


/* Rounding for boundaries. 
 * Due to some chip bugs, go ahead and roung IO to 16
 */
#define DEVICE_IO_ALIGN 16 
#define DEVICE_MEM_ALIGN 4096

struct device_operations default_dev_ops_root;
extern void root_dev_read_resources(device_t dev);
extern void root_dev_set_resources(device_t dev);
extern unsigned int scan_static_bus(device_t bus, unsigned int max);
extern void enable_childrens_resources(device_t dev);
extern void root_dev_enable_resources(device_t dev);
extern unsigned int root_dev_scan_bus(device_t root, unsigned int max);
extern void root_dev_init(device_t dev);
#endif /* DEVICE_H */