]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.11pre1 2.3.11pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:26:08 +0000 (15:26 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:26:08 +0000 (15:26 -0500)
Makefile
arch/i386/kernel/irq.c
arch/i386/kernel/mca.c
arch/i386/kernel/setup.c
drivers/char/pc_keyb.c
drivers/char/vt.c
fs/buffer.c
include/linux/ioport.h
kernel/ksyms.c
kernel/resource.c
mm/swapfile.c

index 5a6f7620471b75d7c13e98751b4c84ad38fdf4c9..d5cddb14f0c815922e1033aebaf9125f9bf7d9a2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 3
-SUBLEVEL = 10
+SUBLEVEL = 11
 EXTRAVERSION =
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
index ea218fe4521470a92aa68dc818074ec73cbfb881..9dc24667bc70e9373d4ae929d4502a130debc706 100644 (file)
@@ -1099,9 +1099,7 @@ __initfunc(void init_IRQ(void))
 
        /* IPI vector for APIC spurious interrupts */
        set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
-#endif 
-       request_region(0x20,0x20,"pic1");
-       request_region(0xa0,0x20,"pic2");
+#endif
 
        /*
         * Set the clock to 100 Hz, we already have a valid
index 8bfd7fa4543c72120ea975a12c64ea74229848b7..a47a0c2092b6b06f2e8fcd32a350f67091b1f570 100644 (file)
@@ -210,6 +210,18 @@ static void mca_configure_adapter_status(int slot) {
 
 /*--------------------------------------------------------------------*/
 
+struct resource mca_standard_resources[] = {
+       { "system control port B (MCA)", 0x60, 0x60 },
+       { "arbitration (MCA)", 0x90, 0x90 },
+       { "card Select Feedback (MCA)", 0x91, 0x91 },
+       { "system Control port A (MCA)", 0x92, 0x92 },
+       { "system board setup (MCA)", 0x94, 0x94 },
+       { "POS (MCA)", 0x96, 0x97 },
+       { "POS (MCA)", 0x100, 0x107 }
+};
+
+#define MCA_STANDARD_RESOURCES (sizeof(mca_standard_resources)/sizeof(struct resource))
+
 __initfunc(void mca_init(void))
 {
        unsigned int i, j;
@@ -319,13 +331,8 @@ __initfunc(void mca_init(void))
 
        restore_flags(flags);
 
-       request_region(0x60,0x01,"system control port B (MCA)");
-       request_region(0x90,0x01,"arbitration (MCA)");
-       request_region(0x91,0x01,"card Select Feedback (MCA)");
-       request_region(0x92,0x01,"system Control port A (MCA)");
-       request_region(0x94,0x01,"system board setup (MCA)");
-       request_region(0x96,0x02,"POS (MCA)");
-       request_region(0x100,0x08,"POS (MCA)");
+       for (i = 0; i < MCA_STANDARD_RESOURCES; i++)
+               request_resource(&pci_io_resource, mca_standard_resources + i);
 
 #ifdef CONFIG_PROC_FS
        mca_do_proc_init();
index c0721b4825ab9b450ec13cff8094b609b9d0c224..20160e173ba9da8dcf5d5fb11879becda19c2168 100644 (file)
@@ -249,12 +249,30 @@ visws_get_board_type_and_rev(void)
 static char command_line[COMMAND_LINE_SIZE] = { 0, };
        char saved_command_line[COMMAND_LINE_SIZE];
 
+struct resource standard_resources[] = {
+       { "dma1", 0x00, 0x1f },
+       { "pic1", 0x20, 0x3f },
+       { "timer", 0x40, 0x5f },
+       { "keyboard", 0x60, 0x6f },
+       { "dma page reg", 0x80, 0x8f },
+       { "pic2", 0xa0, 0xbf },
+       { "dma2", 0xc0, 0xdf },
+       { "fpu", 0xf0, 0xff }
+};
+
+/* For demonstration purposes only.. */
+#define keyboard_resources (standard_resources+3)
+struct resource kbd_status_resource = { "status", 0x60, 0x60 };
+
+#define STANDARD_RESOURCES (sizeof(standard_resources)/sizeof(struct resource))
+
 __initfunc(void setup_arch(char **cmdline_p,
        unsigned long * memory_start_p, unsigned long * memory_end_p))
 {
        unsigned long memory_start, memory_end;
        char c = ' ', *to = command_line, *from = COMMAND_LINE;
        int len = 0;
+       int i;
 
 #ifdef CONFIG_VISWS
        visws_get_board_type_and_rev();
@@ -368,11 +386,9 @@ __initfunc(void setup_arch(char **cmdline_p,
 #endif
 
        /* request I/O space for devices used on all i[345]86 PCs */
-       request_region(0x00,0x20,"dma1");
-       request_region(0x40,0x20,"timer");
-       request_region(0x80,0x10,"dma page reg");
-       request_region(0xc0,0x20,"dma2");
-       request_region(0xf0,0x10,"fpu");
+       for (i = 0; i < STANDARD_RESOURCES; i++)
+               request_resource(&pci_io_resource, standard_resources+i);
+       request_resource(keyboard_resources, &kbd_status_resource);
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
index fc570b8861172ca82233a92bff905a381e8eda9b..1b83e5f069f4508a54dad4e15400103b7abec8fd 100644 (file)
@@ -690,9 +690,6 @@ static char * __init initialize_kbd(void)
 
 void __init pckbd_init_hw(void)
 {
-       /* Get the keyboard controller registers (incomplete decode) */
-       request_region(0x60, 16, "keyboard");
-
        /* Flush any pending input. */
        kbd_clear_input();
 
index b7f51e2f34ded6bbf65795a4245cdd86a15511d5..47b4a1e26aa294b9e3f010cc13f40c555fd9b67e 100644 (file)
@@ -670,7 +670,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
        case KDSIGACCEPT:
        {
                extern int spawnpid, spawnsig;
-               if (!perm)
+               if (!perm || !capable(CAP_KILL))
                  return -EPERM;
                if (arg < 1 || arg > _NSIG || arg == SIGKILL)
                  return -EINVAL;
index 108b385eaa4e4409badefe4a5ba9e769839bd719..ba5013c9e1e5181352af7d5f605acf2d8cab0a49 100644 (file)
@@ -1270,6 +1270,7 @@ int block_flushpage(struct inode *inode, struct page *page, unsigned long offset
                                mark_buffer_clean(bh);
                                clear_bit(BH_Uptodate, &bh->b_state);
                                clear_bit(BH_Mapped, &bh->b_state);
+                               clear_bit(BH_Req, &bh->b_state);
                                bh->b_blocknr = 0;
                                atomic_dec(&bh->b_count);
                        }
index 2f729f96b2562d9f8a35f1cc83f586819d57f300..597b3ebce50540e39a6331925d26c3802266d24a 100644 (file)
@@ -2,56 +2,44 @@
  * ioport.h    Definitions of routines for detecting, reserving and
  *             allocating system resources.
  *
- * Authors:    Donald Becker (becker@cesdis.gsfc.nasa.gov)
- *             David Hinds (dhinds@zen.stanford.edu)
+ * Authors:    Linus Torvalds
  */
 
 #ifndef _LINUX_IOPORT_H
 #define _LINUX_IOPORT_H
 
-#define RES_IO         0
-#define RES_MEM                1
+/*
+ * Resources are tree-like, allowing
+ * nesting etc..
+ */
+struct resource {
+       const char *name;
+       unsigned long start, end;
+       unsigned long flags;
+       struct resource *parent, *sibling, *child;
+};
+
+extern struct resource pci_io_resource;
+extern struct resource pci_mem_resource;
 
 extern void reserve_setup(char *str, int *ints);
+extern int get_resource_list(struct resource *, char *buf, int size);
 
-extern struct resource_entry *iolist, *memlist;
-
-extern int get_resource_list(int class, char *buf);
-extern int check_resource(int class,
-                         unsigned long from, unsigned long extent);
-extern void request_resource(int class,
-                            unsigned long from, unsigned long extent,
-                            const char *name);
-extern void release_resource(int class,
-                            unsigned long from, unsigned long extent);
-extern unsigned long occupy_resource(int class,
-                                    unsigned long base, unsigned long end,
-                                    unsigned long num, unsigned long align,
-                                    const char *name);
-extern void vacate_resource(int class,
-                           unsigned long from, unsigned long extent);
-
-#define get_ioport_list(buf)   get_resource_list(RES_IO, buf)
-#define get_mem_list(buf)      get_resource_list(RES_MEM, buf)
-
-#define HAVE_PORTRESERVE
-/*
- * Call check_region() before probing for your hardware.
- * Once you have found you hardware, register it with request_region().
- * If you unload the driver, use release_region to free ports.
- */
-#define check_region(f,e)              check_resource(RES_IO,f,e)
-#define request_region(f,e,n)          request_resource(RES_IO,f,e,n)
-#define release_region(f,e)            release_resource(RES_IO,f,e)
-#define occupy_region(b,e,n,a,s)       occupy_resource(RES_IO,b,e,n,a,s)
-#define vacate_region(f,e)             vacate_resource(RES_IO,f,e)
-
-#define HAVE_MEMRESERVE
-#define check_mem_region(f,e)          check_resource(RES_MEM,f,e)
-#define request_mem_region(f,e,n)      request_resource(RES_MEM,f,e,n)
-#define release_mem_region(f,e)                release_resource(RES_MEM,f,e)
-#define occupy_mem_region(b,e,n,a,s)   occupy_resource(RES_MEM,b,e,n,a,s)
-#define vacate_mem_region(f,e)         vacate_resource(RES_MEM,f,e)
+extern int request_resource(struct resource *root, struct resource *new);
+extern int release_resource(struct resource *new);
+
+/* Convenience shorthand with allocation */
+#define request_region(start,n,name)   __request_region(&pci_io_resource, (start), (n), (name))
+extern struct resource * __request_region(struct resource *, unsigned long start, unsigned long n, const char *name);
+
+/* Compatibility cruft */
+#define check_region(start,n)  __check_region(&pci_io_resource, (start), (n))
+#define release_region(start,n)        __release_region(&pci_io_resource, (start), (n))
+extern int __check_region(struct resource *, unsigned long, unsigned long);
+extern void __release_region(struct resource *, unsigned long, unsigned long);
+
+#define get_ioport_list(buf)   get_resource_list(&pci_io_resource, buf, PAGE_SIZE)
+#define get_mem_list(buf)      get_resource_list(&pci_mem_resource, buf, PAGE_SIZE)
 
 #define HAVE_AUTOIRQ
 extern void autoirq_setup(int waittime);
index 798015eaaf23dd4f9994d46c099301dcbb56bdc1..4b4155e47fc0cad6f3c58a8ffaf0426a33e9266f 100644 (file)
@@ -308,11 +308,11 @@ EXPORT_SYMBOL(enable_hlt);
 #endif
 
 /* resource handling */
-EXPORT_SYMBOL(check_resource);
 EXPORT_SYMBOL(request_resource);
 EXPORT_SYMBOL(release_resource);
-EXPORT_SYMBOL(occupy_resource);
-EXPORT_SYMBOL(vacate_resource);
+EXPORT_SYMBOL(__request_region);
+EXPORT_SYMBOL(__check_region);
+EXPORT_SYMBOL(__release_region);
 
 /* process management */
 EXPORT_SYMBOL(__wake_up);
index 4c672c6b0113c69817072fee66d8dc0f2a438bee..b0e5327898b7bcb2a43036d4272e217fa6582fa4 100644 (file)
 /*
  *     linux/kernel/resource.c
  *
- * Copyright (C) 1995, 1999    Linus Torvalds
- *                             David Hinds
+ * Copyright (C) 1999  Linus Torvalds
  *
- * Kernel resource management
- *
- * We now distinguish between claiming space for devices (using the
- * 'occupy' and 'vacate' calls), and associating a resource with a
- * device driver (with the 'request', 'release', and 'check' calls).
- * A resource can be claimed even if there is no associated driver
- * (by occupying with name=NULL).  Vacating a resource makes it
- * available for other dynamically configured devices.
+ * Arbitrary resource management.
  */
 
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/malloc.h>
 
-#define RSRC_TABLE_SIZE 128
-
-struct resource_entry {
-       u_long from, num;
-       const char *name;
-       struct resource_entry *next;
-};
-
-struct resource_entry res_list[] = {
-    { 0, 0, NULL, NULL }, /* IO */
-    { 0, 0, NULL, NULL }  /* mem */
-};
-
-static struct resource_entry rsrc_table[RSRC_TABLE_SIZE];
+struct resource pci_io_resource = { "PCI IO", 0x0000, 0xFFFF };
+struct resource pci_mem_resource = { "PCI mem",        0x00000000, 0xFFFFFFFF };
 
 /*
  * This generates reports for /proc/ioports and /proc/memory
  */
-int get_resource_list(int class, char *buf)
+static char * do_resource_list(struct resource *entry, const char *fmt, int offset, char *buf, char *end)
 {
-       struct resource_entry *root = &res_list[class];
-       struct resource_entry *p;
-       int len = 0;
-       char *fmt = (class == RES_IO) ?
-               "%04lx-%04lx : %s\n" : "%08lx-%08lx : %s\n";
-       
-       for (p = root->next; (p) && (len < 4000); p = p->next)
-               len += sprintf(buf+len, fmt, p->from, p->from+p->num-1,
-                              (p->name ? p->name : "occupied"));
-       if (p)
-               len += sprintf(buf+len, "4K limit reached!\n");
-       return len;
+       if (offset < 0)
+               offset = 0;
+
+       while (entry) {
+               const char *name = entry->name;
+               unsigned long from, to;
+
+               if ((int) (end-buf) < 80)
+                       return buf;
+
+               from = entry->start;
+               to = entry->end;
+               if (!name)
+                       name = "<BAD>";
+
+               buf += sprintf(buf, fmt + offset, from, to, name);
+               if (entry->child)
+                       buf = do_resource_list(entry->child, fmt, offset-2, buf, end);
+               entry = entry->sibling;
+       }
+
+       return buf;
 }
 
-/*
- * Basics: find a matching resource entry, or find an insertion point
- */
-static struct resource_entry *
-find_match(struct resource_entry *root, u_long from, u_long num)
+int get_resource_list(struct resource *root, char *buf, int size)
 {
-       struct resource_entry *p;
-       for (p = root; p; p = p->next)
-               if ((p->from == from) && (p->num == num))
-                       return p;
-       return NULL;
-}
+       char *fmt;
+
+       fmt = "        %08lx-%08lx : %s\n";
+       if (root == &pci_io_resource)
+               fmt = "        %04lx-%04lx : %s\n";
+       return do_resource_list(root->child, fmt, 8, buf, buf + size) - buf;
+}      
 
-static struct resource_entry *
-find_gap(struct resource_entry *root, u_long from, u_long num)
+int request_resource(struct resource *root, struct resource *new)
 {
-       struct resource_entry *p;
-       if (from > from+num-1)
-               return NULL;
-       for (p = root; ; p = p->next) {
-               if ((p != root) && (p->from+p->num-1 >= from)) {
-                       p = NULL;
-                       break;
+       unsigned long start = new->start;
+       unsigned long end = new->end;
+       struct resource *tmp, **p;
+
+       if (end < start)
+               return -EINVAL;
+       if (start < root->start)
+               return -EINVAL;
+       if (end > root->end)
+               return -EINVAL;
+       p = &root->child;
+       for (;;) {
+               tmp = *p;
+               if (!tmp || tmp->start > end) {
+                       new->sibling = tmp;
+                       *p = new;
+                       new->parent = root;
+                       return 0;
                }
-               if ((p->next == NULL) || (p->next->from > from+num-1))
-                       break;
+               p = &tmp->sibling;
+               if (tmp->end < start)
+                       continue;
+               return -EBUSY;
        }
-       return p;
 }
 
-/*
- * Call this from a driver to assert ownership of a resource
- */
-void request_resource(int class, unsigned long from,
-                     unsigned long num, const char *name)
+int release_resource(struct resource *old)
 {
-       struct resource_entry *root = &res_list[class];
-       struct resource_entry *p;
-       long flags;
-       int i;
+       struct resource *tmp, **p;
 
-       p = find_match(root, from, num);
-       if (p) {
-               p->name = name;
-               return;
-       }
-
-       save_flags(flags);
-       cli();
-       for (i = 0; i < RSRC_TABLE_SIZE; i++)
-               if (rsrc_table[i].num == 0)
+       p = &old->parent->child;
+       for (;;) {
+               tmp = *p;
+               if (!tmp)
                        break;
-       if (i == RSRC_TABLE_SIZE)
-               printk("warning: resource table is full\n");
-       else {
-               p = find_gap(root, from, num);
-               if (p == NULL) {
-                       restore_flags(flags);
-                       return;
+               if (tmp == old) {
+                       *p = tmp->sibling;
+                       old->parent = NULL;
+                       return 0;
                }
-               rsrc_table[i].name = name;
-               rsrc_table[i].from = from;
-               rsrc_table[i].num = num;
-               rsrc_table[i].next = p->next;
-               p->next = &rsrc_table[i];
+               p = &tmp->sibling;
        }
-       restore_flags(flags);
+       return -EINVAL;
 }
 
-/* 
- * Call these when a driver is unloaded but the device remains
- */
-void release_resource(int class, unsigned long from, unsigned long num)
+struct resource * __request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name)
 {
-       struct resource_entry *root = &res_list[class];
-       struct resource_entry *p;
-       p = find_match(root, from, num);
-       if (p) p->name = NULL;
+       struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
+
+       if (res) {
+               memset(res, 0, sizeof(*res));
+               res->name = name;
+               res->start = start;
+               res->end = start + n - 1;
+               if (request_resource(parent, res) != 0) {
+                       kfree(res);
+                       res = NULL;
+               }
+       }
+       return res;
 }
 
 /*
- * Call these to check a region for conflicts before probing
+ * Compatibility cruft.
+ *
+ * Check-region returns non-zero if something already exists.
+ *
+ * Release-region releases an anonymous region that matches
+ * the IO port range.
  */
-int check_resource(int class, unsigned long from, unsigned long num)
+int __check_region(struct resource *parent, unsigned long start, unsigned long n)
 {
-       struct resource_entry *root = &res_list[class];
-       struct resource_entry *p;
-       p = find_match(root, from, num);
-       if (p != NULL)
-               return (p->name != NULL) ? -EBUSY : 0;
-       return (find_gap(root, from, num) == NULL) ? -EBUSY : 0;
+       struct resource * res;
+
+       res = __request_region(parent, start, n, "check-region");
+       if (!res)
+               return -EBUSY;
+
+       release_resource(res);
+       return 0;
 }
 
-/*
- * Call this to claim a resource for a piece of hardware
- */
-unsigned long occupy_resource(int class, unsigned long base,
-                             unsigned long end, unsigned long num,
-                             unsigned long align, const char *name)
+void __release_region(struct resource *parent, unsigned long start, unsigned long n)
 {
-       struct resource_entry *root = &res_list[class];
-       unsigned long from = 0, till;
-       unsigned long flags;
-       int i;
-       struct resource_entry *p, *q;
+       struct resource **p;
+       unsigned long end;
 
-       if ((base > end-1) || (num > end - base))
-               return 0;
+       p = &parent->child;
+       end = start + n - 1;
 
-       for (i = 0; i < RSRC_TABLE_SIZE; i++)
-               if (rsrc_table[i].num == 0)
-                       break;
-       if (i == RSRC_TABLE_SIZE)
-               return 0;
-
-       save_flags(flags);
-       cli();
-       /* printk("occupy: search in %08lx[%08lx] ", base, end - base); */
-       for (p = root; p != NULL; p = q) {
-               q = p->next;
-               /* Find window in list */
-               from = (p->from+p->num + align-1) & ~(align-1);
-               till = (q == NULL) ? (0 - align) : q->from;
-               /* printk(" %08lx:%08lx", from, till); */
-               /* Clip window with base and end */
-               if (from < base) from = base;
-               if (till > end) till = end;
-               /* See if result is large enougth */
-               if ((from < till) && (from + num < till))
-                       break;
-       }
-       /* printk("\r\n"); */
-       restore_flags(flags);
-
-       if (p == NULL)
-               return 0;
-
-       rsrc_table[i].name = name;
-       rsrc_table[i].from = from;
-       rsrc_table[i].num = num;
-       rsrc_table[i].next = p->next;
-       p->next = &rsrc_table[i];
-       return from;
-}
+       for (;;) {
+               struct resource *tmp = *p;
 
-/*
- * Call this when a resource becomes available for other hardware
- */
-void vacate_resource(int class, unsigned long from, unsigned long num)
-{
-       struct resource_entry *root = &res_list[class];
-       struct resource_entry *p, *q;
-       long flags;
-
-       save_flags(flags);
-       cli();
-       for (p = root; ; p = q) {
-               q = p->next;
-               if (q == NULL)
+               if (!tmp)
                        break;
-               if ((q->from == from) && (q->num == num)) {
-                       q->num = 0;
-                       p->next = q->next;
+               if (tmp->start == start && tmp->end == end) {
+                       *p = tmp->sibling;
                        break;
                }
+               p = &tmp->sibling;
        }
-       restore_flags(flags);
 }
 
-/* Called from init/main.c to reserve IO ports. */
+/*
+ * Called from init/main.c to reserve IO ports.
+ */
+#define MAXRESERVE 4
 void __init reserve_setup(char *str, int *ints)
 {
        int i;
-
-       for (i = 1; i < ints[0]; i += 2)
-               request_region(ints[i], ints[i+1], "reserved");
+       static int reserved = 0;
+       static struct resource reserve[MAXRESERVE];
+
+       for (i = 1; i < ints[0]; i += 2) {
+               int x = reserved;
+               if (x < MAXRESERVE) {
+                       struct resource *res = reserve + x;
+                       res->name = "reserved";
+                       res->start = ints[i];
+                       res->end = res->start + ints[i] - 1;
+                       res->child = NULL;
+                       if (request_resource(&pci_io_resource, res) == 0)
+                               reserved = x+1;
+               }
+       }
 }
index ce18f34f5d4ef1bb8674cfce4651f331ef375205..f43a2ed4a21020a5e214a451909e161464ea4fa9 100644 (file)
@@ -661,7 +661,9 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
                        else
                                p->swap_map[page] = SWAP_MAP_BAD;
                }
-               nr_good_pages = swap_header->info.last_page - i;
+               nr_good_pages = swap_header->info.last_page -
+                               swap_header->info.nr_badpages -
+                               1 /* header page */;
                lock_map_size = (p->max + 7) / 8;
                if (error) 
                        goto bad_swap;