[Bluetooth] Restrict well known PSM to privileged users
[pandora-kernel.git] / drivers / pcmcia / rsrc_nonstatic.c
index 00960a3..c3176b1 100644 (file)
@@ -12,7 +12,6 @@
  * (C) 1999            David A. Hinds
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
@@ -61,7 +60,7 @@ struct socket_data {
        unsigned int                    rsrc_mem_probe;
 };
 
-static DECLARE_MUTEX(rsrc_sem);
+static DEFINE_MUTEX(rsrc_mutex);
 #define MEM_PROBE_LOW  (1 << 0)
 #define MEM_PROBE_HIGH (1 << 1)
 
@@ -73,12 +72,11 @@ static DECLARE_MUTEX(rsrc_sem);
 ======================================================================*/
 
 static struct resource *
-make_resource(unsigned long b, unsigned long n, int flags, char *name)
+make_resource(resource_size_t b, resource_size_t n, int flags, char *name)
 {
-       struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
+       struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
        if (res) {
-               memset(res, 0, sizeof(*res));
                res->name = name;
                res->start = b;
                res->end = b + n - 1;
@@ -88,8 +86,8 @@ make_resource(unsigned long b, unsigned long n, int flags, char *name)
 }
 
 static struct resource *
-claim_region(struct pcmcia_socket *s, unsigned long base, unsigned long size,
-            int type, char *name)
+claim_region(struct pcmcia_socket *s, resource_size_t base,
+               resource_size_t size, int type, char *name)
 {
        struct resource *res, *parent;
 
@@ -200,12 +198,11 @@ static void do_io_probe(struct pcmcia_socket *s, kio_addr_t base, kio_addr_t num
           base, base+num-1);
 
     /* First, what does a floating port look like? */
-    b = kmalloc(256, GFP_KERNEL);
+    b = kzalloc(256, GFP_KERNEL);
     if (!b) {
             printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
             return;
     }
-    memset(b, 0, 256);
     for (i = base, most = 0; i < base+num; i += 8) {
        res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
        if (!res)
@@ -407,98 +404,111 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
 
 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
 {
-    struct socket_data *s_data = s->resource_data;
-    u_long ok;
-    if (m == &s_data->mem_db)
-       return 0;
-    ok = inv_probe(m->next, s);
-    if (ok) {
-       if (m->base >= 0x100000)
-           sub_interval(&s_data->mem_db, m->base, m->num);
-       return ok;
-    }
-    if (m->base < 0x100000)
-       return 0;
-    return do_mem_probe(m->base, m->num, s);
+       struct socket_data *s_data = s->resource_data;
+       u_long ok;
+       if (m == &s_data->mem_db)
+               return 0;
+       ok = inv_probe(m->next, s);
+       if (ok) {
+               if (m->base >= 0x100000)
+                       sub_interval(&s_data->mem_db, m->base, m->num);
+               return ok;
+       }
+       if (m->base < 0x100000)
+               return 0;
+       return do_mem_probe(m->base, m->num, s);
 }
 
-static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
+static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 {
-    struct resource_map *m, mm;
-    static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
-    u_long b, i, ok = 0;
-    struct socket_data *s_data = s->resource_data;
+       struct resource_map *m, mm;
+       static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
+       unsigned long b, i, ok = 0;
+       struct socket_data *s_data = s->resource_data;
 
-    /* We do up to four passes through the list */
-    if (probe_mask & MEM_PROBE_HIGH) {
-       if (inv_probe(s_data->mem_db.next, s) > 0)
-           return;
-       printk(KERN_NOTICE "cs: warning: no high memory space "
-              "available!\n");
-    }
-    if ((probe_mask & MEM_PROBE_LOW) == 0)
-       return;
-    for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
-       mm = *m;
-       /* Only probe < 1 MB */
-       if (mm.base >= 0x100000) continue;
-       if ((mm.base | mm.num) & 0xffff) {
-           ok += do_mem_probe(mm.base, mm.num, s);
-           continue;
+       /* We do up to four passes through the list */
+       if (probe_mask & MEM_PROBE_HIGH) {
+               if (inv_probe(s_data->mem_db.next, s) > 0)
+                       return 0;
+               printk(KERN_NOTICE "cs: warning: no high memory space "
+                      "available!\n");
+               return -ENODEV;
        }
-       /* Special probe for 64K-aligned block */
-       for (i = 0; i < 4; i++) {
-           b = order[i] << 12;
-           if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
-               if (ok >= mem_limit)
-                   sub_interval(&s_data->mem_db, b, 0x10000);
-               else
-                   ok += do_mem_probe(b, 0x10000, s);
-           }
+
+       for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
+               mm = *m;
+               /* Only probe < 1 MB */
+               if (mm.base >= 0x100000)
+                       continue;
+               if ((mm.base | mm.num) & 0xffff) {
+                       ok += do_mem_probe(mm.base, mm.num, s);
+                       continue;
+               }
+               /* Special probe for 64K-aligned block */
+               for (i = 0; i < 4; i++) {
+                       b = order[i] << 12;
+                       if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
+                               if (ok >= mem_limit)
+                                       sub_interval(&s_data->mem_db, b, 0x10000);
+                               else
+                                       ok += do_mem_probe(b, 0x10000, s);
+                       }
+               }
        }
-    }
+
+       if (ok > 0)
+               return 0;
+
+       return -ENODEV;
 }
 
 #else /* CONFIG_PCMCIA_PROBE */
 
-static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
+static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 {
        struct resource_map *m, mm;
        struct socket_data *s_data = s->resource_data;
+       unsigned long ok = 0;
 
        for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
                mm = *m;
-               do_mem_probe(mm.base, mm.num, s);
+               ok += do_mem_probe(mm.base, mm.num, s);
        }
+       if (ok > 0)
+               return 0;
+       return -ENODEV;
 }
 
 #endif /* CONFIG_PCMCIA_PROBE */
 
 
 /*
- * Locking note: Must be called with skt_sem held!
+ * Locking note: Must be called with skt_mutex held!
  */
-static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
+static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
 {
        struct socket_data *s_data = s->resource_data;
-       if (probe_mem) {
-               unsigned int probe_mask;
+       unsigned int probe_mask = MEM_PROBE_LOW;
+       int ret = 0;
+
+       if (!probe_mem)
+               return 0;
 
-               down(&rsrc_sem);
+       mutex_lock(&rsrc_mutex);
 
-               probe_mask = MEM_PROBE_LOW;
-               if (s->features & SS_CAP_PAGE_REGS)
-                       probe_mask = MEM_PROBE_HIGH;
+       if (s->features & SS_CAP_PAGE_REGS)
+               probe_mask = MEM_PROBE_HIGH;
 
-               if (probe_mask & ~s_data->rsrc_mem_probe) {
+       if (probe_mask & ~s_data->rsrc_mem_probe) {
+               if (s->state & SOCKET_PRESENT)
+                       ret = validate_mem(s, probe_mask);
+               if (!ret)
                        s_data->rsrc_mem_probe |= probe_mask;
+       }
 
-                       if (s->state & SOCKET_PRESENT)
-                               validate_mem(s, probe_mask);
-               }
+       mutex_unlock(&rsrc_mutex);
 
-               up(&rsrc_sem);
-       }
+       return ret;
 }
 
 struct pcmcia_align_data {
@@ -509,10 +519,10 @@ struct pcmcia_align_data {
 
 static void
 pcmcia_common_align(void *align_data, struct resource *res,
-                   unsigned long size, unsigned long align)
+                       resource_size_t size, resource_size_t align)
 {
        struct pcmcia_align_data *data = align_data;
-       unsigned long start;
+       resource_size_t start;
        /*
         * Ensure that we have the correct start address
         */
@@ -523,8 +533,8 @@ pcmcia_common_align(void *align_data, struct resource *res,
 }
 
 static void
-pcmcia_align(void *align_data, struct resource *res,
-            unsigned long size, unsigned long align)
+pcmcia_align(void *align_data, struct resource *res, resource_size_t size,
+               resource_size_t align)
 {
        struct pcmcia_align_data *data = align_data;
        struct resource_map *m;
@@ -574,7 +584,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
        struct socket_data *s_data = s->resource_data;
        int ret = -ENOMEM;
 
-       down(&rsrc_sem);
+       mutex_lock(&rsrc_mutex);
        for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
                unsigned long start = m->base;
                unsigned long end = m->base + m->num - 1;
@@ -585,7 +595,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
                ret = adjust_resource(res, r_start, r_end - r_start + 1);
                break;
        }
-       up(&rsrc_sem);
+       mutex_unlock(&rsrc_mutex);
 
        return ret;
 }
@@ -619,7 +629,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
        data.offset = base & data.mask;
        data.map = &s_data->io_db;
 
-       down(&rsrc_sem);
+       mutex_lock(&rsrc_mutex);
 #ifdef CONFIG_PCI
        if (s->cb_dev) {
                ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
@@ -628,7 +638,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
 #endif
                ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
                                        1, pcmcia_align, &data);
-       up(&rsrc_sem);
+       mutex_unlock(&rsrc_mutex);
 
        if (ret != 0) {
                kfree(res);
@@ -661,7 +671,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
                        min = 0x100000UL + base;
                }
 
-               down(&rsrc_sem);
+               mutex_lock(&rsrc_mutex);
 #ifdef CONFIG_PCI
                if (s->cb_dev) {
                        ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
@@ -671,7 +681,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
 #endif
                        ret = allocate_resource(&iomem_resource, res, num, min,
                                                max, 1, pcmcia_align, &data);
-               up(&rsrc_sem);
+               mutex_unlock(&rsrc_mutex);
                if (ret == 0 || low)
                        break;
                low = 1;
@@ -694,7 +704,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
        if (end < start)
                return -EINVAL;
 
-       down(&rsrc_sem);
+       mutex_lock(&rsrc_mutex);
        switch (action) {
        case ADD_MANAGED_RESOURCE:
                ret = add_interval(&data->mem_db, start, size);
@@ -712,7 +722,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
        default:
                ret = -EINVAL;
        }
-       up(&rsrc_sem);
+       mutex_unlock(&rsrc_mutex);
 
        return ret;
 }
@@ -730,7 +740,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
        if (end > IO_SPACE_LIMIT)
                return -EINVAL;
 
-       down(&rsrc_sem);
+       mutex_lock(&rsrc_mutex);
        switch (action) {
        case ADD_MANAGED_RESOURCE:
                if (add_interval(&data->io_db, start, size) != 0) {
@@ -749,7 +759,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
                ret = -EINVAL;
                break;
        }
-       up(&rsrc_sem);
+       mutex_unlock(&rsrc_mutex);
 
        return ret;
 }
@@ -798,8 +808,10 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
                if (res->flags & IORESOURCE_IO) {
                        if (res == &ioport_resource)
                                continue;
-                       printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n",
-                              res->start, res->end);
+                       printk(KERN_INFO "pcmcia: parent PCI bridge I/O "
+                               "window: 0x%llx - 0x%llx\n",
+                               (unsigned long long)res->start,
+                               (unsigned long long)res->end);
                        if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
                                done |= IORESOURCE_IO;
 
@@ -808,8 +820,10 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
                if (res->flags & IORESOURCE_MEM) {
                        if (res == &iomem_resource)
                                continue;
-                       printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n",
-                              res->start, res->end);
+                       printk(KERN_INFO "pcmcia: parent PCI bridge Memory "
+                               "window: 0x%llx - 0x%llx\n",
+                               (unsigned long long)res->start,
+                               (unsigned long long)res->end);
                        if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
                                done |= IORESOURCE_MEM;
                }
@@ -837,10 +851,9 @@ static int nonstatic_init(struct pcmcia_socket *s)
 {
        struct socket_data *data;
 
-       data = kmalloc(sizeof(struct socket_data), GFP_KERNEL);
+       data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
-       memset(data, 0, sizeof(struct socket_data));
 
        data->mem_db.next = &data->mem_db;
        data->io_db.next = &data->io_db;
@@ -857,7 +870,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
        struct socket_data *data = s->resource_data;
        struct resource_map *p, *q;
 
-       down(&rsrc_sem);
+       mutex_lock(&rsrc_mutex);
        for (p = data->mem_db.next; p != &data->mem_db; p = q) {
                q = p->next;
                kfree(p);
@@ -866,7 +879,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
                q = p->next;
                kfree(p);
        }
-       up(&rsrc_sem);
+       mutex_unlock(&rsrc_mutex);
 }
 
 
@@ -891,7 +904,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
        struct resource_map *p;
        ssize_t ret = 0;
 
-       down(&rsrc_sem);
+       mutex_lock(&rsrc_mutex);
        data = s->resource_data;
 
        for (p = data->io_db.next; p != &data->io_db; p = p->next) {
@@ -903,7 +916,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
                                 ((unsigned long) p->base + p->num - 1));
        }
 
-       up(&rsrc_sem);
+       mutex_unlock(&rsrc_mutex);
        return (ret);
 }
 
@@ -943,7 +956,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
        struct resource_map *p;
        ssize_t ret = 0;
 
-       down(&rsrc_sem);
+       mutex_lock(&rsrc_mutex);
        data = s->resource_data;
 
        for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
@@ -955,7 +968,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
                                 ((unsigned long) p->base + p->num - 1));
        }
 
-       up(&rsrc_sem);
+       mutex_unlock(&rsrc_mutex);
        return (ret);
 }