diff options
| -rw-r--r-- | MAINTAINERS | 17 | ||||
| -rw-r--r-- | arch/i386/kernel/hpet.c | 68 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe.c | 6 | ||||
| -rw-r--r-- | arch/um/drivers/chan_kern.c | 12 | ||||
| -rw-r--r-- | arch/um/drivers/mconsole_kern.c | 3 | ||||
| -rw-r--r-- | arch/um/drivers/ubd_kern.c | 13 | ||||
| -rw-r--r-- | arch/um/include/mconsole.h | 2 | ||||
| -rw-r--r-- | arch/um/kernel/mem.c | 3 | ||||
| -rw-r--r-- | arch/um/sys-i386/ldt.c | 3 | ||||
| -rw-r--r-- | arch/x86_64/kernel/i8259.c | 6 | ||||
| -rw-r--r-- | drivers/char/Kconfig | 33 | ||||
| -rw-r--r-- | drivers/isdn/gigaset/bas-gigaset.c | 4 | ||||
| -rw-r--r-- | drivers/isdn/gigaset/common.c | 6 | ||||
| -rw-r--r-- | drivers/isdn/gigaset/ev-layer.c | 4 | ||||
| -rw-r--r-- | drivers/isdn/gigaset/isocdata.c | 4 | ||||
| -rw-r--r-- | drivers/isdn/gigaset/ser-gigaset.c | 2 | ||||
| -rw-r--r-- | drivers/isdn/gigaset/usb-gigaset.c | 4 | ||||
| -rw-r--r-- | fs/hostfs/hostfs_kern.c | 25 | ||||
| -rw-r--r-- | fs/splice.c | 25 | ||||
| -rw-r--r-- | include/asm-powerpc/immap_qe.h | 3 | ||||
| -rw-r--r-- | include/asm-um/pgtable-2level.h | 8 | ||||
| -rw-r--r-- | include/asm-x86_64/hw_irq.h | 2 | ||||
| -rw-r--r-- | kernel/exit.c | 2 | ||||
| -rw-r--r-- | mm/filemap_xip.c | 48 | ||||
| -rw-r--r-- | mm/madvise.c | 19 | ||||
| -rw-r--r-- | mm/shmem.c | 132 | ||||
| -rw-r--r-- | net/bluetooth/hidp/core.c | 23 |
27 files changed, 366 insertions, 111 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 8c8090e02d8e..829407ff41f1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -198,10 +198,25 @@ L: linux-sound@vger.kernel.org | |||
| 198 | W: http://www.stud.uni-karlsruhe.de/~uh1b/ | 198 | W: http://www.stud.uni-karlsruhe.de/~uh1b/ |
| 199 | S: Maintained | 199 | S: Maintained |
| 200 | 200 | ||
| 201 | IPS SCSI RAID DRIVER | ||
| 202 | P: Adaptec OEM Raid Solutions | ||
| 203 | M: aacraid@adaptec.com | ||
| 204 | L: linux-scsi@vger.kernel.org | ||
| 205 | W: http://www.adaptec.com/ | ||
| 206 | S: Maintained | ||
| 207 | |||
| 208 | DPT_I2O SCSI RAID DRIVER | ||
| 209 | P: Adaptec OEM Raid Solutions | ||
| 210 | M: aacraid@adaptec.com | ||
| 211 | L: linux-scsi@vger.kernel.org | ||
| 212 | W: http://www.adaptec.com/ | ||
| 213 | S: Maintained | ||
| 214 | |||
| 201 | AACRAID SCSI RAID DRIVER | 215 | AACRAID SCSI RAID DRIVER |
| 202 | P: Adaptec OEM Raid Solutions | 216 | P: Adaptec OEM Raid Solutions |
| 217 | M: aacraid@adaptec.com | ||
| 203 | L: linux-scsi@vger.kernel.org | 218 | L: linux-scsi@vger.kernel.org |
| 204 | W: http://linux.dell.com/storage.shtml | 219 | W: http://www.adaptec.com/ |
| 205 | S: Supported | 220 | S: Supported |
| 206 | 221 | ||
| 207 | ACPI | 222 | ACPI |
diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c index 76afea67f691..17d73459fc5f 100644 --- a/arch/i386/kernel/hpet.c +++ b/arch/i386/kernel/hpet.c | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | #include <linux/errno.h> | 3 | #include <linux/errno.h> |
| 4 | #include <linux/hpet.h> | 4 | #include <linux/hpet.h> |
| 5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
| 6 | #include <linux/sysdev.h> | ||
| 7 | #include <linux/pm.h> | ||
| 6 | 8 | ||
| 7 | #include <asm/hpet.h> | 9 | #include <asm/hpet.h> |
| 8 | #include <asm/io.h> | 10 | #include <asm/io.h> |
| @@ -307,6 +309,7 @@ int __init hpet_enable(void) | |||
| 307 | out_nohpet: | 309 | out_nohpet: |
| 308 | iounmap(hpet_virt_address); | 310 | iounmap(hpet_virt_address); |
| 309 | hpet_virt_address = NULL; | 311 | hpet_virt_address = NULL; |
| 312 | boot_hpet_disable = 1; | ||
| 310 | return 0; | 313 | return 0; |
| 311 | } | 314 | } |
| 312 | 315 | ||
| @@ -521,3 +524,68 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) | |||
| 521 | return IRQ_HANDLED; | 524 | return IRQ_HANDLED; |
| 522 | } | 525 | } |
| 523 | #endif | 526 | #endif |
| 527 | |||
| 528 | |||
| 529 | /* | ||
| 530 | * Suspend/resume part | ||
| 531 | */ | ||
| 532 | |||
| 533 | #ifdef CONFIG_PM | ||
| 534 | |||
| 535 | static int hpet_suspend(struct sys_device *sys_device, pm_message_t state) | ||
| 536 | { | ||
| 537 | unsigned long cfg = hpet_readl(HPET_CFG); | ||
| 538 | |||
| 539 | cfg &= ~(HPET_CFG_ENABLE|HPET_CFG_LEGACY); | ||
| 540 | hpet_writel(cfg, HPET_CFG); | ||
| 541 | |||
| 542 | return 0; | ||
| 543 | } | ||
| 544 | |||
| 545 | static int hpet_resume(struct sys_device *sys_device) | ||
| 546 | { | ||
| 547 | unsigned int id; | ||
| 548 | |||
| 549 | hpet_start_counter(); | ||
| 550 | |||
| 551 | id = hpet_readl(HPET_ID); | ||
| 552 | |||
| 553 | if (id & HPET_ID_LEGSUP) | ||
| 554 | hpet_enable_int(); | ||
| 555 | |||
| 556 | return 0; | ||
| 557 | } | ||
| 558 | |||
| 559 | static struct sysdev_class hpet_class = { | ||
| 560 | set_kset_name("hpet"), | ||
| 561 | .suspend = hpet_suspend, | ||
| 562 | .resume = hpet_resume, | ||
| 563 | }; | ||
| 564 | |||
| 565 | static struct sys_device hpet_device = { | ||
| 566 | .id = 0, | ||
| 567 | .cls = &hpet_class, | ||
| 568 | }; | ||
| 569 | |||
| 570 | |||
| 571 | static __init int hpet_register_sysfs(void) | ||
| 572 | { | ||
| 573 | int err; | ||
| 574 | |||
| 575 | if (!is_hpet_capable()) | ||
| 576 | return 0; | ||
| 577 | |||
| 578 | err = sysdev_class_register(&hpet_class); | ||
| 579 | |||
| 580 | if (!err) { | ||
| 581 | err = sysdev_register(&hpet_device); | ||
| 582 | if (err) | ||
| 583 | sysdev_class_unregister(&hpet_class); | ||
| 584 | } | ||
| 585 | |||
| 586 | return err; | ||
| 587 | } | ||
| 588 | |||
| 589 | device_initcall(hpet_register_sysfs); | ||
| 590 | |||
| 591 | #endif | ||
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index e3d71e083f35..43f6cc9d7ea0 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
| @@ -251,13 +251,13 @@ static int qe_sdma_init(void) | |||
| 251 | 251 | ||
| 252 | /* allocate 2 internal temporary buffers (512 bytes size each) for | 252 | /* allocate 2 internal temporary buffers (512 bytes size each) for |
| 253 | * the SDMA */ | 253 | * the SDMA */ |
| 254 | sdma_buf_offset = qe_muram_alloc(512 * 2, 64); | 254 | sdma_buf_offset = qe_muram_alloc(512 * 2, 4096); |
| 255 | if (IS_MURAM_ERR(sdma_buf_offset)) | 255 | if (IS_MURAM_ERR(sdma_buf_offset)) |
| 256 | return -ENOMEM; | 256 | return -ENOMEM; |
| 257 | 257 | ||
| 258 | out_be32(&sdma->sdebcr, sdma_buf_offset & QE_SDEBCR_BA_MASK); | 258 | out_be32(&sdma->sdebcr, sdma_buf_offset & QE_SDEBCR_BA_MASK); |
| 259 | out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | (0x1 >> | 259 | out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | |
| 260 | QE_SDMR_CEN_SHIFT))); | 260 | (0x1 << QE_SDMR_CEN_SHIFT))); |
| 261 | 261 | ||
| 262 | return 0; | 262 | return 0; |
| 263 | } | 263 | } |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 7b8baf146acc..9fdfad649536 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
| @@ -236,11 +236,11 @@ void free_irqs(void) | |||
| 236 | struct chan *chan; | 236 | struct chan *chan; |
| 237 | LIST_HEAD(list); | 237 | LIST_HEAD(list); |
| 238 | struct list_head *ele; | 238 | struct list_head *ele; |
| 239 | unsigned long flags; | ||
| 239 | 240 | ||
| 240 | spin_lock_irq(&irqs_to_free_lock); | 241 | spin_lock_irqsave(&irqs_to_free_lock, flags); |
| 241 | list_splice_init(&irqs_to_free, &list); | 242 | list_splice_init(&irqs_to_free, &list); |
| 242 | INIT_LIST_HEAD(&irqs_to_free); | 243 | spin_unlock_irqrestore(&irqs_to_free_lock, flags); |
| 243 | spin_unlock_irq(&irqs_to_free_lock); | ||
| 244 | 244 | ||
| 245 | list_for_each(ele, &list){ | 245 | list_for_each(ele, &list){ |
| 246 | chan = list_entry(ele, struct chan, free_list); | 246 | chan = list_entry(ele, struct chan, free_list); |
| @@ -255,13 +255,15 @@ void free_irqs(void) | |||
| 255 | 255 | ||
| 256 | static void close_one_chan(struct chan *chan, int delay_free_irq) | 256 | static void close_one_chan(struct chan *chan, int delay_free_irq) |
| 257 | { | 257 | { |
| 258 | unsigned long flags; | ||
| 259 | |||
| 258 | if(!chan->opened) | 260 | if(!chan->opened) |
| 259 | return; | 261 | return; |
| 260 | 262 | ||
| 261 | if(delay_free_irq){ | 263 | if(delay_free_irq){ |
| 262 | spin_lock_irq(&irqs_to_free_lock); | 264 | spin_lock_irqsave(&irqs_to_free_lock, flags); |
| 263 | list_add(&chan->free_list, &irqs_to_free); | 265 | list_add(&chan->free_list, &irqs_to_free); |
| 264 | spin_unlock_irq(&irqs_to_free_lock); | 266 | spin_unlock_irqrestore(&irqs_to_free_lock, flags); |
| 265 | } | 267 | } |
| 266 | else { | 268 | else { |
| 267 | if(chan->input) | 269 | if(chan->input) |
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 178b2eff4a8c..65ad2932672c 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
| @@ -615,6 +615,9 @@ void mconsole_remove(struct mc_request *req) | |||
| 615 | err_msg = NULL; | 615 | err_msg = NULL; |
| 616 | err = (*dev->remove)(n, &err_msg); | 616 | err = (*dev->remove)(n, &err_msg); |
| 617 | switch(err){ | 617 | switch(err){ |
| 618 | case 0: | ||
| 619 | err_msg = ""; | ||
| 620 | break; | ||
| 618 | case -ENODEV: | 621 | case -ENODEV: |
| 619 | if(err_msg == NULL) | 622 | if(err_msg == NULL) |
| 620 | err_msg = "Device doesn't exist"; | 623 | err_msg = "Device doesn't exist"; |
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index f98d26e51381..8bd9204ac1ab 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
| @@ -109,10 +109,6 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data) | |||
| 109 | 109 | ||
| 110 | static DEFINE_MUTEX(ubd_lock); | 110 | static DEFINE_MUTEX(ubd_lock); |
| 111 | 111 | ||
| 112 | /* XXX - this made sense in 2.4 days, now it's only used as a boolean, and | ||
| 113 | * probably it doesn't make sense even for that. */ | ||
| 114 | static int do_ubd; | ||
| 115 | |||
| 116 | static int ubd_open(struct inode * inode, struct file * filp); | 112 | static int ubd_open(struct inode * inode, struct file * filp); |
| 117 | static int ubd_release(struct inode * inode, struct file * file); | 113 | static int ubd_release(struct inode * inode, struct file * file); |
| 118 | static int ubd_ioctl(struct inode * inode, struct file * file, | 114 | static int ubd_ioctl(struct inode * inode, struct file * file, |
| @@ -169,6 +165,7 @@ struct ubd { | |||
| 169 | struct platform_device pdev; | 165 | struct platform_device pdev; |
| 170 | struct request_queue *queue; | 166 | struct request_queue *queue; |
| 171 | spinlock_t lock; | 167 | spinlock_t lock; |
| 168 | int active; | ||
| 172 | }; | 169 | }; |
| 173 | 170 | ||
| 174 | #define DEFAULT_COW { \ | 171 | #define DEFAULT_COW { \ |
| @@ -190,6 +187,7 @@ struct ubd { | |||
| 190 | .shared = 0, \ | 187 | .shared = 0, \ |
| 191 | .cow = DEFAULT_COW, \ | 188 | .cow = DEFAULT_COW, \ |
| 192 | .lock = SPIN_LOCK_UNLOCKED, \ | 189 | .lock = SPIN_LOCK_UNLOCKED, \ |
| 190 | .active = 0, \ | ||
| 193 | } | 191 | } |
| 194 | 192 | ||
| 195 | /* Protected by ubd_lock */ | 193 | /* Protected by ubd_lock */ |
| @@ -507,7 +505,6 @@ static void ubd_handler(void) | |||
| 507 | struct ubd *dev; | 505 | struct ubd *dev; |
| 508 | int n; | 506 | int n; |
| 509 | 507 | ||
| 510 | do_ubd = 0; | ||
| 511 | n = os_read_file(thread_fd, &req, sizeof(req)); | 508 | n = os_read_file(thread_fd, &req, sizeof(req)); |
| 512 | if(n != sizeof(req)){ | 509 | if(n != sizeof(req)){ |
| 513 | printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " | 510 | printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " |
| @@ -517,6 +514,7 @@ static void ubd_handler(void) | |||
| 517 | 514 | ||
| 518 | rq = req.req; | 515 | rq = req.req; |
| 519 | dev = rq->rq_disk->private_data; | 516 | dev = rq->rq_disk->private_data; |
| 517 | dev->active = 0; | ||
| 520 | 518 | ||
| 521 | ubd_finish(rq, req.error); | 519 | ubd_finish(rq, req.error); |
| 522 | reactivate_fd(thread_fd, UBD_IRQ); | 520 | reactivate_fd(thread_fd, UBD_IRQ); |
| @@ -1081,11 +1079,12 @@ static void do_ubd_request(request_queue_t *q) | |||
| 1081 | } | 1079 | } |
| 1082 | } | 1080 | } |
| 1083 | else { | 1081 | else { |
| 1084 | if(do_ubd || (req = elv_next_request(q)) == NULL) | 1082 | struct ubd *dev = q->queuedata; |
| 1083 | if(dev->active || (req = elv_next_request(q)) == NULL) | ||
| 1085 | return; | 1084 | return; |
| 1086 | err = prepare_request(req, &io_req); | 1085 | err = prepare_request(req, &io_req); |
| 1087 | if(!err){ | 1086 | if(!err){ |
| 1088 | do_ubd = 1; | 1087 | dev->active = 1; |
| 1089 | n = os_write_file(thread_fd, (char *) &io_req, | 1088 | n = os_write_file(thread_fd, (char *) &io_req, |
| 1090 | sizeof(io_req)); | 1089 | sizeof(io_req)); |
| 1091 | if(n != sizeof(io_req)) | 1090 | if(n != sizeof(io_req)) |
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h index 2666815b6af5..b282839c1625 100644 --- a/arch/um/include/mconsole.h +++ b/arch/um/include/mconsole.h | |||
| @@ -12,6 +12,8 @@ | |||
| 12 | #define u32 uint32_t | 12 | #define u32 uint32_t |
| 13 | #endif | 13 | #endif |
| 14 | 14 | ||
| 15 | #include "sysdep/ptrace.h" | ||
| 16 | |||
| 15 | #define MCONSOLE_MAGIC (0xcafebabe) | 17 | #define MCONSOLE_MAGIC (0xcafebabe) |
| 16 | #define MCONSOLE_MAX_DATA (512) | 18 | #define MCONSOLE_MAX_DATA (512) |
| 17 | #define MCONSOLE_VERSION 2 | 19 | #define MCONSOLE_VERSION 2 |
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index e85d65deea0d..df7d662b98ce 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c | |||
| @@ -64,8 +64,6 @@ static void setup_highmem(unsigned long highmem_start, | |||
| 64 | 64 | ||
| 65 | void mem_init(void) | 65 | void mem_init(void) |
| 66 | { | 66 | { |
| 67 | max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT; | ||
| 68 | |||
| 69 | /* clear the zero-page */ | 67 | /* clear the zero-page */ |
| 70 | memset((void *) empty_zero_page, 0, PAGE_SIZE); | 68 | memset((void *) empty_zero_page, 0, PAGE_SIZE); |
| 71 | 69 | ||
| @@ -80,6 +78,7 @@ void mem_init(void) | |||
| 80 | 78 | ||
| 81 | /* this will put all low memory onto the freelists */ | 79 | /* this will put all low memory onto the freelists */ |
| 82 | totalram_pages = free_all_bootmem(); | 80 | totalram_pages = free_all_bootmem(); |
| 81 | max_low_pfn = totalram_pages; | ||
| 83 | #ifdef CONFIG_HIGHMEM | 82 | #ifdef CONFIG_HIGHMEM |
| 84 | totalhigh_pages = highmem >> PAGE_SHIFT; | 83 | totalhigh_pages = highmem >> PAGE_SHIFT; |
| 85 | totalram_pages += totalhigh_pages; | 84 | totalram_pages += totalhigh_pages; |
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index 4a8b4202ef9e..a939a7ef0227 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c | |||
| @@ -394,7 +394,8 @@ static short * host_ldt_entries = NULL; | |||
| 394 | static void ldt_get_host_info(void) | 394 | static void ldt_get_host_info(void) |
| 395 | { | 395 | { |
| 396 | long ret; | 396 | long ret; |
| 397 | struct ldt_entry * ldt, *tmp; | 397 | struct ldt_entry * ldt; |
| 398 | short *tmp; | ||
| 398 | int i, size, k, order; | 399 | int i, size, k, order; |
| 399 | 400 | ||
| 400 | spin_lock(&host_ldt_lock); | 401 | spin_lock(&host_ldt_lock); |
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 21d95b747437..489426682772 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c | |||
| @@ -45,7 +45,7 @@ | |||
| 45 | 45 | ||
| 46 | /* | 46 | /* |
| 47 | * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: | 47 | * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: |
| 48 | * (these are usually mapped to vectors 0x20-0x2f) | 48 | * (these are usually mapped to vectors 0x30-0x3f) |
| 49 | */ | 49 | */ |
| 50 | 50 | ||
| 51 | /* | 51 | /* |
| @@ -299,7 +299,7 @@ void init_8259A(int auto_eoi) | |||
| 299 | * outb_p - this has to work on a wide range of PC hardware. | 299 | * outb_p - this has to work on a wide range of PC hardware. |
| 300 | */ | 300 | */ |
| 301 | outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */ | 301 | outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */ |
| 302 | outb_p(IRQ0_VECTOR, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */ | 302 | outb_p(IRQ0_VECTOR, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x30-0x37 */ |
| 303 | outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */ | 303 | outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */ |
| 304 | if (auto_eoi) | 304 | if (auto_eoi) |
| 305 | outb_p(0x03, 0x21); /* master does Auto EOI */ | 305 | outb_p(0x03, 0x21); /* master does Auto EOI */ |
| @@ -307,7 +307,7 @@ void init_8259A(int auto_eoi) | |||
| 307 | outb_p(0x01, 0x21); /* master expects normal EOI */ | 307 | outb_p(0x01, 0x21); /* master expects normal EOI */ |
| 308 | 308 | ||
| 309 | outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */ | 309 | outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */ |
| 310 | outb_p(IRQ8_VECTOR, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */ | 310 | outb_p(IRQ8_VECTOR, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x38-0x3f */ |
| 311 | outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */ | 311 | outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */ |
| 312 | outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode | 312 | outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode |
| 313 | is to be investigated) */ | 313 | is to be investigated) */ |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 3429ece4ef92..d0c978fbc204 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
| @@ -386,6 +386,39 @@ config AU1000_SERIAL_CONSOLE | |||
| 386 | If you have an Alchemy AU1000 processor (MIPS based) and you want | 386 | If you have an Alchemy AU1000 processor (MIPS based) and you want |
| 387 | to use a console on a serial port, say Y. Otherwise, say N. | 387 | to use a console on a serial port, say Y. Otherwise, say N. |
| 388 | 388 | ||
| 389 | config SERIAL_DEC | ||
| 390 | bool "DECstation serial support" | ||
| 391 | depends on MACH_DECSTATION | ||
| 392 | default y | ||
| 393 | help | ||
| 394 | This selects whether you want to be asked about drivers for | ||
| 395 | DECstation serial ports. | ||
| 396 | |||
| 397 | Note that the answer to this question won't directly affect the | ||
| 398 | kernel: saying N will just cause the configurator to skip all | ||
| 399 | the questions about DECstation serial ports. | ||
| 400 | |||
| 401 | config SERIAL_DEC_CONSOLE | ||
| 402 | bool "Support for console on a DECstation serial port" | ||
| 403 | depends on SERIAL_DEC | ||
| 404 | default y | ||
| 405 | help | ||
| 406 | If you say Y here, it will be possible to use a serial port as the | ||
| 407 | system console (the system console is the device which receives all | ||
| 408 | kernel messages and warnings and which allows logins in single user | ||
| 409 | mode). Note that the firmware uses ttyS0 as the serial console on | ||
| 410 | the Maxine and ttyS2 on the others. | ||
| 411 | |||
| 412 | If unsure, say Y. | ||
| 413 | |||
| 414 | config ZS | ||
| 415 | bool "Z85C30 Serial Support" | ||
| 416 | depends on SERIAL_DEC | ||
| 417 | default y | ||
| 418 | help | ||
| 419 | Documentation on the Zilog 85C350 serial communications controller | ||
| 420 | is downloadable at <http://www.zilog.com/pdfs/serial/z85c30.pdf> | ||
| 421 | |||
| 389 | config A2232 | 422 | config A2232 |
| 390 | tristate "Commodore A2232 serial support (EXPERIMENTAL)" | 423 | tristate "Commodore A2232 serial support (EXPERIMENTAL)" |
| 391 | depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP | 424 | depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 63e51dd6debe..00e31609a238 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
| @@ -54,7 +54,7 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode"); | |||
| 54 | #define USB_SX353_PRODUCT_ID 0x0022 | 54 | #define USB_SX353_PRODUCT_ID 0x0022 |
| 55 | 55 | ||
| 56 | /* table of devices that work with this driver */ | 56 | /* table of devices that work with this driver */ |
| 57 | static struct usb_device_id gigaset_table [] = { | 57 | static const struct usb_device_id gigaset_table [] = { |
| 58 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) }, | 58 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) }, |
| 59 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) }, | 59 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) }, |
| 60 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) }, | 60 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) }, |
| @@ -2305,7 +2305,7 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
| 2305 | gigaset_unassign(cs); | 2305 | gigaset_unassign(cs); |
| 2306 | } | 2306 | } |
| 2307 | 2307 | ||
| 2308 | static struct gigaset_ops gigops = { | 2308 | static const struct gigaset_ops gigops = { |
| 2309 | gigaset_write_cmd, | 2309 | gigaset_write_cmd, |
| 2310 | gigaset_write_room, | 2310 | gigaset_write_room, |
| 2311 | gigaset_chars_in_buffer, | 2311 | gigaset_chars_in_buffer, |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index b460a73a7c85..6df336bdd571 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
| @@ -944,8 +944,8 @@ static DEFINE_SPINLOCK(driver_lock); | |||
| 944 | struct cardstate *gigaset_get_cs_by_id(int id) | 944 | struct cardstate *gigaset_get_cs_by_id(int id) |
| 945 | { | 945 | { |
| 946 | unsigned long flags; | 946 | unsigned long flags; |
| 947 | static struct cardstate *ret = NULL; | 947 | struct cardstate *ret = NULL; |
| 948 | static struct cardstate *cs; | 948 | struct cardstate *cs; |
| 949 | struct gigaset_driver *drv; | 949 | struct gigaset_driver *drv; |
| 950 | unsigned i; | 950 | unsigned i; |
| 951 | 951 | ||
| @@ -999,7 +999,7 @@ void gigaset_debugdrivers(void) | |||
| 999 | static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) | 999 | static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) |
| 1000 | { | 1000 | { |
| 1001 | unsigned long flags; | 1001 | unsigned long flags; |
| 1002 | static struct cardstate *ret = NULL; | 1002 | struct cardstate *ret = NULL; |
| 1003 | struct gigaset_driver *drv; | 1003 | struct gigaset_driver *drv; |
| 1004 | unsigned index; | 1004 | unsigned index; |
| 1005 | 1005 | ||
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index 4661e2c722bc..cec1ef342fcc 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c | |||
| @@ -409,7 +409,7 @@ static struct reply_t tab_cid[] = /* no dle mode */ //FIXME | |||
| 409 | }; | 409 | }; |
| 410 | #endif | 410 | #endif |
| 411 | 411 | ||
| 412 | static struct resp_type_t resp_type[]= | 412 | static const struct resp_type_t resp_type[] = |
| 413 | { | 413 | { |
| 414 | /*{"", RSP_EMPTY, RT_NOTHING},*/ | 414 | /*{"", RSP_EMPTY, RT_NOTHING},*/ |
| 415 | {"OK", RSP_OK, RT_NOTHING}, | 415 | {"OK", RSP_OK, RT_NOTHING}, |
| @@ -511,7 +511,7 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
| 511 | unsigned char *argv[MAX_REC_PARAMS + 1]; | 511 | unsigned char *argv[MAX_REC_PARAMS + 1]; |
| 512 | int params; | 512 | int params; |
| 513 | int i, j; | 513 | int i, j; |
| 514 | struct resp_type_t *rt; | 514 | const struct resp_type_t *rt; |
| 515 | int curarg; | 515 | int curarg; |
| 516 | unsigned long flags; | 516 | unsigned long flags; |
| 517 | unsigned next, tail, head; | 517 | unsigned next, tail, head; |
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index 8c0eb522dab1..e0505f238807 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c | |||
| @@ -274,7 +274,7 @@ static inline void dump_bytes(enum debuglevel level, const char *tag, | |||
| 274 | * bit 12..10 = number of trailing '1' bits in result | 274 | * bit 12..10 = number of trailing '1' bits in result |
| 275 | * bit 14..13 = number of bits added by stuffing | 275 | * bit 14..13 = number of bits added by stuffing |
| 276 | */ | 276 | */ |
| 277 | static u16 stufftab[5 * 256] = { | 277 | static const u16 stufftab[5 * 256] = { |
| 278 | // previous 1s = 0: | 278 | // previous 1s = 0: |
| 279 | 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, | 279 | 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, |
| 280 | 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f, | 280 | 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f, |
| @@ -629,7 +629,7 @@ static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits) | |||
| 629 | * (replacing 8 by 7 to make it fit; the algorithm won't care) | 629 | * (replacing 8 by 7 to make it fit; the algorithm won't care) |
| 630 | * bit 7 set if there are 5 or more "interior" consecutive '1' bits | 630 | * bit 7 set if there are 5 or more "interior" consecutive '1' bits |
| 631 | */ | 631 | */ |
| 632 | static unsigned char bitcounts[256] = { | 632 | static const unsigned char bitcounts[256] = { |
| 633 | 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, | 633 | 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, |
| 634 | 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, | 634 | 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, |
| 635 | 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, | 635 | 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, |
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index c8b7db65e48f..ea44302e6e7e 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c | |||
| @@ -459,7 +459,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | |||
| 459 | return -EINVAL; | 459 | return -EINVAL; |
| 460 | } | 460 | } |
| 461 | 461 | ||
| 462 | static struct gigaset_ops ops = { | 462 | static const struct gigaset_ops ops = { |
| 463 | gigaset_write_cmd, | 463 | gigaset_write_cmd, |
| 464 | gigaset_write_room, | 464 | gigaset_write_room, |
| 465 | gigaset_chars_in_buffer, | 465 | gigaset_chars_in_buffer, |
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c index 04f2ad7ba8b0..2baef349c12d 100644 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c | |||
| @@ -50,7 +50,7 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode"); | |||
| 50 | #define USB_M105_PRODUCT_ID 0x0009 | 50 | #define USB_M105_PRODUCT_ID 0x0009 |
| 51 | 51 | ||
| 52 | /* table of devices that work with this driver */ | 52 | /* table of devices that work with this driver */ |
| 53 | static struct usb_device_id gigaset_table [] = { | 53 | static const struct usb_device_id gigaset_table [] = { |
| 54 | { USB_DEVICE(USB_M105_VENDOR_ID, USB_M105_PRODUCT_ID) }, | 54 | { USB_DEVICE(USB_M105_VENDOR_ID, USB_M105_PRODUCT_ID) }, |
| 55 | { } /* Terminating entry */ | 55 | { } /* Terminating entry */ |
| 56 | }; | 56 | }; |
| @@ -860,7 +860,7 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
| 860 | gigaset_unassign(cs); | 860 | gigaset_unassign(cs); |
| 861 | } | 861 | } |
| 862 | 862 | ||
| 863 | static struct gigaset_ops ops = { | 863 | static const struct gigaset_ops ops = { |
| 864 | gigaset_write_cmd, | 864 | gigaset_write_cmd, |
| 865 | gigaset_write_room, | 865 | gigaset_write_room, |
| 866 | gigaset_chars_in_buffer, | 866 | gigaset_chars_in_buffer, |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 9baf69773ed1..fd301a910122 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #include "hostfs.h" | 20 | #include "hostfs.h" |
| 21 | #include "kern_util.h" | 21 | #include "kern_util.h" |
| 22 | #include "kern.h" | 22 | #include "kern.h" |
| 23 | #include "user_util.h" | ||
| 24 | #include "init.h" | 23 | #include "init.h" |
| 25 | 24 | ||
| 26 | struct hostfs_inode_info { | 25 | struct hostfs_inode_info { |
| @@ -939,7 +938,7 @@ static const struct address_space_operations hostfs_link_aops = { | |||
| 939 | static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | 938 | static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) |
| 940 | { | 939 | { |
| 941 | struct inode *root_inode; | 940 | struct inode *root_inode; |
| 942 | char *name, *data = d; | 941 | char *host_root_path, *req_root = d; |
| 943 | int err; | 942 | int err; |
| 944 | 943 | ||
| 945 | sb->s_blocksize = 1024; | 944 | sb->s_blocksize = 1024; |
| @@ -948,16 +947,16 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
| 948 | sb->s_op = &hostfs_sbops; | 947 | sb->s_op = &hostfs_sbops; |
| 949 | 948 | ||
| 950 | /* NULL is printed as <NULL> by sprintf: avoid that. */ | 949 | /* NULL is printed as <NULL> by sprintf: avoid that. */ |
| 951 | if (data == NULL) | 950 | if (req_root == NULL) |
| 952 | data = ""; | 951 | req_root = ""; |
| 953 | 952 | ||
| 954 | err = -ENOMEM; | 953 | err = -ENOMEM; |
| 955 | name = kmalloc(strlen(root_ino) + 1 | 954 | host_root_path = kmalloc(strlen(root_ino) + 1 |
| 956 | + strlen(data) + 1, GFP_KERNEL); | 955 | + strlen(req_root) + 1, GFP_KERNEL); |
| 957 | if(name == NULL) | 956 | if(host_root_path == NULL) |
| 958 | goto out; | 957 | goto out; |
| 959 | 958 | ||
| 960 | sprintf(name, "%s/%s", root_ino, data); | 959 | sprintf(host_root_path, "%s/%s", root_ino, req_root); |
| 961 | 960 | ||
| 962 | root_inode = iget(sb, 0); | 961 | root_inode = iget(sb, 0); |
| 963 | if(root_inode == NULL) | 962 | if(root_inode == NULL) |
| @@ -967,10 +966,10 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
| 967 | if(err) | 966 | if(err) |
| 968 | goto out_put; | 967 | goto out_put; |
| 969 | 968 | ||
| 970 | HOSTFS_I(root_inode)->host_filename = name; | 969 | HOSTFS_I(root_inode)->host_filename = host_root_path; |
| 971 | /* Avoid that in the error path, iput(root_inode) frees again name through | 970 | /* Avoid that in the error path, iput(root_inode) frees again |
| 972 | * hostfs_destroy_inode! */ | 971 | * host_root_path through hostfs_destroy_inode! */ |
| 973 | name = NULL; | 972 | host_root_path = NULL; |
| 974 | 973 | ||
| 975 | err = -ENOMEM; | 974 | err = -ENOMEM; |
| 976 | sb->s_root = d_alloc_root(root_inode); | 975 | sb->s_root = d_alloc_root(root_inode); |
| @@ -990,7 +989,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
| 990 | out_put: | 989 | out_put: |
| 991 | iput(root_inode); | 990 | iput(root_inode); |
| 992 | out_free: | 991 | out_free: |
| 993 | kfree(name); | 992 | kfree(host_root_path); |
| 994 | out: | 993 | out: |
| 995 | return(err); | 994 | return(err); |
| 996 | } | 995 | } |
diff --git a/fs/splice.c b/fs/splice.c index 07f6556add0a..5428b0ff3b6f 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -627,18 +627,25 @@ find_page: | |||
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); | 629 | ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); |
| 630 | if (!ret) { | 630 | if (ret) { |
| 631 | if (ret == AOP_TRUNCATED_PAGE) { | ||
| 632 | page_cache_release(page); | ||
| 633 | goto find_page; | ||
| 634 | } | ||
| 635 | if (ret < 0) | ||
| 636 | goto out; | ||
| 631 | /* | 637 | /* |
| 632 | * Return the number of bytes written and mark page as | 638 | * Partial write has happened, so 'ret' already initialized by |
| 633 | * accessed, we are now done! | 639 | * number of bytes written, Where is nothing we have to do here. |
| 634 | */ | 640 | */ |
| 641 | } else | ||
| 635 | ret = this_len; | 642 | ret = this_len; |
| 636 | mark_page_accessed(page); | 643 | /* |
| 637 | balance_dirty_pages_ratelimited(mapping); | 644 | * Return the number of bytes written and mark page as |
| 638 | } else if (ret == AOP_TRUNCATED_PAGE) { | 645 | * accessed, we are now done! |
| 639 | page_cache_release(page); | 646 | */ |
| 640 | goto find_page; | 647 | mark_page_accessed(page); |
| 641 | } | 648 | balance_dirty_pages_ratelimited(mapping); |
| 642 | out: | 649 | out: |
| 643 | page_cache_release(page); | 650 | page_cache_release(page); |
| 644 | unlock_page(page); | 651 | unlock_page(page); |
diff --git a/include/asm-powerpc/immap_qe.h b/include/asm-powerpc/immap_qe.h index 9fdd0491f6a3..1020b7fc0129 100644 --- a/include/asm-powerpc/immap_qe.h +++ b/include/asm-powerpc/immap_qe.h | |||
| @@ -258,8 +258,9 @@ struct ucc_slow { | |||
| 258 | u8 uccs; /* UCCx status register */ | 258 | u8 uccs; /* UCCx status register */ |
| 259 | u8 res3[0x24]; | 259 | u8 res3[0x24]; |
| 260 | __be16 utpt; | 260 | __be16 utpt; |
| 261 | u8 res4[0x52]; | ||
| 261 | u8 guemr; /* UCC general extended mode register */ | 262 | u8 guemr; /* UCC general extended mode register */ |
| 262 | u8 res4[0x200 - 0x091]; | 263 | u8 res5[0x200 - 0x091]; |
| 263 | } __attribute__ ((packed)); | 264 | } __attribute__ ((packed)); |
| 264 | 265 | ||
| 265 | /* QE UCC Fast */ | 266 | /* QE UCC Fast */ |
diff --git a/include/asm-um/pgtable-2level.h b/include/asm-um/pgtable-2level.h index 6050e0eb257e..172a75fde512 100644 --- a/include/asm-um/pgtable-2level.h +++ b/include/asm-um/pgtable-2level.h | |||
| @@ -45,12 +45,12 @@ static inline void pgd_mkuptodate(pgd_t pgd) { } | |||
| 45 | ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) | 45 | ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) |
| 46 | 46 | ||
| 47 | /* | 47 | /* |
| 48 | * Bits 0 through 3 are taken | 48 | * Bits 0 through 4 are taken |
| 49 | */ | 49 | */ |
| 50 | #define PTE_FILE_MAX_BITS 28 | 50 | #define PTE_FILE_MAX_BITS 27 |
| 51 | 51 | ||
| 52 | #define pte_to_pgoff(pte) (pte_val(pte) >> 4) | 52 | #define pte_to_pgoff(pte) (pte_val(pte) >> 5) |
| 53 | 53 | ||
| 54 | #define pgoff_to_pte(off) ((pte_t) { ((off) << 4) + _PAGE_FILE }) | 54 | #define pgoff_to_pte(off) ((pte_t) { ((off) << 5) + _PAGE_FILE }) |
| 55 | 55 | ||
| 56 | #endif | 56 | #endif |
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h index 2e4b7a5ed1c4..6153ae5df2e8 100644 --- a/include/asm-x86_64/hw_irq.h +++ b/include/asm-x86_64/hw_irq.h | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | #define IRQ_MOVE_CLEANUP_VECTOR FIRST_EXTERNAL_VECTOR | 38 | #define IRQ_MOVE_CLEANUP_VECTOR FIRST_EXTERNAL_VECTOR |
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * Vectors 0x20-0x2f are used for ISA interrupts. | 41 | * Vectors 0x30-0x3f are used for ISA interrupts. |
| 42 | */ | 42 | */ |
| 43 | #define IRQ0_VECTOR FIRST_EXTERNAL_VECTOR + 0x10 | 43 | #define IRQ0_VECTOR FIRST_EXTERNAL_VECTOR + 0x10 |
| 44 | #define IRQ1_VECTOR IRQ0_VECTOR + 1 | 44 | #define IRQ1_VECTOR IRQ0_VECTOR + 1 |
diff --git a/kernel/exit.c b/kernel/exit.c index f132349c0325..b55ed4cc9104 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -790,7 +790,7 @@ static void exit_notify(struct task_struct *tsk) | |||
| 790 | 790 | ||
| 791 | pgrp = task_pgrp(tsk); | 791 | pgrp = task_pgrp(tsk); |
| 792 | if ((task_pgrp(t) != pgrp) && | 792 | if ((task_pgrp(t) != pgrp) && |
| 793 | (task_session(t) != task_session(tsk)) && | 793 | (task_session(t) == task_session(tsk)) && |
| 794 | will_become_orphaned_pgrp(pgrp, tsk) && | 794 | will_become_orphaned_pgrp(pgrp, tsk) && |
| 795 | has_stopped_jobs(pgrp)) { | 795 | has_stopped_jobs(pgrp)) { |
| 796 | __kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp); | 796 | __kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp); |
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index 9dd9fbb75139..cbb335813ec0 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c | |||
| @@ -17,6 +17,29 @@ | |||
| 17 | #include "filemap.h" | 17 | #include "filemap.h" |
| 18 | 18 | ||
| 19 | /* | 19 | /* |
| 20 | * We do use our own empty page to avoid interference with other users | ||
| 21 | * of ZERO_PAGE(), such as /dev/zero | ||
| 22 | */ | ||
| 23 | static struct page *__xip_sparse_page; | ||
| 24 | |||
| 25 | static struct page *xip_sparse_page(void) | ||
| 26 | { | ||
| 27 | if (!__xip_sparse_page) { | ||
| 28 | unsigned long zeroes = get_zeroed_page(GFP_HIGHUSER); | ||
| 29 | if (zeroes) { | ||
| 30 | static DEFINE_SPINLOCK(xip_alloc_lock); | ||
| 31 | spin_lock(&xip_alloc_lock); | ||
| 32 | if (!__xip_sparse_page) | ||
| 33 | __xip_sparse_page = virt_to_page(zeroes); | ||
| 34 | else | ||
| 35 | free_page(zeroes); | ||
| 36 | spin_unlock(&xip_alloc_lock); | ||
| 37 | } | ||
| 38 | } | ||
| 39 | return __xip_sparse_page; | ||
| 40 | } | ||
| 41 | |||
| 42 | /* | ||
| 20 | * This is a file read routine for execute in place files, and uses | 43 | * This is a file read routine for execute in place files, and uses |
| 21 | * the mapping->a_ops->get_xip_page() function for the actual low-level | 44 | * the mapping->a_ops->get_xip_page() function for the actual low-level |
| 22 | * stuff. | 45 | * stuff. |
| @@ -162,7 +185,7 @@ EXPORT_SYMBOL_GPL(xip_file_sendfile); | |||
| 162 | * xip_write | 185 | * xip_write |
| 163 | * | 186 | * |
| 164 | * This function walks all vmas of the address_space and unmaps the | 187 | * This function walks all vmas of the address_space and unmaps the |
| 165 | * ZERO_PAGE when found at pgoff. Should it go in rmap.c? | 188 | * __xip_sparse_page when found at pgoff. |
| 166 | */ | 189 | */ |
| 167 | static void | 190 | static void |
| 168 | __xip_unmap (struct address_space * mapping, | 191 | __xip_unmap (struct address_space * mapping, |
| @@ -177,13 +200,16 @@ __xip_unmap (struct address_space * mapping, | |||
| 177 | spinlock_t *ptl; | 200 | spinlock_t *ptl; |
| 178 | struct page *page; | 201 | struct page *page; |
| 179 | 202 | ||
| 203 | page = __xip_sparse_page; | ||
| 204 | if (!page) | ||
| 205 | return; | ||
| 206 | |||
| 180 | spin_lock(&mapping->i_mmap_lock); | 207 | spin_lock(&mapping->i_mmap_lock); |
| 181 | vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { | 208 | vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { |
| 182 | mm = vma->vm_mm; | 209 | mm = vma->vm_mm; |
| 183 | address = vma->vm_start + | 210 | address = vma->vm_start + |
| 184 | ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); | 211 | ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); |
| 185 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 212 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); |
| 186 | page = ZERO_PAGE(0); | ||
| 187 | pte = page_check_address(page, mm, address, &ptl); | 213 | pte = page_check_address(page, mm, address, &ptl); |
| 188 | if (pte) { | 214 | if (pte) { |
| 189 | /* Nuke the page table entry. */ | 215 | /* Nuke the page table entry. */ |
| @@ -222,16 +248,14 @@ xip_file_nopage(struct vm_area_struct * area, | |||
| 222 | + area->vm_pgoff; | 248 | + area->vm_pgoff; |
| 223 | 249 | ||
| 224 | size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 250 | size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
| 225 | if (pgoff >= size) { | 251 | if (pgoff >= size) |
| 226 | return NULL; | 252 | return NOPAGE_SIGBUS; |
| 227 | } | ||
| 228 | 253 | ||
| 229 | page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0); | 254 | page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0); |
| 230 | if (!IS_ERR(page)) { | 255 | if (!IS_ERR(page)) |
| 231 | goto out; | 256 | goto out; |
| 232 | } | ||
| 233 | if (PTR_ERR(page) != -ENODATA) | 257 | if (PTR_ERR(page) != -ENODATA) |
| 234 | return NULL; | 258 | return NOPAGE_SIGBUS; |
| 235 | 259 | ||
| 236 | /* sparse block */ | 260 | /* sparse block */ |
| 237 | if ((area->vm_flags & (VM_WRITE | VM_MAYWRITE)) && | 261 | if ((area->vm_flags & (VM_WRITE | VM_MAYWRITE)) && |
| @@ -241,12 +265,14 @@ xip_file_nopage(struct vm_area_struct * area, | |||
| 241 | page = mapping->a_ops->get_xip_page (mapping, | 265 | page = mapping->a_ops->get_xip_page (mapping, |
| 242 | pgoff*(PAGE_SIZE/512), 1); | 266 | pgoff*(PAGE_SIZE/512), 1); |
| 243 | if (IS_ERR(page)) | 267 | if (IS_ERR(page)) |
| 244 | return NULL; | 268 | return NOPAGE_SIGBUS; |
| 245 | /* unmap page at pgoff from all other vmas */ | 269 | /* unmap page at pgoff from all other vmas */ |
| 246 | __xip_unmap(mapping, pgoff); | 270 | __xip_unmap(mapping, pgoff); |
| 247 | } else { | 271 | } else { |
| 248 | /* not shared and writable, use ZERO_PAGE() */ | 272 | /* not shared and writable, use xip_sparse_page() */ |
| 249 | page = ZERO_PAGE(0); | 273 | page = xip_sparse_page(); |
| 274 | if (!page) | ||
| 275 | return NOPAGE_OOM; | ||
| 250 | } | 276 | } |
| 251 | 277 | ||
| 252 | out: | 278 | out: |
diff --git a/mm/madvise.c b/mm/madvise.c index 77916e9fc52b..603c5257ed6e 100644 --- a/mm/madvise.c +++ b/mm/madvise.c | |||
| @@ -159,9 +159,10 @@ static long madvise_remove(struct vm_area_struct *vma, | |||
| 159 | unsigned long start, unsigned long end) | 159 | unsigned long start, unsigned long end) |
| 160 | { | 160 | { |
| 161 | struct address_space *mapping; | 161 | struct address_space *mapping; |
| 162 | loff_t offset, endoff; | 162 | loff_t offset, endoff; |
| 163 | int error; | ||
| 163 | 164 | ||
| 164 | *prev = vma; | 165 | *prev = NULL; /* tell sys_madvise we drop mmap_sem */ |
| 165 | 166 | ||
| 166 | if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB)) | 167 | if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB)) |
| 167 | return -EINVAL; | 168 | return -EINVAL; |
| @@ -180,7 +181,12 @@ static long madvise_remove(struct vm_area_struct *vma, | |||
| 180 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); | 181 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); |
| 181 | endoff = (loff_t)(end - vma->vm_start - 1) | 182 | endoff = (loff_t)(end - vma->vm_start - 1) |
| 182 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); | 183 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); |
| 183 | return vmtruncate_range(mapping->host, offset, endoff); | 184 | |
| 185 | /* vmtruncate_range needs to take i_mutex and i_alloc_sem */ | ||
| 186 | up_write(¤t->mm->mmap_sem); | ||
| 187 | error = vmtruncate_range(mapping->host, offset, endoff); | ||
| 188 | down_write(¤t->mm->mmap_sem); | ||
| 189 | return error; | ||
| 184 | } | 190 | } |
| 185 | 191 | ||
| 186 | static long | 192 | static long |
| @@ -315,12 +321,15 @@ asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior) | |||
| 315 | if (error) | 321 | if (error) |
| 316 | goto out; | 322 | goto out; |
| 317 | start = tmp; | 323 | start = tmp; |
| 318 | if (start < prev->vm_end) | 324 | if (prev && start < prev->vm_end) |
| 319 | start = prev->vm_end; | 325 | start = prev->vm_end; |
| 320 | error = unmapped_error; | 326 | error = unmapped_error; |
| 321 | if (start >= end) | 327 | if (start >= end) |
| 322 | goto out; | 328 | goto out; |
| 323 | vma = prev->vm_next; | 329 | if (prev) |
| 330 | vma = prev->vm_next; | ||
| 331 | else /* madvise_remove dropped mmap_sem */ | ||
| 332 | vma = find_vma(current->mm, start); | ||
| 324 | } | 333 | } |
| 325 | out: | 334 | out: |
| 326 | up_write(¤t->mm->mmap_sem); | 335 | up_write(¤t->mm->mmap_sem); |
diff --git a/mm/shmem.c b/mm/shmem.c index b8c429a2d271..b2a35ebf071a 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
| @@ -402,26 +402,38 @@ static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long | |||
| 402 | /* | 402 | /* |
| 403 | * shmem_free_swp - free some swap entries in a directory | 403 | * shmem_free_swp - free some swap entries in a directory |
| 404 | * | 404 | * |
| 405 | * @dir: pointer to the directory | 405 | * @dir: pointer to the directory |
| 406 | * @edir: pointer after last entry of the directory | 406 | * @edir: pointer after last entry of the directory |
| 407 | * @punch_lock: pointer to spinlock when needed for the holepunch case | ||
| 407 | */ | 408 | */ |
| 408 | static int shmem_free_swp(swp_entry_t *dir, swp_entry_t *edir) | 409 | static int shmem_free_swp(swp_entry_t *dir, swp_entry_t *edir, |
| 410 | spinlock_t *punch_lock) | ||
| 409 | { | 411 | { |
| 412 | spinlock_t *punch_unlock = NULL; | ||
| 410 | swp_entry_t *ptr; | 413 | swp_entry_t *ptr; |
| 411 | int freed = 0; | 414 | int freed = 0; |
| 412 | 415 | ||
| 413 | for (ptr = dir; ptr < edir; ptr++) { | 416 | for (ptr = dir; ptr < edir; ptr++) { |
| 414 | if (ptr->val) { | 417 | if (ptr->val) { |
| 418 | if (unlikely(punch_lock)) { | ||
| 419 | punch_unlock = punch_lock; | ||
| 420 | punch_lock = NULL; | ||
| 421 | spin_lock(punch_unlock); | ||
| 422 | if (!ptr->val) | ||
| 423 | continue; | ||
| 424 | } | ||
| 415 | free_swap_and_cache(*ptr); | 425 | free_swap_and_cache(*ptr); |
| 416 | *ptr = (swp_entry_t){0}; | 426 | *ptr = (swp_entry_t){0}; |
| 417 | freed++; | 427 | freed++; |
| 418 | } | 428 | } |
| 419 | } | 429 | } |
| 430 | if (punch_unlock) | ||
| 431 | spin_unlock(punch_unlock); | ||
| 420 | return freed; | 432 | return freed; |
| 421 | } | 433 | } |
| 422 | 434 | ||
| 423 | static int shmem_map_and_free_swp(struct page *subdir, | 435 | static int shmem_map_and_free_swp(struct page *subdir, int offset, |
| 424 | int offset, int limit, struct page ***dir) | 436 | int limit, struct page ***dir, spinlock_t *punch_lock) |
| 425 | { | 437 | { |
| 426 | swp_entry_t *ptr; | 438 | swp_entry_t *ptr; |
| 427 | int freed = 0; | 439 | int freed = 0; |
| @@ -431,7 +443,8 @@ static int shmem_map_and_free_swp(struct page *subdir, | |||
| 431 | int size = limit - offset; | 443 | int size = limit - offset; |
| 432 | if (size > LATENCY_LIMIT) | 444 | if (size > LATENCY_LIMIT) |
| 433 | size = LATENCY_LIMIT; | 445 | size = LATENCY_LIMIT; |
| 434 | freed += shmem_free_swp(ptr+offset, ptr+offset+size); | 446 | freed += shmem_free_swp(ptr+offset, ptr+offset+size, |
| 447 | punch_lock); | ||
| 435 | if (need_resched()) { | 448 | if (need_resched()) { |
| 436 | shmem_swp_unmap(ptr); | 449 | shmem_swp_unmap(ptr); |
| 437 | if (*dir) { | 450 | if (*dir) { |
| @@ -481,7 +494,10 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) | |||
| 481 | long nr_swaps_freed = 0; | 494 | long nr_swaps_freed = 0; |
| 482 | int offset; | 495 | int offset; |
| 483 | int freed; | 496 | int freed; |
| 484 | int punch_hole = 0; | 497 | int punch_hole; |
| 498 | spinlock_t *needs_lock; | ||
| 499 | spinlock_t *punch_lock; | ||
| 500 | unsigned long upper_limit; | ||
| 485 | 501 | ||
| 486 | inode->i_ctime = inode->i_mtime = CURRENT_TIME; | 502 | inode->i_ctime = inode->i_mtime = CURRENT_TIME; |
| 487 | idx = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 503 | idx = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
| @@ -492,11 +508,20 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) | |||
| 492 | info->flags |= SHMEM_TRUNCATE; | 508 | info->flags |= SHMEM_TRUNCATE; |
| 493 | if (likely(end == (loff_t) -1)) { | 509 | if (likely(end == (loff_t) -1)) { |
| 494 | limit = info->next_index; | 510 | limit = info->next_index; |
| 511 | upper_limit = SHMEM_MAX_INDEX; | ||
| 495 | info->next_index = idx; | 512 | info->next_index = idx; |
| 513 | needs_lock = NULL; | ||
| 514 | punch_hole = 0; | ||
| 496 | } else { | 515 | } else { |
| 497 | limit = (end + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 516 | if (end + 1 >= inode->i_size) { /* we may free a little more */ |
| 498 | if (limit > info->next_index) | 517 | limit = (inode->i_size + PAGE_CACHE_SIZE - 1) >> |
| 499 | limit = info->next_index; | 518 | PAGE_CACHE_SHIFT; |
| 519 | upper_limit = SHMEM_MAX_INDEX; | ||
| 520 | } else { | ||
| 521 | limit = (end + 1) >> PAGE_CACHE_SHIFT; | ||
| 522 | upper_limit = limit; | ||
| 523 | } | ||
| 524 | needs_lock = &info->lock; | ||
| 500 | punch_hole = 1; | 525 | punch_hole = 1; |
| 501 | } | 526 | } |
| 502 | 527 | ||
| @@ -513,17 +538,30 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) | |||
| 513 | size = limit; | 538 | size = limit; |
| 514 | if (size > SHMEM_NR_DIRECT) | 539 | if (size > SHMEM_NR_DIRECT) |
| 515 | size = SHMEM_NR_DIRECT; | 540 | size = SHMEM_NR_DIRECT; |
| 516 | nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size); | 541 | nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size, needs_lock); |
| 517 | } | 542 | } |
| 518 | 543 | ||
| 519 | /* | 544 | /* |
| 520 | * If there are no indirect blocks or we are punching a hole | 545 | * If there are no indirect blocks or we are punching a hole |
| 521 | * below indirect blocks, nothing to be done. | 546 | * below indirect blocks, nothing to be done. |
| 522 | */ | 547 | */ |
| 523 | if (!topdir || (punch_hole && (limit <= SHMEM_NR_DIRECT))) | 548 | if (!topdir || limit <= SHMEM_NR_DIRECT) |
| 524 | goto done2; | 549 | goto done2; |
| 525 | 550 | ||
| 526 | BUG_ON(limit <= SHMEM_NR_DIRECT); | 551 | /* |
| 552 | * The truncation case has already dropped info->lock, and we're safe | ||
| 553 | * because i_size and next_index have already been lowered, preventing | ||
| 554 | * access beyond. But in the punch_hole case, we still need to take | ||
| 555 | * the lock when updating the swap directory, because there might be | ||
| 556 | * racing accesses by shmem_getpage(SGP_CACHE), shmem_unuse_inode or | ||
| 557 | * shmem_writepage. However, whenever we find we can remove a whole | ||
| 558 | * directory page (not at the misaligned start or end of the range), | ||
| 559 | * we first NULLify its pointer in the level above, and then have no | ||
| 560 | * need to take the lock when updating its contents: needs_lock and | ||
| 561 | * punch_lock (either pointing to info->lock or NULL) manage this. | ||
| 562 | */ | ||
| 563 | |||
| 564 | upper_limit -= SHMEM_NR_DIRECT; | ||
| 527 | limit -= SHMEM_NR_DIRECT; | 565 | limit -= SHMEM_NR_DIRECT; |
| 528 | idx = (idx > SHMEM_NR_DIRECT)? (idx - SHMEM_NR_DIRECT): 0; | 566 | idx = (idx > SHMEM_NR_DIRECT)? (idx - SHMEM_NR_DIRECT): 0; |
| 529 | offset = idx % ENTRIES_PER_PAGE; | 567 | offset = idx % ENTRIES_PER_PAGE; |
| @@ -543,8 +581,14 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) | |||
| 543 | if (*dir) { | 581 | if (*dir) { |
| 544 | diroff = ((idx - ENTRIES_PER_PAGEPAGE/2) % | 582 | diroff = ((idx - ENTRIES_PER_PAGEPAGE/2) % |
| 545 | ENTRIES_PER_PAGEPAGE) / ENTRIES_PER_PAGE; | 583 | ENTRIES_PER_PAGEPAGE) / ENTRIES_PER_PAGE; |
| 546 | if (!diroff && !offset) { | 584 | if (!diroff && !offset && upper_limit >= stage) { |
| 547 | *dir = NULL; | 585 | if (needs_lock) { |
| 586 | spin_lock(needs_lock); | ||
| 587 | *dir = NULL; | ||
| 588 | spin_unlock(needs_lock); | ||
| 589 | needs_lock = NULL; | ||
| 590 | } else | ||
| 591 | *dir = NULL; | ||
| 548 | nr_pages_to_free++; | 592 | nr_pages_to_free++; |
| 549 | list_add(&middir->lru, &pages_to_free); | 593 | list_add(&middir->lru, &pages_to_free); |
| 550 | } | 594 | } |
| @@ -570,39 +614,55 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) | |||
| 570 | } | 614 | } |
| 571 | stage = idx + ENTRIES_PER_PAGEPAGE; | 615 | stage = idx + ENTRIES_PER_PAGEPAGE; |
| 572 | middir = *dir; | 616 | middir = *dir; |
| 573 | *dir = NULL; | 617 | if (punch_hole) |
| 574 | nr_pages_to_free++; | 618 | needs_lock = &info->lock; |
| 575 | list_add(&middir->lru, &pages_to_free); | 619 | if (upper_limit >= stage) { |
| 620 | if (needs_lock) { | ||
| 621 | spin_lock(needs_lock); | ||
| 622 | *dir = NULL; | ||
| 623 | spin_unlock(needs_lock); | ||
| 624 | needs_lock = NULL; | ||
| 625 | } else | ||
| 626 | *dir = NULL; | ||
| 627 | nr_pages_to_free++; | ||
| 628 | list_add(&middir->lru, &pages_to_free); | ||
| 629 | } | ||
| 576 | shmem_dir_unmap(dir); | 630 | shmem_dir_unmap(dir); |
| 577 | cond_resched(); | 631 | cond_resched(); |
| 578 | dir = shmem_dir_map(middir); | 632 | dir = shmem_dir_map(middir); |
| 579 | diroff = 0; | 633 | diroff = 0; |
| 580 | } | 634 | } |
| 635 | punch_lock = needs_lock; | ||
| 581 | subdir = dir[diroff]; | 636 | subdir = dir[diroff]; |
| 582 | if (subdir && page_private(subdir)) { | 637 | if (subdir && !offset && upper_limit-idx >= ENTRIES_PER_PAGE) { |
| 638 | if (needs_lock) { | ||
| 639 | spin_lock(needs_lock); | ||
| 640 | dir[diroff] = NULL; | ||
| 641 | spin_unlock(needs_lock); | ||
| 642 | punch_lock = NULL; | ||
| 643 | } else | ||
| 644 | dir[diroff] = NULL; | ||
| 645 | nr_pages_to_free++; | ||
| 646 | list_add(&subdir->lru, &pages_to_free); | ||
| 647 | } | ||
| 648 | if (subdir && page_private(subdir) /* has swap entries */) { | ||
| 583 | size = limit - idx; | 649 | size = limit - idx; |
| 584 | if (size > ENTRIES_PER_PAGE) | 650 | if (size > ENTRIES_PER_PAGE) |
| 585 | size = ENTRIES_PER_PAGE; | 651 | size = ENTRIES_PER_PAGE; |
| 586 | freed = shmem_map_and_free_swp(subdir, | 652 | freed = shmem_map_and_free_swp(subdir, |
| 587 | offset, size, &dir); | 653 | offset, size, &dir, punch_lock); |
| 588 | if (!dir) | 654 | if (!dir) |
| 589 | dir = shmem_dir_map(middir); | 655 | dir = shmem_dir_map(middir); |
| 590 | nr_swaps_freed += freed; | 656 | nr_swaps_freed += freed; |
| 591 | if (offset) | 657 | if (offset || punch_lock) { |
| 592 | spin_lock(&info->lock); | 658 | spin_lock(&info->lock); |
| 593 | set_page_private(subdir, page_private(subdir) - freed); | 659 | set_page_private(subdir, |
| 594 | if (offset) | 660 | page_private(subdir) - freed); |
| 595 | spin_unlock(&info->lock); | 661 | spin_unlock(&info->lock); |
| 596 | if (!punch_hole) | 662 | } else |
| 597 | BUG_ON(page_private(subdir) > offset); | 663 | BUG_ON(page_private(subdir) != freed); |
| 598 | } | ||
| 599 | if (offset) | ||
| 600 | offset = 0; | ||
| 601 | else if (subdir && !page_private(subdir)) { | ||
| 602 | dir[diroff] = NULL; | ||
| 603 | nr_pages_to_free++; | ||
| 604 | list_add(&subdir->lru, &pages_to_free); | ||
| 605 | } | 664 | } |
| 665 | offset = 0; | ||
| 606 | } | 666 | } |
| 607 | done1: | 667 | done1: |
| 608 | shmem_dir_unmap(dir); | 668 | shmem_dir_unmap(dir); |
| @@ -614,8 +674,16 @@ done2: | |||
| 614 | * generic_delete_inode did it, before we lowered next_index. | 674 | * generic_delete_inode did it, before we lowered next_index. |
| 615 | * Also, though shmem_getpage checks i_size before adding to | 675 | * Also, though shmem_getpage checks i_size before adding to |
| 616 | * cache, no recheck after: so fix the narrow window there too. | 676 | * cache, no recheck after: so fix the narrow window there too. |
| 677 | * | ||
| 678 | * Recalling truncate_inode_pages_range and unmap_mapping_range | ||
| 679 | * every time for punch_hole (which never got a chance to clear | ||
| 680 | * SHMEM_PAGEIN at the start of vmtruncate_range) is expensive, | ||
| 681 | * yet hardly ever necessary: try to optimize them out later. | ||
| 617 | */ | 682 | */ |
| 618 | truncate_inode_pages_range(inode->i_mapping, start, end); | 683 | truncate_inode_pages_range(inode->i_mapping, start, end); |
| 684 | if (punch_hole) | ||
| 685 | unmap_mapping_range(inode->i_mapping, start, | ||
| 686 | end - start, 1); | ||
| 619 | } | 687 | } |
| 620 | 688 | ||
| 621 | spin_lock(&info->lock); | 689 | spin_lock(&info->lock); |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index ecfe8da1ce6b..d342e89b8bdd 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
| @@ -679,6 +679,27 @@ static void hidp_close(struct hid_device *hid) | |||
| 679 | { | 679 | { |
| 680 | } | 680 | } |
| 681 | 681 | ||
| 682 | static const struct { | ||
| 683 | __u16 idVendor; | ||
| 684 | __u16 idProduct; | ||
| 685 | unsigned quirks; | ||
| 686 | } hidp_blacklist[] = { | ||
| 687 | /* Apple wireless Mighty Mouse */ | ||
| 688 | { 0x05ac, 0x030c, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, | ||
| 689 | |||
| 690 | { } /* Terminating entry */ | ||
| 691 | }; | ||
| 692 | |||
| 693 | static void hidp_setup_quirks(struct hid_device *hid) | ||
| 694 | { | ||
| 695 | unsigned int n; | ||
| 696 | |||
| 697 | for (n = 0; hidp_blacklist[n].idVendor; n++) | ||
| 698 | if (hidp_blacklist[n].idVendor == le16_to_cpu(hid->vendor) && | ||
| 699 | hidp_blacklist[n].idProduct == le16_to_cpu(hid->product)) | ||
| 700 | hid->quirks = hidp_blacklist[n].quirks; | ||
| 701 | } | ||
| 702 | |||
| 682 | static inline void hidp_setup_hid(struct hidp_session *session, struct hidp_connadd_req *req) | 703 | static inline void hidp_setup_hid(struct hidp_session *session, struct hidp_connadd_req *req) |
| 683 | { | 704 | { |
| 684 | struct hid_device *hid = session->hid; | 705 | struct hid_device *hid = session->hid; |
| @@ -708,6 +729,8 @@ static inline void hidp_setup_hid(struct hidp_session *session, struct hidp_conn | |||
| 708 | 729 | ||
| 709 | hid->hidinput_input_event = hidp_hidinput_event; | 730 | hid->hidinput_input_event = hidp_hidinput_event; |
| 710 | 731 | ||
| 732 | hidp_setup_quirks(hid); | ||
| 733 | |||
| 711 | list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) | 734 | list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) |
| 712 | hidp_send_report(session, report); | 735 | hidp_send_report(session, report); |
| 713 | 736 | ||
