Rev 2187 | Rev 9499 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2187 | Rev 2216 | ||
---|---|---|---|
1 | #include |
1 | #include |
2 | #include |
2 | #include |
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | #include |
5 | #include |
6 | 6 | ||
7 | #include "acpi.h" |
7 | #include "acpi.h" |
8 | #include "acpi_bus.h" |
8 | #include "acpi_bus.h" |
9 | #include "dmdev.h" |
9 | #include "dmdev.h" |
10 | 10 | ||
11 | #define PREFIX "ACPI: " |
11 | #define PREFIX "ACPI: " |
12 | 12 | ||
13 | #define ACPI_BUS_CLASS "system_bus" |
13 | #define ACPI_BUS_CLASS "system_bus" |
14 | #define ACPI_BUS_HID "KLBSYBUS" |
14 | #define ACPI_BUS_HID "KLBSYBUS" |
15 | #define ACPI_BUS_DEVICE_NAME "System Bus" |
15 | #define ACPI_BUS_DEVICE_NAME "System Bus" |
16 | 16 | ||
17 | 17 | ||
18 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) |
18 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) |
19 | 19 | ||
20 | LIST_HEAD(acpi_device_list); |
20 | LIST_HEAD(acpi_device_list); |
21 | LIST_HEAD(acpi_bus_id_list); |
21 | LIST_HEAD(acpi_bus_id_list); |
22 | LIST_HEAD(dmdev_tree); |
22 | LIST_HEAD(dmdev_tree); |
23 | 23 | ||
24 | 24 | ||
25 | struct acpi_device_bus_id |
25 | struct acpi_device_bus_id |
26 | { |
26 | { |
27 | char bus_id[15]; |
27 | char bus_id[15]; |
28 | unsigned int instance_no; |
28 | unsigned int instance_no; |
29 | struct list_head node; |
29 | struct list_head node; |
30 | }; |
30 | }; |
31 | 31 | ||
32 | 32 | ||
33 | #define ACPI_NS_ROOT_PATH "\\" |
33 | #define ACPI_NS_ROOT_PATH "\\" |
34 | #define ACPI_NS_SYSTEM_BUS "_SB_" |
34 | #define ACPI_NS_SYSTEM_BUS "_SB_" |
35 | 35 | ||
36 | enum acpi_irq_model_id { |
36 | enum acpi_irq_model_id { |
37 | ACPI_IRQ_MODEL_PIC = 0, |
37 | ACPI_IRQ_MODEL_PIC = 0, |
38 | ACPI_IRQ_MODEL_IOAPIC, |
38 | ACPI_IRQ_MODEL_IOAPIC, |
39 | ACPI_IRQ_MODEL_IOSAPIC, |
39 | ACPI_IRQ_MODEL_IOSAPIC, |
40 | ACPI_IRQ_MODEL_PLATFORM, |
40 | ACPI_IRQ_MODEL_PLATFORM, |
41 | ACPI_IRQ_MODEL_COUNT |
41 | ACPI_IRQ_MODEL_COUNT |
42 | }; |
42 | }; |
43 | 43 | ||
44 | enum acpi_bus_removal_type { |
44 | enum acpi_bus_removal_type { |
45 | ACPI_BUS_REMOVAL_NORMAL = 0, |
45 | ACPI_BUS_REMOVAL_NORMAL = 0, |
46 | ACPI_BUS_REMOVAL_EJECT, |
46 | ACPI_BUS_REMOVAL_EJECT, |
47 | ACPI_BUS_REMOVAL_SUPRISE, |
47 | ACPI_BUS_REMOVAL_SUPRISE, |
48 | ACPI_BUS_REMOVAL_TYPE_COUNT |
48 | ACPI_BUS_REMOVAL_TYPE_COUNT |
49 | }; |
49 | }; |
50 | 50 | ||
51 | 51 | ||
52 | #define PCI_MAX_DEVICES 32 |
52 | #define PCI_MAX_DEVICES 32 |
53 | #define PCI_MAX_PINS 4 |
53 | #define PCI_MAX_PINS 4 |
54 | 54 | ||
55 | #define IRQ_TABLE_ENTRIES (PCI_MAX_DEVICES * PCI_MAX_PINS) |
55 | #define IRQ_TABLE_ENTRIES (PCI_MAX_DEVICES * PCI_MAX_PINS) |
56 | 56 | ||
57 | static int irqtable[IRQ_TABLE_ENTRIES]; |
57 | static int irqtable[IRQ_TABLE_ENTRIES]; |
58 | static ACPI_HANDLE pci_root_handle; |
58 | static ACPI_HANDLE pci_root_handle; |
59 | 59 | ||
60 | 60 | ||
61 | #define addr_offset(addr, off) \ |
61 | #define addr_offset(addr, off) \ |
62 | (addr_t)((addr_t)(addr) + (addr_t)(off)) |
62 | (addr_t)((addr_t)(addr) + (addr_t)(off)) |
63 | 63 | ||
64 | //#define acpi_remap( addr ) \ |
64 | //#define acpi_remap( addr ) \ |
65 | // (addr_t)((addr_t)(addr) + OS_BASE) |
65 | // (addr_t)((addr_t)(addr) + OS_BASE) |
66 | 66 | ||
67 | #define acpi_remap( addr ) MapIoMem((void*)(addr),4096, 0x01) |
67 | #define acpi_remap( addr ) MapIoMem((void*)(addr),4096, 0x01) |
68 | 68 | ||
69 | char* strdup(const char *str); |
69 | char* strdup(const char *str); |
70 | 70 | int sprintf(char *buf, const char *fmt, ...); |
|
- | 71 | ||
71 | void print_pci_irqs(); |
72 | void print_pci_irqs(); |
72 | 73 | ||
73 | 74 | ||
74 | struct acpi_device *acpi_root; |
75 | struct acpi_device *acpi_root; |
75 | 76 | ||
76 | extern struct resource iomem_resource; |
77 | extern struct resource iomem_resource; |
77 | extern struct resource ioport_resource; |
78 | extern struct resource ioport_resource; |
78 | 79 | ||
79 | enum pic_mode |
80 | enum pic_mode |
80 | { |
81 | { |
81 | IO_PIC = 0, |
82 | IO_PIC = 0, |
82 | IO_APIC |
83 | IO_APIC |
83 | }; |
84 | }; |
84 | 85 | ||
85 | static ACPI_STATUS |
86 | static ACPI_STATUS |
86 | resource_to_addr(ACPI_RESOURCE *resource, ACPI_RESOURCE_ADDRESS64 *addr); |
87 | resource_to_addr(ACPI_RESOURCE *resource, ACPI_RESOURCE_ADDRESS64 *addr); |
87 | 88 | ||
88 | static void create_dm_list(); |
89 | static void create_dm_list(); |
89 | 90 | ||
90 | static void print_dm_list(); |
91 | static void print_dm_list(); |
91 | 92 | ||
92 | int write_device_dat(char *path); |
93 | int write_device_dat(char *path); |
93 | 94 | ||
94 | 95 | ||
95 | static void set_pic_mode(enum pic_mode mode) |
96 | static void set_pic_mode(enum pic_mode mode) |
96 | { |
97 | { |
97 | ACPI_OBJECT arg1; |
98 | ACPI_OBJECT arg1; |
98 | ACPI_OBJECT_LIST args; |
99 | ACPI_OBJECT_LIST args; |
99 | ACPI_STATUS as; |
100 | ACPI_STATUS as; |
100 | 101 | ||
101 | arg1.Type = ACPI_TYPE_INTEGER; |
102 | arg1.Type = ACPI_TYPE_INTEGER; |
102 | arg1.Integer.Value = mode; |
103 | arg1.Integer.Value = mode; |
103 | args.Count = 1; |
104 | args.Count = 1; |
104 | args.Pointer = &arg1; |
105 | args.Pointer = &arg1; |
105 | 106 | ||
106 | as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL); |
107 | as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL); |
107 | /* |
108 | /* |
108 | * We can silently ignore failure as it may not be implemented, ACPI should |
109 | * We can silently ignore failure as it may not be implemented, ACPI should |
109 | * provide us with correct information anyway |
110 | * provide us with correct information anyway |
110 | */ |
111 | */ |
111 | if (ACPI_SUCCESS(as)) |
112 | if (ACPI_SUCCESS(as)) |
112 | dbgprintf(PREFIX "machine set to %s mode\n", mode ? "APIC" : "PIC"); |
113 | dbgprintf(PREFIX "machine set to %s mode\n", mode ? "APIC" : "PIC"); |
113 | } |
114 | } |
114 | 115 | ||
115 | 116 | ||
116 | 117 | ||
117 | static bool pci_use_crs = false; |
118 | static bool pci_use_crs = false; |
118 | 119 | ||
119 | #define IORESOURCE_BUS 0x00001000 |
120 | #define IORESOURCE_BUS 0x00001000 |
120 | 121 | ||
121 | 122 | ||
122 | extern struct list_head acpi_pci_roots; |
123 | extern struct list_head acpi_pci_roots; |
123 | 124 | ||
124 | #define ACPI_PCI_ROOT_CLASS "pci_bridge" |
125 | #define ACPI_PCI_ROOT_CLASS "pci_bridge" |
125 | #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" |
126 | #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" |
126 | 127 | ||
127 | static ACPI_STATUS |
128 | static ACPI_STATUS |
128 | get_root_bridge_busnr_callback(ACPI_RESOURCE *resource, void *data) |
129 | get_root_bridge_busnr_callback(ACPI_RESOURCE *resource, void *data) |
129 | { |
130 | { |
130 | struct resource *res = data; |
131 | struct resource *res = data; |
131 | ACPI_RESOURCE_ADDRESS64 address; |
132 | ACPI_RESOURCE_ADDRESS64 address; |
132 | 133 | ||
133 | if (resource->Type != ACPI_RESOURCE_TYPE_ADDRESS16 && |
134 | if (resource->Type != ACPI_RESOURCE_TYPE_ADDRESS16 && |
134 | resource->Type != ACPI_RESOURCE_TYPE_ADDRESS32 && |
135 | resource->Type != ACPI_RESOURCE_TYPE_ADDRESS32 && |
135 | resource->Type != ACPI_RESOURCE_TYPE_ADDRESS64) |
136 | resource->Type != ACPI_RESOURCE_TYPE_ADDRESS64) |
136 | return AE_OK; |
137 | return AE_OK; |
137 | 138 | ||
138 | AcpiResourceToAddress64(resource, &address); |
139 | AcpiResourceToAddress64(resource, &address); |
139 | if ((address.AddressLength > 0) && |
140 | if ((address.AddressLength > 0) && |
140 | (address.ResourceType == ACPI_BUS_NUMBER_RANGE)) { |
141 | (address.ResourceType == ACPI_BUS_NUMBER_RANGE)) { |
141 | res->start = address.Minimum; |
142 | res->start = address.Minimum; |
142 | res->end = address.Minimum + address.AddressLength - 1; |
143 | res->end = address.Minimum + address.AddressLength - 1; |
143 | } |
144 | } |
144 | 145 | ||
145 | return AE_OK; |
146 | return AE_OK; |
146 | } |
147 | } |
147 | 148 | ||
148 | 149 | ||
149 | 150 | ||
150 | static ACPI_STATUS try_get_root_bridge_busnr(ACPI_HANDLE handle, |
151 | static ACPI_STATUS try_get_root_bridge_busnr(ACPI_HANDLE handle, |
151 | struct resource *res) |
152 | struct resource *res) |
152 | { |
153 | { |
153 | ACPI_STATUS status; |
154 | ACPI_STATUS status; |
154 | 155 | ||
155 | res->start = -1; |
156 | res->start = -1; |
156 | status = |
157 | status = |
157 | AcpiWalkResources(handle, METHOD_NAME__CRS, |
158 | AcpiWalkResources(handle, METHOD_NAME__CRS, |
158 | get_root_bridge_busnr_callback, res); |
159 | get_root_bridge_busnr_callback, res); |
159 | if (ACPI_FAILURE(status)) |
160 | if (ACPI_FAILURE(status)) |
160 | return status; |
161 | return status; |
161 | if (res->start == -1) |
162 | if (res->start == -1) |
162 | return AE_ERROR; |
163 | return AE_ERROR; |
163 | return AE_OK; |
164 | return AE_OK; |
164 | } |
165 | } |
165 | 166 | ||
166 | 167 | ||
167 | static void acpi_pci_bridge_scan(struct acpi_device *device) |
168 | static void acpi_pci_bridge_scan(struct acpi_device *device) |
168 | { |
169 | { |
169 | int status; |
170 | int status; |
170 | struct acpi_device *child = NULL; |
171 | struct acpi_device *child = NULL; |
171 | 172 | ||
172 | if (device->flags.bus_address) |
173 | if (device->flags.bus_address) |
173 | if (device->parent && device->parent->ops.bind) { |
174 | if (device->parent && device->parent->ops.bind) { |
174 | status = device->parent->ops.bind(device); |
175 | status = device->parent->ops.bind(device); |
175 | if (!status) { |
176 | if (!status) { |
176 | list_for_each_entry(child, &device->children, node) |
177 | list_for_each_entry(child, &device->children, node) |
177 | acpi_pci_bridge_scan(child); |
178 | acpi_pci_bridge_scan(child); |
178 | } |
179 | } |
179 | } |
180 | } |
180 | } |
181 | } |
181 | 182 | ||
182 | 183 | ||
183 | 184 | ||
184 | struct pci_root_info |
185 | struct pci_root_info |
185 | { |
186 | { |
186 | struct acpi_device *bridge; |
187 | struct acpi_device *bridge; |
187 | char *name; |
188 | char *name; |
188 | unsigned int res_num; |
189 | unsigned int res_num; |
189 | struct resource *res; |
190 | struct resource *res; |
190 | struct pci_bus *bus; |
191 | struct pci_bus *bus; |
191 | int busnum; |
192 | int busnum; |
192 | }; |
193 | }; |
193 | 194 | ||
194 | 195 | ||
195 | static ACPI_STATUS |
196 | static ACPI_STATUS |
196 | resource_to_addr(ACPI_RESOURCE *resource, ACPI_RESOURCE_ADDRESS64 *addr) |
197 | resource_to_addr(ACPI_RESOURCE *resource, ACPI_RESOURCE_ADDRESS64 *addr) |
197 | { |
198 | { |
198 | ACPI_STATUS status; |
199 | ACPI_STATUS status; |
199 | struct acpi_resource_memory24 *memory24; |
200 | struct acpi_resource_memory24 *memory24; |
200 | struct acpi_resource_memory32 *memory32; |
201 | struct acpi_resource_memory32 *memory32; |
201 | struct acpi_resource_fixed_memory32 *fixed_memory32; |
202 | struct acpi_resource_fixed_memory32 *fixed_memory32; |
202 | 203 | ||
203 | memset(addr, 0, sizeof(*addr)); |
204 | memset(addr, 0, sizeof(*addr)); |
204 | switch (resource->Type) { |
205 | switch (resource->Type) { |
205 | case ACPI_RESOURCE_TYPE_MEMORY24: |
206 | case ACPI_RESOURCE_TYPE_MEMORY24: |
206 | memory24 = &resource->Data.Memory24; |
207 | memory24 = &resource->Data.Memory24; |
207 | addr->ResourceType = ACPI_MEMORY_RANGE; |
208 | addr->ResourceType = ACPI_MEMORY_RANGE; |
208 | addr->Minimum = memory24->Minimum; |
209 | addr->Minimum = memory24->Minimum; |
209 | addr->AddressLength = memory24->AddressLength; |
210 | addr->AddressLength = memory24->AddressLength; |
210 | addr->Maximum = addr->Minimum + addr->AddressLength - 1; |
211 | addr->Maximum = addr->Minimum + addr->AddressLength - 1; |
211 | return AE_OK; |
212 | return AE_OK; |
212 | case ACPI_RESOURCE_TYPE_MEMORY32: |
213 | case ACPI_RESOURCE_TYPE_MEMORY32: |
213 | memory32 = &resource->Data.Memory32; |
214 | memory32 = &resource->Data.Memory32; |
214 | addr->ResourceType = ACPI_MEMORY_RANGE; |
215 | addr->ResourceType = ACPI_MEMORY_RANGE; |
215 | addr->Minimum = memory32->Minimum; |
216 | addr->Minimum = memory32->Minimum; |
216 | addr->AddressLength = memory32->AddressLength; |
217 | addr->AddressLength = memory32->AddressLength; |
217 | addr->Maximum = addr->Minimum + addr->AddressLength - 1; |
218 | addr->Maximum = addr->Minimum + addr->AddressLength - 1; |
218 | return AE_OK; |
219 | return AE_OK; |
219 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
220 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
220 | fixed_memory32 = &resource->Data.FixedMemory32; |
221 | fixed_memory32 = &resource->Data.FixedMemory32; |
221 | addr->ResourceType = ACPI_MEMORY_RANGE; |
222 | addr->ResourceType = ACPI_MEMORY_RANGE; |
222 | addr->Minimum = fixed_memory32->Address; |
223 | addr->Minimum = fixed_memory32->Address; |
223 | addr->AddressLength = fixed_memory32->AddressLength; |
224 | addr->AddressLength = fixed_memory32->AddressLength; |
224 | addr->Maximum = addr->Minimum + addr->AddressLength - 1; |
225 | addr->Maximum = addr->Minimum + addr->AddressLength - 1; |
225 | return AE_OK; |
226 | return AE_OK; |
226 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
227 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
227 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
228 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
228 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
229 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
229 | status = AcpiResourceToAddress64(resource, addr); |
230 | status = AcpiResourceToAddress64(resource, addr); |
230 | if (ACPI_SUCCESS(status) && |
231 | if (ACPI_SUCCESS(status) && |
231 | (addr->ResourceType == ACPI_MEMORY_RANGE || |
232 | (addr->ResourceType == ACPI_MEMORY_RANGE || |
232 | addr->ResourceType == ACPI_IO_RANGE) && |
233 | addr->ResourceType == ACPI_IO_RANGE) && |
233 | addr->AddressLength > 0) { |
234 | addr->AddressLength > 0) { |
234 | return AE_OK; |
235 | return AE_OK; |
235 | } |
236 | } |
236 | break; |
237 | break; |
237 | } |
238 | } |
238 | return AE_ERROR; |
239 | return AE_ERROR; |
239 | } |
240 | } |
240 | 241 | ||
241 | 242 | ||
242 | static ACPI_STATUS |
243 | static ACPI_STATUS |
243 | count_resource(ACPI_RESOURCE *acpi_res, void *data) |
244 | count_resource(ACPI_RESOURCE *acpi_res, void *data) |
244 | { |
245 | { |
245 | struct pci_root_info *info = data; |
246 | struct pci_root_info *info = data; |
246 | ACPI_RESOURCE_ADDRESS64 addr; |
247 | ACPI_RESOURCE_ADDRESS64 addr; |
247 | ACPI_STATUS status; |
248 | ACPI_STATUS status; |
248 | 249 | ||
249 | status = resource_to_addr(acpi_res, &addr); |
250 | status = resource_to_addr(acpi_res, &addr); |
250 | if (ACPI_SUCCESS(status)) |
251 | if (ACPI_SUCCESS(status)) |
251 | info->res_num++; |
252 | info->res_num++; |
252 | return AE_OK; |
253 | return AE_OK; |
253 | } |
254 | } |
254 | 255 | ||
255 | 256 | ||
256 | static ACPI_STATUS setup_resource(ACPI_RESOURCE *acpi_res, void *data) |
257 | static ACPI_STATUS setup_resource(ACPI_RESOURCE *acpi_res, void *data) |
257 | { |
258 | { |
258 | struct pci_root_info *info = data; |
259 | struct pci_root_info *info = data; |
259 | struct resource *res; |
260 | struct resource *res; |
260 | struct acpi_resource_address64 addr; |
261 | struct acpi_resource_address64 addr; |
261 | ACPI_STATUS status; |
262 | ACPI_STATUS status; |
262 | unsigned long flags; |
263 | unsigned long flags; |
263 | u64 start, end; |
264 | u64 start, end; |
264 | 265 | ||
265 | status = resource_to_addr(acpi_res, &addr); |
266 | status = resource_to_addr(acpi_res, &addr); |
266 | if (!ACPI_SUCCESS(status)) |
267 | if (!ACPI_SUCCESS(status)) |
267 | return AE_OK; |
268 | return AE_OK; |
268 | 269 | ||
269 | if (addr.ResourceType == ACPI_MEMORY_RANGE) |
270 | if (addr.ResourceType == ACPI_MEMORY_RANGE) |
270 | { |
271 | { |
271 | flags = IORESOURCE_MEM; |
272 | flags = IORESOURCE_MEM; |
272 | if (addr.Info.Mem.Caching == ACPI_PREFETCHABLE_MEMORY) |
273 | if (addr.Info.Mem.Caching == ACPI_PREFETCHABLE_MEMORY) |
273 | flags |= IORESOURCE_PREFETCH; |
274 | flags |= IORESOURCE_PREFETCH; |
274 | } |
275 | } |
275 | else if (addr.ResourceType == ACPI_IO_RANGE) |
276 | else if (addr.ResourceType == ACPI_IO_RANGE) |
276 | { |
277 | { |
277 | flags = IORESOURCE_IO; |
278 | flags = IORESOURCE_IO; |
278 | } else |
279 | } else |
279 | return AE_OK; |
280 | return AE_OK; |
280 | 281 | ||
281 | start = addr.Minimum + addr.TranslationOffset; |
282 | start = addr.Minimum + addr.TranslationOffset; |
282 | end = addr.Maximum + addr.TranslationOffset; |
283 | end = addr.Maximum + addr.TranslationOffset; |
283 | 284 | ||
284 | res = &info->res[info->res_num]; |
285 | res = &info->res[info->res_num]; |
285 | res->name = info->name; |
286 | res->name = info->name; |
286 | res->flags = flags; |
287 | res->flags = flags; |
287 | res->start = start; |
288 | res->start = start; |
288 | res->end = end; |
289 | res->end = end; |
289 | res->child = NULL; |
290 | res->child = NULL; |
290 | 291 | ||
291 | if (!pci_use_crs) { |
292 | if (!pci_use_crs) { |
292 | printk("host bridge window %pR (ignored)\n", res); |
293 | printk("host bridge window %pR (ignored)\n", res); |
293 | return AE_OK; |
294 | return AE_OK; |
294 | } |
295 | } |
295 | 296 | ||
296 | info->res_num++; |
297 | info->res_num++; |
297 | if (addr.TranslationOffset) |
298 | if (addr.TranslationOffset) |
298 | dev_info(NULL, "host bridge window %pR " |
299 | dev_info(NULL, "host bridge window %pR " |
299 | "(PCI address [%#llx-%#llx])\n", |
300 | "(PCI address [%#llx-%#llx])\n", |
300 | res, res->start - addr.TranslationOffset, |
301 | res, res->start - addr.TranslationOffset, |
301 | res->end - addr.TranslationOffset); |
302 | res->end - addr.TranslationOffset); |
302 | else |
303 | else |
303 | dev_info(NULL, |
304 | dev_info(NULL, |
304 | "host bridge window %pR\n", res); |
305 | "host bridge window %pR\n", res); |
305 | 306 | ||
306 | return AE_OK; |
307 | return AE_OK; |
307 | } |
308 | } |
308 | 309 | ||
309 | 310 | ||
310 | 311 | ||
311 | static void |
312 | static void |
312 | get_current_resources(struct acpi_device *device, int busnum, |
313 | get_current_resources(struct acpi_device *device, int busnum, |
313 | int domain, struct pci_bus *bus) |
314 | int domain, struct pci_bus *bus) |
314 | { |
315 | { |
315 | struct pci_root_info info; |
316 | struct pci_root_info info; |
316 | size_t size; |
317 | size_t size; |
317 | 318 | ||
318 | char buf[64]; |
319 | char buf[64]; |
319 | 320 | ||
320 | // if (pci_use_crs) |
321 | // if (pci_use_crs) |
321 | // pci_bus_remove_resources(bus); |
322 | // pci_bus_remove_resources(bus); |
322 | 323 | ||
323 | info.bridge = device; |
324 | info.bridge = device; |
324 | info.bus = bus; |
325 | info.bus = bus; |
325 | info.res_num = 0; |
326 | info.res_num = 0; |
326 | AcpiWalkResources(device->handle, METHOD_NAME__CRS, count_resource, |
327 | AcpiWalkResources(device->handle, METHOD_NAME__CRS, count_resource, |
327 | &info); |
328 | &info); |
328 | if (!info.res_num) |
329 | if (!info.res_num) |
329 | return; |
330 | return; |
330 | 331 | ||
331 | size = sizeof(*info.res) * info.res_num; |
332 | size = sizeof(*info.res) * info.res_num; |
332 | info.res = kmalloc(size, GFP_KERNEL); |
333 | info.res = kmalloc(size, GFP_KERNEL); |
333 | if (!info.res) |
334 | if (!info.res) |
334 | goto res_alloc_fail; |
335 | goto res_alloc_fail; |
335 | 336 | ||
336 | vsprintf(buf,"PCI Bus %04x:%02x", domain, busnum); |
337 | sprintf(buf,"PCI Bus %04x:%02x", domain, busnum); |
- | 338 | ||
337 | info.name = strdup(buf); |
339 | info.name = strdup(buf); |
338 | 340 | ||
339 | if (!info.name) |
341 | if (!info.name) |
340 | goto name_alloc_fail; |
342 | goto name_alloc_fail; |
341 | 343 | ||
342 | info.res_num = 0; |
344 | info.res_num = 0; |
343 | AcpiWalkResources(device->handle, METHOD_NAME__CRS, setup_resource, |
345 | AcpiWalkResources(device->handle, METHOD_NAME__CRS, setup_resource, |
344 | &info); |
346 | &info); |
345 | 347 | ||
346 | return; |
348 | return; |
347 | 349 | ||
348 | name_alloc_fail: |
350 | name_alloc_fail: |
349 | kfree(info.res); |
351 | kfree(info.res); |
350 | res_alloc_fail: |
352 | res_alloc_fail: |
351 | return; |
353 | return; |
352 | } |
354 | } |
353 | 355 | ||
354 | 356 | ||
355 | struct pci_ops pci_root_ops = { |
357 | struct pci_ops pci_root_ops = { |
356 | .read = NULL, |
358 | .read = NULL, |
357 | .write = NULL, |
359 | .write = NULL, |
358 | }; |
360 | }; |
359 | 361 | ||
360 | 362 | ||
361 | struct pci_bus* pci_acpi_scan_root(struct acpi_pci_root *root) |
363 | struct pci_bus* pci_acpi_scan_root(struct acpi_pci_root *root) |
362 | { |
364 | { |
363 | struct acpi_device *device = root->device; |
365 | struct acpi_device *device = root->device; |
364 | int domain = root->segment; |
366 | int domain = root->segment; |
365 | int busnum = root->secondary.start; |
367 | int busnum = root->secondary.start; |
366 | struct pci_bus *bus; |
368 | struct pci_bus *bus; |
367 | struct pci_sysdata *sd; |
369 | struct pci_sysdata *sd; |
368 | int node = 0; |
370 | int node = 0; |
369 | 371 | ||
370 | if (domain ) { |
372 | if (domain ) { |
371 | printk(KERN_WARNING "pci_bus %04x:%02x: " |
373 | printk(KERN_WARNING "pci_bus %04x:%02x: " |
372 | "ignored (multiple domains not supported)\n", |
374 | "ignored (multiple domains not supported)\n", |
373 | domain, busnum); |
375 | domain, busnum); |
374 | return NULL; |
376 | return NULL; |
375 | } |
377 | } |
376 | 378 | ||
377 | node = -1; |
379 | node = -1; |
378 | /* Allocate per-root-bus (not per bus) arch-specific data. |
380 | /* Allocate per-root-bus (not per bus) arch-specific data. |
379 | * TODO: leak; this memory is never freed. |
381 | * TODO: leak; this memory is never freed. |
380 | * It's arguable whether it's worth the trouble to care. |
382 | * It's arguable whether it's worth the trouble to care. |
381 | */ |
383 | */ |
382 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); |
384 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); |
383 | if (!sd) { |
385 | if (!sd) { |
384 | printk(KERN_WARNING "pci_bus %04x:%02x: " |
386 | printk(KERN_WARNING "pci_bus %04x:%02x: " |
385 | "ignored (out of memory)\n", domain, busnum); |
387 | "ignored (out of memory)\n", domain, busnum); |
386 | return NULL; |
388 | return NULL; |
387 | } |
389 | } |
388 | 390 | ||
389 | sd->domain = domain; |
391 | sd->domain = domain; |
390 | sd->node = node; |
392 | sd->node = node; |
391 | /* |
393 | /* |
392 | * Maybe the desired pci bus has been already scanned. In such case |
394 | * Maybe the desired pci bus has been already scanned. In such case |
393 | * it is unnecessary to scan the pci bus with the given domain,busnum. |
395 | * it is unnecessary to scan the pci bus with the given domain,busnum. |
394 | */ |
396 | */ |
395 | bus = pci_find_bus(domain, busnum); |
397 | bus = pci_find_bus(domain, busnum); |
396 | if (bus) { |
398 | if (bus) { |
397 | /* |
399 | /* |
398 | * If the desired bus exits, the content of bus->sysdata will |
400 | * If the desired bus exits, the content of bus->sysdata will |
399 | * be replaced by sd. |
401 | * be replaced by sd. |
400 | */ |
402 | */ |
401 | memcpy(bus->sysdata, sd, sizeof(*sd)); |
403 | memcpy(bus->sysdata, sd, sizeof(*sd)); |
402 | kfree(sd); |
404 | kfree(sd); |
403 | } else { |
405 | } else { |
404 | bus = pci_create_bus(busnum, &pci_root_ops, sd); |
406 | bus = pci_create_bus(busnum, &pci_root_ops, sd); |
405 | if (bus) { |
407 | if (bus) { |
406 | get_current_resources(device, busnum, domain, bus); |
408 | get_current_resources(device, busnum, domain, bus); |
407 | bus->subordinate = pci_scan_child_bus(bus); |
409 | bus->subordinate = pci_scan_child_bus(bus); |
408 | } |
410 | } |
409 | } |
411 | } |
410 | 412 | ||
411 | if (!bus) |
413 | if (!bus) |
412 | kfree(sd); |
414 | kfree(sd); |
413 | 415 | ||
414 | if (bus && node != -1) { |
416 | if (bus && node != -1) { |
415 | printk("on NUMA node %d\n", node); |
417 | printk("on NUMA node %d\n", node); |
416 | } |
418 | } |
417 | 419 | ||
418 | return bus; |
420 | return bus; |
419 | } |
421 | } |
420 | 422 | ||
421 | 423 | ||
422 | 424 | ||
423 | static int acpi_pci_root_add(struct acpi_device *device) |
425 | static int acpi_pci_root_add(struct acpi_device *device) |
424 | { |
426 | { |
425 | unsigned long long segment, bus; |
427 | unsigned long long segment, bus; |
426 | ACPI_STATUS status; |
428 | ACPI_STATUS status; |
427 | int result; |
429 | int result; |
428 | struct acpi_pci_root *root; |
430 | struct acpi_pci_root *root; |
429 | ACPI_HANDLE handle; |
431 | ACPI_HANDLE handle; |
430 | struct acpi_device *child; |
432 | struct acpi_device *child; |
431 | u32 flags, base_flags; |
433 | u32 flags, base_flags; |
432 | 434 | ||
433 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
435 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
434 | if (!root) |
436 | if (!root) |
435 | return -ENOMEM; |
437 | return -ENOMEM; |
436 | 438 | ||
437 | segment = 0; |
439 | segment = 0; |
438 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, |
440 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, |
439 | &segment); |
441 | &segment); |
440 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
442 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
441 | printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); |
443 | printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); |
442 | result = -ENODEV; |
444 | result = -ENODEV; |
443 | goto end; |
445 | goto end; |
444 | } |
446 | } |
445 | 447 | ||
446 | /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ |
448 | /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ |
447 | root->secondary.flags = IORESOURCE_BUS; |
449 | root->secondary.flags = IORESOURCE_BUS; |
448 | status = try_get_root_bridge_busnr(device->handle, &root->secondary); |
450 | status = try_get_root_bridge_busnr(device->handle, &root->secondary); |
449 | if (ACPI_FAILURE(status)) |
451 | if (ACPI_FAILURE(status)) |
450 | { |
452 | { |
451 | /* |
453 | /* |
452 | * We need both the start and end of the downstream bus range |
454 | * We need both the start and end of the downstream bus range |
453 | * to interpret _CBA (MMCONFIG base address), so it really is |
455 | * to interpret _CBA (MMCONFIG base address), so it really is |
454 | * supposed to be in _CRS. If we don't find it there, all we |
456 | * supposed to be in _CRS. If we don't find it there, all we |
455 | * can do is assume [_BBN-0xFF] or [0-0xFF]. |
457 | * can do is assume [_BBN-0xFF] or [0-0xFF]. |
456 | */ |
458 | */ |
457 | root->secondary.end = 0xFF; |
459 | root->secondary.end = 0xFF; |
458 | printk(KERN_WARNING PREFIX |
460 | printk(KERN_WARNING PREFIX |
459 | "no secondary bus range in _CRS\n"); |
461 | "no secondary bus range in _CRS\n"); |
460 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); |
462 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); |
461 | if (ACPI_SUCCESS(status)) |
463 | if (ACPI_SUCCESS(status)) |
462 | root->secondary.start = bus; |
464 | root->secondary.start = bus; |
463 | else if (status == AE_NOT_FOUND) |
465 | else if (status == AE_NOT_FOUND) |
464 | root->secondary.start = 0; |
466 | root->secondary.start = 0; |
465 | else { |
467 | else { |
466 | printk(KERN_ERR PREFIX "can't evaluate _BBN\n"); |
468 | printk(KERN_ERR PREFIX "can't evaluate _BBN\n"); |
467 | result = -ENODEV; |
469 | result = -ENODEV; |
468 | goto end; |
470 | goto end; |
469 | } |
471 | } |
470 | } |
472 | } |
471 | 473 | ||
472 | INIT_LIST_HEAD(&root->node); |
474 | INIT_LIST_HEAD(&root->node); |
473 | root->device = device; |
475 | root->device = device; |
474 | root->segment = segment & 0xFFFF; |
476 | root->segment = segment & 0xFFFF; |
475 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
477 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
476 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
478 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
477 | device->driver_data = root; |
479 | device->driver_data = root; |
478 | 480 | ||
479 | /* |
481 | /* |
480 | * All supported architectures that use ACPI have support for |
482 | * All supported architectures that use ACPI have support for |
481 | * PCI domains, so we indicate this in _OSC support capabilities. |
483 | * PCI domains, so we indicate this in _OSC support capabilities. |
482 | */ |
484 | */ |
483 | // flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; |
485 | // flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; |
484 | // acpi_pci_osc_support(root, flags); |
486 | // acpi_pci_osc_support(root, flags); |
485 | 487 | ||
486 | /* |
488 | /* |
487 | * TBD: Need PCI interface for enumeration/configuration of roots. |
489 | * TBD: Need PCI interface for enumeration/configuration of roots. |
488 | */ |
490 | */ |
489 | 491 | ||
490 | /* TBD: Locking */ |
492 | /* TBD: Locking */ |
491 | list_add_tail(&root->node, &acpi_pci_roots); |
493 | list_add_tail(&root->node, &acpi_pci_roots); |
492 | 494 | ||
493 | printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n", |
495 | printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n", |
494 | acpi_device_name(device), acpi_device_bid(device), |
496 | acpi_device_name(device), acpi_device_bid(device), |
495 | root->segment, &root->secondary); |
497 | root->segment, &root->secondary); |
496 | 498 | ||
497 | /* |
499 | /* |
498 | * Scan the Root Bridge |
500 | * Scan the Root Bridge |
499 | * -------------------- |
501 | * -------------------- |
500 | * Must do this prior to any attempt to bind the root device, as the |
502 | * Must do this prior to any attempt to bind the root device, as the |
501 | * PCI namespace does not get created until this call is made (and |
503 | * PCI namespace does not get created until this call is made (and |
502 | * thus the root bridge's pci_dev does not exist). |
504 | * thus the root bridge's pci_dev does not exist). |
503 | */ |
505 | */ |
504 | 506 | ||
505 | root->bus = pci_acpi_scan_root(root); |
507 | root->bus = pci_acpi_scan_root(root); |
506 | if (!root->bus) { |
508 | if (!root->bus) { |
507 | printk(KERN_ERR PREFIX |
509 | printk(KERN_ERR PREFIX |
508 | "Bus %04x:%02x not present in PCI namespace\n", |
510 | "Bus %04x:%02x not present in PCI namespace\n", |
509 | root->segment, (unsigned int)root->secondary.start); |
511 | root->segment, (unsigned int)root->secondary.start); |
510 | result = -ENODEV; |
512 | result = -ENODEV; |
511 | goto end; |
513 | goto end; |
512 | } |
514 | } |
513 | 515 | ||
514 | /* |
516 | /* |
515 | * Attach ACPI-PCI Context |
517 | * Attach ACPI-PCI Context |
516 | * ----------------------- |
518 | * ----------------------- |
517 | * Thus binding the ACPI and PCI devices. |
519 | * Thus binding the ACPI and PCI devices. |
518 | */ |
520 | */ |
519 | result = acpi_pci_bind_root(device); |
521 | result = acpi_pci_bind_root(device); |
520 | if (result) |
522 | if (result) |
521 | goto end; |
523 | goto end; |
522 | 524 | ||
523 | /* |
525 | /* |
524 | * PCI Routing Table |
526 | * PCI Routing Table |
525 | * ----------------- |
527 | * ----------------- |
526 | * Evaluate and parse _PRT, if exists. |
528 | * Evaluate and parse _PRT, if exists. |
527 | */ |
529 | */ |
528 | status = AcpiGetHandle(device->handle, METHOD_NAME__PRT, &handle); |
530 | status = AcpiGetHandle(device->handle, METHOD_NAME__PRT, &handle); |
529 | if (ACPI_SUCCESS(status)) |
531 | if (ACPI_SUCCESS(status)) |
530 | result = acpi_pci_irq_add_prt(device->handle, root->bus); |
532 | result = acpi_pci_irq_add_prt(device->handle, root->bus); |
531 | 533 | ||
532 | /* |
534 | /* |
533 | * Scan and bind all _ADR-Based Devices |
535 | * Scan and bind all _ADR-Based Devices |
534 | */ |
536 | */ |
535 | list_for_each_entry(child, &device->children, node) |
537 | list_for_each_entry(child, &device->children, node) |
536 | acpi_pci_bridge_scan(child); |
538 | acpi_pci_bridge_scan(child); |
537 | 539 | ||
538 | return 0; |
540 | return 0; |
539 | 541 | ||
540 | end: |
542 | end: |
541 | if (!list_empty(&root->node)) |
543 | if (!list_empty(&root->node)) |
542 | list_del(&root->node); |
544 | list_del(&root->node); |
543 | kfree(root); |
545 | kfree(root); |
544 | return result; |
546 | return result; |
545 | } |
547 | } |
546 | 548 | ||
547 | 549 | ||
548 | static const struct acpi_device_ids root_device_ids[] = |
550 | static const struct acpi_device_ids root_device_ids[] = |
549 | { |
551 | { |
550 | {"PNP0A03", 0}, |
552 | {"PNP0A03", 0}, |
551 | {"", 0}, |
553 | {"", 0}, |
552 | }; |
554 | }; |
553 | 555 | ||
554 | void acpi_init_pci(struct acpi_device *device) |
556 | void acpi_init_pci(struct acpi_device *device) |
555 | { |
557 | { |
556 | struct acpi_device *child; |
558 | struct acpi_device *child; |
557 | 559 | ||
558 | if ( !acpi_match_device_ids(device, root_device_ids) ) |
560 | if ( !acpi_match_device_ids(device, root_device_ids) ) |
559 | { |
561 | { |
560 | dbgprintf(PREFIX "PCI root %s\n", device->pnp.bus_id); |
562 | dbgprintf(PREFIX "PCI root %s\n", device->pnp.bus_id); |
561 | acpi_pci_root_add(device); |
563 | acpi_pci_root_add(device); |
562 | }; |
564 | }; |
563 | 565 | ||
564 | list_for_each_entry(child, &device->children, node) |
566 | list_for_each_entry(child, &device->children, node) |
565 | { |
567 | { |
566 | acpi_init_pci(child); |
568 | acpi_init_pci(child); |
567 | }; |
569 | }; |
568 | 570 | ||
569 | }; |
571 | }; |
570 | 572 | ||
571 | 573 | ||
572 | u32_t drvEntry(int action, char *cmdline) |
574 | u32_t drvEntry(int action, char *cmdline) |
573 | { |
575 | { |
574 | u32_t retval; |
576 | u32_t retval; |
575 | 577 | ||
576 | ACPI_STATUS status; |
578 | ACPI_STATUS status; |
577 | 579 | ||
578 | int i; |
580 | int i; |
579 | 581 | ||
580 | if(action != 1) |
582 | if(action != 1) |
581 | return 0; |
583 | return 0; |
582 | 584 | ||
583 | if( !dbg_open("/rd/1/drivers/acpi.log") ) |
585 | if( !dbg_open("/rd/1/drivers/acpi.log") ) |
584 | { |
586 | { |
585 | printf("Can't open /rd/1/drivers/acpi.log\nExit\n"); |
587 | printf("Can't open /rd/1/drivers/acpi.log\nExit\n"); |
586 | return 0; |
588 | return 0; |
587 | } |
589 | } |
588 | 590 | ||
589 | status = AcpiReallocateRootTable(); |
- | |
590 | if (ACPI_FAILURE(status)) { |
- | |
591 | dbgprintf("Unable to reallocate ACPI tables\n"); |
- | |
592 | goto err; |
- | |
593 | } |
- | |
594 | - | ||
595 | status = AcpiInitializeSubsystem(); |
591 | status = AcpiInitializeSubsystem(); |
596 | if (status != AE_OK) { |
592 | if (status != AE_OK) { |
597 | dbgprintf("AcpiInitializeSubsystem failed (%s)\n", |
593 | dbgprintf("AcpiInitializeSubsystem failed (%s)\n", |
598 | AcpiFormatException(status)); |
594 | AcpiFormatException(status)); |
599 | goto err; |
595 | goto err; |
600 | } |
596 | } |
601 | 597 | ||
602 | status = AcpiInitializeTables(NULL, 0, TRUE); |
598 | status = AcpiInitializeTables (NULL, 16, FALSE); |
603 | if (status != AE_OK) { |
599 | if (status != AE_OK) { |
604 | dbgprintf("AcpiInitializeTables failed (%s)\n", |
600 | dbgprintf("AcpiInitializeTables failed (%s)\n", |
605 | AcpiFormatException(status)); |
601 | AcpiFormatException(status)); |
606 | goto err; |
602 | goto err; |
607 | } |
603 | } |
608 | 604 | ||
609 | status = AcpiLoadTables(); |
605 | status = AcpiLoadTables(); |
610 | if (status != AE_OK) { |
606 | if (status != AE_OK) { |
611 | dbgprintf("AcpiLoadTables failed (%s)\n", |
607 | dbgprintf("AcpiLoadTables failed (%s)\n", |
612 | AcpiFormatException(status)); |
608 | AcpiFormatException(status)); |
613 | goto err; |
609 | goto err; |
614 | } |
610 | } |
615 | 611 | ||
616 | // u32_t mode = ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE; |
612 | // u32_t mode = ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE; |
617 | 613 | ||
618 | status = AcpiEnableSubsystem(ACPI_NO_HANDLER_INIT | ACPI_NO_HARDWARE_INIT); |
614 | status = AcpiEnableSubsystem(ACPI_NO_HANDLER_INIT | ACPI_NO_HARDWARE_INIT); |
619 | if (status != AE_OK) { |
615 | if (status != AE_OK) { |
620 | dbgprintf("AcpiEnableSubsystem failed (%s)\n", |
616 | dbgprintf("AcpiEnableSubsystem failed (%s)\n", |
621 | AcpiFormatException(status)); |
617 | AcpiFormatException(status)); |
622 | goto err; |
618 | goto err; |
623 | } |
619 | } |
624 | 620 | ||
625 | status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION); |
621 | status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION); |
626 | if (ACPI_FAILURE (status)) |
622 | if (ACPI_FAILURE (status)) |
627 | { |
623 | { |
628 | dbgprintf("AcpiInitializeObjects failed (%s)\n", |
624 | dbgprintf("AcpiInitializeObjects failed (%s)\n", |
629 | AcpiFormatException(status)); |
625 | AcpiFormatException(status)); |
630 | goto err; |
626 | goto err; |
631 | } |
627 | } |
632 | 628 | ||
633 | 629 | ||
634 | set_pic_mode(IO_APIC); |
630 | set_pic_mode(IO_APIC); |
635 | 631 | ||
636 | acpi_scan(); |
632 | acpi_scan(); |
637 | 633 | ||
638 | acpi_init_pci(acpi_root); |
634 | acpi_init_pci(acpi_root); |
639 | 635 | ||
640 | print_pci_irqs(); |
636 | print_pci_irqs(); |
641 | 637 | ||
642 | create_dm_list(); |
638 | create_dm_list(); |
643 | 639 | ||
644 | print_dm_list(); |
640 | print_dm_list(); |
645 | 641 | ||
646 | write_device_dat("/RD/1/DRIVERS/DEVICES.DAT"); |
642 | write_device_dat("/RD/1/DRIVERS/DEVICES.DAT"); |
647 | 643 | ||
648 | err: |
644 | err: |
649 | 645 | ||
650 | return 0; |
646 | return 0; |
651 | 647 | ||
652 | }; |
648 | }; |
653 | 649 | ||
654 | char* strdup(const char *str) |
650 | char* strdup(const char *str) |
655 | { |
651 | { |
656 | size_t len = strlen (str) + 1; |
652 | size_t len = strlen (str) + 1; |
657 | char *copy = malloc(len); |
653 | char *copy = malloc(len); |
658 | if (copy) |
654 | if (copy) |
659 | { |
655 | { |
660 | memcpy (copy, str, len); |
656 | memcpy (copy, str, len); |
661 | } |
657 | } |
662 | return copy; |
658 | return copy; |
663 | } |
659 | } |
664 | 660 | ||
665 | 661 | ||
666 | static void dm_add_pci_bus(struct pci_bus *bus) |
662 | static void dm_add_pci_bus(struct pci_bus *bus) |
667 | { |
663 | { |
668 | struct pci_bus *tbus; |
664 | struct pci_bus *tbus; |
669 | struct pci_dev *dev; |
665 | struct pci_dev *dev; |
670 | dmdev_t *dmdev; |
666 | dmdev_t *dmdev; |
671 | 667 | ||
672 | dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL); |
668 | dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL); |
673 | 669 | ||
674 | // INIT_LIST_HEAD(&dmdev->list); |
670 | // INIT_LIST_HEAD(&dmdev->list); |
675 | // dmdev->type = 1; |
671 | // dmdev->type = 1; |
676 | // dmdev->acpi_dev = bus->self->acpi_dev; |
672 | // dmdev->acpi_dev = bus->self->acpi_dev; |
677 | // dmdev->pci_dev = bus->self; |
673 | // dmdev->pci_dev = bus->self; |
678 | // list_add_tail(&dmdev->list, &dmdev_tree); |
674 | // list_add_tail(&dmdev->list, &dmdev_tree); |
679 | 675 | ||
680 | list_for_each_entry(dev, &bus->devices, bus_list) |
676 | list_for_each_entry(dev, &bus->devices, bus_list) |
681 | { |
677 | { |
682 | dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL); |
678 | dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL); |
683 | 679 | ||
684 | INIT_LIST_HEAD(&dmdev->list); |
680 | INIT_LIST_HEAD(&dmdev->list); |
685 | dmdev->type = 1; |
681 | dmdev->type = 1; |
686 | dmdev->acpi_dev = dev->acpi_dev; |
682 | dmdev->acpi_dev = dev->acpi_dev; |
687 | dmdev->pci_dev = dev; |
683 | dmdev->pci_dev = dev; |
688 | list_add_tail(&dmdev->list, &dmdev_tree); |
684 | list_add_tail(&dmdev->list, &dmdev_tree); |
689 | }; |
685 | }; |
690 | 686 | ||
691 | list_for_each_entry(tbus, &bus->children, node) |
687 | list_for_each_entry(tbus, &bus->children, node) |
692 | { |
688 | { |
693 | dm_add_pci_bus(tbus); |
689 | dm_add_pci_bus(tbus); |
694 | }; |
690 | }; |
695 | 691 | ||
696 | }; |
692 | }; |
697 | 693 | ||
698 | static ACPI_STATUS |
694 | static ACPI_STATUS |
699 | count_dev_resources(ACPI_RESOURCE *acpi_res, void *data) |
695 | count_dev_resources(ACPI_RESOURCE *acpi_res, void *data) |
700 | { |
696 | { |
701 | (*(int*)data)++; |
697 | (*(int*)data)++; |
702 | return AE_OK; |
698 | return AE_OK; |
703 | } |
699 | } |
704 | 700 | ||
705 | 701 | ||
706 | static void dm_add_acpi(struct acpi_device *device) |
702 | static void dm_add_acpi(struct acpi_device *device) |
707 | { |
703 | { |
708 | struct acpi_device *child; |
704 | struct acpi_device *child; |
709 | ACPI_DEVICE_INFO *info = NULL; |
705 | ACPI_DEVICE_INFO *info = NULL; |
710 | ACPI_STATUS status; |
706 | ACPI_STATUS status; |
711 | 707 | ||
712 | dmdev_t *dmdev; |
708 | dmdev_t *dmdev; |
713 | uint32_t res_num = 0; |
709 | uint32_t res_num = 0; |
714 | 710 | ||
715 | status = AcpiGetObjectInfo(device->handle, &info); |
711 | status = AcpiGetObjectInfo(device->handle, &info); |
716 | 712 | ||
717 | if ( (status == AE_OK) && (info->Valid & ACPI_VALID_HID)) |
713 | if ( (status == AE_OK) && (info->Valid & ACPI_VALID_HID)) |
718 | { |
714 | { |
719 | if( strcmp(info->HardwareId.String,"PNP0C0F") == 0) |
715 | if( strcmp(info->HardwareId.String,"PNP0C0F") == 0) |
720 | { |
716 | { |
721 | kfree(info); |
717 | kfree(info); |
722 | return; |
718 | return; |
723 | }; |
719 | }; |
724 | }; |
720 | }; |
725 | 721 | ||
726 | kfree(info); |
722 | kfree(info); |
727 | 723 | ||
728 | if(device->pci_dev == NULL) |
724 | if(device->pci_dev == NULL) |
729 | { |
725 | { |
730 | AcpiWalkResources(device->handle, METHOD_NAME__CRS, |
726 | AcpiWalkResources(device->handle, METHOD_NAME__CRS, |
731 | count_dev_resources, &res_num); |
727 | count_dev_resources, &res_num); |
732 | 728 | ||
733 | if(res_num != 0) |
729 | if(res_num != 0) |
734 | { |
730 | { |
735 | dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL); |
731 | dmdev = (dmdev_t*)kzalloc(sizeof(dmdev_t),GFP_KERNEL); |
736 | 732 | ||
737 | INIT_LIST_HEAD(&dmdev->list); |
733 | INIT_LIST_HEAD(&dmdev->list); |
738 | dmdev->type = 0; |
734 | dmdev->type = 0; |
739 | dmdev->acpi_dev = device; |
735 | dmdev->acpi_dev = device; |
740 | dmdev->pci_dev = NULL; |
736 | dmdev->pci_dev = NULL; |
741 | list_add_tail(&dmdev->list, &dmdev_tree); |
737 | list_add_tail(&dmdev->list, &dmdev_tree); |
742 | }; |
738 | }; |
743 | }; |
739 | }; |
744 | list_for_each_entry(child, &device->children, node) |
740 | list_for_each_entry(child, &device->children, node) |
745 | { |
741 | { |
746 | dm_add_acpi(child); |
742 | dm_add_acpi(child); |
747 | }; |
743 | }; |
748 | }; |
744 | }; |
749 | 745 | ||
750 | static void create_dm_list() |
746 | static void create_dm_list() |
751 | { |
747 | { |
752 | struct acpi_pci_root *root; |
748 | struct acpi_pci_root *root; |
753 | 749 | ||
754 | 750 | ||
755 | list_for_each_entry(root, &acpi_pci_roots, node) |
751 | list_for_each_entry(root, &acpi_pci_roots, node) |
756 | { |
752 | { |
757 | struct pci_bus *pbus, *tbus; |
753 | struct pci_bus *pbus, *tbus; |
758 | struct pci_dev *dev; |
754 | struct pci_dev *dev; |
759 | 755 | ||
760 | pbus = root->bus; |
756 | pbus = root->bus; |
761 | 757 | ||
762 | dm_add_pci_bus(pbus); |
758 | dm_add_pci_bus(pbus); |
763 | }; |
759 | }; |
764 | 760 | ||
765 | dm_add_acpi(acpi_root); |
761 | dm_add_acpi(acpi_root); |
766 | }; |
762 | }; |
767 | 763 | ||
768 | static void print_pci_resource(struct resource *res) |
764 | static void print_pci_resource(struct resource *res) |
769 | { |
765 | { |
770 | if(res->flags !=0 ) |
766 | if(res->flags !=0 ) |
771 | { |
767 | { |
772 | if(res->flags & IORESOURCE_IO) |
768 | if(res->flags & IORESOURCE_IO) |
773 | dbgprintf(" IO range "); |
769 | dbgprintf(" IO range "); |
774 | else if(res->flags & IORESOURCE_MEM) |
770 | else if(res->flags & IORESOURCE_MEM) |
775 | dbgprintf(" MMIO range "); |
771 | dbgprintf(" MMIO range "); |
776 | dbgprintf("%x - %x\n", res->start, res->end); |
772 | dbgprintf("%x - %x\n", res->start, res->end); |
777 | }; |
773 | }; |
778 | }; |
774 | }; |
779 | 775 | ||
780 | static ACPI_STATUS |
776 | static ACPI_STATUS |
781 | print_acpi_resource(ACPI_RESOURCE *acpi_res, void *data) |
777 | print_acpi_resource(ACPI_RESOURCE *acpi_res, void *data) |
782 | { |
778 | { |
783 | ACPI_RESOURCE_ADDRESS64 addr; |
779 | ACPI_RESOURCE_ADDRESS64 addr; |
784 | ACPI_STATUS status; |
780 | ACPI_STATUS status; |
785 | int i; |
781 | int i; |
786 | 782 | ||
787 | switch (acpi_res->Type) |
783 | switch (acpi_res->Type) |
788 | { |
784 | { |
789 | case ACPI_RESOURCE_TYPE_IRQ: |
785 | case ACPI_RESOURCE_TYPE_IRQ: |
790 | { |
786 | { |
791 | ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*)&acpi_res->Data; |
787 | ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*)&acpi_res->Data; |
792 | dbgprintf(" IRQ %d\n", irq_data->Interrupts[0]); |
788 | dbgprintf(" IRQ %d\n", irq_data->Interrupts[0]); |
793 | }; |
789 | }; |
794 | break; |
790 | break; |
795 | 791 | ||
796 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
792 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
797 | { |
793 | { |
798 | ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*)&acpi_res->Data; |
794 | ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*)&acpi_res->Data; |
799 | dbgprintf(" IRQ %d\n", irq_data->Interrupts[0]); |
795 | dbgprintf(" IRQ %d\n", irq_data->Interrupts[0]); |
800 | }; |
796 | }; |
801 | break; |
797 | break; |
802 | 798 | ||
803 | case ACPI_RESOURCE_TYPE_DMA: |
799 | case ACPI_RESOURCE_TYPE_DMA: |
804 | { |
800 | { |
805 | ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &acpi_res->Data; |
801 | ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &acpi_res->Data; |
806 | for(i=0; i < dma_data->ChannelCount; i++) |
802 | for(i=0; i < dma_data->ChannelCount; i++) |
807 | { |
803 | { |
808 | dbgprintf(" DMA %s channel %d\n", |
804 | dbgprintf(" DMA %s channel %d\n", |
809 | dma_data->Type == ACPI_TYPE_A ? "Type A": |
805 | dma_data->Type == ACPI_TYPE_A ? "Type A": |
810 | dma_data->Type == ACPI_TYPE_B ? "Type B" : |
806 | dma_data->Type == ACPI_TYPE_B ? "Type B" : |
811 | dma_data->Type == ACPI_TYPE_F ? "Type F" : "", |
807 | dma_data->Type == ACPI_TYPE_F ? "Type F" : "", |
812 | dma_data->Channels[i]); |
808 | dma_data->Channels[i]); |
813 | } |
809 | } |
814 | }; |
810 | }; |
815 | break; |
811 | break; |
816 | 812 | ||
817 | case ACPI_RESOURCE_TYPE_IO: |
813 | case ACPI_RESOURCE_TYPE_IO: |
818 | { |
814 | { |
819 | ACPI_RESOURCE_IO *io_data = (ACPI_RESOURCE_IO*) &acpi_res->Data; |
815 | ACPI_RESOURCE_IO *io_data = (ACPI_RESOURCE_IO*) &acpi_res->Data; |
820 | 816 | ||
821 | dbgprintf(" IO range 0%x-0%x\n",io_data->Minimum, |
817 | dbgprintf(" IO range 0%x-0%x\n",io_data->Minimum, |
822 | io_data->Minimum+io_data->AddressLength-1); |
818 | io_data->Minimum+io_data->AddressLength-1); |
823 | } |
819 | } |
824 | break; |
820 | break; |
825 | 821 | ||
826 | case ACPI_RESOURCE_TYPE_FIXED_IO: |
822 | case ACPI_RESOURCE_TYPE_FIXED_IO: |
827 | { |
823 | { |
828 | ACPI_RESOURCE_FIXED_IO *io_data = (ACPI_RESOURCE_FIXED_IO*) &acpi_res->Data; |
824 | ACPI_RESOURCE_FIXED_IO *io_data = (ACPI_RESOURCE_FIXED_IO*) &acpi_res->Data; |
829 | dbgprintf(" Fixed IO range 0%x-0%x\n",io_data->Address, |
825 | dbgprintf(" Fixed IO range 0%x-0%x\n",io_data->Address, |
830 | io_data->Address+io_data->AddressLength-1); |
826 | io_data->Address+io_data->AddressLength-1); |
831 | }; |
827 | }; |
832 | break; |
828 | break; |
833 | 829 | ||
834 | case ACPI_RESOURCE_TYPE_MEMORY24: |
830 | case ACPI_RESOURCE_TYPE_MEMORY24: |
835 | case ACPI_RESOURCE_TYPE_MEMORY32: |
831 | case ACPI_RESOURCE_TYPE_MEMORY32: |
836 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
832 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
837 | { |
833 | { |
838 | ACPI_RESOURCE_ADDRESS64 addr64; |
834 | ACPI_RESOURCE_ADDRESS64 addr64; |
839 | resource_to_addr(acpi_res, &addr64); |
835 | resource_to_addr(acpi_res, &addr64); |
840 | dbgprintf(" Memory range 0%x-0%x\n", |
836 | dbgprintf(" Memory range 0%x-0%x\n", |
841 | (uint32_t)addr64.Minimum, (uint32_t)addr64.Maximum); |
837 | (uint32_t)addr64.Minimum, (uint32_t)addr64.Maximum); |
842 | } |
838 | } |
843 | break; |
839 | break; |
844 | 840 | ||
845 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
841 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
846 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
842 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
847 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
843 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
848 | { |
844 | { |
849 | ACPI_RESOURCE_ADDRESS64 addr64; |
845 | ACPI_RESOURCE_ADDRESS64 addr64; |
850 | ACPI_STATUS status; |
846 | ACPI_STATUS status; |
851 | 847 | ||
852 | status = AcpiResourceToAddress64(acpi_res, &addr64); |
848 | status = AcpiResourceToAddress64(acpi_res, &addr64); |
853 | if (ACPI_SUCCESS(status)) |
849 | if (ACPI_SUCCESS(status)) |
854 | { |
850 | { |
855 | dbgprintf(" Address range 0%x-0%x\n", |
851 | dbgprintf(" Address range 0%x-0%x\n", |
856 | (uint32_t)addr64.Minimum, (uint32_t)addr64.Maximum); |
852 | (uint32_t)addr64.Minimum, (uint32_t)addr64.Maximum); |
857 | } |
853 | } |
858 | }; |
854 | }; |
859 | break; |
855 | break; |
860 | }; |
856 | }; |
861 | 857 | ||
862 | return AE_OK; |
858 | return AE_OK; |
863 | }; |
859 | }; |
864 | 860 | ||
865 | 861 | ||
866 | static void print_dm_list() |
862 | static void print_dm_list() |
867 | { |
863 | { |
868 | struct pci_dev *pcidev; |
864 | struct pci_dev *pcidev; |
869 | struct acpi_device *acpidev; |
865 | struct acpi_device *acpidev; |
870 | dmdev_t *dmdev; |
866 | dmdev_t *dmdev; |
871 | uint32_t i; |
867 | uint32_t i; |
872 | 868 | ||
873 | dbgprintf("\nDevices:\n"); |
869 | dbgprintf("\nDevices:\n"); |
874 | 870 | ||
875 | list_for_each_entry(dmdev, &dmdev_tree, list) |
871 | list_for_each_entry(dmdev, &dmdev_tree, list) |
876 | { |
872 | { |
877 | switch(dmdev->type) |
873 | switch(dmdev->type) |
878 | { |
874 | { |
879 | case 0: |
875 | case 0: |
880 | if(dmdev->acpi_dev != NULL) |
876 | if(dmdev->acpi_dev != NULL) |
881 | { |
877 | { |
882 | acpidev = dmdev->acpi_dev; |
878 | acpidev = dmdev->acpi_dev; |
883 | dbgprintf("\n%s\n", acpidev->pnp.bus_id); |
879 | dbgprintf("\n%s\n", acpidev->pnp.bus_id); |
884 | AcpiWalkResources(acpidev->handle, METHOD_NAME__CRS, |
880 | AcpiWalkResources(acpidev->handle, METHOD_NAME__CRS, |
885 | print_acpi_resource, NULL); |
881 | print_acpi_resource, NULL); |
886 | }; |
882 | }; |
887 | break; |
883 | break; |
888 | 884 | ||
889 | case 1: |
885 | case 1: |
890 | if(dmdev->pci_dev != NULL) |
886 | if(dmdev->pci_dev != NULL) |
891 | { |
887 | { |
892 | pcidev = dmdev->pci_dev; |
888 | pcidev = dmdev->pci_dev; |
893 | dbgprintf("\nPCI_%x_%x bus:%d devfn: %x\n", |
889 | dbgprintf("\nPCI_%x_%x bus:%d devfn: %x\n", |
894 | pcidev->vendor, pcidev->device, |
890 | pcidev->vendor, pcidev->device, |
895 | pcidev->busnr, pcidev->devfn); |
891 | pcidev->busnr, pcidev->devfn); |
896 | 892 | ||
897 | for(i = 0; i < DEVICE_COUNT_RESOURCE; i++) |
893 | for(i = 0; i < DEVICE_COUNT_RESOURCE; i++) |
898 | print_pci_resource(&pcidev->resource[i]); |
894 | print_pci_resource(&pcidev->resource[i]); |
899 | 895 | ||
900 | if(pcidev->pin) |
896 | if(pcidev->pin) |
901 | dbgprintf(" APIC IRQ: %d\n", acpi_get_irq(pcidev)); |
897 | dbgprintf(" APIC IRQ: %d\n", acpi_get_irq(pcidev)); |
902 | }; |
898 | }; |
903 | break; |
899 | break; |
904 | }; |
900 | }; |
905 | }; |
901 | }; |
906 | }; |
902 | }; |
907 | 903 | ||
908 | 904 | ||
909 | typedef struct |
905 | typedef struct |
910 | { |
906 | { |
911 | uint32_t busaddr; |
907 | uint32_t busaddr; |
912 | uint32_t devid; |
908 | uint32_t devid; |
913 | uint32_t irq; |
909 | uint32_t irq; |
914 | uint32_t unused; |
910 | uint32_t unused; |
915 | }devinfo_t; |
911 | }devinfo_t; |
916 | 912 | ||
917 | #pragma pack(push, 1) |
913 | #pragma pack(push, 1) |
918 | typedef struct |
914 | typedef struct |
919 | { |
915 | { |
920 | char sec; |
916 | char sec; |
921 | char min; |
917 | char min; |
922 | char hour; |
918 | char hour; |
923 | char rsv; |
919 | char rsv; |
924 | }detime_t; |
920 | }detime_t; |
925 | 921 | ||
926 | typedef struct |
922 | typedef struct |
927 | { |
923 | { |
928 | char day; |
924 | char day; |
929 | char month; |
925 | char month; |
930 | short year; |
926 | short year; |
931 | }dedate_t; |
927 | }dedate_t; |
932 | 928 | ||
933 | typedef struct |
929 | typedef struct |
934 | { |
930 | { |
935 | unsigned attr; |
931 | unsigned attr; |
936 | unsigned flags; |
932 | unsigned flags; |
937 | union |
933 | union |
938 | { |
934 | { |
939 | detime_t ctime; |
935 | detime_t ctime; |
940 | unsigned cr_time; |
936 | unsigned cr_time; |
941 | }; |
937 | }; |
942 | union |
938 | union |
943 | { |
939 | { |
944 | dedate_t cdate; |
940 | dedate_t cdate; |
945 | unsigned cr_date; |
941 | unsigned cr_date; |
946 | }; |
942 | }; |
947 | union |
943 | union |
948 | { |
944 | { |
949 | detime_t atime; |
945 | detime_t atime; |
950 | unsigned acc_time; |
946 | unsigned acc_time; |
951 | }; |
947 | }; |
952 | union |
948 | union |
953 | { |
949 | { |
954 | dedate_t adate; |
950 | dedate_t adate; |
955 | unsigned acc_date; |
951 | unsigned acc_date; |
956 | }; |
952 | }; |
957 | union |
953 | union |
958 | { |
954 | { |
959 | detime_t mtime; |
955 | detime_t mtime; |
960 | unsigned mod_time; |
956 | unsigned mod_time; |
961 | }; |
957 | }; |
962 | union |
958 | union |
963 | { |
959 | { |
964 | dedate_t mdate; |
960 | dedate_t mdate; |
965 | unsigned mod_date; |
961 | unsigned mod_date; |
966 | }; |
962 | }; |
967 | unsigned size; |
963 | unsigned size; |
968 | unsigned size_high; |
964 | unsigned size_high; |
969 | } FILEINFO; |
965 | } FILEINFO; |
970 | 966 | ||
971 | #pragma pack(pop) |
967 | #pragma pack(pop) |
972 | 968 | ||
973 | 969 | ||
974 | int write_device_dat(char *path) |
970 | int write_device_dat(char *path) |
975 | { |
971 | { |
976 | struct pci_dev *pcidev; |
972 | struct pci_dev *pcidev; |
977 | dmdev_t *dmdev; |
973 | dmdev_t *dmdev; |
978 | devinfo_t *data; |
974 | devinfo_t *data; |
979 | int writes; |
975 | int writes; |
980 | int len; |
976 | int len; |
981 | int i = 0; |
977 | int i = 0; |
982 | 978 | ||
983 | list_for_each_entry(dmdev, &dmdev_tree, list) |
979 | list_for_each_entry(dmdev, &dmdev_tree, list) |
984 | { |
980 | { |
985 | if(dmdev->type ==1) |
981 | if(dmdev->type ==1) |
986 | { |
982 | { |
987 | if(dmdev->pci_dev != NULL) |
983 | if(dmdev->pci_dev != NULL) |
988 | { |
984 | { |
989 | pcidev = dmdev->pci_dev; |
985 | pcidev = dmdev->pci_dev; |
990 | if(pcidev->pin) |
986 | if(pcidev->pin) |
991 | i++; |
987 | i++; |
992 | }; |
988 | }; |
993 | }; |
989 | }; |
994 | }; |
990 | }; |
995 | 991 | ||
996 | len = sizeof(devinfo_t)*i + 4; |
992 | len = sizeof(devinfo_t)*i + 4; |
997 | data = (devinfo_t*)malloc(len); |
993 | data = (devinfo_t*)malloc(len); |
998 | 994 | ||
999 | i = 0; |
995 | i = 0; |
1000 | 996 | ||
1001 | list_for_each_entry(dmdev, &dmdev_tree, list) |
997 | list_for_each_entry(dmdev, &dmdev_tree, list) |
1002 | { |
998 | { |
1003 | if(dmdev->type == 1) |
999 | if(dmdev->type == 1) |
1004 | { |
1000 | { |
1005 | 1001 | ||
1006 | if(dmdev->pci_dev != NULL) |
1002 | if(dmdev->pci_dev != NULL) |
1007 | { |
1003 | { |
1008 | pcidev = dmdev->pci_dev; |
1004 | pcidev = dmdev->pci_dev; |
1009 | if(pcidev->pin && (acpi_get_irq(pcidev) != -1) ) |
1005 | if(pcidev->pin && (acpi_get_irq(pcidev) != -1) ) |
1010 | { |
1006 | { |
1011 | data[i].busaddr = (pcidev->busnr<<8)|pcidev->devfn; |
1007 | data[i].busaddr = (pcidev->busnr<<8)|pcidev->devfn; |
1012 | data[i].devid = ((uint32_t)pcidev->device<<16) | |
1008 | data[i].devid = ((uint32_t)pcidev->device<<16) | |
1013 | pcidev->vendor; |
1009 | pcidev->vendor; |
1014 | data[i].irq = acpi_get_irq(pcidev); |
1010 | data[i].irq = acpi_get_irq(pcidev); |
1015 | data[i].unused = 0; |
1011 | data[i].unused = 0; |
1016 | i++; |
1012 | i++; |
1017 | } |
1013 | } |
1018 | }; |
1014 | }; |
1019 | }; |
1015 | }; |
1020 | }; |
1016 | }; |
1021 | 1017 | ||
1022 | data[i].busaddr = -1; |
1018 | data[i].busaddr = -1; |
1023 | 1019 | ||
1024 | FILEINFO info; |
1020 | FILEINFO info; |
1025 | 1021 | ||
1026 | int offset = 0; |
1022 | int offset = 0; |
1027 | 1023 | ||
1028 | if(get_fileinfo(path,&info)) |
1024 | if(get_fileinfo(path,&info)) |
1029 | { |
1025 | { |
1030 | if( create_file(path)) |
1026 | if( create_file(path)) |
1031 | { |
1027 | { |
1032 | free(data); |
1028 | free(data); |
1033 | return false; |
1029 | return false; |
1034 | } |
1030 | } |
1035 | } |
1031 | } |
1036 | else |
1032 | else |
1037 | set_file_size(path, 0); |
1033 | set_file_size(path, 0); |
1038 | 1034 | ||
1039 | write_file(path, data, 0, len, &writes); |
1035 | write_file(path, data, 0, len, &writes); |
1040 | 1036 | ||
1041 | return true; |
1037 | return true; |
1042 | };16)><16)>8)|pcidev-><8)|pcidev->>> |
1038 | };16)><16)>8)|pcidev-><8)|pcidev->>> |