1 |
/* |
/* |
2 |
* Copyright (C) 2005-2006 Anders Gavare. All rights reserved. |
* Copyright (C) 2005-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: device.c,v 1.26 2006/04/06 19:17:37 debug Exp $ |
* $Id: device.c,v 1.32 2006/12/30 13:30:51 debug Exp $ |
29 |
* |
* |
30 |
* Device registry framework. |
* Device registry framework. |
31 |
*/ |
*/ |
35 |
#include <string.h> |
#include <string.h> |
36 |
|
|
37 |
#include "device.h" |
#include "device.h" |
38 |
|
#include "machine.h" |
39 |
#include "memory.h" |
#include "memory.h" |
40 |
#include "misc.h" |
#include "misc.h" |
41 |
|
|
265 |
struct device_entry *p; |
struct device_entry *p; |
266 |
struct devinit devinit; |
struct devinit devinit; |
267 |
char *s2, *s3; |
char *s2, *s3; |
268 |
size_t len; |
size_t len, interrupt_path_len = strlen(machine->path) + 100; |
269 |
int quoted; |
int quoted; |
270 |
|
|
271 |
memset(&devinit, 0, sizeof(struct devinit)); |
memset(&devinit, 0, sizeof(struct devinit)); |
288 |
} |
} |
289 |
memcpy(devinit.name, name_and_params, len); |
memcpy(devinit.name, name_and_params, len); |
290 |
devinit.name[len] = '\0'; |
devinit.name[len] = '\0'; |
291 |
devinit.dma_irq_nr = -1; |
|
292 |
|
/* Allocate space for the default interrupt name: */ |
293 |
|
devinit.interrupt_path = malloc(interrupt_path_len + 1); |
294 |
|
if (devinit.interrupt_path == NULL) { |
295 |
|
fprintf(stderr, "device_add(): out of memory\n"); |
296 |
|
exit(1); |
297 |
|
} |
298 |
|
snprintf(devinit.interrupt_path, interrupt_path_len, |
299 |
|
"%s.cpu[%i]", machine->path, machine->bootstrap_cpu); |
300 |
|
|
301 |
p = device_lookup(devinit.name); |
p = device_lookup(devinit.name); |
302 |
if (p == NULL) { |
if (p == NULL) { |
352 |
} |
} |
353 |
} else if (strncmp(s2, "irq=", 4) == 0) { |
} else if (strncmp(s2, "irq=", 4) == 0) { |
354 |
devinit.irq_nr = mystrtoull(s3, NULL, 0); |
devinit.irq_nr = mystrtoull(s3, NULL, 0); |
355 |
} else if (strncmp(s2, "dma_irq=", 8) == 0) { |
|
356 |
devinit.dma_irq_nr = mystrtoull(s3, NULL, 0); |
/* New-style interrupt path: */ |
357 |
|
snprintf(devinit.interrupt_path, interrupt_path_len,s3); |
358 |
|
if (strchr(devinit.interrupt_path, ' ') != NULL) |
359 |
|
*strchr(devinit.interrupt_path, ' ') = '\0'; |
360 |
|
|
361 |
|
if (strncmp(s3, "none", 4) == 0) |
362 |
|
devinit.interrupt_path[0] = '\0'; |
363 |
} else if (strncmp(s2, "in_use=", 7) == 0) { |
} else if (strncmp(s2, "in_use=", 7) == 0) { |
364 |
devinit.in_use = mystrtoull(s3, NULL, 0); |
devinit.in_use = mystrtoull(s3, NULL, 0); |
365 |
} else if (strncmp(s2, "name2=", 6) == 0) { |
} else if (strncmp(s2, "name2=", 6) == 0) { |
416 |
goto return_fail; |
goto return_fail; |
417 |
} |
} |
418 |
|
|
419 |
|
free(devinit.interrupt_path); |
420 |
free(devinit.name); |
free(devinit.name); |
421 |
return devinit.return_ptr; |
return devinit.return_ptr; |
422 |
|
|