From 056e6d89aab51babaa5f75c16832b19c55a68bc4 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 30 Jul 2007 22:50:13 +0200 Subject: [IA64] fix a few section mismatch warnings Fix the following section mismatch warnings: WARNING: vmlinux.o(.text+0x41902): Section mismatch: reference to .init.text:__alloc_bootmem (between 'ia64_mca_cpu_init' and 'ia64_do_tlb_purge') WARNING: vmlinux.o(.text+0x49222): Section mismatch: reference to .init.text:__alloc_bootmem (between 'register_intr' and 'iosapic_register_intr') WARNING: vmlinux.o(.text+0x62beb2): Section mismatch: reference to .init.text:__alloc_bootmem_node (between 'hubdev_init_node' and 'cnodeid_get_geoid') Signed-off-by: Sam Ravnborg Signed-off-by: Tony Luck --- arch/ia64/kernel/iosapic.c | 2 +- arch/ia64/kernel/mca.c | 17 +++++++++++------ arch/ia64/sn/kernel/io_common.c | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 91e6dc1e7baf..f4bd285effe6 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -560,7 +560,7 @@ iosapic_reassign_vector (int irq) } } -static struct iosapic_rte_info *iosapic_alloc_rte (void) +static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void) { int i; struct iosapic_rte_info *rte; diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 4b5daa3cc0fe..ff28620cb992 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -1750,8 +1750,17 @@ format_mca_init_stack(void *mca_data, unsigned long offset, strncpy(p->comm, type, sizeof(p->comm)-1); } -/* Do per-CPU MCA-related initialization. */ +/* Caller prevents this from being called after init */ +static void * __init_refok mca_bootmem(void) +{ + void *p; + p = alloc_bootmem(sizeof(struct ia64_mca_cpu) * NR_CPUS + + KERNEL_STACK_SIZE); + return (void *)ALIGN((unsigned long)p, KERNEL_STACK_SIZE); +} + +/* Do per-CPU MCA-related initialization. */ void __cpuinit ia64_mca_cpu_init(void *cpu_data) { @@ -1763,11 +1772,7 @@ ia64_mca_cpu_init(void *cpu_data) int cpu; first_time = 0; - mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu) - * NR_CPUS + KERNEL_STACK_SIZE); - mca_data = (void *)(((unsigned long)mca_data + - KERNEL_STACK_SIZE - 1) & - (-KERNEL_STACK_SIZE)); + mca_data = mca_bootmem(); for (cpu = 0; cpu < NR_CPUS; cpu++) { format_mca_init_stack(mca_data, offsetof(struct ia64_mca_cpu, mca_stack), diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index 787ed642dd49..4594770e685a 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -391,7 +391,7 @@ void sn_bus_free_sysdata(void) * hubdev_init_node() - Creates the HUB data structure and link them to it's * own NODE specific data area. */ -void hubdev_init_node(nodepda_t * npda, cnodeid_t node) +void __init hubdev_init_node(nodepda_t * npda, cnodeid_t node) { struct hubdev_info *hubdev_info; int size; -- cgit v1.2.2 From 8a2d8693054a6cd86cc959576322b30e66e31208 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 19 Jul 2007 18:32:43 +0300 Subject: [IA64] Allow smp_call_function_single() to current cpu This removes the requirement for callers to get_cpu() to check in simple cases. i386 and x86_64 already received a similar treatment. Signed-off-by: Avi Kivity Signed-off-by: Tony Luck --- arch/ia64/kernel/smp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 0982882bfb80..4e446aa5f4ac 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -346,7 +346,7 @@ smp_flush_tlb_mm (struct mm_struct *mm) } /* - * Run a function on another CPU + * Run a function on a specific CPU * The function to run. This must be fast and non-blocking. * An arbitrary pointer to pass to the function. * Currently unused. @@ -366,9 +366,11 @@ smp_call_function_single (int cpuid, void (*func) (void *info), void *info, int int me = get_cpu(); /* prevent preemption and reschedule on another processor */ if (cpuid == me) { - printk(KERN_INFO "%s: trying to call self\n", __FUNCTION__); + local_irq_disable(); + func(info); + local_irq_enable(); put_cpu(); - return -EBUSY; + return 0; } data.func = func; -- cgit v1.2.2 From 1b30859b8d42b3161954a81da7f96055a4617220 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 30 Jul 2007 00:28:42 +0200 Subject: [IA64] Remove a few duplicate includes This patch removes a few duplicate includes from arch/ia64/ Acked-by: Jes Sorensen Signed-off-by: Jesper Juhl Signed-off-by: Tony Luck --- arch/ia64/ia32/sys_ia32.c | 1 - arch/ia64/kernel/setup.c | 1 - arch/ia64/sn/kernel/setup.c | 1 - 3 files changed, 3 deletions(-) diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index af10462d44d4..a3405b3c1eef 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 7cecd2964200..cd9a37a552c3 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -60,7 +60,6 @@ #include #include #include -#include #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE) # error "struct cpuinfo_ia64 too big!" diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 684b1c984a44..1f38a3a68390 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.2 From c4c376f7e16deeba8f0542eabcaca19b712e7be1 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Mon, 30 Jul 2007 11:54:41 +0900 Subject: [IA64] Fix registered interrupt check Fix the problem that interrupts are not initialized correctly at PCI hotplug or driver reloading time. By vector domain change, the iosapic_rte_info structure was changed to be on the iosapic_intr_info[irq].rtes list even after the interrupts are unregistered. So iosapic_intr_info[irq].rtes list must not be checked to see if there are registered interrupts (RTEs) on the irq. We must check iosapic_intr_info[irq].count counter instead. Signed-off-by: Kenji Kaneshige Signed-off-by: Tony Luck --- arch/ia64/kernel/iosapic.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index f4bd285effe6..5f6d98e866ea 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -142,7 +142,7 @@ struct iosapic_rte_info { static struct iosapic_intr_info { struct list_head rtes; /* RTEs using this vector (empty => * not an IOSAPIC interrupt) */ - int count; /* # of RTEs that shares this vector */ + int count; /* # of registered RTEs */ u32 low32; /* current value of low word of * Redirection table entry */ unsigned int dest; /* destination CPU physical ID */ @@ -313,7 +313,7 @@ mask_irq (unsigned int irq) int rte_index; struct iosapic_rte_info *rte; - if (list_empty(&iosapic_intr_info[irq].rtes)) + if (!iosapic_intr_info[irq].count) return; /* not an IOSAPIC interrupt! */ /* set only the mask bit */ @@ -331,7 +331,7 @@ unmask_irq (unsigned int irq) int rte_index; struct iosapic_rte_info *rte; - if (list_empty(&iosapic_intr_info[irq].rtes)) + if (!iosapic_intr_info[irq].count) return; /* not an IOSAPIC interrupt! */ low32 = iosapic_intr_info[irq].low32 &= ~IOSAPIC_MASK; @@ -363,7 +363,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) dest = cpu_physical_id(first_cpu(mask)); - if (list_empty(&iosapic_intr_info[irq].rtes)) + if (!iosapic_intr_info[irq].count) return; /* not an IOSAPIC interrupt */ set_irq_affinity_info(irq, dest, redir); @@ -542,7 +542,7 @@ iosapic_reassign_vector (int irq) { int new_irq; - if (!list_empty(&iosapic_intr_info[irq].rtes)) { + if (iosapic_intr_info[irq].count) { new_irq = create_irq(); if (new_irq < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); @@ -677,7 +677,7 @@ get_target_cpu (unsigned int gsi, int irq) * In case of vector shared by multiple RTEs, all RTEs that * share the vector need to use the same destination CPU. */ - if (!list_empty(&iosapic_intr_info[irq].rtes)) + if (iosapic_intr_info[irq].count) return iosapic_intr_info[irq].dest; /* -- cgit v1.2.2 From 216fcd29af47ab53ffd87e82139fcc4095e34d91 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Mon, 30 Jul 2007 11:56:30 +0900 Subject: [IA64] Fix possible race in destroy_and_reserve_irq() Currently, destroy_and_reserve_irq() sets irq_status[irq] UNUSED using clear_irq_vector() and sets irq_status[irq] RSVD using reserve_irq(). But there is a race window because vector_lock is once released between them. This patch fixes this race window. Signed-off-by: Kenji Kaneshige Signed-off-by: Tony Luck --- arch/ia64/kernel/irq_ia64.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 9386b955eed1..c47c8acc96e3 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -101,15 +101,6 @@ int check_irq_used(int irq) return -1; } -static void reserve_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&vector_lock, flags); - irq_status[irq] = IRQ_RSVD; - spin_unlock_irqrestore(&vector_lock, flags); -} - static inline int find_unassigned_irq(void) { int irq; @@ -302,10 +293,14 @@ static cpumask_t vector_allocation_domain(int cpu) void destroy_and_reserve_irq(unsigned int irq) { + unsigned long flags; + dynamic_irq_cleanup(irq); - clear_irq_vector(irq); - reserve_irq(irq); + spin_lock_irqsave(&vector_lock, flags); + __clear_irq_vector(irq); + irq_status[irq] = IRQ_RSVD; + spin_unlock_irqrestore(&vector_lock, flags); } static int __reassign_irq_vector(int irq, int cpu) -- cgit v1.2.2 From dbf0c89c80e47a2a132048dcded0dcc2a59c74ad Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 26 Jul 2007 18:43:01 +0100 Subject: pata_cmd64x: Correct the speed ranges I must have been half asleep when doing the original code Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_cmd64x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index dc443e7dc37c..e34b632487d7 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -31,7 +31,7 @@ #include #define DRV_NAME "pata_cmd64x" -#define DRV_VERSION "0.2.3" +#define DRV_VERSION "0.2.4" /* * CMD64x specific registers definition. @@ -397,7 +397,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = ATA_UDMA1, + .udma_mask = ATA_UDMA2, .port_ops = &cmd64x_port_ops }, { /* CMD 646 rev 1 */ @@ -412,7 +412,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = ATA_UDMA2, + .udma_mask = ATA_UDMA4, .port_ops = &cmd648_port_ops }, { /* CMD 649 */ @@ -420,7 +420,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = ATA_UDMA3, + .udma_mask = ATA_UDMA5, .port_ops = &cmd648_port_ops } }; -- cgit v1.2.2 From 6fdc99a224bd52020c602c3d4d57e5f8a75f6bb8 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 26 Jul 2007 18:41:30 +0100 Subject: libata-sff; Unbreak non DMA capable controllers again Seems nobody else is checking/testing this case as it keeps getting horked. If we have no BAR4 mapping on an SFF controller this is *NOT* an error, it just means it isn't doing BMDMA. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 6c289c7b1322..1cce2198baaf 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -573,6 +573,10 @@ int ata_pci_init_bmdma(struct ata_host *host) struct pci_dev *pdev = to_pci_dev(gdev); int i, rc; + /* No BAR4 allocation: No DMA */ + if (pci_resource_start(pdev, 4) == 0) + return 0; + /* TODO: If we get no DMA mask we should fall back to PIO */ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) -- cgit v1.2.2 From 0b62e13b5c9b4871641973e024cc9dd440b5bb58 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 27 Jul 2007 14:43:35 +0900 Subject: pci: rename __pci_reenable_device() to pci_reenable_device() Rename __pci_reenable_device() to pci_reenable_device(). Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 6 +++--- drivers/pci/pci-driver.c | 2 +- drivers/pci/pci.c | 7 +++---- include/linux/pci.h | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index ad070861bb53..6089fbc5b89f 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -973,10 +973,10 @@ static int piix_pci_device_resume(struct pci_dev *pdev) pci_restore_state(pdev); /* PCI device wasn't disabled during suspend. Use - * __pci_reenable_device() to avoid affecting the - * enable count. + * pci_reenable_device() to avoid affecting the enable + * count. */ - rc = __pci_reenable_device(pdev); + rc = pci_reenable_device(pdev); if (rc) dev_printk(KERN_ERR, &pdev->dev, "failed to enable " "device after resume (%d)\n", rc); diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 8e58ea3d95c0..004bc2487270 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -310,7 +310,7 @@ static int pci_default_resume(struct pci_dev *pci_dev) /* restore the PCI config space */ pci_restore_state(pci_dev); /* if the device was enabled before suspend, reenable */ - retval = __pci_reenable_device(pci_dev); + retval = pci_reenable_device(pci_dev); /* if the device was busmaster before the suspend, make it busmaster again */ if (pci_dev->is_busmaster) pci_set_master(pci_dev); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1ee9cd9c86e2..37c00f6fd801 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -695,14 +695,13 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars) } /** - * __pci_reenable_device - Resume abandoned device + * pci_reenable_device - Resume abandoned device * @dev: PCI device to be resumed * * Note this function is a backend of pci_default_resume and is not supposed * to be called by normal code, write proper resume handler and use it instead. */ -int -__pci_reenable_device(struct pci_dev *dev) +int pci_reenable_device(struct pci_dev *dev) { if (atomic_read(&dev->enable_cnt)) return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1); @@ -1604,7 +1603,7 @@ early_param("pci", pci_setup); device_initcall(pci_init); EXPORT_SYMBOL_GPL(pci_restore_bars); -EXPORT_SYMBOL(__pci_reenable_device); +EXPORT_SYMBOL(pci_reenable_device); EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pcim_enable_device); diff --git a/include/linux/pci.h b/include/linux/pci.h index d8f8a3a96644..e7d8d4e19a53 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -534,7 +534,7 @@ static inline int pci_write_config_dword(struct pci_dev *dev, int where, u32 val int __must_check pci_enable_device(struct pci_dev *dev); int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); -int __must_check __pci_reenable_device(struct pci_dev *); +int __must_check pci_reenable_device(struct pci_dev *); int __must_check pcim_enable_device(struct pci_dev *pdev); void pcim_pin_device(struct pci_dev *pdev); -- cgit v1.2.2 From 8c3832ebeb049c5744ece888daae253c683257c3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 27 Jul 2007 14:53:28 +0900 Subject: ata_piix: implement piix_borken_suspend() Separate out broken suspend blacklist matching into piix_broken_suspend(). Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 60 +++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 6089fbc5b89f..fb3b9594651d 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -890,37 +890,38 @@ static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev) } #ifdef CONFIG_PM -static struct dmi_system_id piix_broken_suspend_dmi_table[] = { - { - .ident = "TECRA M5", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M5"), +static int piix_broken_suspend(void) +{ + static struct dmi_system_id sysids[] = { + { + .ident = "TECRA M5", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M5"), + }, }, - }, - { - .ident = "Satellite U200", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U200"), + { + .ident = "Satellite U205", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U205"), + }, }, - }, - { - .ident = "Satellite U205", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U205"), + { + .ident = "Portege M500", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M500"), + }, }, - }, - { - .ident = "Portege M500", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M500"), - }, - }, - { } -}; + { } + }; + + if (dmi_check_system(sysids)) + return 1; + + return 0; +} static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { @@ -937,8 +938,7 @@ static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) * cycles and power trying to do something to the sleeping * beauty. */ - if (dmi_check_system(piix_broken_suspend_dmi_table) && - mesg.event == PM_EVENT_SUSPEND) { + if (piix_broken_suspend() && mesg.event == PM_EVENT_SUSPEND) { pci_save_state(pdev); /* mark its power state as "unknown", since we don't -- cgit v1.2.2 From 7abe79c353caf868053c2ddcada7f4c20c8251e6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 27 Jul 2007 14:55:07 +0900 Subject: ata_piix: add Tecra M3 to broken suspend blacklist Add Tecra M3 to the broken suspend blacklist. Tecra M3 doesn't have proper DMI_PRODUCT_NAME but has an OEM_STRING instead. Match it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index fb3b9594651d..a78832ea81fa 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -916,10 +916,18 @@ static int piix_broken_suspend(void) }, { } }; + static const char *oemstrs[] = { + "Tecra M3,", + }; + int i; if (dmi_check_system(sysids)) return 1; + for (i = 0; i < ARRAY_SIZE(oemstrs); i++) + if (dmi_find_device(DMI_DEV_TYPE_OEM_STRING, oemstrs[i], NULL)) + return 1; + return 0; } -- cgit v1.2.2 From 5d6aca8defe77dfd0f0169cc015b900129078648 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 28 Jul 2007 16:25:25 +0900 Subject: libata: blacklist SAMSUNG HD401LJ / ZZ100-15 for NCQ SAMSUNG HD401LJ / ZZ100-15 does spurious completion of NCQ commands. Disable NCQ. Reported by Ulrich in bugzilla #8805. Signed-off-by: Tejun Heo Cc: Ulrich Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 6001aae0b884..60e78bef469f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3788,6 +3788,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, }, { "ST9160821AS", "3.CLF", ATA_HORKAGE_NONCQ, }, + { "SAMSUNG HD401LJ", "ZZ100-15", ATA_HORKAGE_NONCQ, }, /* Devices with NCQ limits */ -- cgit v1.2.2 From 4761c06cb39011c9cc3fef9e6bbfb4c50ceb307d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 31 Jul 2007 22:02:41 +0200 Subject: pata_sis: fix MWDMA for <= UDMA66 chipsets and UDMA for UDMA33 chipsets * Fix MWDMA timings setup in sis_old_set_dmamode() and sis_66_set_dmamode(). The old timings were overclocked (even worse behavior than sis5513 IDE driver which depends on BIOS to program correct timings), the new timings are taken from the datasheet (they match timings from ATA spec). * Fix UDMA timings setup in sis_old_set_dmamode(). Misplaced pci_write_config_word() call resulted in UDMA timings never being set. * Fix comments for sis_133_early_set_dmamode() and sis_133_set_dmamode(): - only the former function handles early SiS 961 bridges - both functions lack MWDMA timings setup * Fix typos in sis_100_set_piomode() and sis_133_set_piomode() comments. * Bump driver version. Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_sis.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 9a829a7cbc60..66bd0e83ac07 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -2,6 +2,7 @@ * pata_sis.c - SiS ATA driver * * (C) 2005 Red Hat + * (C) 2007 Bartlomiej Zolnierkiewicz * * Based upon linux/drivers/ide/pci/sis5513.c * Copyright (C) 1999-2000 Andre Hedrick @@ -35,7 +36,7 @@ #include "sis.h" #define DRV_NAME "pata_sis" -#define DRV_VERSION "0.5.1" +#define DRV_VERSION "0.5.2" struct sis_chipset { u16 device; /* PCI host ID */ @@ -237,7 +238,7 @@ static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev) } /** - * sis_100_set_pioode - Initialize host controller PATA PIO timings + * sis_100_set_piomode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring * @adev: Device we are configuring for. * @@ -262,7 +263,7 @@ static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev) } /** - * sis_133_set_pioode - Initialize host controller PATA PIO timings + * sis_133_set_piomode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring * @adev: Device we are configuring for. * @@ -334,7 +335,7 @@ static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev) int drive_pci = sis_old_port_base(adev); u16 timing; - const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 }; + const u16 mwdma_bits[] = { 0x008, 0x302, 0x301 }; const u16 udma_bits[] = { 0xE000, 0xC000, 0xA000 }; pci_read_config_word(pdev, drive_pci, &timing); @@ -342,15 +343,15 @@ static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev) if (adev->dma_mode < XFER_UDMA_0) { /* bits 3-0 hold recovery timing bits 8-10 active timing and the higer bits are dependant on the device */ - timing &= ~ 0x870F; + timing &= ~0x870F; timing |= mwdma_bits[speed]; - pci_write_config_word(pdev, drive_pci, timing); } else { /* Bit 15 is UDMA on/off, bit 13-14 are cycle time */ speed = adev->dma_mode - XFER_UDMA_0; timing &= ~0x6000; timing |= udma_bits[speed]; } + pci_write_config_word(pdev, drive_pci, timing); } /** @@ -373,7 +374,7 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev) int drive_pci = sis_old_port_base(adev); u16 timing; - const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 }; + const u16 mwdma_bits[] = { 0x008, 0x302, 0x301 }; const u16 udma_bits[] = { 0xF000, 0xD000, 0xB000, 0xA000, 0x9000}; pci_read_config_word(pdev, drive_pci, &timing); @@ -432,8 +433,7 @@ static void sis_100_set_dmamode (struct ata_port *ap, struct ata_device *adev) * @adev: Device to program * * Set UDMA/MWDMA mode for device, in host controller PCI config space. - * Handles early SiS 961 bridges. Supports MWDMA as well unlike - * the old ide/pci driver. + * Handles early SiS 961 bridges. * * LOCKING: * None (inherited from caller). @@ -467,8 +467,6 @@ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *a * @adev: Device to program * * Set UDMA/MWDMA mode for device, in host controller PCI config space. - * Handles early SiS 961 bridges. Supports MWDMA as well unlike - * the old ide/pci driver. * * LOCKING: * None (inherited from caller). -- cgit v1.2.2 From 224685c0d1ca5970364c9f5d4f21ea1aa64c381e Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Wed, 1 Aug 2007 21:18:44 +0900 Subject: [IA64] Fix wrong access to irq_desc[] in iosapic_register_intr(). In error path we must unlock irq_desc[irq].lock before we change 'irq'. Signed-off-by: Kenji Kaneshige Signed-off-by: Tony Luck --- arch/ia64/kernel/iosapic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 5f6d98e866ea..cfe4654838f4 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -794,8 +794,9 @@ iosapic_register_intr (unsigned int gsi, err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); if (err < 0) { + spin_unlock(&irq_desc[irq].lock); irq = err; - goto unlock_all; + goto unlock_iosapic_lock; } /* @@ -811,7 +812,7 @@ iosapic_register_intr (unsigned int gsi, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), cpu_logical_id(dest), dest, irq_to_vector(irq)); - unlock_all: + spin_unlock(&irq_desc[irq].lock); unlock_iosapic_lock: spin_unlock_irqrestore(&iosapic_lock, flags); -- cgit v1.2.2 From 40d485753423b87239cc16b6c8141ef8792324d9 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Aug 2007 12:37:17 -0700 Subject: [IA64] SN2: Fix up sn2_rtc clock If the sn2_rtc clock is present then it is a must have since sn2_rtc provides a synchronized time source on Altix systems. So elevate the priority to 450. Otherwise the ITC would take precendence. Altix systems currently do not boot because the ITC clocksource is broken. It seems to assume that ITCs are synchronized and as a result nanosleep hangs (may be fixed in a different patch). While we are at it: Remove the sn2_mc definition. The sn2_rtc has a fixed address. No point in reading the address from memory. Removing it avoids touching one cacheline. Signed-off-by: Christoph Lameter Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/sn2/timer.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/ia64/sn/kernel/sn2/timer.c b/arch/ia64/sn/kernel/sn2/timer.c index 19e25d2b64fc..cf67fc562054 100644 --- a/arch/ia64/sn/kernel/sn2/timer.c +++ b/arch/ia64/sn/kernel/sn2/timer.c @@ -23,16 +23,14 @@ extern unsigned long sn_rtc_cycles_per_second; -static void __iomem *sn2_mc; - static cycle_t read_sn2(void) { - return (cycle_t)readq(sn2_mc); + return (cycle_t)readq(RTC_COUNTER_ADDR); } static struct clocksource clocksource_sn2 = { .name = "sn2_rtc", - .rating = 300, + .rating = 450, .read = read_sn2, .mask = (1LL << 55) - 1, .mult = 0, @@ -58,7 +56,6 @@ ia64_sn_udelay (unsigned long usecs) void __init sn_timer_init(void) { - sn2_mc = RTC_COUNTER_ADDR; clocksource_sn2.fsys_mmio = RTC_COUNTER_ADDR; clocksource_sn2.mult = clocksource_hz2mult(sn_rtc_cycles_per_second, clocksource_sn2.shift); -- cgit v1.2.2 From b718f91c14604e4ab5cdfe8d3baff8111425ea7d Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 1 Aug 2007 13:49:45 -0700 Subject: [IA64] ITC: Reduce rating for ITC clock if ITCs are drifty Make sure to reduce the rating of the ITC clock if ITCs are drifty. If they are drifting then we have not synchronized the ITC values, nor are we doing the jitter compensation (useless since drift may increase the differentials arbitrarily). Without this patch it is possible that the ITC clock becomes selected as the system clock on systems with drifty ITCs which will result in nanosleep hanging. One can still select the itc clock manually on such systems via clocksource=itc (Produces nice hangs on SGI Altix.) Signed-off-by: Christoph Lameter Signed-off-by: Tony Luck --- arch/ia64/kernel/time.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 6c0e9e2e1b82..98cfc90cab1d 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -240,7 +240,21 @@ ia64_init_itm (void) if (!nojitter) itc_jitter_data.itc_jitter = 1; #endif - } + } else + /* + * ITC is drifty and we have not synchronized the ITCs in smpboot.c. + * ITC values may fluctuate significantly between processors. + * Clock should not be used for hrtimers. Mark itc as only + * useful for boot and testing. + * + * Note that jitter compensation is off! There is no point of + * synchronizing ITCs since they may be large differentials + * that change over time. + * + * The only way to fix this would be to repeatedly sync the + * ITCs. Until that time we have to avoid ITC. + */ + clocksource_itc.rating = 50; /* Setup the CPU local timer tick */ ia64_cpu_local_tick(); -- cgit v1.2.2 From 32a70a817acbb96fcfcc7543932222467c771207 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 1 Aug 2007 23:46:42 +0200 Subject: ide: Fix an overrun found in the CS5535 IDE driver As found by the Coverity checker, and reported by Adrian Bunk, this fixes a overrun error in the CS5535 IDE driver. Somebody got a little excited with the if() statement - the CS5535 only supports UDMA 0-4. Bart: Not a bug per se since the upper layer will never feed this function with speed > XFER_UDMA_4 (thanks to ->ultra_mask being set to 0x1f). Worth fixing anyway. Signed-off-by: Jordan Crouse Cc: Adrian Bunk Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cs5535.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index ce44e38390aa..9bd526db03cf 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -116,7 +116,7 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed) reg &= 0x80000000UL; /* Preserve the PIO format bit */ - if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7) + if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_4) reg |= cs5535_udma_timings[speed - XFER_UDMA_0]; else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0]; -- cgit v1.2.2 From 8663fd6d0de7144c9e8455b733aeb38fe80788ed Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 1 Aug 2007 23:46:43 +0200 Subject: alim15x3: Correct HP detect Direct port of Alan's fix for pata_ali. Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/alim15x3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 5511c86733dc..025689de50e9 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -593,7 +593,7 @@ static struct dmi_system_id cable_dmi_table[] = { .ident = "HP Pavilion N5430", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_BOARD_NAME, "OmniBook N32N-736"), + DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"), }, }, { } -- cgit v1.2.2 From 1955f6814fb58ffa06af4873a445307d60b23fb1 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 1 Aug 2007 23:46:44 +0200 Subject: sis5513: Add FSC Amilo A1630 PCI subvendor/dev to laptops Recognise the FSC Amilo A1630's incarnation of a SiS5513 chip as laptop to get UDMA100 support. Signed-off-by: David Lamparter Cc: Lionel Bouton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sis5513.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 63fbb79e8178..26f24802d3e8 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -801,6 +801,7 @@ struct sis_laptop { static const struct sis_laptop sis_laptop[] = { /* devid, subvendor, subdev */ { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ + { 0x5513, 0x1734, 0x105f }, /* FSC Amilo A1630 */ /* end marker */ { 0, } }; -- cgit v1.2.2 From b37c6b842b30fc8e90965ec242f624283d0032a3 Mon Sep 17 00:00:00 2001 From: Meelis Roos Date: Wed, 1 Aug 2007 23:46:44 +0200 Subject: ide: fix runtogether printk's in cmd64x IDE driver Fix a couple of runtogether printks in cmd64x.c IDE driver by adding proper newlines. Signed-off-by: Meelis Roos Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cmd64x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 19633c5aba15..0e3b5de26e69 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -475,11 +475,11 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha switch (rev) { case 0x07: case 0x05: - printk("%s: UltraDMA capable", name); + printk("%s: UltraDMA capable\n", name); break; case 0x03: default: - printk("%s: MultiWord DMA force limited", name); + printk("%s: MultiWord DMA force limited\n", name); break; case 0x01: printk("%s: MultiWord DMA limited, " -- cgit v1.2.2 From ab0579685d34eb2c6b101534796ba64c8b9107b5 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 1 Aug 2007 23:46:44 +0200 Subject: ide: eliminate warnings in ide-tape.c drivers/ide/ide-tape.c: In function '__idetape_kmalloc_stage': drivers/ide/ide-tape.c:2588: warning: large integer implicitly truncated to unsigned type drivers/ide/ide-tape.c:2616: warning: large integer implicitly truncated to unsigned type b_size in struct idetape_bh is an unsigned short. We sometimes assigne PAGE_SIZE to it and PAGE_SIZE can be 64K or larger, so make it a u32. Signed-off-by: Stephen Rothwell Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-tape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index e82bfa5e0ab8..1fa57947bca0 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -640,7 +640,7 @@ typedef enum { } idetape_chrdev_direction_t; struct idetape_bh { - unsigned short b_size; + u32 b_size; atomic_t b_count; struct idetape_bh *b_reqnext; char *b_data; -- cgit v1.2.2 From cc60d8baa35c995bf8c40a9730b894993ddb43b9 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Wed, 1 Aug 2007 23:46:44 +0200 Subject: drivers/ide/arm/icside.c: kmalloc + memset conversion to kzalloc Is this a bug? In original verison memset cleared sizeof(state) bytes instead of sizeof(*state). If it was intentional then this patch is invalid. If not intentional -> valid :) Please review. Bart: Yes, it is a bug so this patch is a valid bugfix. :-) drivers/ide/arm/icside.c | 18883 -> 18849 (-34 bytes) Signed-off-by: Mariusz Kozlowski Cc: Andrew Morton Cc: Russell King Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/arm/icside.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index c89b5f4b2d04..8a9b98fcb66d 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -693,13 +693,12 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id) if (ret) goto out; - state = kmalloc(sizeof(struct icside_state), GFP_KERNEL); + state = kzalloc(sizeof(struct icside_state), GFP_KERNEL); if (!state) { ret = -ENOMEM; goto release; } - memset(state, 0, sizeof(state)); state->type = ICS_TYPE_NOTYPE; state->dev = &ec->dev; -- cgit v1.2.2 From 41ead3c918f48710ca1e03eb7b770eabcbbd260b Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Wed, 1 Aug 2007 23:46:45 +0200 Subject: drivers/scsi/ide-scsi.c: kmalloc + memset conversion to kzalloc drivers/scsi/ide-scsi.c | 34642 -> 34536 (-106 bytes) drivers/scsi/ide-scsi.o | 171728 -> 171524 (-204 bytes) Signed-off-by: Mariusz Kozlowski Cc: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index bb90df8bdce4..1cc01acc2808 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -328,17 +328,15 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co u8 *buf; /* stuff a sense request in front of our current request */ - pc = kmalloc (sizeof (idescsi_pc_t), GFP_ATOMIC); - rq = kmalloc (sizeof (struct request), GFP_ATOMIC); - buf = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC); - if (pc == NULL || rq == NULL || buf == NULL) { + pc = kzalloc(sizeof(idescsi_pc_t), GFP_ATOMIC); + rq = kmalloc(sizeof(struct request), GFP_ATOMIC); + buf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC); + if (!pc || !rq || !buf) { kfree(buf); kfree(rq); kfree(pc); return -ENOMEM; } - memset (pc, 0, sizeof (idescsi_pc_t)); - memset (buf, 0, SCSI_SENSE_BUFFERSIZE); ide_init_drive_cmd(rq); rq->special = (char *) pc; pc->rq = rq; -- cgit v1.2.2 From 070224339b52f0e4f8e6c991a5ad9630a7a9e6da Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 1 Aug 2007 23:46:45 +0200 Subject: cs5520: fix PIO auto-tuning in ->ide_dma_check method Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cs5520.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index bccedf9b8b28..b89e81656875 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -133,7 +133,7 @@ static void cs5520_tune_drive(ide_drive_t *drive, u8 pio) static int cs5520_config_drive_xfer_rate(ide_drive_t *drive) { /* Tune the drive for PIO modes up to PIO 4 */ - cs5520_tune_drive(drive, 4); + cs5520_tune_drive(drive, 255); /* Then tell the core to use DMA operations */ return 0; -- cgit v1.2.2 From bc0b0b5c4bab02790937c9070a7701ee70feaac9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 1 Aug 2007 23:46:45 +0200 Subject: cs5535: PIO fixes * Fix cs5535_tuneproc() to pass PIO transfer mode value instead of PIO mode number to cs5535_set_speed() (fixes random PIO timings being programmed and a possible OOPS). Do a little cleanup while at it. * Fix cs5535_set_speed() to check if the mate device is present (fixes PIO0 taskfile timings being used if there is no other device on the cable). * Use cs5535_tuneproc() in cs5535_dma_check(). The old code had the same issue as cs5535_tuneproc() and add additionally caused 0x00-0x04 transfer mode values (== default PIO, default PIO w/ IORDY + two invalid values) being set on the device instead of values 0x08-0x0c (XFER_PIO_[0,4]). Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cs5535.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 9bd526db03cf..082ca7da2cbc 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -2,6 +2,7 @@ * linux/drivers/ide/pci/cs5535.c * * Copyright (C) 2004-2005 Advanced Micro Devices, Inc. + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * History: * 09/20/2005 - Jaya Kumar @@ -83,14 +84,17 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed) /* Set the PIO timings */ if ((speed & XFER_MODE) == XFER_PIO) { - u8 pioa; - u8 piob; - u8 cmd; + ide_drive_t *pair = &drive->hwif->drives[drive->dn ^ 1]; + u8 cmd, pioa; - pioa = speed - XFER_PIO_0; - piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]), - 255, 4); - cmd = pioa < piob ? pioa : piob; + cmd = pioa = speed - XFER_PIO_0; + + if (pair->present) { + u8 piob = ide_get_best_pio_mode(pair, 255, 4); + + if (piob < cmd) + cmd = piob; + } /* Write the speed of the current drive */ reg = (cs5535_pio_cmd_timings[cmd] << 16) | @@ -151,32 +155,22 @@ static int cs5535_set_drive(ide_drive_t *drive, u8 speed) * * A callback from the upper layers for PIO-only tuning. */ -static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed) +static void cs5535_tuneproc(ide_drive_t *drive, u8 pio) { - u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, - XFER_PIO_4 }; - - /* cs5535 max pio is pio 4, best_pio will check the blacklist. - i think we don't need to rate_filter the incoming xferspeed - since we know we're only going to choose pio */ - xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4); - ide_config_drive_speed(drive, modes[xferspeed]); - cs5535_set_speed(drive, xferspeed); + pio = ide_get_best_pio_mode(drive, pio, 4); + ide_config_drive_speed(drive, XFER_PIO_0 + pio); + cs5535_set_speed(drive, XFER_PIO_0 + pio); } static int cs5535_dma_check(ide_drive_t *drive) { - u8 speed; - drive->init_speed = 0; if (ide_tune_dma(drive)) return 0; - if (ide_use_fast_pio(drive)) { - speed = ide_get_best_pio_mode(drive, 255, 4); - cs5535_set_drive(drive, speed); - } + if (ide_use_fast_pio(drive)) + cs5535_tuneproc(drive, 255); return -1; } -- cgit v1.2.2 From 68aaf8150308dbf9d0e5ccd5bc05491ba575f966 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 1 Aug 2007 23:46:46 +0200 Subject: it8213: PIO fixes (take 2) * Rename it8213_tuneproc() to it8213_tune_pio() and add it8213_tuneproc() wrapper. Move finding of the best PIO mode to the new wrapper. * Add setting of transfer mode on the device to it8213_tuneproc(). * Don't call it8213_dma_2_pio() for PIO modes in it8213_tune_chipset(). * Use it8213_tuneproc() in it8213_config_drive_for_dma(). v2: * Remove PIO modes from it8213_dma_2_pio(), they are no longer needed there (Noticed by Sergei) Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/it8213.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c index 95dbed7e6022..70b3245dbf62 100644 --- a/drivers/ide/pci/it8213.c +++ b/drivers/ide/pci/it8213.c @@ -21,7 +21,7 @@ * it8213_dma_2_pio - return the PIO mode matching DMA * @xfer_rate: transfer speed * - * Returns the nearest equivalent PIO timing for the PIO or DMA + * Returns the nearest equivalent PIO timing for the DMA * mode requested by the controller. */ @@ -35,34 +35,28 @@ static u8 it8213_dma_2_pio (u8 xfer_rate) { case XFER_UDMA_1: case XFER_UDMA_0: case XFER_MW_DMA_2: - case XFER_PIO_4: return 4; case XFER_MW_DMA_1: - case XFER_PIO_3: return 3; case XFER_SW_DMA_2: - case XFER_PIO_2: return 2; case XFER_MW_DMA_0: case XFER_SW_DMA_1: case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: default: return 0; } } /* - * it8213_tuneproc - tune a drive + * it8213_tune_pio - tune a drive * @drive: drive to tune * @pio: desired PIO mode * * Set the interface PIO mode. */ -static void it8213_tuneproc (ide_drive_t *drive, u8 pio) +static void it8213_tune_pio(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -82,8 +76,6 @@ static void it8213_tuneproc (ide_drive_t *drive, u8 pio) { 2, 1 }, { 2, 3 }, }; - pio = ide_get_best_pio_mode(drive, pio, 4); - spin_lock_irqsave(&tune_lock, flags); pci_read_config_word(dev, master_port, &master_data); @@ -113,6 +105,13 @@ static void it8213_tuneproc (ide_drive_t *drive, u8 pio) spin_unlock_irqrestore(&tune_lock, flags); } +static void it8213_tuneproc(ide_drive_t *drive, u8 pio) +{ + pio = ide_get_best_pio_mode(drive, pio, 4); + it8213_tune_pio(drive, pio); + ide_config_drive_speed(drive, XFER_PIO_0 + pio); +} + /** * it8213_tune_chipset - set controller timings * @drive: Drive to set up @@ -193,7 +192,12 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed) if (reg55 & w_flag) pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); } - it8213_tuneproc(drive, it8213_dma_2_pio(speed)); + + if (speed > XFER_PIO_4) + it8213_tune_pio(drive, it8213_dma_2_pio(speed)); + else + it8213_tune_pio(drive, speed - XFER_PIO_0); + return ide_config_drive_speed(drive, speed); } @@ -209,13 +213,10 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed) static int it8213_config_drive_for_dma (ide_drive_t *drive) { - u8 pio; - if (ide_tune_dma(drive)) return 0; - pio = ide_get_best_pio_mode(drive, 255, 4); - it8213_tune_chipset(drive, XFER_PIO_0 + pio); + it8213_tuneproc(drive, 255); return -1; } -- cgit v1.2.2 From 8b6b33be3280fd776335079124ecd176e6a40797 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 1 Aug 2007 23:46:46 +0200 Subject: jmicron: PIO fixes * Set transfer mode on the device in jmicron_tuneproc(), also add pio == 255 == "auto-tune" handling. * Use jmicron_tuneproc() in jmicron_config_drive_for_dma(). * Remove no longer needed config_jmicron_chipset_for_pio(). Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/jmicron.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index d7ce9dd8de16..65a0ff352b98 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c @@ -83,23 +83,10 @@ static u8 __devinit ata66_jmicron(ide_hwif_t *hwif) return ATA_CBL_PATA80; } -static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted) +static void jmicron_tuneproc(ide_drive_t *drive, u8 pio) { - return; -} - -/** - * config_jmicron_chipset_for_pio - set drive timings - * @drive: drive to tune - * @speed we want - * - */ - -static void config_jmicron_chipset_for_pio (ide_drive_t *drive, byte set_speed) -{ - u8 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5); - if (set_speed) - (void) ide_config_drive_speed(drive, speed); + pio = ide_get_best_pio_mode(drive, pio, 5); + ide_config_drive_speed(drive, XFER_PIO_0 + pio); } /** @@ -132,7 +119,7 @@ static int jmicron_config_drive_for_dma (ide_drive_t *drive) if (ide_tune_dma(drive)) return 0; - config_jmicron_chipset_for_pio(drive, 1); + jmicron_tuneproc(drive, 255); return -1; } -- cgit v1.2.2 From 0c8de52d76e4bec6e9168b47be29f11b3bb92768 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 1 Aug 2007 23:46:46 +0200 Subject: piix/slc90e66: fix PIO1 handling in ->speedproc method (take 2) * Don't call {piix,slc90e66}_dma_2_pio() for PIO modes in {piix,slc90e66}_tune_chipset(). * Add PIO1 handling to {piix,slc90e66}_tune_chipset(). * Bump driver version. v2: * Remove PIO modes from {piix,slc90e66}_dma_2_pio(), they are no longer needed there (Noticed by Sergei) Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/piix.c | 17 ++++++++--------- drivers/ide/pci/slc90e66.c | 15 +++++++-------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 4f69cd067e5e..5cfa9378bbb8 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/piix.c Version 0.50 Jun 10, 2007 + * linux/drivers/ide/pci/piix.c Version 0.51 Jul 6, 2007 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-2000 Andre Hedrick @@ -109,7 +109,7 @@ static int no_piix_dma; * piix_dma_2_pio - return the PIO mode matching DMA * @xfer_rate: transfer speed * - * Returns the nearest equivalent PIO timing for the PIO or DMA + * Returns the nearest equivalent PIO timing for the DMA * mode requested by the controller. */ @@ -123,20 +123,14 @@ static u8 piix_dma_2_pio (u8 xfer_rate) { case XFER_UDMA_1: case XFER_UDMA_0: case XFER_MW_DMA_2: - case XFER_PIO_4: return 4; case XFER_MW_DMA_1: - case XFER_PIO_3: return 3; case XFER_SW_DMA_2: - case XFER_PIO_2: return 2; case XFER_MW_DMA_0: case XFER_SW_DMA_1: case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: default: return 0; } @@ -269,6 +263,7 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: + case XFER_PIO_1: case XFER_PIO_0: break; default: return -1; } @@ -299,7 +294,11 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); } - piix_tune_pio(drive, piix_dma_2_pio(speed)); + if (speed > XFER_PIO_4) + piix_tune_pio(drive, piix_dma_2_pio(speed)); + else + piix_tune_pio(drive, speed - XFER_PIO_0); + return ide_config_drive_speed(drive, speed); } diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 8e655f2db5cb..628b0664f576 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/slc90e66.c Version 0.14 February 8, 2007 + * linux/drivers/ide/pci/slc90e66.c Version 0.15 Jul 6, 2007 * * Copyright (C) 2000-2002 Andre Hedrick * Copyright (C) 2006-2007 MontaVista Software, Inc. @@ -29,20 +29,14 @@ static u8 slc90e66_dma_2_pio (u8 xfer_rate) { case XFER_UDMA_1: case XFER_UDMA_0: case XFER_MW_DMA_2: - case XFER_PIO_4: return 4; case XFER_MW_DMA_1: - case XFER_PIO_3: return 3; case XFER_SW_DMA_2: - case XFER_PIO_2: return 2; case XFER_MW_DMA_0: case XFER_SW_DMA_1: case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: default: return 0; } @@ -136,6 +130,7 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: + case XFER_PIO_1: case XFER_PIO_0: break; default: return -1; } @@ -156,7 +151,11 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); } - slc90e66_tune_pio(drive, slc90e66_dma_2_pio(speed)); + if (speed > XFER_PIO_4) + slc90e66_tune_pio(drive, slc90e66_dma_2_pio(speed)); + else + slc90e66_tune_pio(drive, speed - XFER_PIO_0); + return ide_config_drive_speed(drive, speed); } -- cgit v1.2.2 From 3fcece66911c9d485c1e2050ba033fde607b5130 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 1 Aug 2007 23:46:46 +0200 Subject: scc_pata: PIO fixes * Use pio == 255 == "auto-tune" in scc_config_drive_for_dma() instead of forcing PIO4 on PIO fallback. Fix comment while at it. * Rename scc_tuneproc() to scc_tune_pio() and add scc_tuneproc() wrapper. Move finding of the best PIO mode and setting of transfer mode on the device to the new wrapper. * Fix scc_tune_chipset() to tune PIO modes. Do a small cleanup while at it. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/scc_pata.c | 61 +++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 41 deletions(-) diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index bf19ddfa6cda..eeb0a6d434aa 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -190,7 +190,7 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count) } /** - * scc_tuneproc - tune a drive PIO mode + * scc_tune_pio - tune a drive PIO mode * @drive: drive to tune * @mode_wanted: the target operating mode * @@ -198,7 +198,7 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count) * controller. */ -static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted) +static void scc_tune_pio(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct scc_ports *ports = ide_get_hwifdata(hwif); @@ -207,41 +207,25 @@ static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted) unsigned long piosht_port = ctl_base + 0x000; unsigned long pioct_port = ctl_base + 0x004; unsigned long reg; - unsigned char speed = XFER_PIO_0; int offset; - mode_wanted = ide_get_best_pio_mode(drive, mode_wanted, 4); - switch (mode_wanted) { - case 4: - speed = XFER_PIO_4; - break; - case 3: - speed = XFER_PIO_3; - break; - case 2: - speed = XFER_PIO_2; - break; - case 1: - speed = XFER_PIO_1; - break; - case 0: - default: - speed = XFER_PIO_0; - break; - } - reg = in_be32((void __iomem *)cckctrl_port); if (reg & CCKCTRL_ATACLKOEN) { offset = 1; /* 133MHz */ } else { offset = 0; /* 100MHz */ } - reg = JCHSTtbl[offset][mode_wanted] << 16 | JCHHTtbl[offset][mode_wanted]; + reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio]; out_be32((void __iomem *)piosht_port, reg); - reg = JCHCTtbl[offset][mode_wanted]; + reg = JCHCTtbl[offset][pio]; out_be32((void __iomem *)pioct_port, reg); +} - ide_config_drive_speed(drive, speed); +static void scc_tuneproc(ide_drive_t *drive, u8 pio) +{ + pio = ide_get_best_pio_mode(drive, pio, 4); + scc_tune_pio(drive, pio); + ide_config_drive_speed(drive, XFER_PIO_0 + pio); } /** @@ -280,26 +264,21 @@ static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) switch (speed) { case XFER_UDMA_6: - idx = 6; - break; case XFER_UDMA_5: - idx = 5; - break; case XFER_UDMA_4: - idx = 4; - break; case XFER_UDMA_3: - idx = 3; - break; case XFER_UDMA_2: - idx = 2; - break; case XFER_UDMA_1: - idx = 1; - break; case XFER_UDMA_0: - idx = 0; + idx = speed - XFER_UDMA_0; break; + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + scc_tune_pio(drive, speed - XFER_PIO_0); + return ide_config_drive_speed(drive, speed); default: return 1; } @@ -329,7 +308,7 @@ static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) * required. * If the drive isn't suitable for DMA or we hit other problems * then we will drop down to PIO and set up PIO appropriately. - * (return 1) + * (return -1) */ static int scc_config_drive_for_dma(ide_drive_t *drive) @@ -338,7 +317,7 @@ static int scc_config_drive_for_dma(ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - scc_tuneproc(drive, 4); + scc_tuneproc(drive, 255); return -1; } -- cgit v1.2.2 From fd0cbdd378258fdf44eac5ea091256a4a665315b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 2 Aug 2007 00:18:38 +0200 Subject: Fix WARN_ON() on bitfield ops for all other archs Fixes WARN_ON() on bitfiels ops for all architectures that have been left out in 8d4fbcfbe0a4bfc73e7f0297c59ae514e1f1436f. Cc: Alexey Dobriyan Cc: Herbert Xu Cc: Haavard Skinnemoen Cc: Matthew Wilcox Cc: Kyle McMartin Cc: Martin Schwidefsky Acked-by: Paul Mundt Signed-off-by: Heiko Carstens Signed-off-by: Linus Torvalds --- include/asm-avr32/bug.h | 2 +- include/asm-parisc/bug.h | 2 +- include/asm-s390/bug.h | 2 +- include/asm-sh/bug.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/asm-avr32/bug.h b/include/asm-avr32/bug.h index afdcd79a2966..331d45bab18f 100644 --- a/include/asm-avr32/bug.h +++ b/include/asm-avr32/bug.h @@ -57,7 +57,7 @@ #define WARN_ON(condition) \ ({ \ - typeof(condition) __ret_warn_on = (condition); \ + int __ret_warn_on = !!(condition); \ if (unlikely(__ret_warn_on)) \ _BUG_OR_WARN(BUGFLAG_WARNING); \ unlikely(__ret_warn_on); \ diff --git a/include/asm-parisc/bug.h b/include/asm-parisc/bug.h index 83ba510ed5d8..8cfc553fc837 100644 --- a/include/asm-parisc/bug.h +++ b/include/asm-parisc/bug.h @@ -74,7 +74,7 @@ #define WARN_ON(x) ({ \ - typeof(x) __ret_warn_on = (x); \ + int __ret_warn_on = !!(x); \ if (__builtin_constant_p(__ret_warn_on)) { \ if (__ret_warn_on) \ __WARN(); \ diff --git a/include/asm-s390/bug.h b/include/asm-s390/bug.h index 838684dc6d35..384e3621e341 100644 --- a/include/asm-s390/bug.h +++ b/include/asm-s390/bug.h @@ -50,7 +50,7 @@ #define BUG() __EMIT_BUG(0) #define WARN_ON(x) ({ \ - typeof(x) __ret_warn_on = (x); \ + int __ret_warn_on = !!(x); \ if (__builtin_constant_p(__ret_warn_on)) { \ if (__ret_warn_on) \ __EMIT_BUG(BUGFLAG_WARNING); \ diff --git a/include/asm-sh/bug.h b/include/asm-sh/bug.h index 46f925c815ac..a78d482e8b2f 100644 --- a/include/asm-sh/bug.h +++ b/include/asm-sh/bug.h @@ -61,7 +61,7 @@ do { \ } while (0) #define WARN_ON(x) ({ \ - typeof(x) __ret_warn_on = (x); \ + int __ret_warn_on = !!(x); \ if (__builtin_constant_p(__ret_warn_on)) { \ if (__ret_warn_on) \ __WARN(); \ -- cgit v1.2.2 From 0fc4969b866671dfe39b1a9119d0fdc7ea0f63e5 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 1 Aug 2007 17:13:19 +0200 Subject: genirq: temporary fix for level-triggered IRQ resend Marcin Slusarz reported a ne2k-pci "hung network interface" regression. delayed disable relies on the ability to re-trigger the interrupt in the case that a real interrupt happens after the software disable was set. In this case we actually disable the interrupt on the hardware level _after_ it occurred. On enable_irq, we need to re-trigger the interrupt. On i386 this relies on a hardware resend mechanism (send_IPI_self()). Actually we only need the resend for edge type interrupts. Level type interrupts come back once enable_irq() re-enables the interrupt line. I assume that the interrupt in question is level triggered because it is shared and above the legacy irqs 0-15: 17: 12 IO-APIC-fasteoi eth1, eth0 Looking into the IO_APIC code, the resend via send_IPI_self() happens unconditionally. So the resend is done for level and edge interrupts. This makes the problem more mysterious. The code in question lib8390.c does disable_irq(); fiddle_with_the_network_card_hardware() enable_irq(); The fiddle_with_the_network_card_hardware() might cause interrupts, which are cleared in the same code path again, Marcin found that when he disables the irq line on the hardware level (removing the delayed disable) the card is kept alive. So the difference is that we can get a resend on enable_irq, when an interrupt happens during the time, where we are in the disabled region. Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds --- kernel/irq/resend.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c index 5bfeaed7e487..c38272746887 100644 --- a/kernel/irq/resend.c +++ b/kernel/irq/resend.c @@ -62,6 +62,15 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq) */ desc->chip->enable(irq); + /* + * Temporary hack to figure out more about the problem, which + * is causing the ancient network cards to die. + */ + if (desc->handle_irq != handle_edge_irq) { + WARN_ON_ONCE(1); + return; + } + if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { desc->status = (status & ~IRQ_PENDING) | IRQ_REPLAY; -- cgit v1.2.2 From 04668873daa822aa6c806ba28d1143db8dcb26e8 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 1 Aug 2007 19:04:51 +0100 Subject: FRV: Enable the MB86943 PCI arbiter correctly Enable the MB93090 motherboard's MB86943 PCI arbiter correctly by assigning to the register rather than comparing against it. This is required to support bus mastering. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/frv/mb93090-mb00/pci-vdk.c | 3 ++- include/asm-frv/mb86943a.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c index 0b581e3cf7c7..6d51f133fb23 100644 --- a/arch/frv/mb93090-mb00/pci-vdk.c +++ b/arch/frv/mb93090-mb00/pci-vdk.c @@ -400,7 +400,8 @@ int __init pcibios_init(void) __reg_MB86943_pci_sl_mem_base = __region_CS2 + 0x08000000; mb(); - *(volatile unsigned long *)(__region_CS2+0x01300014) == 1; + /* enable PCI arbitration */ + __reg_MB86943_pci_arbiter = MB86943_PCIARB_EN; ioport_resource.start = (__reg_MB86943_sl_pci_io_base << 9) & 0xfffffc00; ioport_resource.end = (__reg_MB86943_sl_pci_io_range << 9) | 0x3ff; diff --git a/include/asm-frv/mb86943a.h b/include/asm-frv/mb86943a.h index b89fd0b56bb3..e87ef924bfb4 100644 --- a/include/asm-frv/mb86943a.h +++ b/include/asm-frv/mb86943a.h @@ -36,4 +36,7 @@ #define __reg_MB86943_pci_sl_io_base *(volatile uint32_t *) (__region_CS1 + 0x70) #define __reg_MB86943_pci_sl_mem_base *(volatile uint32_t *) (__region_CS1 + 0x78) +#define __reg_MB86943_pci_arbiter *(volatile uint32_t *) (__region_CS2 + 0x01300014) +#define MB86943_PCIARB_EN 0x00000001 + #endif /* _ASM_MB86943A_H */ -- cgit v1.2.2 From 3e1928e8793208802589aae851b6685671187242 Mon Sep 17 00:00:00 2001 From: Tino Keitel Date: Thu, 12 Jul 2007 00:11:34 +0200 Subject: HID: remove the Applie IR sensor from the hid_blacklist The IR sensor in some newer Apple computers has no other driver in the kernel, yet. However, the macmini driver in lirc requires a HID device for the IR sensor. Cc: Soeren Sonnenburg Signed-off-by: Tino Keitel Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-quirks.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 775b9f3b8ce3..2b7e2de77413 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -61,7 +61,6 @@ #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b -#define USB_DEVICE_ID_APPLE_IR 0x8240 #define USB_VENDOR_ID_ATEN 0x0557 #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 @@ -315,7 +314,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, -- cgit v1.2.2 From 2dea64b4aace953924848ac9ab05217da20a7932 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 11 Jul 2007 12:12:11 +0200 Subject: USB HID: update description of USBHID in MAINTAINERS Make it more clear to users what kinds of hardware USBHID handles, so that they can send reports and queries properly. Signed-off-by: Jiri Kosina --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1e15a0edc313..e65e96a14bec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3754,7 +3754,7 @@ L: linux-usb-devel@lists.sourceforge.net W: http://www.linux-usb.org/gadget S: Maintained -USB HID/HIDBP DRIVERS +USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...) P: Jiri Kosina M: jkosina@suse.cz L: linux-usb-devel@lists.sourceforge.net -- cgit v1.2.2 From 9fdcfed8ebc4f5273179f8ff00ab83a6403016de Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Mon, 30 Jul 2007 12:00:48 +0200 Subject: USB HID: Add all Logitech Harmonies to blacklist This patch adds the entire range of Logitech's ProductIDs that are reserved for their Harmony remotes. The in-kernel HID driver can't do anything with these, and now there is a GPL user-space application that can handle them: http://www.sf.net/projects/harmonycontrol Signed-off-by: Phil Dibowitz Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-quirks.c | 132 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 2b7e2de77413..09743c521e20 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -197,6 +197,70 @@ #define USB_VENDOR_ID_LOGITECH 0x046d #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 +#define USB_DEVICE_ID_LOGITECH_HARMONY 0xc110 +#define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111 +#define USB_DEVICE_ID_LOGITECH_HARMONY_3 0xc112 +#define USB_DEVICE_ID_LOGITECH_HARMONY_4 0xc113 +#define USB_DEVICE_ID_LOGITECH_HARMONY_5 0xc114 +#define USB_DEVICE_ID_LOGITECH_HARMONY_6 0xc115 +#define USB_DEVICE_ID_LOGITECH_HARMONY_7 0xc116 +#define USB_DEVICE_ID_LOGITECH_HARMONY_8 0xc117 +#define USB_DEVICE_ID_LOGITECH_HARMONY_9 0xc118 +#define USB_DEVICE_ID_LOGITECH_HARMONY_10 0xc119 +#define USB_DEVICE_ID_LOGITECH_HARMONY_11 0xc11a +#define USB_DEVICE_ID_LOGITECH_HARMONY_12 0xc11b +#define USB_DEVICE_ID_LOGITECH_HARMONY_13 0xc11c +#define USB_DEVICE_ID_LOGITECH_HARMONY_14 0xc11d +#define USB_DEVICE_ID_LOGITECH_HARMONY_15 0xc11e +#define USB_DEVICE_ID_LOGITECH_HARMONY_16 0xc11f +#define USB_DEVICE_ID_LOGITECH_HARMONY_17 0xc120 +#define USB_DEVICE_ID_LOGITECH_HARMONY_18 0xc121 +#define USB_DEVICE_ID_LOGITECH_HARMONY_19 0xc122 +#define USB_DEVICE_ID_LOGITECH_HARMONY_20 0xc123 +#define USB_DEVICE_ID_LOGITECH_HARMONY_21 0xc124 +#define USB_DEVICE_ID_LOGITECH_HARMONY_22 0xc125 +#define USB_DEVICE_ID_LOGITECH_HARMONY_23 0xc126 +#define USB_DEVICE_ID_LOGITECH_HARMONY_24 0xc127 +#define USB_DEVICE_ID_LOGITECH_HARMONY_25 0xc128 +#define USB_DEVICE_ID_LOGITECH_HARMONY_26 0xc129 +#define USB_DEVICE_ID_LOGITECH_HARMONY_27 0xc12a +#define USB_DEVICE_ID_LOGITECH_HARMONY_28 0xc12b +#define USB_DEVICE_ID_LOGITECH_HARMONY_29 0xc12c +#define USB_DEVICE_ID_LOGITECH_HARMONY_30 0xc12d +#define USB_DEVICE_ID_LOGITECH_HARMONY_31 0xc12e +#define USB_DEVICE_ID_LOGITECH_HARMONY_32 0xc12f +#define USB_DEVICE_ID_LOGITECH_HARMONY_33 0xc130 +#define USB_DEVICE_ID_LOGITECH_HARMONY_34 0xc131 +#define USB_DEVICE_ID_LOGITECH_HARMONY_35 0xc132 +#define USB_DEVICE_ID_LOGITECH_HARMONY_36 0xc133 +#define USB_DEVICE_ID_LOGITECH_HARMONY_37 0xc134 +#define USB_DEVICE_ID_LOGITECH_HARMONY_38 0xc135 +#define USB_DEVICE_ID_LOGITECH_HARMONY_39 0xc136 +#define USB_DEVICE_ID_LOGITECH_HARMONY_40 0xc137 +#define USB_DEVICE_ID_LOGITECH_HARMONY_41 0xc138 +#define USB_DEVICE_ID_LOGITECH_HARMONY_42 0xc139 +#define USB_DEVICE_ID_LOGITECH_HARMONY_43 0xc13a +#define USB_DEVICE_ID_LOGITECH_HARMONY_44 0xc13b +#define USB_DEVICE_ID_LOGITECH_HARMONY_45 0xc13c +#define USB_DEVICE_ID_LOGITECH_HARMONY_46 0xc13d +#define USB_DEVICE_ID_LOGITECH_HARMONY_47 0xc13e +#define USB_DEVICE_ID_LOGITECH_HARMONY_48 0xc13f +#define USB_DEVICE_ID_LOGITECH_HARMONY_49 0xc140 +#define USB_DEVICE_ID_LOGITECH_HARMONY_50 0xc141 +#define USB_DEVICE_ID_LOGITECH_HARMONY_51 0xc142 +#define USB_DEVICE_ID_LOGITECH_HARMONY_52 0xc143 +#define USB_DEVICE_ID_LOGITECH_HARMONY_53 0xc144 +#define USB_DEVICE_ID_LOGITECH_HARMONY_54 0xc145 +#define USB_DEVICE_ID_LOGITECH_HARMONY_55 0xc146 +#define USB_DEVICE_ID_LOGITECH_HARMONY_56 0xc147 +#define USB_DEVICE_ID_LOGITECH_HARMONY_57 0xc148 +#define USB_DEVICE_ID_LOGITECH_HARMONY_58 0xc149 +#define USB_DEVICE_ID_LOGITECH_HARMONY_59 0xc14a +#define USB_DEVICE_ID_LOGITECH_HARMONY_60 0xc14b +#define USB_DEVICE_ID_LOGITECH_HARMONY_61 0xc14c +#define USB_DEVICE_ID_LOGITECH_HARMONY_62 0xc14d +#define USB_DEVICE_ID_LOGITECH_HARMONY_63 0xc14e +#define USB_DEVICE_ID_LOGITECH_HARMONY_64 0xc14f #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 #define USB_DEVICE_ID_LOGITECH_KBD 0xc311 #define USB_DEVICE_ID_S510_RECEIVER 0xc50c @@ -220,6 +284,9 @@ #define USB_DEVICE_ID_NCR_FIRST 0x0300 #define USB_DEVICE_ID_NCR_LAST 0x03ff +#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 +#define USB_DEVICE_ID_N_S_HARMONY 0xc359 + #define USB_VENDOR_ID_NEC 0x073e #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 @@ -461,6 +528,71 @@ static const struct hid_blacklist { { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_4, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_5, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_6, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_7, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_8, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_9, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_10, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_11, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_12, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_13, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_14, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_15, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_16, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_17, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_18, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_19, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_20, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_21, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_22, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_23, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_24, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_25, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_26, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_27, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_28, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_29, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_30, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_31, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_32, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_33, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_34, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_35, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_36, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_37, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_38, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_39, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_40, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_41, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_42, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_43, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_44, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_45, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_46, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_47, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_48, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_49, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_50, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_51, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_52, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_53, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_54, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_55, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_56, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_57, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_58, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_59, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_60, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_61, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_62, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_63, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_64, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY, HID_QUIRK_IGNORE }, { 0, 0 } }; -- cgit v1.2.2 From 04a9b7ffceff4337d9e63476b5c71e9b79249969 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 30 Jul 2007 14:38:26 +0200 Subject: USB HID: add ASUS LCM to the blacklist Some of ASUS' notebooks (e.g G Series) include a tiny oled display, which is attached to an internal USB bus. Unfortunatly the device reports a wrong DeviceDescriptor and is therefore identified as a HID device... Signed-off-by: Christian Lamparter Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-quirks.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 09743c521e20..6b21a214f419 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -62,6 +62,9 @@ #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b +#define USB_VENDOR_ID_ASUS 0x0b05 +#define USB_DEVICE_ID_ASUS_LCM 0x1726 + #define USB_VENDOR_ID_ATEN 0x0557 #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 #define USB_DEVICE_ID_ATEN_CS124U 0x2202 @@ -381,6 +384,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE}, { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, -- cgit v1.2.2 From de1a7b03282310d143cb0add74e909daffedda01 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 30 Jul 2007 15:15:26 +0200 Subject: USB HID: fix a possible NULL pointer dereference when we fail to allocate memory If, in usb_hid_configure(), we fail to allocate storage for 'usbhid', "if (!(usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL)))", then we'll jump to the 'fail:' label where we have this code: usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbout); usb_free_urb(usbhid->urbctrl); Since we got here because we couldn't allocate storage for 'usbhid', what we have here is a NULL pointer dereference - ouch... This patch solves that little problem by adding a new 'fail_no_usbhid:' label after the problematic calls to usb_free_urb() and jumps to that one instead, in the problem case. Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index b2baeaeba9be..3ff74685875d 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -743,7 +743,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) hid->quirks = quirks; if (!(usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL))) - goto fail; + goto fail_no_usbhid; hid->driver_data = usbhid; usbhid->hid = hid; @@ -877,6 +877,7 @@ fail: usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbout); usb_free_urb(usbhid->urbctrl); +fail_no_usbhid: hid_free_buffers(dev, hid); hid_free_device(hid); -- cgit v1.2.2 From cda5ecf80bad94b4113722f037af818e7453dd2d Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 30 Jul 2007 15:40:06 +0200 Subject: USB HID: fix memory leak of usbhid_device Add forgotten freeing of usbhid_device structure. Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 3ff74685875d..6e7393460ead 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -877,6 +877,7 @@ fail: usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbout); usb_free_urb(usbhid->urbctrl); + kfree(usbhid); fail_no_usbhid: hid_free_buffers(dev, hid); hid_free_device(hid); @@ -912,6 +913,7 @@ static void hid_disconnect(struct usb_interface *intf) usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbctrl); usb_free_urb(usbhid->urbout); + kfree(usbhid); hid_free_buffers(hid_to_usb_dev(hid), hid); hid_free_device(hid); -- cgit v1.2.2 From 22f675f320f721e9eaa2bbf7b883316b408c6c8f Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 1 Aug 2007 12:32:27 +0200 Subject: HID: Never call hid_free_buffers() when usbhid_device has been freed We can't call hid_free_buffers() when the underlying usbhid_device has already been freed. Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 6e7393460ead..0a1f2b52a12f 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -877,9 +877,9 @@ fail: usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbout); usb_free_urb(usbhid->urbctrl); + hid_free_buffers(dev, hid); kfree(usbhid); fail_no_usbhid: - hid_free_buffers(dev, hid); hid_free_device(hid); return NULL; @@ -913,9 +913,9 @@ static void hid_disconnect(struct usb_interface *intf) usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbctrl); usb_free_urb(usbhid->urbout); - kfree(usbhid); hid_free_buffers(hid_to_usb_dev(hid), hid); + kfree(usbhid); hid_free_device(hid); } -- cgit v1.2.2 From 59acc08fd95aefb5430458a08a82b15a4174ed74 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Thu, 2 Aug 2007 18:16:46 +0800 Subject: [x86 setup] video setup: Fix VBE DDC reading Add memory operand constraint and write-only modifier to the inline assembly to effect the writing of the EDID block to boot_params.edid_info. Without this, gcc would think the EDID query was dead code and would eliminate it. Signed-off-by: Antonino Daplas Signed-off-by: H. Peter Anvin --- arch/i386/boot/video-vesa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/i386/boot/video-vesa.c b/arch/i386/boot/video-vesa.c index e6aa9eb8d93a..f1bc71e948cf 100644 --- a/arch/i386/boot/video-vesa.c +++ b/arch/i386/boot/video-vesa.c @@ -268,7 +268,7 @@ void vesa_store_edid(void) dx = 0; /* EDID block number */ di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */ asm(INT10 - : "+a" (ax), "+b" (bx), "+d" (dx) + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info) : "c" (cx), "D" (di) : "esi"); #endif /* CONFIG_FIRMWARE_EDID */ -- cgit v1.2.2 From 362a7016637648c6aefc98b706298baedfaa1543 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: remove cache_hot_time remove the last unused remains of cache_hot_time. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 - include/linux/topology.h | 1 - kernel/sched.c | 2 -- 3 files changed, 4 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 2e490271acf6..81eec7e36c84 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -734,7 +734,6 @@ struct sched_domain { unsigned long max_interval; /* Maximum balance interval ms */ unsigned int busy_factor; /* less balancing by factor if busy */ unsigned int imbalance_pct; /* No balance until over watermark */ - unsigned long long cache_hot_time; /* Task considered cache hot (ns) */ unsigned int cache_nice_tries; /* Leave cache hot tasks for # tries */ unsigned int busy_idx; unsigned int idle_idx; diff --git a/include/linux/topology.h b/include/linux/topology.h index d0890a7e5bab..525d437b1253 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h @@ -185,7 +185,6 @@ .max_interval = 64*num_online_cpus(), \ .busy_factor = 128, \ .imbalance_pct = 133, \ - .cache_hot_time = (10*1000000), \ .cache_nice_tries = 1, \ .busy_idx = 3, \ .idle_idx = 3, \ diff --git a/kernel/sched.c b/kernel/sched.c index 238a76957e86..1641235f8e9a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5269,8 +5269,6 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd) sizeof(int), 0644, proc_dointvec_minmax); set_table_entry(&table[8], 9, "imbalance_pct", &sd->imbalance_pct, sizeof(int), 0644, proc_dointvec_minmax); - set_table_entry(&table[9], 10, "cache_hot_time", &sd->cache_hot_time, - sizeof(long long), 0644, proc_doulongvec_minmax); set_table_entry(&table[10], 11, "cache_nice_tries", &sd->cache_nice_tries, sizeof(int), 0644, proc_dointvec_minmax); -- cgit v1.2.2 From 5a4f3ea77e1b0c72a3ec136c881eb0d64aa1d25e Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: tidy up left over smpnice code 1. The only place that RTPRIO_TO_LOAD_WEIGHT() is used is in the call to move_tasks() in the function active_load_balance() and its purpose here is just to make sure that the load to be moved is big enough to ensure that exactly one task is moved (if there's one available). This can be accomplished by using ULONG_MAX instead and this allows RTPRIO_TO_LOAD_WEIGHT() to be deleted. 2. This, in turn, allows PRIO_TO_LOAD_WEIGHT() to be deleted. 3. This allows load_weight() to be deleted which allows TIME_SLICE_NICE_ZERO to be deleted along with the comment above it. Signed-off-by: Peter Williams Signed-off-by: Ingo Molnar --- kernel/sched.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 1641235f8e9a..ed8cebf53286 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -727,19 +727,6 @@ static void update_curr_load(struct rq *rq, u64 now) * slice expiry etc. */ -/* - * Assume: static_prio_timeslice(NICE_TO_PRIO(0)) == DEF_TIMESLICE - * If static_prio_timeslice() is ever changed to break this assumption then - * this code will need modification - */ -#define TIME_SLICE_NICE_ZERO DEF_TIMESLICE -#define load_weight(lp) \ - (((lp) * SCHED_LOAD_SCALE) / TIME_SLICE_NICE_ZERO) -#define PRIO_TO_LOAD_WEIGHT(prio) \ - load_weight(static_prio_timeslice(prio)) -#define RTPRIO_TO_LOAD_WEIGHT(rp) \ - (PRIO_TO_LOAD_WEIGHT(MAX_RT_PRIO) + load_weight(rp)) - #define WEIGHT_IDLEPRIO 2 #define WMULT_IDLEPRIO (1 << 31) @@ -2908,8 +2895,7 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu) schedstat_inc(sd, alb_cnt); if (move_tasks(target_rq, target_cpu, busiest_rq, 1, - RTPRIO_TO_LOAD_WEIGHT(100), sd, CPU_IDLE, - NULL)) + ULONG_MAX, sd, CPU_IDLE, NULL)) schedstat_inc(sd, alb_pushed); else schedstat_inc(sd, alb_failed); -- cgit v1.2.2 From ecf691daf7afb418537ba459290191a0a5853be5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: calc_delta_mine(): use fixed limit use fixed limit in calc_delta_mine() - this saves an instruction :) Signed-off-by: Ingo Molnar --- kernel/sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched.c b/kernel/sched.c index ed8cebf53286..b2bc8fa24ba7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -657,7 +657,7 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight, tmp = (tmp * lw->inv_weight) >> WMULT_SHIFT; } - return (unsigned long)min(tmp, (u64)sysctl_sched_runtime_limit); + return (unsigned long)min(tmp, (u64)(unsigned long)LONG_MAX); } static inline unsigned long -- cgit v1.2.2 From cb1c4fc924d7eeb3fb723ad72705d4a70e9781fd Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: uninline calc_delta_mine() uninline calc_delta_mine(): text data bss dec hex filename 29162 4162 24 33348 8244 sched.o.before 29039 4162 24 33225 81c9 sched.o.after Signed-off-by: Ingo Molnar --- kernel/sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched.c b/kernel/sched.c index b2bc8fa24ba7..ff4aa17d65c8 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -637,7 +637,7 @@ static u64 div64_likely32(u64 divident, unsigned long divisor) #define WMULT_SHIFT 32 -static inline unsigned long +static unsigned long calc_delta_mine(unsigned long delta_exec, unsigned long weight, struct load_weight *lw) { -- cgit v1.2.2 From 4e6f96f313561d86d248edf0eaff2336d8217e1b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: uninline inc/dec_nr_running() uninline inc_nr_running() and dec_nr_running(): text data bss dec hex filename 29039 4162 24 33225 81c9 sched.o.before 29027 4162 24 33213 81bd sched.o.after Signed-off-by: Ingo Molnar --- kernel/sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index ff4aa17d65c8..7bed2c58b986 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -782,13 +782,13 @@ dec_load(struct rq *rq, const struct task_struct *p, u64 now) update_load_sub(&rq->ls.load, p->se.load.weight); } -static inline void inc_nr_running(struct task_struct *p, struct rq *rq, u64 now) +static void inc_nr_running(struct task_struct *p, struct rq *rq, u64 now) { rq->nr_running++; inc_load(rq, p, now); } -static inline void dec_nr_running(struct task_struct *p, struct rq *rq, u64 now) +static void dec_nr_running(struct task_struct *p, struct rq *rq, u64 now) { rq->nr_running--; dec_load(rq, p, now); -- cgit v1.2.2 From cad60d93e18ba52b6f069b2edb031c89bf603b07 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: ->task_new cleanup make sched_class.task_new == NULL a 'default method', this allows the removal of task_rt_new. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 2 +- kernel/sched.c | 11 ++++++++--- kernel/sched_fair.c | 4 +--- kernel/sched_rt.c | 10 ---------- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 81eec7e36c84..c9e0c2a6a950 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -874,7 +874,7 @@ struct sched_class { void (*set_curr_task) (struct rq *rq); void (*task_tick) (struct rq *rq, struct task_struct *p); - void (*task_new) (struct rq *rq, struct task_struct *p); + void (*task_new) (struct rq *rq, struct task_struct *p, u64 now); }; struct load_weight { diff --git a/kernel/sched.c b/kernel/sched.c index 7bed2c58b986..915c75e5a276 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1641,22 +1641,27 @@ void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags) unsigned long flags; struct rq *rq; int this_cpu; + u64 now; rq = task_rq_lock(p, &flags); BUG_ON(p->state != TASK_RUNNING); this_cpu = smp_processor_id(); /* parent's CPU */ + now = rq_clock(rq); p->prio = effective_prio(p); - if (!sysctl_sched_child_runs_first || (clone_flags & CLONE_VM) || - task_cpu(p) != this_cpu || !current->se.on_rq) { + if (!p->sched_class->task_new || !sysctl_sched_child_runs_first || + (clone_flags & CLONE_VM) || task_cpu(p) != this_cpu || + !current->se.on_rq) { + activate_task(rq, p, 0); } else { /* * Let the scheduling class do new task startup * management (if any): */ - p->sched_class->task_new(rq, p); + p->sched_class->task_new(rq, p, now); + inc_nr_running(p, rq, now); } check_preempt_curr(rq, p); task_rq_unlock(rq, &flags); diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 6971db0a7160..243da6cae71c 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1041,11 +1041,10 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr) * monopolize the CPU. Note: the parent runqueue is locked, * the child is not running yet. */ -static void task_new_fair(struct rq *rq, struct task_struct *p) +static void task_new_fair(struct rq *rq, struct task_struct *p, u64 now) { struct cfs_rq *cfs_rq = task_cfs_rq(p); struct sched_entity *se = &p->se; - u64 now = rq_clock(rq); sched_info_queued(p); @@ -1072,7 +1071,6 @@ static void task_new_fair(struct rq *rq, struct task_struct *p) p->se.wait_runtime = -(sysctl_sched_granularity / 2); __enqueue_entity(cfs_rq, se); - inc_nr_running(p, rq, now); } #ifdef CONFIG_FAIR_GROUP_SCHED diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 1192a2741b99..ade20dc422f1 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -229,15 +229,6 @@ static void task_tick_rt(struct rq *rq, struct task_struct *p) requeue_task_rt(rq, p); } -/* - * No parent/child timeslice management necessary for RT tasks, - * just activate them: - */ -static void task_new_rt(struct rq *rq, struct task_struct *p) -{ - activate_task(rq, p, 1); -} - static struct sched_class rt_sched_class __read_mostly = { .enqueue_task = enqueue_task_rt, .dequeue_task = dequeue_task_rt, @@ -251,5 +242,4 @@ static struct sched_class rt_sched_class __read_mostly = { .load_balance = load_balance_rt, .task_tick = task_tick_rt, - .task_new = task_new_rt, }; -- cgit v1.2.2 From 9c2172459a47c99adf9c968180a8a57d9ff84efa Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: move load-calculation functions move load-calculation functions so that they can use the per-policy declarations and methods. Signed-off-by: Ingo Molnar --- kernel/sched.c | 132 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 915c75e5a276..a9d374061a46 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -678,46 +678,6 @@ static void update_load_sub(struct load_weight *lw, unsigned long dec) lw->inv_weight = 0; } -static void __update_curr_load(struct rq *rq, struct load_stat *ls) -{ - if (rq->curr != rq->idle && ls->load.weight) { - ls->delta_exec += ls->delta_stat; - ls->delta_fair += calc_delta_fair(ls->delta_stat, &ls->load); - ls->delta_stat = 0; - } -} - -/* - * Update delta_exec, delta_fair fields for rq. - * - * delta_fair clock advances at a rate inversely proportional to - * total load (rq->ls.load.weight) on the runqueue, while - * delta_exec advances at the same rate as wall-clock (provided - * cpu is not idle). - * - * delta_exec / delta_fair is a measure of the (smoothened) load on this - * runqueue over any given interval. This (smoothened) load is used - * during load balance. - * - * This function is called /before/ updating rq->ls.load - * and when switching tasks. - */ -static void update_curr_load(struct rq *rq, u64 now) -{ - struct load_stat *ls = &rq->ls; - u64 start; - - start = ls->load_update_start; - ls->load_update_start = now; - ls->delta_stat += now - start; - /* - * Stagger updates to ls->delta_fair. Very frequent updates - * can be expensive. - */ - if (ls->delta_stat >= sysctl_sched_stat_granularity) - __update_curr_load(rq, ls); -} - /* * To aid in avoiding the subversion of "niceness" due to uneven distribution * of tasks with abnormal "nice" values across CPUs the contribution that @@ -768,32 +728,6 @@ static const u32 prio_to_wmult[40] = { /* 15 */ 119304647, 148102320, 186737708, 238609294, 286331153, }; -static inline void -inc_load(struct rq *rq, const struct task_struct *p, u64 now) -{ - update_curr_load(rq, now); - update_load_add(&rq->ls.load, p->se.load.weight); -} - -static inline void -dec_load(struct rq *rq, const struct task_struct *p, u64 now) -{ - update_curr_load(rq, now); - update_load_sub(&rq->ls.load, p->se.load.weight); -} - -static void inc_nr_running(struct task_struct *p, struct rq *rq, u64 now) -{ - rq->nr_running++; - inc_load(rq, p, now); -} - -static void dec_nr_running(struct task_struct *p, struct rq *rq, u64 now) -{ - rq->nr_running--; - dec_load(rq, p, now); -} - static void activate_task(struct rq *rq, struct task_struct *p, int wakeup); /* @@ -824,6 +758,72 @@ static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, #define sched_class_highest (&rt_sched_class) +static void __update_curr_load(struct rq *rq, struct load_stat *ls) +{ + if (rq->curr != rq->idle && ls->load.weight) { + ls->delta_exec += ls->delta_stat; + ls->delta_fair += calc_delta_fair(ls->delta_stat, &ls->load); + ls->delta_stat = 0; + } +} + +/* + * Update delta_exec, delta_fair fields for rq. + * + * delta_fair clock advances at a rate inversely proportional to + * total load (rq->ls.load.weight) on the runqueue, while + * delta_exec advances at the same rate as wall-clock (provided + * cpu is not idle). + * + * delta_exec / delta_fair is a measure of the (smoothened) load on this + * runqueue over any given interval. This (smoothened) load is used + * during load balance. + * + * This function is called /before/ updating rq->ls.load + * and when switching tasks. + */ +static void update_curr_load(struct rq *rq, u64 now) +{ + struct load_stat *ls = &rq->ls; + u64 start; + + start = ls->load_update_start; + ls->load_update_start = now; + ls->delta_stat += now - start; + /* + * Stagger updates to ls->delta_fair. Very frequent updates + * can be expensive. + */ + if (ls->delta_stat >= sysctl_sched_stat_granularity) + __update_curr_load(rq, ls); +} + +static inline void +inc_load(struct rq *rq, const struct task_struct *p, u64 now) +{ + update_curr_load(rq, now); + update_load_add(&rq->ls.load, p->se.load.weight); +} + +static inline void +dec_load(struct rq *rq, const struct task_struct *p, u64 now) +{ + update_curr_load(rq, now); + update_load_sub(&rq->ls.load, p->se.load.weight); +} + +static void inc_nr_running(struct task_struct *p, struct rq *rq, u64 now) +{ + rq->nr_running++; + inc_load(rq, p, now); +} + +static void dec_nr_running(struct task_struct *p, struct rq *rq, u64 now) +{ + rq->nr_running--; + dec_load(rq, p, now); +} + static void set_load_weight(struct task_struct *p) { task_rq(p)->cfs.wait_runtime -= p->se.wait_runtime; -- cgit v1.2.2 From c3c7011969274768818842b0a08ec45d88f45b4f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: add schedstat_set() API add the schedstat_set() API, to allow the reduction of CONFIG_SCHEDSTAT related #ifdefs. No code changed. Signed-off-by: Ingo Molnar --- kernel/sched_stats.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h index c63c38f6fa6e..c20a94dda61e 100644 --- a/kernel/sched_stats.h +++ b/kernel/sched_stats.h @@ -116,6 +116,7 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta) } # define schedstat_inc(rq, field) do { (rq)->field++; } while (0) # define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0) +# define schedstat_set(var, val) do { var = (val); } while (0) #else /* !CONFIG_SCHEDSTATS */ static inline void rq_sched_info_arrive(struct rq *rq, unsigned long long delta) @@ -125,6 +126,7 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta) {} # define schedstat_inc(rq, field) do { } while (0) # define schedstat_add(rq, field, amt) do { } while (0) +# define schedstat_set(var, val) do { } while (0) #endif #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) -- cgit v1.2.2 From 8179ca23d513717cc5e3dc81a1ffe01af0955468 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: use schedstat_set() API make use of the new schedstat_set() API to eliminate two #ifdef sections. No functional changes: text data bss dec hex filename 29009 4122 28 33159 8187 sched.o.before 29009 4122 28 33159 8187 sched.o.after Signed-off-by: Ingo Molnar --- kernel/sched_fair.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 243da6cae71c..5bf7285ad02c 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -292,10 +292,7 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, u64 now) return; delta_exec = curr->delta_exec; -#ifdef CONFIG_SCHEDSTATS - if (unlikely(delta_exec > curr->exec_max)) - curr->exec_max = delta_exec; -#endif + schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max)); curr->sum_exec_runtime += delta_exec; cfs_rq->exec_clock += delta_exec; @@ -425,13 +422,7 @@ __update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) { unsigned long delta_fair = se->delta_fair_run; -#ifdef CONFIG_SCHEDSTATS - { - s64 delta_wait = now - se->wait_start; - if (unlikely(delta_wait > se->wait_max)) - se->wait_max = delta_wait; - } -#endif + schedstat_set(se->wait_max, max(se->wait_max, now - se->wait_start)); if (unlikely(se->load.weight != NICE_0_LOAD)) delta_fair = calc_weighted(delta_fair, se->load.weight, -- cgit v1.2.2 From 6cfb0d5d06bea2b8791f32145eae539d524e5f6c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: reduce debug code move the rest of the debugging/instrumentation code to under CONFIG_SCHEDSTATS too. This reduces code size and speeds code up: text data bss dec hex filename 33044 4122 28 37194 914a sched.o.before 32708 4122 28 36858 8ffa sched.o.after Signed-off-by: Ingo Molnar --- kernel/sched.c | 28 ++++++++++++++++++---------- kernel/sched_debug.c | 22 ++++++++++++++++------ kernel/sched_fair.c | 4 ++-- kernel/sched_rt.c | 4 ++-- 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index a9d374061a46..72bb9483d949 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -983,18 +983,21 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) u64 clock_offset, fair_clock_offset; clock_offset = old_rq->clock - new_rq->clock; - fair_clock_offset = old_rq->cfs.fair_clock - - new_rq->cfs.fair_clock; - if (p->se.wait_start) - p->se.wait_start -= clock_offset; + fair_clock_offset = old_rq->cfs.fair_clock - new_rq->cfs.fair_clock; + if (p->se.wait_start_fair) p->se.wait_start_fair -= fair_clock_offset; + if (p->se.sleep_start_fair) + p->se.sleep_start_fair -= fair_clock_offset; + +#ifdef CONFIG_SCHEDSTATS + if (p->se.wait_start) + p->se.wait_start -= clock_offset; if (p->se.sleep_start) p->se.sleep_start -= clock_offset; if (p->se.block_start) p->se.block_start -= clock_offset; - if (p->se.sleep_start_fair) - p->se.sleep_start_fair -= fair_clock_offset; +#endif __set_task_cpu(p, new_cpu); } @@ -1555,17 +1558,19 @@ int fastcall wake_up_state(struct task_struct *p, unsigned int state) static void __sched_fork(struct task_struct *p) { p->se.wait_start_fair = 0; - p->se.wait_start = 0; p->se.exec_start = 0; p->se.sum_exec_runtime = 0; p->se.delta_exec = 0; p->se.delta_fair_run = 0; p->se.delta_fair_sleep = 0; p->se.wait_runtime = 0; + p->se.sleep_start_fair = 0; + +#ifdef CONFIG_SCHEDSTATS + p->se.wait_start = 0; p->se.sum_wait_runtime = 0; p->se.sum_sleep_runtime = 0; p->se.sleep_start = 0; - p->se.sleep_start_fair = 0; p->se.block_start = 0; p->se.sleep_max = 0; p->se.block_max = 0; @@ -1573,6 +1578,7 @@ static void __sched_fork(struct task_struct *p) p->se.wait_max = 0; p->se.wait_runtime_overruns = 0; p->se.wait_runtime_underruns = 0; +#endif INIT_LIST_HEAD(&p->run_list); p->se.on_rq = 0; @@ -6579,12 +6585,14 @@ void normalize_rt_tasks(void) do_each_thread(g, p) { p->se.fair_key = 0; p->se.wait_runtime = 0; + p->se.exec_start = 0; p->se.wait_start_fair = 0; + p->se.sleep_start_fair = 0; +#ifdef CONFIG_SCHEDSTATS p->se.wait_start = 0; - p->se.exec_start = 0; p->se.sleep_start = 0; - p->se.sleep_start_fair = 0; p->se.block_start = 0; +#endif task_rq(p)->cfs.fair_clock = 0; task_rq(p)->clock = 0; diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index 0eca442b7792..1c61e5315ad2 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c @@ -44,11 +44,16 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p, u64 now) (long long)p->se.wait_runtime, (long long)(p->nvcsw + p->nivcsw), p->prio, +#ifdef CONFIG_SCHEDSTATS (long long)p->se.sum_exec_runtime, (long long)p->se.sum_wait_runtime, (long long)p->se.sum_sleep_runtime, (long long)p->se.wait_runtime_overruns, - (long long)p->se.wait_runtime_underruns); + (long long)p->se.wait_runtime_underruns +#else + 0LL, 0LL, 0LL, 0LL, 0LL +#endif + ); } static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu, u64 now) @@ -171,7 +176,7 @@ static int sched_debug_show(struct seq_file *m, void *v) u64 now = ktime_to_ns(ktime_get()); int cpu; - SEQ_printf(m, "Sched Debug Version: v0.05, %s %.*s\n", + SEQ_printf(m, "Sched Debug Version: v0.05-v20, %s %.*s\n", init_utsname()->release, (int)strcspn(init_utsname()->version, " "), init_utsname()->version); @@ -235,21 +240,24 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m) #define P(F) \ SEQ_printf(m, "%-25s:%20Ld\n", #F, (long long)p->F) - P(se.wait_start); + P(se.wait_runtime); P(se.wait_start_fair); P(se.exec_start); - P(se.sleep_start); P(se.sleep_start_fair); + P(se.sum_exec_runtime); + +#ifdef CONFIG_SCHEDSTATS + P(se.wait_start); + P(se.sleep_start); P(se.block_start); P(se.sleep_max); P(se.block_max); P(se.exec_max); P(se.wait_max); - P(se.wait_runtime); P(se.wait_runtime_overruns); P(se.wait_runtime_underruns); P(se.sum_wait_runtime); - P(se.sum_exec_runtime); +#endif SEQ_printf(m, "%-25s:%20Ld\n", "nr_switches", (long long)(p->nvcsw + p->nivcsw)); P(se.load.weight); @@ -269,7 +277,9 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m) void proc_sched_set_task(struct task_struct *p) { +#ifdef CONFIG_SCHEDSTATS p->se.sleep_max = p->se.block_max = p->se.exec_max = p->se.wait_max = 0; p->se.wait_runtime_overruns = p->se.wait_runtime_underruns = 0; +#endif p->se.sum_exec_runtime = 0; } diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 5bf7285ad02c..6f579ff5a9bc 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -349,7 +349,7 @@ static inline void update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) { se->wait_start_fair = cfs_rq->fair_clock; - se->wait_start = now; + schedstat_set(se->wait_start, now); } /* @@ -447,7 +447,7 @@ update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) } se->wait_start_fair = 0; - se->wait_start = 0; + schedstat_set(se->wait_start, 0); } static inline void diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index ade20dc422f1..002fcf8d3f64 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -18,8 +18,8 @@ static inline void update_curr_rt(struct rq *rq, u64 now) delta_exec = now - curr->se.exec_start; if (unlikely((s64)delta_exec < 0)) delta_exec = 0; - if (unlikely(delta_exec > curr->se.exec_max)) - curr->se.exec_max = delta_exec; + + schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec)); curr->se.sum_exec_runtime += delta_exec; curr->se.exec_start = now; -- cgit v1.2.2 From 94c18227d1e3f02de5b345bd3cd5c960214dc9c8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Aug 2007 17:41:40 +0200 Subject: [PATCH] sched: reduce task_struct size more task_struct size reduction, by moving the debugging/instrumentation fields to under CONFIG_SCHEDSTATS: (i386, nodebug): size ---- pre-CFS 1328 CFS 1472 CFS+patch 1376 Signed-off-by: Ingo Molnar --- include/linux/sched.h | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index c9e0c2a6a950..17249fae5014 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -904,23 +904,28 @@ struct sched_entity { struct rb_node run_node; unsigned int on_rq; + u64 exec_start; + u64 sum_exec_runtime; u64 wait_start_fair; + u64 sleep_start_fair; + +#ifdef CONFIG_SCHEDSTATS u64 wait_start; - u64 exec_start; + u64 wait_max; + s64 sum_wait_runtime; + u64 sleep_start; - u64 sleep_start_fair; - u64 block_start; u64 sleep_max; + s64 sum_sleep_runtime; + + u64 block_start; u64 block_max; u64 exec_max; - u64 wait_max; - u64 last_ran; - u64 sum_exec_runtime; - s64 sum_wait_runtime; - s64 sum_sleep_runtime; unsigned long wait_runtime_overruns; unsigned long wait_runtime_underruns; +#endif + #ifdef CONFIG_FAIR_GROUP_SCHED struct sched_entity *parent; /* rq on which this entity is (to be) queued: */ -- cgit v1.2.2 From 9534f71ca33e5a9de26dfd43c76af86e005005dd Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Mon, 30 Jul 2007 16:33:26 -0400 Subject: SELinux: restore proper NetLabel caching behavior A small fix to the SELinux/NetLabel glue code to ensure that the NetLabel cache is utilized when possible. This was broken when the SELinux/NetLabel glue code was reorganized in the last kernel release. Signed-off-by: Paul Moore Acked-by: Stephen Smalley Signed-off-by: James Morris --- include/net/netlabel.h | 2 ++ security/selinux/netlabel.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/net/netlabel.h b/include/net/netlabel.h index ffbc7f28335a..2e5b2f6f9fa0 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h @@ -132,6 +132,8 @@ struct netlbl_lsm_secattr_catmap { #define NETLBL_SECATTR_CACHE 0x00000002 #define NETLBL_SECATTR_MLS_LVL 0x00000004 #define NETLBL_SECATTR_MLS_CAT 0x00000008 +#define NETLBL_SECATTR_CACHEABLE (NETLBL_SECATTR_MLS_LVL | \ + NETLBL_SECATTR_MLS_CAT) struct netlbl_lsm_secattr { u32 flags; diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 051b14c88e2d..d243ddc723a5 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -162,9 +162,13 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u32 base_sid, u32 *sid) netlbl_secattr_init(&secattr); rc = netlbl_skbuff_getattr(skb, &secattr); - if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) + if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) { rc = security_netlbl_secattr_to_sid(&secattr, base_sid, sid); - else + if (rc == 0 && + (secattr.flags & NETLBL_SECATTR_CACHEABLE) && + (secattr.flags & NETLBL_SECATTR_CACHE)) + netlbl_cache_add(skb, &secattr); + } else *sid = SECSID_NULL; netlbl_secattr_destroy(&secattr); @@ -307,11 +311,15 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, netlbl_secattr_init(&secattr); rc = netlbl_skbuff_getattr(skb, &secattr); - if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) + if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) { rc = security_netlbl_secattr_to_sid(&secattr, SECINITSID_NETMSG, &nlbl_sid); - else + if (rc == 0 && + (secattr.flags & NETLBL_SECATTR_CACHEABLE) && + (secattr.flags & NETLBL_SECATTR_CACHE)) + netlbl_cache_add(skb, &secattr); + } else nlbl_sid = SECINITSID_UNLABELED; netlbl_secattr_destroy(&secattr); if (rc != 0) -- cgit v1.2.2 From 088999e98b8caecd31adc3b62223a228555c5ab7 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Wed, 1 Aug 2007 11:12:58 -0400 Subject: SELinux: remove redundant pointer checks before calling kfree() We don't need to check for NULL pointers before calling kfree(). Signed-off-by: Paul Moore Acked-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/hooks.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 0fac6829c63a..6237933f7d82 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4658,8 +4658,7 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) static void selinux_release_secctx(char *secdata, u32 seclen) { - if (secdata) - kfree(secdata); + kfree(secdata); } #ifdef CONFIG_KEYS -- cgit v1.2.2 From e6e0871cce2ae04f5790543ad2f4ec36b23260ba Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Wed, 1 Aug 2007 11:12:59 -0400 Subject: Net/Security: fix memory leaks from security_secid_to_secctx() The security_secid_to_secctx() function returns memory that must be freed by a call to security_release_secctx() which was not always happening. This patch fixes two of these problems (all that I could find in the kernel source at present). Signed-off-by: Paul Moore Acked-by: Stephen Smalley Signed-off-by: James Morris --- net/netlabel/netlabel_user.c | 4 +++- net/xfrm/xfrm_policy.c | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 89dcc485653b..85a96a3fddaa 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -113,8 +113,10 @@ struct audit_buffer *netlbl_audit_start_common(int type, if (audit_info->secid != 0 && security_secid_to_secctx(audit_info->secid, &secctx, - &secctx_len) == 0) + &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); + security_release_secctx(secctx, secctx_len); + } return audit_buf; } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 95a47304336d..e5a3be03aa0d 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2195,9 +2195,10 @@ void xfrm_audit_log(uid_t auid, u32 sid, int type, int result, } if (sid != 0 && - security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) + security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); - else + security_release_secctx(secctx, secctx_len); + } else audit_log_task_context(audit_buf); if (xp) { -- cgit v1.2.2 From 463c9a9f7d1f746c251761cef3af5c808394b7e1 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 2 Aug 2007 13:45:49 -0400 Subject: [x86 setup] EDD: add missing =m constraint Add a missing =m constraint to the EDD-probing code, that could have caused improper dead-code elimination. Signed-off-by: H. Peter Anvin --- arch/i386/boot/edd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/i386/boot/edd.c b/arch/i386/boot/edd.c index 77d92daf7923..658834d9f92a 100644 --- a/arch/i386/boot/edd.c +++ b/arch/i386/boot/edd.c @@ -127,7 +127,7 @@ static int get_edd_info(u8 devno, struct edd_info *ei) ax = 0x4800; dx = devno; asm("pushfl; int $0x13; popfl" - : "+a" (ax), "+d" (dx) + : "+a" (ax), "+d" (dx), "=m" (ei->params) : "S" (&ei->params) : "ebx", "ecx", "edi"); -- cgit v1.2.2 From c3887cd7253299cac2a6dc5ea792613a5ba5bf6a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 2 Aug 2007 13:50:43 -0400 Subject: [x86 setup] Document grub < 0.93 as broken Grub older than 0.93 are broken when the kernel setup is bigger than 8K. This was fixed in 2002, and 0.93 was the first grub version which fixed this bug. Signed-off-by: H. Peter Anvin --- Documentation/Changes | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/Changes b/Documentation/Changes index 73a8617f1861..cb2b141b1c3e 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -45,6 +45,7 @@ o nfs-utils 1.0.5 # showmount --version o procps 3.2.0 # ps --version o oprofile 0.9 # oprofiled --version o udev 081 # udevinfo -V +o grub 0.93 # grub --version Kernel compilation ================== -- cgit v1.2.2 From 5bd5c03c317085339deb044ba52fce131a6a0b67 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Sun, 24 Jun 2007 19:22:29 +0200 Subject: [JFFS2] Prevent oops after 'node added in wrong place' debug check jffs2_add_physical_node_ref() should never really return error -- it's an internal debugging check which triggered. We really need to work out why and stop it happening. But in the meantime, let's make the failure mode a little less nasty. Signed-off-by: Joakim Tjernlund Signed-off-by: David Woodhouse --- fs/jffs2/write.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c index c9fe0ab3a329..1406f2ce20a7 100644 --- a/fs/jffs2/write.c +++ b/fs/jffs2/write.c @@ -173,6 +173,12 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 flash_ofs |= REF_NORMAL; } fn->raw = jffs2_add_physical_node_ref(c, flash_ofs, PAD(sizeof(*ri)+datalen), f->inocache); + if (IS_ERR(fn->raw)) { + void *hold_err = fn->raw; + /* Release the full_dnode which is now useless, and return */ + jffs2_free_full_dnode(fn); + return ERR_PTR(PTR_ERR(hold_err)); + } fn->ofs = je32_to_cpu(ri->offset); fn->size = je32_to_cpu(ri->dsize); fn->frags = 0; @@ -291,6 +297,12 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff } /* Mark the space used */ fd->raw = jffs2_add_physical_node_ref(c, flash_ofs | REF_PRISTINE, PAD(sizeof(*rd)+namelen), f->inocache); + if (IS_ERR(fd->raw)) { + void *hold_err = fd->raw; + /* Release the full_dirent which is now useless, and return */ + jffs2_free_full_dirent(fd); + return ERR_PTR(PTR_ERR(hold_err)); + } if (retried) { jffs2_dbg_acct_sanity_check(c,NULL); -- cgit v1.2.2 From 71c23397752c0e40722d931ab9152342e9673336 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 29 Jun 2007 13:39:57 +0100 Subject: [JFFS2] Deletion dirents should be REF_NORMAL, not REF_PRISTINE. Otherwise they'll never actually get garbage-collected. Noted by Jonathan Larmour. Signed-off-by: David Woodhouse --- fs/jffs2/nodelist.h | 5 +++++ fs/jffs2/readinode.c | 2 +- fs/jffs2/scan.c | 3 ++- fs/jffs2/write.c | 3 ++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h index 25126a062cae..bc5509fe577b 100644 --- a/fs/jffs2/nodelist.h +++ b/fs/jffs2/nodelist.h @@ -139,6 +139,11 @@ static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_nod #define ref_obsolete(ref) (((ref)->flash_offset & 3) == REF_OBSOLETE) #define mark_ref_normal(ref) do { (ref)->flash_offset = ref_offset(ref) | REF_NORMAL; } while(0) +/* Dirent nodes should be REF_PRISTINE only if they are not a deletion + dirent. Deletion dirents should be REF_NORMAL so that GC gets to + throw them away when appropriate */ +#define dirent_node_state(rd) ( (je32_to_cpu((rd)->ino)?REF_PRISTINE:REF_NORMAL) ) + /* NB: REF_PRISTINE for an inode-less node (ref->next_in_ino == NULL) indicates it is an unknown node of type JFFS2_NODETYPE_RWCOMPAT_COPY, so it'll get copied. If you need to do anything different to GC inode-less nodes, then diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 7b363786c2d2..170da20b97c7 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -613,7 +613,7 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r jeb->unchecked_size -= len; c->used_size += len; c->unchecked_size -= len; - ref->flash_offset = ref_offset(ref) | REF_PRISTINE; + ref->flash_offset = ref_offset(ref) | dirent_node_state(rd); spin_unlock(&c->erase_completion_lock); } diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 2a1c976c7924..6c75cd433342 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c @@ -1049,7 +1049,8 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo return -ENOMEM; } - fd->raw = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rd->totlen)), ic); + fd->raw = jffs2_link_node_ref(c, jeb, ofs | dirent_node_state(rd), + PAD(je32_to_cpu(rd->totlen)), ic); fd->next = NULL; fd->version = je32_to_cpu(rd->version); diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c index 1406f2ce20a7..bc6185933664 100644 --- a/fs/jffs2/write.c +++ b/fs/jffs2/write.c @@ -296,7 +296,8 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff return ERR_PTR(ret?ret:-EIO); } /* Mark the space used */ - fd->raw = jffs2_add_physical_node_ref(c, flash_ofs | REF_PRISTINE, PAD(sizeof(*rd)+namelen), f->inocache); + fd->raw = jffs2_add_physical_node_ref(c, flash_ofs | dirent_node_state(rd), + PAD(sizeof(*rd)+namelen), f->inocache); if (IS_ERR(fd->raw)) { void *hold_err = fd->raw; /* Release the full_dirent which is now useless, and return */ -- cgit v1.2.2 From 7b687707d769112aee220bafd50fa113363717ff Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 28 Jun 2007 19:49:36 +0100 Subject: [JFFS2] Fix suspend failure with JFFS2 GC thread. The try_to_freeze() call was in the wrong place; we need it in the signal-pending loop now that a pending freeze also makes signal_pending() return true. Signed-off-by: David Woodhouse --- fs/jffs2/background.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c index 143c5530caf3..504643f2e98b 100644 --- a/fs/jffs2/background.c +++ b/fs/jffs2/background.c @@ -84,7 +84,7 @@ static int jffs2_garbage_collect_thread(void *_c) set_freezable(); for (;;) { allow_signal(SIGHUP); - + again: if (!jffs2_thread_should_wake(c)) { set_current_state (TASK_INTERRUPTIBLE); D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n")); @@ -95,9 +95,6 @@ static int jffs2_garbage_collect_thread(void *_c) schedule(); } - if (try_to_freeze()) - continue; - /* This thread is purely an optimisation. But if it runs when other things could be running, it actually makes things a lot worse. Use yield() and put it at the back of the runqueue @@ -112,6 +109,9 @@ static int jffs2_garbage_collect_thread(void *_c) siginfo_t info; unsigned long signr; + if (try_to_freeze()) + goto again; + signr = dequeue_signal_lock(current, ¤t->blocked, &info); switch(signr) { -- cgit v1.2.2 From b8e3ec30c232eb76c96ecab52205fe46e8b0473a Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 5 Jul 2007 01:57:26 -0400 Subject: [JFFS2] Print correct node offset when complaining about broken data CRC Debugging the hardware problems in OLPC trac #1905 would be a whole lot easier if the correct node offsets were printed for the offending nodes. Signed-off-by: David Woodhouse --- fs/jffs2/readinode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 170da20b97c7..b5baa356fed2 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -104,7 +104,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info if (crc != tn->data_crc) { JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", - ofs, tn->data_crc, crc); + ref_offset(ref), tn->data_crc, crc); return 1; } -- cgit v1.2.2 From 47af05dd4b98b57eeb682596a0df42d106e02167 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Thu, 19 Jul 2007 16:45:18 -0400 Subject: [MTD] Fix potential leak in rfd_ftl_add_mtd This fixes a leak in the !mtd->erasesize error path (Coverity 1765). Signed-off-by: Florin Malita Signed-off-by: David Woodhouse --- drivers/mtd/rfd_ftl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c index d4b1ba8f23ef..006c03aacb55 100644 --- a/drivers/mtd/rfd_ftl.c +++ b/drivers/mtd/rfd_ftl.c @@ -779,6 +779,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) else { if (!mtd->erasesize) { printk(KERN_WARNING PREFIX "please provide block_size"); + kfree(part); return; } else -- cgit v1.2.2 From 9d7b4b5562b60c826c71cf2e1b7b63add42e527f Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Wed, 18 Jul 2007 14:56:11 +0200 Subject: [MTD] [NAND] Fix refactoring of EDB7312 hwcontrol function. The patch ensures that the current code (kernel 2.6.22) uses the bits like the code prior to the refactoring. The variable "bits" is employed in a useful way now. Signed-off-by: Roland Stigge Signed-off-by: David Woodhouse --- drivers/mtd/nand/edb7312.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c index 1daf8231aaef..0146cdc48039 100644 --- a/drivers/mtd/nand/edb7312.c +++ b/drivers/mtd/nand/edb7312.c @@ -74,7 +74,7 @@ static struct mtd_partition partition_info[] = { /* * hardware specific access to control-lines * - * NAND_NCE: bit 0 -> bit 7 + * NAND_NCE: bit 0 -> bit 6 (bit 7 = 1) * NAND_CLE: bit 1 -> bit 4 * NAND_ALE: bit 2 -> bit 5 */ @@ -83,12 +83,12 @@ static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) struct nand_chip *chip = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { - unsigned char bits; + unsigned char bits = 0x80; - bits = (ctrl & (NAND_CLE | NAND_ALE)) << 3; - bits = (ctrl & NAND_NCE) << 7; + bits |= (ctrl & (NAND_CLE | NAND_ALE)) << 3; + bits |= (ctrl & NAND_NCE) ? 0x00 : 0x40; - clps_writeb((clps_readb(ep7312_pxdr) & 0xB0) | 0x10, + clps_writeb((clps_readb(ep7312_pxdr) & 0xF0) | bits, ep7312_pxdr); } if (cmd != NAND_CMD_NONE) -- cgit v1.2.2 From 06a7643cd3d440a1d15a6b3aa7ee431f3f4791b4 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 23 Jul 2007 16:06:50 +0300 Subject: [MTD] [NAND] fix race in nand_base.c When we mark block bad we have to get chip because this involves writing to the page's OOB. We hit this bug in UBI - we observed random obscure crashes when it marks block bad from the background thread and there is some parallel task which utilizes flash. This patch also adds a TODO note about BBT table protection which it seems does not exist. Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_base.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 7e68203fe1ba..4b019c6304e7 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -24,6 +24,7 @@ * if we have HW ecc support. * The AG-AND chips have nice features for speed improvement, * which are not supported yet. Read / program 4 pages in one go. + * BBT table is not serialized, has to be fixed * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -360,6 +361,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) /* We write two bytes, so we dont have to mess with 16 bit * access */ + nand_get_device(chip, mtd, FL_WRITING); ofs += mtd->oobsize; chip->ops.len = chip->ops.ooblen = 2; chip->ops.datbuf = NULL; @@ -367,9 +369,11 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) chip->ops.ooboffs = chip->badblockpos & ~0x01; ret = nand_do_write_oob(mtd, ofs, &chip->ops); + nand_release_device(mtd); } if (!ret) mtd->ecc_stats.badblocks++; + return ret; } -- cgit v1.2.2 From a4265f8d9241ba583e48380f1b9e60cfcb798449 Mon Sep 17 00:00:00 2001 From: Ivan Kuten Date: Thu, 24 May 2007 14:35:58 +0300 Subject: [MTD] [NAND] at91_nand rdy_pin fix The patch below fixes nand driver for AT91 boards which do not have NAND R/B signal connected to gpio (rdy_pin is not connected). Signed-off-by: Ivan Kuten Acked-by: Andrew Victor Signed-off-by: David Woodhouse --- drivers/mtd/nand/at91_nand.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/at91_nand.c b/drivers/mtd/nand/at91_nand.c index 512e999177f7..b2a5672df6e0 100644 --- a/drivers/mtd/nand/at91_nand.c +++ b/drivers/mtd/nand/at91_nand.c @@ -128,7 +128,10 @@ static int __init at91_nand_probe(struct platform_device *pdev) nand_chip->IO_ADDR_R = host->io_base; nand_chip->IO_ADDR_W = host->io_base; nand_chip->cmd_ctrl = at91_nand_cmd_ctrl; - nand_chip->dev_ready = at91_nand_device_ready; + + if (host->board->rdy_pin) + nand_chip->dev_ready = at91_nand_device_ready; + nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ nand_chip->chip_delay = 20; /* 20us command delay time */ -- cgit v1.2.2 From 515495a1da9abf339b922b7919c4950e85b87b42 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 28 May 2007 19:17:54 +0100 Subject: [MTD] [NAND] nand_base.c: fix type of eccpos pointer The nand_base.c driver implicitly casts the uint32_t eccpos array to 'int *', which is not only not guaranteed to be the same sign as the source, but is not guaranteed to be the same size. Fix by changing nand_base.c to use uint32_t referencing the eccpos fields. Signed-off-by: Ben Dooks Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_base.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 4b019c6304e7..24ac6778b1a8 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -772,7 +772,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *p = buf; uint8_t *ecc_calc = chip->buffers->ecccalc; uint8_t *ecc_code = chip->buffers->ecccode; - int *eccpos = chip->ecc.layout->eccpos; + uint32_t *eccpos = chip->ecc.layout->eccpos; chip->ecc.read_page_raw(mtd, chip, buf); @@ -814,7 +814,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *p = buf; uint8_t *ecc_calc = chip->buffers->ecccalc; uint8_t *ecc_code = chip->buffers->ecccode; - int *eccpos = chip->ecc.layout->eccpos; + uint32_t *eccpos = chip->ecc.layout->eccpos; for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { chip->ecc.hwctl(mtd, NAND_ECC_READ); @@ -1420,7 +1420,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, int eccsteps = chip->ecc.steps; uint8_t *ecc_calc = chip->buffers->ecccalc; const uint8_t *p = buf; - int *eccpos = chip->ecc.layout->eccpos; + uint32_t *eccpos = chip->ecc.layout->eccpos; /* Software ecc calculation */ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) @@ -1446,7 +1446,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, int eccsteps = chip->ecc.steps; uint8_t *ecc_calc = chip->buffers->ecccalc; const uint8_t *p = buf; - int *eccpos = chip->ecc.layout->eccpos; + uint32_t *eccpos = chip->ecc.layout->eccpos; for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { chip->ecc.hwctl(mtd, NAND_ECC_WRITE); -- cgit v1.2.2