diff options
Diffstat (limited to 'libdde_linux26/lib/src/arch/l4')
-rw-r--r-- | libdde_linux26/lib/src/arch/l4/param.c | 63 | ||||
-rw-r--r-- | libdde_linux26/lib/src/arch/l4/pci.c | 31 | ||||
-rw-r--r-- | libdde_linux26/lib/src/arch/l4/softirq.c | 14 |
3 files changed, 92 insertions, 16 deletions
diff --git a/libdde_linux26/lib/src/arch/l4/param.c b/libdde_linux26/lib/src/arch/l4/param.c index 5bd83f32..c459428a 100644 --- a/libdde_linux26/lib/src/arch/l4/param.c +++ b/libdde_linux26/lib/src/arch/l4/param.c @@ -26,6 +26,69 @@ STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, simple_strtoul); STANDARD_PARAM_DEF(long, long, "%li", long, simple_strtol); STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, simple_strtoul); +int param_set_charp(const char *val, struct kernel_param *kp) +{ + if (!val) { + printk(KERN_ERR "%s: string parameter expected\n", + kp->name); + return -EINVAL; + } + + if (strlen(val) > 1024) { + printk(KERN_ERR "%s: string parameter too long\n", + kp->name); + return -ENOSPC; + } + + *(char **)kp->arg = (char *)val; + return 0; +} + +int param_get_charp(char *buffer, struct kernel_param *kp) +{ + return sprintf(buffer, "%s", *((char **)kp->arg)); +} + +int param_set_bool(const char *val, struct kernel_param *kp) +{ + /* No equals means "set"... */ + if (!val) val = "1"; + + /* One of =[yYnN01] */ + switch (val[0]) { + case 'y': case 'Y': case '1': + *(int *)kp->arg = 1; + return 0; + case 'n': case 'N': case '0': + *(int *)kp->arg = 0; + return 0; + } + return -EINVAL; +} + +int param_get_bool(char *buffer, struct kernel_param *kp) +{ + /* Y and N chosen as being relatively non-coder friendly */ + return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'Y' : 'N'); +} + +int param_set_invbool(const char *val, struct kernel_param *kp) +{ + int boolval, ret; + struct kernel_param dummy; + + dummy.arg = &boolval; + ret = param_set_bool(val, &dummy); + if (ret == 0) + *(int *)kp->arg = !boolval; + return ret; +} + +int param_get_invbool(char *buffer, struct kernel_param *kp) +{ + return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'N' : 'Y'); +} + int printk_ratelimit(void) { return 0; diff --git a/libdde_linux26/lib/src/arch/l4/pci.c b/libdde_linux26/lib/src/arch/l4/pci.c index c393fd3a..b50a7353 100644 --- a/libdde_linux26/lib/src/arch/l4/pci.c +++ b/libdde_linux26/lib/src/arch/l4/pci.c @@ -24,10 +24,6 @@ typedef struct l4dde_pci_dev { /** List of Linux-DDEKit PCIDev mappings */ static LIST_HEAD(pcidev_mappings); -/** PCI bus */ -static struct pci_bus *pci_bus = NULL; -static struct pci_bus *pci_bus1 = NULL; - static int l4dde26_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); static int l4dde26_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); @@ -187,18 +183,21 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) void __init l4dde26_init_pci(void) { ddekit_pci_init(); - - // TODO it's a temporary solution to handle 2 buses. - // we need to find a way to detect buses. - pci_bus = pci_create_bus(NULL, 0, &dde_pcibus_ops, NULL); - Assert(pci_bus); - - pci_do_scan_bus(pci_bus); - - pci_bus1 = pci_create_bus(NULL, 2, &dde_pcibus_ops, NULL); - Assert(pci_bus1); - - pci_do_scan_bus(pci_bus1); + int nr; + char found[256] = { }; + int bus, slot, func; + + for (nr = 0; ; nr++) { + if (ddekit_pci_get_device(nr, &bus, &slot, &func) != 0) + break; + if (!found[bus]) { + struct pci_bus *pci_bus = pci_create_bus(NULL, bus, &dde_pcibus_ops, NULL); + Assert(pci_bus); + pci_do_scan_bus(pci_bus); + + found[bus] = 1; + } + } INITIALIZE_INITVAR(dde26_pci); } diff --git a/libdde_linux26/lib/src/arch/l4/softirq.c b/libdde_linux26/lib/src/arch/l4/softirq.c index 247a414f..d93bfaff 100644 --- a/libdde_linux26/lib/src/arch/l4/softirq.c +++ b/libdde_linux26/lib/src/arch/l4/softirq.c @@ -67,6 +67,20 @@ void tasklet_init(struct tasklet_struct *t, t->data = data; } +void tasklet_kill(struct tasklet_struct *t) +{ + if (in_interrupt()) + printk("Attempt to kill tasklet from interrupt\n"); + + while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { + do + yield(); + while (test_bit(TASKLET_STATE_SCHED, &t->state)); + } + tasklet_unlock_wait(t); + clear_bit(TASKLET_STATE_SCHED, &t->state); +} + /* enqueue tasklet */ static void __tasklet_enqueue(struct tasklet_struct *t, struct tasklet_head *listhead) |