diff options
author | Adrian Bunk <bunk@r063144.stusta.swh.mhn.de> | 2006-03-20 12:30:36 -0500 |
---|---|---|
committer | Adrian Bunk <bunk@r063144.stusta.swh.mhn.de> | 2006-03-20 12:30:36 -0500 |
commit | 0f76ee451484d02c7405d92e7bceb39b415abb01 (patch) | |
tree | 9722f84281f786ba48971dde057f5171a49969e4 /drivers | |
parent | 01d206a7c1167639f6ca6dac22140fbdca017558 (diff) | |
parent | 7705a8792b0fc82fd7d4dd923724606bbfd9fb20 (diff) |
Merge with git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers')
429 files changed, 9040 insertions, 7258 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 619dd964c51c..5c69b86db624 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -69,7 +69,7 @@ obj-$(CONFIG_EISA) += eisa/ | |||
69 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 69 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
70 | obj-$(CONFIG_MMC) += mmc/ | 70 | obj-$(CONFIG_MMC) += mmc/ |
71 | obj-$(CONFIG_INFINIBAND) += infiniband/ | 71 | obj-$(CONFIG_INFINIBAND) += infiniband/ |
72 | obj-$(CONFIG_SGI_IOC4) += sn/ | 72 | obj-$(CONFIG_SGI_SN) += sn/ |
73 | obj-y += firmware/ | 73 | obj-y += firmware/ |
74 | obj-$(CONFIG_CRYPTO) += crypto/ | 74 | obj-$(CONFIG_CRYPTO) += crypto/ |
75 | obj-$(CONFIG_SUPERH) += sh/ | 75 | obj-$(CONFIG_SUPERH) += sh/ |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 0cce28c4025b..33e2ca847a26 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -247,7 +247,7 @@ config ACPI_CUSTOM_DSDT_FILE | |||
247 | Enter the full path name to the file wich includes the AmlCode declaration. | 247 | Enter the full path name to the file wich includes the AmlCode declaration. |
248 | 248 | ||
249 | config ACPI_BLACKLIST_YEAR | 249 | config ACPI_BLACKLIST_YEAR |
250 | int "Disable ACPI for systems before Jan 1st this year" if X86 | 250 | int "Disable ACPI for systems before Jan 1st this year" if X86_32 |
251 | default 0 | 251 | default 0 |
252 | help | 252 | help |
253 | enter a 4-digit year, eg. 2001 to disable ACPI by default | 253 | enter a 4-digit year, eg. 2001 to disable ACPI by default |
@@ -285,9 +285,8 @@ config ACPI_SYSTEM | |||
285 | dump your ACPI DSDT table using /proc/acpi/dsdt. | 285 | dump your ACPI DSDT table using /proc/acpi/dsdt. |
286 | 286 | ||
287 | config X86_PM_TIMER | 287 | config X86_PM_TIMER |
288 | bool "Power Management Timer Support" | 288 | bool "Power Management Timer Support" if EMBEDDED |
289 | depends on X86 | 289 | depends on X86 |
290 | depends on !X86_64 | ||
291 | default y | 290 | default y |
292 | help | 291 | help |
293 | The Power Management Timer is available on all ACPI-capable, | 292 | The Power Management Timer is available on all ACPI-capable, |
@@ -298,9 +297,8 @@ config X86_PM_TIMER | |||
298 | voltage scaling, unlike the commonly used Time Stamp Counter | 297 | voltage scaling, unlike the commonly used Time Stamp Counter |
299 | (TSC) timing source. | 298 | (TSC) timing source. |
300 | 299 | ||
301 | So, if you see messages like 'Losing too many ticks!' in the | 300 | You should nearly always say Y here because many modern |
302 | kernel logs, and/or you are using this on a notebook which | 301 | systems require this timer. |
303 | does not yet have an HPET, you should say "Y" here. | ||
304 | 302 | ||
305 | config ACPI_CONTAINER | 303 | config ACPI_CONTAINER |
306 | tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)" | 304 | tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)" |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index be2dae52f6fa..eb730a80952c 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -94,7 +94,9 @@ static int set_max_cstate(struct dmi_system_id *id) | |||
94 | return 0; | 94 | return 0; |
95 | } | 95 | } |
96 | 96 | ||
97 | static struct dmi_system_id __initdata processor_power_dmi_table[] = { | 97 | /* Actually this shouldn't be __cpuinitdata, would be better to fix the |
98 | callers to only run once -AK */ | ||
99 | static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { | ||
98 | { set_max_cstate, "IBM ThinkPad R40e", { | 100 | { set_max_cstate, "IBM ThinkPad R40e", { |
99 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | 101 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), |
100 | DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1}, | 102 | DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1}, |
@@ -899,7 +901,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) | |||
899 | case ACPI_STATE_C3: | 901 | case ACPI_STATE_C3: |
900 | acpi_processor_power_verify_c3(pr, cx); | 902 | acpi_processor_power_verify_c3(pr, cx); |
901 | #ifdef ARCH_APICTIMER_STOPS_ON_C3 | 903 | #ifdef ARCH_APICTIMER_STOPS_ON_C3 |
902 | if (c->x86_vendor == X86_VENDOR_INTEL) { | 904 | if (cx->valid && c->x86_vendor == X86_VENDOR_INTEL) { |
903 | on_each_cpu(switch_APIC_timer_to_ipi, | 905 | on_each_cpu(switch_APIC_timer_to_ipi, |
904 | &mask, 1, 1); | 906 | &mask, 1, 1); |
905 | } | 907 | } |
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 7d6481d9fbec..4038dbfa63a0 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c | |||
@@ -391,8 +391,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, | |||
391 | * Ensure a 32-bit boundary for the structure | 391 | * Ensure a 32-bit boundary for the structure |
392 | */ | 392 | */ |
393 | extra_struct_bytes = | 393 | extra_struct_bytes = |
394 | ACPI_ROUND_UP_to_32_bITS(resource_length) - | 394 | ACPI_ROUND_UP_to_32_bITS(resource_length); |
395 | resource_length; | ||
396 | break; | 395 | break; |
397 | 396 | ||
398 | case ACPI_RESOURCE_NAME_END_TAG: | 397 | case ACPI_RESOURCE_NAME_END_TAG: |
@@ -408,8 +407,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, | |||
408 | * Add vendor data and ensure a 32-bit boundary for the structure | 407 | * Add vendor data and ensure a 32-bit boundary for the structure |
409 | */ | 408 | */ |
410 | extra_struct_bytes = | 409 | extra_struct_bytes = |
411 | ACPI_ROUND_UP_to_32_bITS(resource_length) - | 410 | ACPI_ROUND_UP_to_32_bITS(resource_length); |
412 | resource_length; | ||
413 | break; | 411 | break; |
414 | 412 | ||
415 | case ACPI_RESOURCE_NAME_ADDRESS32: | 413 | case ACPI_RESOURCE_NAME_ADDRESS32: |
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 14f6a6201da3..05983a312d50 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c | |||
@@ -555,7 +555,7 @@ fore200e_pca_reset(struct fore200e* fore200e) | |||
555 | } | 555 | } |
556 | 556 | ||
557 | 557 | ||
558 | static int __init | 558 | static int __devinit |
559 | fore200e_pca_map(struct fore200e* fore200e) | 559 | fore200e_pca_map(struct fore200e* fore200e) |
560 | { | 560 | { |
561 | DPRINTK(2, "device %s being mapped in memory\n", fore200e->name); | 561 | DPRINTK(2, "device %s being mapped in memory\n", fore200e->name); |
@@ -589,7 +589,7 @@ fore200e_pca_unmap(struct fore200e* fore200e) | |||
589 | } | 589 | } |
590 | 590 | ||
591 | 591 | ||
592 | static int __init | 592 | static int __devinit |
593 | fore200e_pca_configure(struct fore200e* fore200e) | 593 | fore200e_pca_configure(struct fore200e* fore200e) |
594 | { | 594 | { |
595 | struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev; | 595 | struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev; |
@@ -2125,7 +2125,7 @@ fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags) | |||
2125 | } | 2125 | } |
2126 | 2126 | ||
2127 | 2127 | ||
2128 | static int __init | 2128 | static int __devinit |
2129 | fore200e_irq_request(struct fore200e* fore200e) | 2129 | fore200e_irq_request(struct fore200e* fore200e) |
2130 | { | 2130 | { |
2131 | if (request_irq(fore200e->irq, fore200e_interrupt, SA_SHIRQ, fore200e->name, fore200e->atm_dev) < 0) { | 2131 | if (request_irq(fore200e->irq, fore200e_interrupt, SA_SHIRQ, fore200e->name, fore200e->atm_dev) < 0) { |
@@ -2148,7 +2148,7 @@ fore200e_irq_request(struct fore200e* fore200e) | |||
2148 | } | 2148 | } |
2149 | 2149 | ||
2150 | 2150 | ||
2151 | static int __init | 2151 | static int __devinit |
2152 | fore200e_get_esi(struct fore200e* fore200e) | 2152 | fore200e_get_esi(struct fore200e* fore200e) |
2153 | { | 2153 | { |
2154 | struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA); | 2154 | struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA); |
@@ -2180,7 +2180,7 @@ fore200e_get_esi(struct fore200e* fore200e) | |||
2180 | } | 2180 | } |
2181 | 2181 | ||
2182 | 2182 | ||
2183 | static int __init | 2183 | static int __devinit |
2184 | fore200e_alloc_rx_buf(struct fore200e* fore200e) | 2184 | fore200e_alloc_rx_buf(struct fore200e* fore200e) |
2185 | { | 2185 | { |
2186 | int scheme, magn, nbr, size, i; | 2186 | int scheme, magn, nbr, size, i; |
@@ -2245,7 +2245,7 @@ fore200e_alloc_rx_buf(struct fore200e* fore200e) | |||
2245 | } | 2245 | } |
2246 | 2246 | ||
2247 | 2247 | ||
2248 | static int __init | 2248 | static int __devinit |
2249 | fore200e_init_bs_queue(struct fore200e* fore200e) | 2249 | fore200e_init_bs_queue(struct fore200e* fore200e) |
2250 | { | 2250 | { |
2251 | int scheme, magn, i; | 2251 | int scheme, magn, i; |
@@ -2308,7 +2308,7 @@ fore200e_init_bs_queue(struct fore200e* fore200e) | |||
2308 | } | 2308 | } |
2309 | 2309 | ||
2310 | 2310 | ||
2311 | static int __init | 2311 | static int __devinit |
2312 | fore200e_init_rx_queue(struct fore200e* fore200e) | 2312 | fore200e_init_rx_queue(struct fore200e* fore200e) |
2313 | { | 2313 | { |
2314 | struct host_rxq* rxq = &fore200e->host_rxq; | 2314 | struct host_rxq* rxq = &fore200e->host_rxq; |
@@ -2368,7 +2368,7 @@ fore200e_init_rx_queue(struct fore200e* fore200e) | |||
2368 | } | 2368 | } |
2369 | 2369 | ||
2370 | 2370 | ||
2371 | static int __init | 2371 | static int __devinit |
2372 | fore200e_init_tx_queue(struct fore200e* fore200e) | 2372 | fore200e_init_tx_queue(struct fore200e* fore200e) |
2373 | { | 2373 | { |
2374 | struct host_txq* txq = &fore200e->host_txq; | 2374 | struct host_txq* txq = &fore200e->host_txq; |
@@ -2431,7 +2431,7 @@ fore200e_init_tx_queue(struct fore200e* fore200e) | |||
2431 | } | 2431 | } |
2432 | 2432 | ||
2433 | 2433 | ||
2434 | static int __init | 2434 | static int __devinit |
2435 | fore200e_init_cmd_queue(struct fore200e* fore200e) | 2435 | fore200e_init_cmd_queue(struct fore200e* fore200e) |
2436 | { | 2436 | { |
2437 | struct host_cmdq* cmdq = &fore200e->host_cmdq; | 2437 | struct host_cmdq* cmdq = &fore200e->host_cmdq; |
@@ -2487,7 +2487,7 @@ fore200e_param_bs_queue(struct fore200e* fore200e, | |||
2487 | } | 2487 | } |
2488 | 2488 | ||
2489 | 2489 | ||
2490 | static int __init | 2490 | static int __devinit |
2491 | fore200e_initialize(struct fore200e* fore200e) | 2491 | fore200e_initialize(struct fore200e* fore200e) |
2492 | { | 2492 | { |
2493 | struct cp_queues __iomem * cpq; | 2493 | struct cp_queues __iomem * cpq; |
@@ -2539,7 +2539,7 @@ fore200e_initialize(struct fore200e* fore200e) | |||
2539 | } | 2539 | } |
2540 | 2540 | ||
2541 | 2541 | ||
2542 | static void __init | 2542 | static void __devinit |
2543 | fore200e_monitor_putc(struct fore200e* fore200e, char c) | 2543 | fore200e_monitor_putc(struct fore200e* fore200e, char c) |
2544 | { | 2544 | { |
2545 | struct cp_monitor __iomem * monitor = fore200e->cp_monitor; | 2545 | struct cp_monitor __iomem * monitor = fore200e->cp_monitor; |
@@ -2551,7 +2551,7 @@ fore200e_monitor_putc(struct fore200e* fore200e, char c) | |||
2551 | } | 2551 | } |
2552 | 2552 | ||
2553 | 2553 | ||
2554 | static int __init | 2554 | static int __devinit |
2555 | fore200e_monitor_getc(struct fore200e* fore200e) | 2555 | fore200e_monitor_getc(struct fore200e* fore200e) |
2556 | { | 2556 | { |
2557 | struct cp_monitor __iomem * monitor = fore200e->cp_monitor; | 2557 | struct cp_monitor __iomem * monitor = fore200e->cp_monitor; |
@@ -2576,7 +2576,7 @@ fore200e_monitor_getc(struct fore200e* fore200e) | |||
2576 | } | 2576 | } |
2577 | 2577 | ||
2578 | 2578 | ||
2579 | static void __init | 2579 | static void __devinit |
2580 | fore200e_monitor_puts(struct fore200e* fore200e, char* str) | 2580 | fore200e_monitor_puts(struct fore200e* fore200e, char* str) |
2581 | { | 2581 | { |
2582 | while (*str) { | 2582 | while (*str) { |
@@ -2591,7 +2591,7 @@ fore200e_monitor_puts(struct fore200e* fore200e, char* str) | |||
2591 | } | 2591 | } |
2592 | 2592 | ||
2593 | 2593 | ||
2594 | static int __init | 2594 | static int __devinit |
2595 | fore200e_start_fw(struct fore200e* fore200e) | 2595 | fore200e_start_fw(struct fore200e* fore200e) |
2596 | { | 2596 | { |
2597 | int ok; | 2597 | int ok; |
@@ -2622,7 +2622,7 @@ fore200e_start_fw(struct fore200e* fore200e) | |||
2622 | } | 2622 | } |
2623 | 2623 | ||
2624 | 2624 | ||
2625 | static int __init | 2625 | static int __devinit |
2626 | fore200e_load_fw(struct fore200e* fore200e) | 2626 | fore200e_load_fw(struct fore200e* fore200e) |
2627 | { | 2627 | { |
2628 | u32* fw_data = (u32*) fore200e->bus->fw_data; | 2628 | u32* fw_data = (u32*) fore200e->bus->fw_data; |
@@ -2648,7 +2648,7 @@ fore200e_load_fw(struct fore200e* fore200e) | |||
2648 | } | 2648 | } |
2649 | 2649 | ||
2650 | 2650 | ||
2651 | static int __init | 2651 | static int __devinit |
2652 | fore200e_register(struct fore200e* fore200e) | 2652 | fore200e_register(struct fore200e* fore200e) |
2653 | { | 2653 | { |
2654 | struct atm_dev* atm_dev; | 2654 | struct atm_dev* atm_dev; |
@@ -2675,7 +2675,7 @@ fore200e_register(struct fore200e* fore200e) | |||
2675 | } | 2675 | } |
2676 | 2676 | ||
2677 | 2677 | ||
2678 | static int __init | 2678 | static int __devinit |
2679 | fore200e_init(struct fore200e* fore200e) | 2679 | fore200e_init(struct fore200e* fore200e) |
2680 | { | 2680 | { |
2681 | if (fore200e_register(fore200e) < 0) | 2681 | if (fore200e_register(fore200e) < 0) |
@@ -2721,7 +2721,7 @@ fore200e_init(struct fore200e* fore200e) | |||
2721 | return -EBUSY; | 2721 | return -EBUSY; |
2722 | 2722 | ||
2723 | fore200e_supply(fore200e); | 2723 | fore200e_supply(fore200e); |
2724 | 2724 | ||
2725 | /* all done, board initialization is now complete */ | 2725 | /* all done, board initialization is now complete */ |
2726 | fore200e->state = FORE200E_STATE_COMPLETE; | 2726 | fore200e->state = FORE200E_STATE_COMPLETE; |
2727 | return 0; | 2727 | return 0; |
diff --git a/drivers/base/base.h b/drivers/base/base.h index e3b548d46cff..5735b38582d0 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -19,6 +19,10 @@ extern void bus_remove_driver(struct device_driver *); | |||
19 | extern void driver_detach(struct device_driver * drv); | 19 | extern void driver_detach(struct device_driver * drv); |
20 | extern int driver_probe_device(struct device_driver *, struct device *); | 20 | extern int driver_probe_device(struct device_driver *, struct device *); |
21 | 21 | ||
22 | extern void sysdev_shutdown(void); | ||
23 | extern int sysdev_suspend(pm_message_t state); | ||
24 | extern int sysdev_resume(void); | ||
25 | |||
22 | static inline struct class_device *to_class_dev(struct kobject *obj) | 26 | static inline struct class_device *to_class_dev(struct kobject *obj) |
23 | { | 27 | { |
24 | return container_of(obj, struct class_device, kobj); | 28 | return container_of(obj, struct class_device, kobj); |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 29f6af554e71..c3141565d59d 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -133,6 +133,8 @@ static struct kobj_type ktype_bus = { | |||
133 | decl_subsys(bus, &ktype_bus, NULL); | 133 | decl_subsys(bus, &ktype_bus, NULL); |
134 | 134 | ||
135 | 135 | ||
136 | #ifdef CONFIG_HOTPLUG | ||
137 | |||
136 | /* Manually detach a device from its associated driver. */ | 138 | /* Manually detach a device from its associated driver. */ |
137 | static int driver_helper(struct device *dev, void *data) | 139 | static int driver_helper(struct device *dev, void *data) |
138 | { | 140 | { |
@@ -193,6 +195,7 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
193 | } | 195 | } |
194 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | 196 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); |
195 | 197 | ||
198 | #endif | ||
196 | 199 | ||
197 | static struct device * next_device(struct klist_iter * i) | 200 | static struct device * next_device(struct klist_iter * i) |
198 | { | 201 | { |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index d1a05224627e..105a0d61eb1f 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -303,7 +303,7 @@ static int block_size_init(void) | |||
303 | */ | 303 | */ |
304 | #ifdef CONFIG_ARCH_MEMORY_PROBE | 304 | #ifdef CONFIG_ARCH_MEMORY_PROBE |
305 | static ssize_t | 305 | static ssize_t |
306 | memory_probe_store(struct class *class, const char __user *buf, size_t count) | 306 | memory_probe_store(struct class *class, const char *buf, size_t count) |
307 | { | 307 | { |
308 | u64 phys_addr; | 308 | u64 phys_addr; |
309 | int ret; | 309 | int ret; |
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index 0a7aa07b9a2a..317edbf0feca 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c | |||
@@ -9,10 +9,9 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include "../base.h" | ||
12 | #include "power.h" | 13 | #include "power.h" |
13 | 14 | ||
14 | extern int sysdev_resume(void); | ||
15 | |||
16 | 15 | ||
17 | /** | 16 | /** |
18 | * resume_device - Restore state for one device. | 17 | * resume_device - Restore state for one device. |
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c index c2475f3134ea..8826a5b6673e 100644 --- a/drivers/base/power/shutdown.c +++ b/drivers/base/power/shutdown.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | #include <asm/semaphore.h> | 13 | #include <asm/semaphore.h> |
14 | 14 | ||
15 | #include "../base.h" | ||
15 | #include "power.h" | 16 | #include "power.h" |
16 | 17 | ||
17 | #define to_dev(node) container_of(node, struct device, kobj.entry) | 18 | #define to_dev(node) container_of(node, struct device, kobj.entry) |
@@ -28,7 +29,6 @@ extern struct subsystem devices_subsys; | |||
28 | * they only get one called once when interrupts are disabled. | 29 | * they only get one called once when interrupts are disabled. |
29 | */ | 30 | */ |
30 | 31 | ||
31 | extern int sysdev_shutdown(void); | ||
32 | 32 | ||
33 | /** | 33 | /** |
34 | * device_shutdown - call ->shutdown() on each device to shutdown. | 34 | * device_shutdown - call ->shutdown() on each device to shutdown. |
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 50501764d050..8660779fb288 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
@@ -9,10 +9,9 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include "../base.h" | ||
12 | #include "power.h" | 13 | #include "power.h" |
13 | 14 | ||
14 | extern int sysdev_suspend(pm_message_t state); | ||
15 | |||
16 | /* | 15 | /* |
17 | * The entries in the dpm_active list are in a depth first order, simply | 16 | * The entries in the dpm_active list are in a depth first order, simply |
18 | * because children are guaranteed to be discovered after parents, and | 17 | * because children are guaranteed to be discovered after parents, and |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index f3a0c562bcb5..40d7242a07c1 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
@@ -27,22 +27,30 @@ | |||
27 | 27 | ||
28 | static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) | 28 | static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) |
29 | { | 29 | { |
30 | return sprintf(buf, "%u\n", dev->power.power_state.event); | 30 | if (dev->power.power_state.event) |
31 | return sprintf(buf, "2\n"); | ||
32 | else | ||
33 | return sprintf(buf, "0\n"); | ||
31 | } | 34 | } |
32 | 35 | ||
33 | static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) | 36 | static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) |
34 | { | 37 | { |
35 | pm_message_t state; | 38 | pm_message_t state; |
36 | char * rest; | 39 | int error = -EINVAL; |
37 | int error = 0; | ||
38 | 40 | ||
39 | state.event = simple_strtoul(buf, &rest, 10); | 41 | state.event = PM_EVENT_SUSPEND; |
40 | if (*rest) | 42 | /* Older apps expected to write "3" here - confused with PCI D3 */ |
41 | return -EINVAL; | 43 | if ((n == 1) && !strcmp(buf, "3")) |
42 | if (state.event) | ||
43 | error = dpm_runtime_suspend(dev, state); | 44 | error = dpm_runtime_suspend(dev, state); |
44 | else | 45 | |
46 | if ((n == 1) && !strcmp(buf, "2")) | ||
47 | error = dpm_runtime_suspend(dev, state); | ||
48 | |||
49 | if ((n == 1) && !strcmp(buf, "0")) { | ||
45 | dpm_runtime_resume(dev); | 50 | dpm_runtime_resume(dev); |
51 | error = 0; | ||
52 | } | ||
53 | |||
46 | return error ? error : n; | 54 | return error ? error : n; |
47 | } | 55 | } |
48 | 56 | ||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 66ed8f2fece5..6fc23ab127bd 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -21,8 +21,11 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/string.h> | 22 | #include <linux/string.h> |
23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
24 | #include <linux/device.h> | ||
24 | #include <asm/semaphore.h> | 25 | #include <asm/semaphore.h> |
25 | 26 | ||
27 | #include "base.h" | ||
28 | |||
26 | extern struct subsystem devices_subsys; | 29 | extern struct subsystem devices_subsys; |
27 | 30 | ||
28 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) | 31 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) |
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 6ede1f352c29..37b8cda3e8bc 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/timer.h> | 41 | #include <linux/timer.h> |
42 | #include <linux/pci.h> | 42 | #include <linux/pci.h> |
43 | #include <linux/init.h> | 43 | #include <linux/init.h> |
44 | #include <linux/random.h> | ||
44 | #include <asm/io.h> | 45 | #include <asm/io.h> |
45 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
46 | #include "DAC960.h" | 47 | #include "DAC960.h" |
@@ -3463,7 +3464,7 @@ static inline boolean DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, | |||
3463 | Command->SegmentCount, Command->DmaDirection); | 3464 | Command->SegmentCount, Command->DmaDirection); |
3464 | 3465 | ||
3465 | if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) { | 3466 | if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) { |
3466 | 3467 | add_disk_randomness(Request->rq_disk); | |
3467 | end_that_request_last(Request, UpToDate); | 3468 | end_that_request_last(Request, UpToDate); |
3468 | 3469 | ||
3469 | if (Command->Completion) { | 3470 | if (Command->Completion) { |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 139cbba76180..8b1331677407 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -433,12 +433,12 @@ config CDROM_PKTCDVD_BUFFERS | |||
433 | This controls the maximum number of active concurrent packets. More | 433 | This controls the maximum number of active concurrent packets. More |
434 | concurrent packets can increase write performance, but also require | 434 | concurrent packets can increase write performance, but also require |
435 | more memory. Each concurrent packet will require approximately 64Kb | 435 | more memory. Each concurrent packet will require approximately 64Kb |
436 | of non-swappable kernel memory, memory which will be allocated at | 436 | of non-swappable kernel memory, memory which will be allocated when |
437 | pktsetup time. | 437 | a disc is opened for writing. |
438 | 438 | ||
439 | config CDROM_PKTCDVD_WCACHE | 439 | config CDROM_PKTCDVD_WCACHE |
440 | bool "Enable write caching" | 440 | bool "Enable write caching (EXPERIMENTAL)" |
441 | depends on CDROM_PKTCDVD | 441 | depends on CDROM_PKTCDVD && EXPERIMENTAL |
442 | help | 442 | help |
443 | If enabled, write caching will be set for the CD-R/W device. For now | 443 | If enabled, write caching will be set for the CD-R/W device. For now |
444 | this option is dangerous unless the CD-RW media is known good, as we | 444 | this option is dangerous unless the CD-RW media is known good, as we |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 12d7b9bdfa93..0d65394707db 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -2183,6 +2183,7 @@ static void cciss_softirq_done(struct request *rq) | |||
2183 | { | 2183 | { |
2184 | CommandList_struct *cmd = rq->completion_data; | 2184 | CommandList_struct *cmd = rq->completion_data; |
2185 | ctlr_info_t *h = hba[cmd->ctlr]; | 2185 | ctlr_info_t *h = hba[cmd->ctlr]; |
2186 | unsigned long flags; | ||
2186 | u64bit temp64; | 2187 | u64bit temp64; |
2187 | int i, ddir; | 2188 | int i, ddir; |
2188 | 2189 | ||
@@ -2205,10 +2206,10 @@ static void cciss_softirq_done(struct request *rq) | |||
2205 | printk("Done with %p\n", rq); | 2206 | printk("Done with %p\n", rq); |
2206 | #endif /* CCISS_DEBUG */ | 2207 | #endif /* CCISS_DEBUG */ |
2207 | 2208 | ||
2208 | spin_lock_irq(&h->lock); | 2209 | spin_lock_irqsave(&h->lock, flags); |
2209 | end_that_request_last(rq, rq->errors); | 2210 | end_that_request_last(rq, rq->errors); |
2210 | cmd_free(h, cmd,1); | 2211 | cmd_free(h, cmd,1); |
2211 | spin_unlock_irq(&h->lock); | 2212 | spin_unlock_irqrestore(&h->lock, flags); |
2212 | } | 2213 | } |
2213 | 2214 | ||
2214 | /* checks the status of the job and calls complete buffers to mark all | 2215 | /* checks the status of the job and calls complete buffers to mark all |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 93affeeef7bd..bc9b2bcd7dba 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -43,8 +43,6 @@ | |||
43 | * | 43 | * |
44 | *************************************************************************/ | 44 | *************************************************************************/ |
45 | 45 | ||
46 | #define VERSION_CODE "v0.2.0a 2004-07-14 Jens Axboe (axboe@suse.de) and petero2@telia.com" | ||
47 | |||
48 | #include <linux/pktcdvd.h> | 46 | #include <linux/pktcdvd.h> |
49 | #include <linux/config.h> | 47 | #include <linux/config.h> |
50 | #include <linux/module.h> | 48 | #include <linux/module.h> |
@@ -60,6 +58,7 @@ | |||
60 | #include <linux/suspend.h> | 58 | #include <linux/suspend.h> |
61 | #include <scsi/scsi_cmnd.h> | 59 | #include <scsi/scsi_cmnd.h> |
62 | #include <scsi/scsi_ioctl.h> | 60 | #include <scsi/scsi_ioctl.h> |
61 | #include <scsi/scsi.h> | ||
63 | 62 | ||
64 | #include <asm/uaccess.h> | 63 | #include <asm/uaccess.h> |
65 | 64 | ||
@@ -131,7 +130,7 @@ static struct bio *pkt_bio_alloc(int nr_iovecs) | |||
131 | /* | 130 | /* |
132 | * Allocate a packet_data struct | 131 | * Allocate a packet_data struct |
133 | */ | 132 | */ |
134 | static struct packet_data *pkt_alloc_packet_data(void) | 133 | static struct packet_data *pkt_alloc_packet_data(int frames) |
135 | { | 134 | { |
136 | int i; | 135 | int i; |
137 | struct packet_data *pkt; | 136 | struct packet_data *pkt; |
@@ -140,11 +139,12 @@ static struct packet_data *pkt_alloc_packet_data(void) | |||
140 | if (!pkt) | 139 | if (!pkt) |
141 | goto no_pkt; | 140 | goto no_pkt; |
142 | 141 | ||
143 | pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE); | 142 | pkt->frames = frames; |
143 | pkt->w_bio = pkt_bio_alloc(frames); | ||
144 | if (!pkt->w_bio) | 144 | if (!pkt->w_bio) |
145 | goto no_bio; | 145 | goto no_bio; |
146 | 146 | ||
147 | for (i = 0; i < PAGES_PER_PACKET; i++) { | 147 | for (i = 0; i < frames / FRAMES_PER_PAGE; i++) { |
148 | pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO); | 148 | pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO); |
149 | if (!pkt->pages[i]) | 149 | if (!pkt->pages[i]) |
150 | goto no_page; | 150 | goto no_page; |
@@ -152,7 +152,7 @@ static struct packet_data *pkt_alloc_packet_data(void) | |||
152 | 152 | ||
153 | spin_lock_init(&pkt->lock); | 153 | spin_lock_init(&pkt->lock); |
154 | 154 | ||
155 | for (i = 0; i < PACKET_MAX_SIZE; i++) { | 155 | for (i = 0; i < frames; i++) { |
156 | struct bio *bio = pkt_bio_alloc(1); | 156 | struct bio *bio = pkt_bio_alloc(1); |
157 | if (!bio) | 157 | if (!bio) |
158 | goto no_rd_bio; | 158 | goto no_rd_bio; |
@@ -162,14 +162,14 @@ static struct packet_data *pkt_alloc_packet_data(void) | |||
162 | return pkt; | 162 | return pkt; |
163 | 163 | ||
164 | no_rd_bio: | 164 | no_rd_bio: |
165 | for (i = 0; i < PACKET_MAX_SIZE; i++) { | 165 | for (i = 0; i < frames; i++) { |
166 | struct bio *bio = pkt->r_bios[i]; | 166 | struct bio *bio = pkt->r_bios[i]; |
167 | if (bio) | 167 | if (bio) |
168 | bio_put(bio); | 168 | bio_put(bio); |
169 | } | 169 | } |
170 | 170 | ||
171 | no_page: | 171 | no_page: |
172 | for (i = 0; i < PAGES_PER_PACKET; i++) | 172 | for (i = 0; i < frames / FRAMES_PER_PAGE; i++) |
173 | if (pkt->pages[i]) | 173 | if (pkt->pages[i]) |
174 | __free_page(pkt->pages[i]); | 174 | __free_page(pkt->pages[i]); |
175 | bio_put(pkt->w_bio); | 175 | bio_put(pkt->w_bio); |
@@ -186,12 +186,12 @@ static void pkt_free_packet_data(struct packet_data *pkt) | |||
186 | { | 186 | { |
187 | int i; | 187 | int i; |
188 | 188 | ||
189 | for (i = 0; i < PACKET_MAX_SIZE; i++) { | 189 | for (i = 0; i < pkt->frames; i++) { |
190 | struct bio *bio = pkt->r_bios[i]; | 190 | struct bio *bio = pkt->r_bios[i]; |
191 | if (bio) | 191 | if (bio) |
192 | bio_put(bio); | 192 | bio_put(bio); |
193 | } | 193 | } |
194 | for (i = 0; i < PAGES_PER_PACKET; i++) | 194 | for (i = 0; i < pkt->frames / FRAMES_PER_PAGE; i++) |
195 | __free_page(pkt->pages[i]); | 195 | __free_page(pkt->pages[i]); |
196 | bio_put(pkt->w_bio); | 196 | bio_put(pkt->w_bio); |
197 | kfree(pkt); | 197 | kfree(pkt); |
@@ -206,17 +206,17 @@ static void pkt_shrink_pktlist(struct pktcdvd_device *pd) | |||
206 | list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) { | 206 | list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) { |
207 | pkt_free_packet_data(pkt); | 207 | pkt_free_packet_data(pkt); |
208 | } | 208 | } |
209 | INIT_LIST_HEAD(&pd->cdrw.pkt_free_list); | ||
209 | } | 210 | } |
210 | 211 | ||
211 | static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets) | 212 | static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets) |
212 | { | 213 | { |
213 | struct packet_data *pkt; | 214 | struct packet_data *pkt; |
214 | 215 | ||
215 | INIT_LIST_HEAD(&pd->cdrw.pkt_free_list); | 216 | BUG_ON(!list_empty(&pd->cdrw.pkt_free_list)); |
216 | INIT_LIST_HEAD(&pd->cdrw.pkt_active_list); | 217 | |
217 | spin_lock_init(&pd->cdrw.active_list_lock); | ||
218 | while (nr_packets > 0) { | 218 | while (nr_packets > 0) { |
219 | pkt = pkt_alloc_packet_data(); | 219 | pkt = pkt_alloc_packet_data(pd->settings.size >> 2); |
220 | if (!pkt) { | 220 | if (!pkt) { |
221 | pkt_shrink_pktlist(pd); | 221 | pkt_shrink_pktlist(pd); |
222 | return 0; | 222 | return 0; |
@@ -381,6 +381,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command * | |||
381 | memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE); | 381 | memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE); |
382 | if (sizeof(rq->cmd) > CDROM_PACKET_SIZE) | 382 | if (sizeof(rq->cmd) > CDROM_PACKET_SIZE) |
383 | memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE); | 383 | memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE); |
384 | rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); | ||
384 | 385 | ||
385 | rq->ref_count++; | 386 | rq->ref_count++; |
386 | rq->flags |= REQ_NOMERGE; | 387 | rq->flags |= REQ_NOMERGE; |
@@ -646,7 +647,7 @@ static void pkt_copy_bio_data(struct bio *src_bio, int seg, int offs, struct pag | |||
646 | * b) The data can be used as cache to avoid read requests if we receive a | 647 | * b) The data can be used as cache to avoid read requests if we receive a |
647 | * new write request for the same zone. | 648 | * new write request for the same zone. |
648 | */ | 649 | */ |
649 | static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, int *offsets) | 650 | static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec) |
650 | { | 651 | { |
651 | int f, p, offs; | 652 | int f, p, offs; |
652 | 653 | ||
@@ -654,15 +655,15 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, in | |||
654 | p = 0; | 655 | p = 0; |
655 | offs = 0; | 656 | offs = 0; |
656 | for (f = 0; f < pkt->frames; f++) { | 657 | for (f = 0; f < pkt->frames; f++) { |
657 | if (pages[f] != pkt->pages[p]) { | 658 | if (bvec[f].bv_page != pkt->pages[p]) { |
658 | void *vfrom = kmap_atomic(pages[f], KM_USER0) + offsets[f]; | 659 | void *vfrom = kmap_atomic(bvec[f].bv_page, KM_USER0) + bvec[f].bv_offset; |
659 | void *vto = page_address(pkt->pages[p]) + offs; | 660 | void *vto = page_address(pkt->pages[p]) + offs; |
660 | memcpy(vto, vfrom, CD_FRAMESIZE); | 661 | memcpy(vto, vfrom, CD_FRAMESIZE); |
661 | kunmap_atomic(vfrom, KM_USER0); | 662 | kunmap_atomic(vfrom, KM_USER0); |
662 | pages[f] = pkt->pages[p]; | 663 | bvec[f].bv_page = pkt->pages[p]; |
663 | offsets[f] = offs; | 664 | bvec[f].bv_offset = offs; |
664 | } else { | 665 | } else { |
665 | BUG_ON(offsets[f] != offs); | 666 | BUG_ON(bvec[f].bv_offset != offs); |
666 | } | 667 | } |
667 | offs += CD_FRAMESIZE; | 668 | offs += CD_FRAMESIZE; |
668 | if (offs >= PAGE_SIZE) { | 669 | if (offs >= PAGE_SIZE) { |
@@ -951,7 +952,7 @@ try_next_bio: | |||
951 | 952 | ||
952 | pd->current_sector = zone + pd->settings.size; | 953 | pd->current_sector = zone + pd->settings.size; |
953 | pkt->sector = zone; | 954 | pkt->sector = zone; |
954 | pkt->frames = pd->settings.size >> 2; | 955 | BUG_ON(pkt->frames != pd->settings.size >> 2); |
955 | pkt->write_size = 0; | 956 | pkt->write_size = 0; |
956 | 957 | ||
957 | /* | 958 | /* |
@@ -992,18 +993,17 @@ try_next_bio: | |||
992 | static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) | 993 | static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) |
993 | { | 994 | { |
994 | struct bio *bio; | 995 | struct bio *bio; |
995 | struct page *pages[PACKET_MAX_SIZE]; | ||
996 | int offsets[PACKET_MAX_SIZE]; | ||
997 | int f; | 996 | int f; |
998 | int frames_write; | 997 | int frames_write; |
998 | struct bio_vec *bvec = pkt->w_bio->bi_io_vec; | ||
999 | 999 | ||
1000 | for (f = 0; f < pkt->frames; f++) { | 1000 | for (f = 0; f < pkt->frames; f++) { |
1001 | pages[f] = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; | 1001 | bvec[f].bv_page = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; |
1002 | offsets[f] = (f * CD_FRAMESIZE) % PAGE_SIZE; | 1002 | bvec[f].bv_offset = (f * CD_FRAMESIZE) % PAGE_SIZE; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | /* | 1005 | /* |
1006 | * Fill-in pages[] and offsets[] with data from orig_bios. | 1006 | * Fill-in bvec with data from orig_bios. |
1007 | */ | 1007 | */ |
1008 | frames_write = 0; | 1008 | frames_write = 0; |
1009 | spin_lock(&pkt->lock); | 1009 | spin_lock(&pkt->lock); |
@@ -1025,11 +1025,11 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) { | 1027 | if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) { |
1028 | pages[f] = src_bvl->bv_page; | 1028 | bvec[f].bv_page = src_bvl->bv_page; |
1029 | offsets[f] = src_bvl->bv_offset + src_offs; | 1029 | bvec[f].bv_offset = src_bvl->bv_offset + src_offs; |
1030 | } else { | 1030 | } else { |
1031 | pkt_copy_bio_data(bio, segment, src_offs, | 1031 | pkt_copy_bio_data(bio, segment, src_offs, |
1032 | pages[f], offsets[f]); | 1032 | bvec[f].bv_page, bvec[f].bv_offset); |
1033 | } | 1033 | } |
1034 | src_offs += CD_FRAMESIZE; | 1034 | src_offs += CD_FRAMESIZE; |
1035 | frames_write++; | 1035 | frames_write++; |
@@ -1043,7 +1043,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
1043 | BUG_ON(frames_write != pkt->write_size); | 1043 | BUG_ON(frames_write != pkt->write_size); |
1044 | 1044 | ||
1045 | if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) { | 1045 | if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) { |
1046 | pkt_make_local_copy(pkt, pages, offsets); | 1046 | pkt_make_local_copy(pkt, bvec); |
1047 | pkt->cache_valid = 1; | 1047 | pkt->cache_valid = 1; |
1048 | } else { | 1048 | } else { |
1049 | pkt->cache_valid = 0; | 1049 | pkt->cache_valid = 0; |
@@ -1056,17 +1056,9 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
1056 | pkt->w_bio->bi_bdev = pd->bdev; | 1056 | pkt->w_bio->bi_bdev = pd->bdev; |
1057 | pkt->w_bio->bi_end_io = pkt_end_io_packet_write; | 1057 | pkt->w_bio->bi_end_io = pkt_end_io_packet_write; |
1058 | pkt->w_bio->bi_private = pkt; | 1058 | pkt->w_bio->bi_private = pkt; |
1059 | for (f = 0; f < pkt->frames; f++) { | 1059 | for (f = 0; f < pkt->frames; f++) |
1060 | if ((f + 1 < pkt->frames) && (pages[f + 1] == pages[f]) && | 1060 | if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset)) |
1061 | (offsets[f + 1] = offsets[f] + CD_FRAMESIZE)) { | 1061 | BUG(); |
1062 | if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE * 2, offsets[f])) | ||
1063 | BUG(); | ||
1064 | f++; | ||
1065 | } else { | ||
1066 | if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE, offsets[f])) | ||
1067 | BUG(); | ||
1068 | } | ||
1069 | } | ||
1070 | VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt); | 1062 | VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt); |
1071 | 1063 | ||
1072 | atomic_set(&pkt->io_wait, 1); | 1064 | atomic_set(&pkt->io_wait, 1); |
@@ -1505,40 +1497,42 @@ static int pkt_set_write_settings(struct pktcdvd_device *pd) | |||
1505 | } | 1497 | } |
1506 | 1498 | ||
1507 | /* | 1499 | /* |
1508 | * 0 -- we can write to this track, 1 -- we can't | 1500 | * 1 -- we can write to this track, 0 -- we can't |
1509 | */ | 1501 | */ |
1510 | static int pkt_good_track(track_information *ti) | 1502 | static int pkt_writable_track(struct pktcdvd_device *pd, track_information *ti) |
1511 | { | 1503 | { |
1512 | /* | 1504 | switch (pd->mmc3_profile) { |
1513 | * only good for CD-RW at the moment, not DVD-RW | 1505 | case 0x1a: /* DVD+RW */ |
1514 | */ | 1506 | case 0x12: /* DVD-RAM */ |
1507 | /* The track is always writable on DVD+RW/DVD-RAM */ | ||
1508 | return 1; | ||
1509 | default: | ||
1510 | break; | ||
1511 | } | ||
1515 | 1512 | ||
1516 | /* | 1513 | if (!ti->packet || !ti->fp) |
1517 | * FIXME: only for FP | ||
1518 | */ | ||
1519 | if (ti->fp == 0) | ||
1520 | return 0; | 1514 | return 0; |
1521 | 1515 | ||
1522 | /* | 1516 | /* |
1523 | * "good" settings as per Mt Fuji. | 1517 | * "good" settings as per Mt Fuji. |
1524 | */ | 1518 | */ |
1525 | if (ti->rt == 0 && ti->blank == 0 && ti->packet == 1) | 1519 | if (ti->rt == 0 && ti->blank == 0) |
1526 | return 0; | 1520 | return 1; |
1527 | 1521 | ||
1528 | if (ti->rt == 0 && ti->blank == 1 && ti->packet == 1) | 1522 | if (ti->rt == 0 && ti->blank == 1) |
1529 | return 0; | 1523 | return 1; |
1530 | 1524 | ||
1531 | if (ti->rt == 1 && ti->blank == 0 && ti->packet == 1) | 1525 | if (ti->rt == 1 && ti->blank == 0) |
1532 | return 0; | 1526 | return 1; |
1533 | 1527 | ||
1534 | printk("pktcdvd: bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet); | 1528 | printk("pktcdvd: bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet); |
1535 | return 1; | 1529 | return 0; |
1536 | } | 1530 | } |
1537 | 1531 | ||
1538 | /* | 1532 | /* |
1539 | * 0 -- we can write to this disc, 1 -- we can't | 1533 | * 1 -- we can write to this disc, 0 -- we can't |
1540 | */ | 1534 | */ |
1541 | static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di) | 1535 | static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di) |
1542 | { | 1536 | { |
1543 | switch (pd->mmc3_profile) { | 1537 | switch (pd->mmc3_profile) { |
1544 | case 0x0a: /* CD-RW */ | 1538 | case 0x0a: /* CD-RW */ |
@@ -1547,10 +1541,10 @@ static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di) | |||
1547 | case 0x1a: /* DVD+RW */ | 1541 | case 0x1a: /* DVD+RW */ |
1548 | case 0x13: /* DVD-RW */ | 1542 | case 0x13: /* DVD-RW */ |
1549 | case 0x12: /* DVD-RAM */ | 1543 | case 0x12: /* DVD-RAM */ |
1550 | return 0; | ||
1551 | default: | ||
1552 | printk("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile); | ||
1553 | return 1; | 1544 | return 1; |
1545 | default: | ||
1546 | VPRINTK("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile); | ||
1547 | return 0; | ||
1554 | } | 1548 | } |
1555 | 1549 | ||
1556 | /* | 1550 | /* |
@@ -1559,25 +1553,25 @@ static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di) | |||
1559 | */ | 1553 | */ |
1560 | if (di->disc_type == 0xff) { | 1554 | if (di->disc_type == 0xff) { |
1561 | printk("pktcdvd: Unknown disc. No track?\n"); | 1555 | printk("pktcdvd: Unknown disc. No track?\n"); |
1562 | return 1; | 1556 | return 0; |
1563 | } | 1557 | } |
1564 | 1558 | ||
1565 | if (di->disc_type != 0x20 && di->disc_type != 0) { | 1559 | if (di->disc_type != 0x20 && di->disc_type != 0) { |
1566 | printk("pktcdvd: Wrong disc type (%x)\n", di->disc_type); | 1560 | printk("pktcdvd: Wrong disc type (%x)\n", di->disc_type); |
1567 | return 1; | 1561 | return 0; |
1568 | } | 1562 | } |
1569 | 1563 | ||
1570 | if (di->erasable == 0) { | 1564 | if (di->erasable == 0) { |
1571 | printk("pktcdvd: Disc not erasable\n"); | 1565 | printk("pktcdvd: Disc not erasable\n"); |
1572 | return 1; | 1566 | return 0; |
1573 | } | 1567 | } |
1574 | 1568 | ||
1575 | if (di->border_status == PACKET_SESSION_RESERVED) { | 1569 | if (di->border_status == PACKET_SESSION_RESERVED) { |
1576 | printk("pktcdvd: Can't write to last track (reserved)\n"); | 1570 | printk("pktcdvd: Can't write to last track (reserved)\n"); |
1577 | return 1; | 1571 | return 0; |
1578 | } | 1572 | } |
1579 | 1573 | ||
1580 | return 0; | 1574 | return 1; |
1581 | } | 1575 | } |
1582 | 1576 | ||
1583 | static int pkt_probe_settings(struct pktcdvd_device *pd) | 1577 | static int pkt_probe_settings(struct pktcdvd_device *pd) |
@@ -1602,23 +1596,9 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) | |||
1602 | return ret; | 1596 | return ret; |
1603 | } | 1597 | } |
1604 | 1598 | ||
1605 | if (pkt_good_disc(pd, &di)) | 1599 | if (!pkt_writable_disc(pd, &di)) |
1606 | return -ENXIO; | 1600 | return -EROFS; |
1607 | 1601 | ||
1608 | switch (pd->mmc3_profile) { | ||
1609 | case 0x1a: /* DVD+RW */ | ||
1610 | printk("pktcdvd: inserted media is DVD+RW\n"); | ||
1611 | break; | ||
1612 | case 0x13: /* DVD-RW */ | ||
1613 | printk("pktcdvd: inserted media is DVD-RW\n"); | ||
1614 | break; | ||
1615 | case 0x12: /* DVD-RAM */ | ||
1616 | printk("pktcdvd: inserted media is DVD-RAM\n"); | ||
1617 | break; | ||
1618 | default: | ||
1619 | printk("pktcdvd: inserted media is CD-R%s\n", di.erasable ? "W" : ""); | ||
1620 | break; | ||
1621 | } | ||
1622 | pd->type = di.erasable ? PACKET_CDRW : PACKET_CDR; | 1602 | pd->type = di.erasable ? PACKET_CDRW : PACKET_CDR; |
1623 | 1603 | ||
1624 | track = 1; /* (di.last_track_msb << 8) | di.last_track_lsb; */ | 1604 | track = 1; /* (di.last_track_msb << 8) | di.last_track_lsb; */ |
@@ -1627,9 +1607,9 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) | |||
1627 | return ret; | 1607 | return ret; |
1628 | } | 1608 | } |
1629 | 1609 | ||
1630 | if (pkt_good_track(&ti)) { | 1610 | if (!pkt_writable_track(pd, &ti)) { |
1631 | printk("pktcdvd: can't write to this track\n"); | 1611 | printk("pktcdvd: can't write to this track\n"); |
1632 | return -ENXIO; | 1612 | return -EROFS; |
1633 | } | 1613 | } |
1634 | 1614 | ||
1635 | /* | 1615 | /* |
@@ -1639,11 +1619,11 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) | |||
1639 | pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2; | 1619 | pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2; |
1640 | if (pd->settings.size == 0) { | 1620 | if (pd->settings.size == 0) { |
1641 | printk("pktcdvd: detected zero packet size!\n"); | 1621 | printk("pktcdvd: detected zero packet size!\n"); |
1642 | pd->settings.size = 128; | 1622 | return -ENXIO; |
1643 | } | 1623 | } |
1644 | if (pd->settings.size > PACKET_MAX_SECTORS) { | 1624 | if (pd->settings.size > PACKET_MAX_SECTORS) { |
1645 | printk("pktcdvd: packet size is too big\n"); | 1625 | printk("pktcdvd: packet size is too big\n"); |
1646 | return -ENXIO; | 1626 | return -EROFS; |
1647 | } | 1627 | } |
1648 | pd->settings.fp = ti.fp; | 1628 | pd->settings.fp = ti.fp; |
1649 | pd->offset = (be32_to_cpu(ti.track_start) << 2) & (pd->settings.size - 1); | 1629 | pd->offset = (be32_to_cpu(ti.track_start) << 2) & (pd->settings.size - 1); |
@@ -1685,7 +1665,7 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) | |||
1685 | break; | 1665 | break; |
1686 | default: | 1666 | default: |
1687 | printk("pktcdvd: unknown data mode\n"); | 1667 | printk("pktcdvd: unknown data mode\n"); |
1688 | return 1; | 1668 | return -EROFS; |
1689 | } | 1669 | } |
1690 | return 0; | 1670 | return 0; |
1691 | } | 1671 | } |
@@ -1895,8 +1875,8 @@ static int pkt_open_write(struct pktcdvd_device *pd) | |||
1895 | unsigned int write_speed, media_write_speed, read_speed; | 1875 | unsigned int write_speed, media_write_speed, read_speed; |
1896 | 1876 | ||
1897 | if ((ret = pkt_probe_settings(pd))) { | 1877 | if ((ret = pkt_probe_settings(pd))) { |
1898 | DPRINTK("pktcdvd: %s failed probe\n", pd->name); | 1878 | VPRINTK("pktcdvd: %s failed probe\n", pd->name); |
1899 | return -EIO; | 1879 | return ret; |
1900 | } | 1880 | } |
1901 | 1881 | ||
1902 | if ((ret = pkt_set_write_settings(pd))) { | 1882 | if ((ret = pkt_set_write_settings(pd))) { |
@@ -1987,8 +1967,14 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) | |||
1987 | if ((ret = pkt_set_segment_merging(pd, q))) | 1967 | if ((ret = pkt_set_segment_merging(pd, q))) |
1988 | goto out_unclaim; | 1968 | goto out_unclaim; |
1989 | 1969 | ||
1990 | if (write) | 1970 | if (write) { |
1971 | if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { | ||
1972 | printk("pktcdvd: not enough memory for buffers\n"); | ||
1973 | ret = -ENOMEM; | ||
1974 | goto out_unclaim; | ||
1975 | } | ||
1991 | printk("pktcdvd: %lukB available on disc\n", lba << 1); | 1976 | printk("pktcdvd: %lukB available on disc\n", lba << 1); |
1977 | } | ||
1992 | 1978 | ||
1993 | return 0; | 1979 | return 0; |
1994 | 1980 | ||
@@ -2014,6 +2000,8 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush) | |||
2014 | pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); | 2000 | pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); |
2015 | bd_release(pd->bdev); | 2001 | bd_release(pd->bdev); |
2016 | blkdev_put(pd->bdev); | 2002 | blkdev_put(pd->bdev); |
2003 | |||
2004 | pkt_shrink_pktlist(pd); | ||
2017 | } | 2005 | } |
2018 | 2006 | ||
2019 | static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor) | 2007 | static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor) |
@@ -2046,10 +2034,9 @@ static int pkt_open(struct inode *inode, struct file *file) | |||
2046 | goto out_dec; | 2034 | goto out_dec; |
2047 | } | 2035 | } |
2048 | } else { | 2036 | } else { |
2049 | if (pkt_open_dev(pd, file->f_mode & FMODE_WRITE)) { | 2037 | ret = pkt_open_dev(pd, file->f_mode & FMODE_WRITE); |
2050 | ret = -EIO; | 2038 | if (ret) |
2051 | goto out_dec; | 2039 | goto out_dec; |
2052 | } | ||
2053 | /* | 2040 | /* |
2054 | * needed here as well, since ext2 (among others) may change | 2041 | * needed here as well, since ext2 (among others) may change |
2055 | * the blocksize at mount time | 2042 | * the blocksize at mount time |
@@ -2379,12 +2366,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
2379 | /* This is safe, since we have a reference from open(). */ | 2366 | /* This is safe, since we have a reference from open(). */ |
2380 | __module_get(THIS_MODULE); | 2367 | __module_get(THIS_MODULE); |
2381 | 2368 | ||
2382 | if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { | ||
2383 | printk("pktcdvd: not enough memory for buffers\n"); | ||
2384 | ret = -ENOMEM; | ||
2385 | goto out_mem; | ||
2386 | } | ||
2387 | |||
2388 | pd->bdev = bdev; | 2369 | pd->bdev = bdev; |
2389 | set_blocksize(bdev, CD_FRAMESIZE); | 2370 | set_blocksize(bdev, CD_FRAMESIZE); |
2390 | 2371 | ||
@@ -2395,7 +2376,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
2395 | if (IS_ERR(pd->cdrw.thread)) { | 2376 | if (IS_ERR(pd->cdrw.thread)) { |
2396 | printk("pktcdvd: can't start kernel thread\n"); | 2377 | printk("pktcdvd: can't start kernel thread\n"); |
2397 | ret = -ENOMEM; | 2378 | ret = -ENOMEM; |
2398 | goto out_thread; | 2379 | goto out_mem; |
2399 | } | 2380 | } |
2400 | 2381 | ||
2401 | proc = create_proc_entry(pd->name, 0, pkt_proc); | 2382 | proc = create_proc_entry(pd->name, 0, pkt_proc); |
@@ -2406,8 +2387,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
2406 | DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b)); | 2387 | DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b)); |
2407 | return 0; | 2388 | return 0; |
2408 | 2389 | ||
2409 | out_thread: | ||
2410 | pkt_shrink_pktlist(pd); | ||
2411 | out_mem: | 2390 | out_mem: |
2412 | blkdev_put(bdev); | 2391 | blkdev_put(bdev); |
2413 | /* This is safe: open() is still holding a reference. */ | 2392 | /* This is safe: open() is still holding a reference. */ |
@@ -2437,11 +2416,12 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
2437 | * The door gets locked when the device is opened, so we | 2416 | * The door gets locked when the device is opened, so we |
2438 | * have to unlock it or else the eject command fails. | 2417 | * have to unlock it or else the eject command fails. |
2439 | */ | 2418 | */ |
2440 | pkt_lock_door(pd, 0); | 2419 | if (pd->refcnt == 1) |
2420 | pkt_lock_door(pd, 0); | ||
2441 | return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); | 2421 | return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); |
2442 | 2422 | ||
2443 | default: | 2423 | default: |
2444 | printk("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); | 2424 | VPRINTK("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); |
2445 | return -ENOTTY; | 2425 | return -ENOTTY; |
2446 | } | 2426 | } |
2447 | 2427 | ||
@@ -2503,6 +2483,10 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd) | |||
2503 | goto out_mem; | 2483 | goto out_mem; |
2504 | pd->disk = disk; | 2484 | pd->disk = disk; |
2505 | 2485 | ||
2486 | INIT_LIST_HEAD(&pd->cdrw.pkt_free_list); | ||
2487 | INIT_LIST_HEAD(&pd->cdrw.pkt_active_list); | ||
2488 | spin_lock_init(&pd->cdrw.active_list_lock); | ||
2489 | |||
2506 | spin_lock_init(&pd->lock); | 2490 | spin_lock_init(&pd->lock); |
2507 | spin_lock_init(&pd->iosched.lock); | 2491 | spin_lock_init(&pd->iosched.lock); |
2508 | sprintf(pd->name, "pktcdvd%d", idx); | 2492 | sprintf(pd->name, "pktcdvd%d", idx); |
@@ -2567,8 +2551,6 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd) | |||
2567 | 2551 | ||
2568 | blkdev_put(pd->bdev); | 2552 | blkdev_put(pd->bdev); |
2569 | 2553 | ||
2570 | pkt_shrink_pktlist(pd); | ||
2571 | |||
2572 | remove_proc_entry(pd->name, pkt_proc); | 2554 | remove_proc_entry(pd->name, pkt_proc); |
2573 | DPRINTK("pktcdvd: writer %s unmapped\n", pd->name); | 2555 | DPRINTK("pktcdvd: writer %s unmapped\n", pd->name); |
2574 | 2556 | ||
@@ -2678,7 +2660,6 @@ static int __init pkt_init(void) | |||
2678 | 2660 | ||
2679 | pkt_proc = proc_mkdir("pktcdvd", proc_root_driver); | 2661 | pkt_proc = proc_mkdir("pktcdvd", proc_root_driver); |
2680 | 2662 | ||
2681 | DPRINTK("pktcdvd: %s\n", VERSION_CODE); | ||
2682 | return 0; | 2663 | return 0; |
2683 | 2664 | ||
2684 | out: | 2665 | out: |
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index e522d19ad886..7e21b1ff27c4 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -474,18 +474,6 @@ static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long | |||
474 | /* ======================== Card services HCI interaction ======================== */ | 474 | /* ======================== Card services HCI interaction ======================== */ |
475 | 475 | ||
476 | 476 | ||
477 | static struct device *bt3c_device(void) | ||
478 | { | ||
479 | static struct device dev = { | ||
480 | .bus_id = "pcmcia", | ||
481 | }; | ||
482 | kobject_set_name(&dev.kobj, "bt3c"); | ||
483 | kobject_init(&dev.kobj); | ||
484 | |||
485 | return &dev; | ||
486 | } | ||
487 | |||
488 | |||
489 | static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count) | 477 | static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count) |
490 | { | 478 | { |
491 | char *ptr = (char *) firmware; | 479 | char *ptr = (char *) firmware; |
@@ -574,6 +562,7 @@ static int bt3c_open(bt3c_info_t *info) | |||
574 | { | 562 | { |
575 | const struct firmware *firmware; | 563 | const struct firmware *firmware; |
576 | struct hci_dev *hdev; | 564 | struct hci_dev *hdev; |
565 | client_handle_t handle; | ||
577 | int err; | 566 | int err; |
578 | 567 | ||
579 | spin_lock_init(&(info->lock)); | 568 | spin_lock_init(&(info->lock)); |
@@ -605,8 +594,10 @@ static int bt3c_open(bt3c_info_t *info) | |||
605 | 594 | ||
606 | hdev->owner = THIS_MODULE; | 595 | hdev->owner = THIS_MODULE; |
607 | 596 | ||
597 | handle = info->link.handle; | ||
598 | |||
608 | /* Load firmware */ | 599 | /* Load firmware */ |
609 | err = request_firmware(&firmware, "BT3CPCC.bin", bt3c_device()); | 600 | err = request_firmware(&firmware, "BT3CPCC.bin", &handle_to_dev(handle)); |
610 | if (err < 0) { | 601 | if (err < 0) { |
611 | BT_ERR("Firmware request failed"); | 602 | BT_ERR("Firmware request failed"); |
612 | goto error; | 603 | goto error; |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 193446e6a08a..e27617259552 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -42,8 +42,6 @@ | |||
42 | #include <linux/proc_fs.h> | 42 | #include <linux/proc_fs.h> |
43 | #include <linux/seq_file.h> | 43 | #include <linux/seq_file.h> |
44 | 44 | ||
45 | #include <asm/bug.h> | ||
46 | |||
47 | #include <asm/vio.h> | 45 | #include <asm/vio.h> |
48 | #include <asm/scatterlist.h> | 46 | #include <asm/scatterlist.h> |
49 | #include <asm/iseries/hv_types.h> | 47 | #include <asm/iseries/hv_types.h> |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 4c67727d75b1..05ba410682a3 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -222,7 +222,7 @@ config SYNCLINKMP | |||
222 | 222 | ||
223 | config SYNCLINK_GT | 223 | config SYNCLINK_GT |
224 | tristate "SyncLink GT/AC support" | 224 | tristate "SyncLink GT/AC support" |
225 | depends on SERIAL_NONSTANDARD | 225 | depends on SERIAL_NONSTANDARD && PCI |
226 | help | 226 | help |
227 | Support for SyncLink GT and SyncLink AC families of | 227 | Support for SyncLink GT and SyncLink AC families of |
228 | synchronous and asynchronous serial adapters | 228 | synchronous and asynchronous serial adapters |
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index 486ed8a11b59..a4d425d2dce2 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig | |||
@@ -15,22 +15,23 @@ config AGP | |||
15 | due to kernel allocation issues), you could use PCI accesses | 15 | due to kernel allocation issues), you could use PCI accesses |
16 | and have up to a couple gigs of texture space. | 16 | and have up to a couple gigs of texture space. |
17 | 17 | ||
18 | Note that this is the only means to have XFree4/GLX use | 18 | Note that this is the only means to have X/GLX use |
19 | write-combining with MTRR support on the AGP bus. Without it, OpenGL | 19 | write-combining with MTRR support on the AGP bus. Without it, OpenGL |
20 | direct rendering will be a lot slower but still faster than PIO. | 20 | direct rendering will be a lot slower but still faster than PIO. |
21 | 21 | ||
22 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
23 | use GLX or DRI. If unsure, say N. | ||
24 | |||
25 | To compile this driver as a module, choose M here: the | 22 | To compile this driver as a module, choose M here: the |
26 | module will be called agpgart. | 23 | module will be called agpgart. |
27 | 24 | ||
25 | You should say Y here if you want to use GLX or DRI. | ||
26 | |||
27 | If unsure, say N. | ||
28 | |||
28 | config AGP_ALI | 29 | config AGP_ALI |
29 | tristate "ALI chipset support" | 30 | tristate "ALI chipset support" |
30 | depends on AGP && X86_32 | 31 | depends on AGP && X86_32 |
31 | ---help--- | 32 | ---help--- |
32 | This option gives you AGP support for the GLX component of | 33 | This option gives you AGP support for the GLX component of |
33 | XFree86 4.x on the following ALi chipsets. The supported chipsets | 34 | X on the following ALi chipsets. The supported chipsets |
34 | include M1541, M1621, M1631, M1632, M1641,M1647,and M1651. | 35 | include M1541, M1621, M1631, M1632, M1641,M1647,and M1651. |
35 | For the ALi-chipset question, ALi suggests you refer to | 36 | For the ALi-chipset question, ALi suggests you refer to |
36 | <http://www.ali.com.tw/eng/support/index.shtml>. | 37 | <http://www.ali.com.tw/eng/support/index.shtml>. |
@@ -40,28 +41,19 @@ config AGP_ALI | |||
40 | timing issues, this chipset cannot do AGP 2x with the G200. | 41 | timing issues, this chipset cannot do AGP 2x with the G200. |
41 | This is a hardware limitation. AGP 1x seems to be fine, though. | 42 | This is a hardware limitation. AGP 1x seems to be fine, though. |
42 | 43 | ||
43 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
44 | use GLX or DRI. If unsure, say N. | ||
45 | |||
46 | config AGP_ATI | 44 | config AGP_ATI |
47 | tristate "ATI chipset support" | 45 | tristate "ATI chipset support" |
48 | depends on AGP && X86_32 | 46 | depends on AGP && X86_32 |
49 | ---help--- | 47 | ---help--- |
50 | This option gives you AGP support for the GLX component of | 48 | This option gives you AGP support for the GLX component of |
51 | XFree86 4.x on the ATI RadeonIGP family of chipsets. | 49 | X on the ATI RadeonIGP family of chipsets. |
52 | |||
53 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
54 | use GLX or DRI. If unsure, say N. | ||
55 | 50 | ||
56 | config AGP_AMD | 51 | config AGP_AMD |
57 | tristate "AMD Irongate, 761, and 762 chipset support" | 52 | tristate "AMD Irongate, 761, and 762 chipset support" |
58 | depends on AGP && X86_32 | 53 | depends on AGP && X86_32 |
59 | help | 54 | help |
60 | This option gives you AGP support for the GLX component of | 55 | This option gives you AGP support for the GLX component of |
61 | XFree86 4.x on AMD Irongate, 761, and 762 chipsets. | 56 | X on AMD Irongate, 761, and 762 chipsets. |
62 | |||
63 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
64 | use GLX or DRI. If unsure, say N. | ||
65 | 57 | ||
66 | config AGP_AMD64 | 58 | config AGP_AMD64 |
67 | tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU | 59 | tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU |
@@ -69,45 +61,38 @@ config AGP_AMD64 | |||
69 | default y if GART_IOMMU | 61 | default y if GART_IOMMU |
70 | help | 62 | help |
71 | This option gives you AGP support for the GLX component of | 63 | This option gives you AGP support for the GLX component of |
72 | XFree86 4.x using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. | 64 | X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. |
73 | You still need an external AGP bridge like the AMD 8151, VIA | 65 | You still need an external AGP bridge like the AMD 8151, VIA |
74 | K8T400M, SiS755. It may also support other AGP bridges when loaded | 66 | K8T400M, SiS755. It may also support other AGP bridges when loaded |
75 | with agp_try_unsupported=1. | 67 | with agp_try_unsupported=1. |
76 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
77 | use GLX or DRI. If unsure, say Y | ||
78 | 68 | ||
79 | config AGP_INTEL | 69 | config AGP_INTEL |
80 | tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support" | 70 | tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support" |
81 | depends on AGP && X86 | 71 | depends on AGP && X86 |
82 | help | 72 | help |
83 | This option gives you AGP support for the GLX component of XFree86 4.x | 73 | This option gives you AGP support for the GLX component of X |
84 | on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875, | 74 | on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875, |
85 | E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G, | 75 | E7205 and E7505 chipsets and full support for the 810, 815, 830M, |
86 | 852GM, 855GM, 865G and I915 integrated graphics chipsets. | 76 | 845G, 852GM, 855GM, 865G and I915 integrated graphics chipsets. |
77 | |||
87 | 78 | ||
88 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
89 | use GLX or DRI, or if you have any Intel integrated graphics | ||
90 | chipsets. If unsure, say Y. | ||
91 | 79 | ||
92 | config AGP_NVIDIA | 80 | config AGP_NVIDIA |
93 | tristate "NVIDIA nForce/nForce2 chipset support" | 81 | tristate "NVIDIA nForce/nForce2 chipset support" |
94 | depends on AGP && X86_32 | 82 | depends on AGP && X86_32 |
95 | help | 83 | help |
96 | This option gives you AGP support for the GLX component of | 84 | This option gives you AGP support for the GLX component of |
97 | XFree86 4.x on the following NVIDIA chipsets. The supported chipsets | 85 | X on NVIDIA chipsets including nForce and nForce2 |
98 | include nForce and nForce2 | ||
99 | 86 | ||
100 | config AGP_SIS | 87 | config AGP_SIS |
101 | tristate "SiS chipset support" | 88 | tristate "SiS chipset support" |
102 | depends on AGP && X86_32 | 89 | depends on AGP && X86_32 |
103 | help | 90 | help |
104 | This option gives you AGP support for the GLX component of | 91 | This option gives you AGP support for the GLX component of |
105 | XFree86 4.x on Silicon Integrated Systems [SiS] chipsets. | 92 | X on Silicon Integrated Systems [SiS] chipsets. |
106 | 93 | ||
107 | Note that 5591/5592 AGP chipsets are NOT supported. | 94 | Note that 5591/5592 AGP chipsets are NOT supported. |
108 | 95 | ||
109 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
110 | use GLX or DRI. If unsure, say N. | ||
111 | 96 | ||
112 | config AGP_SWORKS | 97 | config AGP_SWORKS |
113 | tristate "Serverworks LE/HE chipset support" | 98 | tristate "Serverworks LE/HE chipset support" |
@@ -121,10 +106,7 @@ config AGP_VIA | |||
121 | depends on AGP && X86_32 | 106 | depends on AGP && X86_32 |
122 | help | 107 | help |
123 | This option gives you AGP support for the GLX component of | 108 | This option gives you AGP support for the GLX component of |
124 | XFree86 4.x on VIA MVP3/Apollo Pro chipsets. | 109 | X on VIA MVP3/Apollo Pro chipsets. |
125 | |||
126 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
127 | use GLX or DRI. If unsure, say N. | ||
128 | 110 | ||
129 | config AGP_I460 | 111 | config AGP_I460 |
130 | tristate "Intel 460GX chipset support" | 112 | tristate "Intel 460GX chipset support" |
@@ -159,9 +141,6 @@ config AGP_EFFICEON | |||
159 | This option gives you AGP support for the Transmeta Efficeon | 141 | This option gives you AGP support for the Transmeta Efficeon |
160 | series processors with integrated northbridges. | 142 | series processors with integrated northbridges. |
161 | 143 | ||
162 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
163 | use GLX or DRI. If unsure, say Y. | ||
164 | |||
165 | config AGP_SGI_TIOCA | 144 | config AGP_SGI_TIOCA |
166 | tristate "SGI TIO chipset AGP support" | 145 | tristate "SGI TIO chipset AGP support" |
167 | depends on AGP && (IA64_SGI_SN2 || IA64_GENERIC) | 146 | depends on AGP && (IA64_SGI_SN2 || IA64_GENERIC) |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 9964c508c111..1251b2515bbe 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -516,8 +516,10 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev) | |||
516 | pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase); | 516 | pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase); |
517 | 517 | ||
518 | /* if x86-64 aperture base is beyond 4G, exit here */ | 518 | /* if x86-64 aperture base is beyond 4G, exit here */ |
519 | if ( (apbase & 0x7fff) >> (32 - 25) ) | 519 | if ( (apbase & 0x7fff) >> (32 - 25) ) { |
520 | return -ENODEV; | 520 | printk(KERN_INFO PFX "aperture base > 4G\n"); |
521 | return -ENODEV; | ||
522 | } | ||
521 | 523 | ||
522 | apbase = (apbase & 0x7fff) << 25; | 524 | apbase = (apbase & 0x7fff) << 25; |
523 | 525 | ||
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 268f78d926d3..efef9999f1cf 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
@@ -468,9 +468,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, | |||
468 | 468 | ||
469 | switch (pdev->device) { | 469 | switch (pdev->device) { |
470 | case 0x0006: | 470 | case 0x0006: |
471 | /* ServerWorks CNB20HE | 471 | printk (KERN_ERR PFX "ServerWorks CNB20HE is unsupported due to lack of documentation.\n"); |
472 | Fail silently.*/ | ||
473 | printk (KERN_ERR PFX "Detected ServerWorks CNB20HE chipset: No AGP present.\n"); | ||
474 | return -ENODEV; | 472 | return -ENODEV; |
475 | 473 | ||
476 | case PCI_DEVICE_ID_SERVERWORKS_HE: | 474 | case PCI_DEVICE_ID_SERVERWORKS_HE: |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 71b8b32b075f..107df9fdba4e 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -980,7 +980,7 @@ extern int drm_put_head(drm_head_t * head); | |||
980 | extern unsigned int drm_debug; | 980 | extern unsigned int drm_debug; |
981 | extern unsigned int drm_cards_limit; | 981 | extern unsigned int drm_cards_limit; |
982 | extern drm_head_t **drm_heads; | 982 | extern drm_head_t **drm_heads; |
983 | extern struct drm_sysfs_class *drm_class; | 983 | extern struct class *drm_class; |
984 | extern struct proc_dir_entry *drm_proc_root; | 984 | extern struct proc_dir_entry *drm_proc_root; |
985 | 985 | ||
986 | /* Proc support (drm_proc.h) */ | 986 | /* Proc support (drm_proc.h) */ |
@@ -1011,11 +1011,9 @@ extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); | |||
1011 | extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); | 1011 | extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); |
1012 | 1012 | ||
1013 | /* sysfs support (drm_sysfs.c) */ | 1013 | /* sysfs support (drm_sysfs.c) */ |
1014 | struct drm_sysfs_class; | 1014 | extern struct class *drm_sysfs_create(struct module *owner, char *name); |
1015 | extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner, | 1015 | extern void drm_sysfs_destroy(struct class *cs); |
1016 | char *name); | 1016 | extern struct class_device *drm_sysfs_device_add(struct class *cs, |
1017 | extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); | ||
1018 | extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, | ||
1019 | drm_head_t *head); | 1017 | drm_head_t *head); |
1020 | extern void drm_sysfs_device_remove(struct class_device *class_dev); | 1018 | extern void drm_sysfs_device_remove(struct class_device *class_dev); |
1021 | 1019 | ||
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 8fd6357a48da..2c17e88a8847 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
@@ -85,7 +85,6 @@ | |||
85 | {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ | 85 | {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ |
86 | {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 86 | {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
87 | {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 87 | {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
88 | {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | ||
89 | {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ | 88 | {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ |
90 | {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 89 | {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
91 | {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ | 90 | {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ |
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 7a9263ff3007..68073e14fdec 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
@@ -50,7 +50,7 @@ module_param_named(cards_limit, drm_cards_limit, int, 0444); | |||
50 | module_param_named(debug, drm_debug, int, 0600); | 50 | module_param_named(debug, drm_debug, int, 0600); |
51 | 51 | ||
52 | drm_head_t **drm_heads; | 52 | drm_head_t **drm_heads; |
53 | struct drm_sysfs_class *drm_class; | 53 | struct class *drm_class; |
54 | struct proc_dir_entry *drm_proc_root; | 54 | struct proc_dir_entry *drm_proc_root; |
55 | 55 | ||
56 | static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, | 56 | static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 68e43ddc16ae..0b9f98a7eb10 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /* | 2 | /* |
2 | * drm_sysfs.c - Modifications to drm_sysfs_class.c to support | 3 | * drm_sysfs.c - Modifications to drm_sysfs_class.c to support |
3 | * extra sysfs attribute from DRM. Normal drm_sysfs_class | 4 | * extra sysfs attribute from DRM. Normal drm_sysfs_class |
@@ -19,36 +20,6 @@ | |||
19 | #include "drm_core.h" | 20 | #include "drm_core.h" |
20 | #include "drmP.h" | 21 | #include "drmP.h" |
21 | 22 | ||
22 | struct drm_sysfs_class { | ||
23 | struct class_device_attribute attr; | ||
24 | struct class class; | ||
25 | }; | ||
26 | #define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) | ||
27 | |||
28 | struct simple_dev { | ||
29 | dev_t dev; | ||
30 | struct class_device class_dev; | ||
31 | }; | ||
32 | #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) | ||
33 | |||
34 | static void release_simple_dev(struct class_device *class_dev) | ||
35 | { | ||
36 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
37 | kfree(s_dev); | ||
38 | } | ||
39 | |||
40 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | ||
41 | { | ||
42 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
43 | return print_dev_t(buf, s_dev->dev); | ||
44 | } | ||
45 | |||
46 | static void drm_sysfs_class_release(struct class *class) | ||
47 | { | ||
48 | struct drm_sysfs_class *cs = to_drm_sysfs_class(class); | ||
49 | kfree(cs); | ||
50 | } | ||
51 | |||
52 | /* Display the version of drm_core. This doesn't work right in current design */ | 23 | /* Display the version of drm_core. This doesn't work right in current design */ |
53 | static ssize_t version_show(struct class *dev, char *buf) | 24 | static ssize_t version_show(struct class *dev, char *buf) |
54 | { | 25 | { |
@@ -69,38 +40,16 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL); | |||
69 | * Note, the pointer created here is to be destroyed when finished by making a | 40 | * Note, the pointer created here is to be destroyed when finished by making a |
70 | * call to drm_sysfs_destroy(). | 41 | * call to drm_sysfs_destroy(). |
71 | */ | 42 | */ |
72 | struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) | 43 | struct class *drm_sysfs_create(struct module *owner, char *name) |
73 | { | 44 | { |
74 | struct drm_sysfs_class *cs; | 45 | struct class *class; |
75 | int retval; | 46 | |
76 | 47 | class = class_create(owner, name); | |
77 | cs = kmalloc(sizeof(*cs), GFP_KERNEL); | 48 | if (!class) |
78 | if (!cs) { | 49 | return class; |
79 | retval = -ENOMEM; | 50 | |
80 | goto error; | 51 | class_create_file(class, &class_attr_version); |
81 | } | 52 | return class; |
82 | memset(cs, 0x00, sizeof(*cs)); | ||
83 | |||
84 | cs->class.name = name; | ||
85 | cs->class.class_release = drm_sysfs_class_release; | ||
86 | cs->class.release = release_simple_dev; | ||
87 | |||
88 | cs->attr.attr.name = "dev"; | ||
89 | cs->attr.attr.mode = S_IRUGO; | ||
90 | cs->attr.attr.owner = owner; | ||
91 | cs->attr.show = show_dev; | ||
92 | cs->attr.store = NULL; | ||
93 | |||
94 | retval = class_register(&cs->class); | ||
95 | if (retval) | ||
96 | goto error; | ||
97 | class_create_file(&cs->class, &class_attr_version); | ||
98 | |||
99 | return cs; | ||
100 | |||
101 | error: | ||
102 | kfree(cs); | ||
103 | return ERR_PTR(retval); | ||
104 | } | 53 | } |
105 | 54 | ||
106 | /** | 55 | /** |
@@ -110,12 +59,13 @@ struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) | |||
110 | * Note, the pointer to be destroyed must have been created with a call to | 59 | * Note, the pointer to be destroyed must have been created with a call to |
111 | * drm_sysfs_create(). | 60 | * drm_sysfs_create(). |
112 | */ | 61 | */ |
113 | void drm_sysfs_destroy(struct drm_sysfs_class *cs) | 62 | void drm_sysfs_destroy(struct class *class) |
114 | { | 63 | { |
115 | if ((cs == NULL) || (IS_ERR(cs))) | 64 | if ((class == NULL) || (IS_ERR(class))) |
116 | return; | 65 | return; |
117 | 66 | ||
118 | class_unregister(&cs->class); | 67 | class_remove_file(class, &class_attr_version); |
68 | class_destroy(class); | ||
119 | } | 69 | } |
120 | 70 | ||
121 | static ssize_t show_dri(struct class_device *class_device, char *buf) | 71 | static ssize_t show_dri(struct class_device *class_device, char *buf) |
@@ -132,7 +82,7 @@ static struct class_device_attribute class_device_attrs[] = { | |||
132 | 82 | ||
133 | /** | 83 | /** |
134 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver | 84 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver |
135 | * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. | 85 | * @cs: pointer to the struct class that this device should be registered to. |
136 | * @dev: the dev_t for the device to be added. | 86 | * @dev: the dev_t for the device to be added. |
137 | * @device: a pointer to a struct device that is assiociated with this class device. | 87 | * @device: a pointer to a struct device that is assiociated with this class device. |
138 | * @fmt: string for the class device's name | 88 | * @fmt: string for the class device's name |
@@ -141,46 +91,26 @@ static struct class_device_attribute class_device_attrs[] = { | |||
141 | * class. A "dev" file will be created, showing the dev_t for the device. The | 91 | * class. A "dev" file will be created, showing the dev_t for the device. The |
142 | * pointer to the struct class_device will be returned from the call. Any further | 92 | * pointer to the struct class_device will be returned from the call. Any further |
143 | * sysfs files that might be required can be created using this pointer. | 93 | * sysfs files that might be required can be created using this pointer. |
144 | * Note: the struct drm_sysfs_class passed to this function must have previously been | 94 | * Note: the struct class passed to this function must have previously been |
145 | * created with a call to drm_sysfs_create(). | 95 | * created with a call to drm_sysfs_create(). |
146 | */ | 96 | */ |
147 | struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, | 97 | struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) |
148 | drm_head_t *head) | ||
149 | { | 98 | { |
150 | struct simple_dev *s_dev = NULL; | 99 | struct class_device *class_dev; |
151 | int i, retval; | 100 | int i; |
152 | |||
153 | if ((cs == NULL) || (IS_ERR(cs))) { | ||
154 | retval = -ENODEV; | ||
155 | goto error; | ||
156 | } | ||
157 | |||
158 | s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL); | ||
159 | if (!s_dev) { | ||
160 | retval = -ENOMEM; | ||
161 | goto error; | ||
162 | } | ||
163 | memset(s_dev, 0x00, sizeof(*s_dev)); | ||
164 | |||
165 | s_dev->dev = MKDEV(DRM_MAJOR, head->minor); | ||
166 | s_dev->class_dev.dev = &(head->dev->pdev)->dev; | ||
167 | s_dev->class_dev.class = &cs->class; | ||
168 | 101 | ||
169 | snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor); | 102 | class_dev = class_device_create(cs, NULL, |
170 | retval = class_device_register(&s_dev->class_dev); | 103 | MKDEV(DRM_MAJOR, head->minor), |
171 | if (retval) | 104 | &(head->dev->pdev)->dev, |
172 | goto error; | 105 | "card%d", head->minor); |
106 | if (!class_dev) | ||
107 | return NULL; | ||
173 | 108 | ||
174 | class_device_create_file(&s_dev->class_dev, &cs->attr); | 109 | class_set_devdata(class_dev, head); |
175 | class_set_devdata(&s_dev->class_dev, head); | ||
176 | 110 | ||
177 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 111 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
178 | class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]); | 112 | class_device_create_file(class_dev, &class_device_attrs[i]); |
179 | return &s_dev->class_dev; | 113 | return class_dev; |
180 | |||
181 | error: | ||
182 | kfree(s_dev); | ||
183 | return ERR_PTR(retval); | ||
184 | } | 114 | } |
185 | 115 | ||
186 | /** | 116 | /** |
@@ -192,10 +122,9 @@ error: | |||
192 | */ | 122 | */ |
193 | void drm_sysfs_device_remove(struct class_device *class_dev) | 123 | void drm_sysfs_device_remove(struct class_device *class_dev) |
194 | { | 124 | { |
195 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
196 | int i; | 125 | int i; |
197 | 126 | ||
198 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 127 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
199 | class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]); | 128 | class_device_remove_file(class_dev, &class_device_attrs[i]); |
200 | class_device_unregister(&s_dev->class_dev); | 129 | class_device_unregister(class_dev); |
201 | } | 130 | } |
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index a1381c61aa63..d3879ac9970f 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c | |||
@@ -202,10 +202,15 @@ void i915_driver_irq_postinstall(drm_device_t * dev) | |||
202 | void i915_driver_irq_uninstall(drm_device_t * dev) | 202 | void i915_driver_irq_uninstall(drm_device_t * dev) |
203 | { | 203 | { |
204 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 204 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
205 | u16 temp; | ||
206 | |||
205 | if (!dev_priv) | 207 | if (!dev_priv) |
206 | return; | 208 | return; |
207 | 209 | ||
208 | I915_WRITE16(I915REG_HWSTAM, 0xffff); | 210 | I915_WRITE16(I915REG_HWSTAM, 0xffff); |
209 | I915_WRITE16(I915REG_INT_MASK_R, 0xffff); | 211 | I915_WRITE16(I915REG_INT_MASK_R, 0xffff); |
210 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); | 212 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); |
213 | |||
214 | temp = I915_READ16(I915REG_INT_IDENTITY_R); | ||
215 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); | ||
211 | } | 216 | } |
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index 291dbf4c8186..c08fa5076f05 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c | |||
@@ -161,6 +161,7 @@ void r300_init_reg_flags(void) | |||
161 | ADD_RANGE(R300_VAP_PVS_CNTL_1, 3); | 161 | ADD_RANGE(R300_VAP_PVS_CNTL_1, 3); |
162 | ADD_RANGE(R300_GB_ENABLE, 1); | 162 | ADD_RANGE(R300_GB_ENABLE, 1); |
163 | ADD_RANGE(R300_GB_MSPOS0, 5); | 163 | ADD_RANGE(R300_GB_MSPOS0, 5); |
164 | ADD_RANGE(R300_TX_CNTL, 1); | ||
164 | ADD_RANGE(R300_TX_ENABLE, 1); | 165 | ADD_RANGE(R300_TX_ENABLE, 1); |
165 | ADD_RANGE(0x4200, 4); | 166 | ADD_RANGE(0x4200, 4); |
166 | ADD_RANGE(0x4214, 1); | 167 | ADD_RANGE(0x4214, 1); |
@@ -489,6 +490,50 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, | |||
489 | 490 | ||
490 | return 0; | 491 | return 0; |
491 | } | 492 | } |
493 | static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, | ||
494 | drm_radeon_kcmd_buffer_t *cmdbuf) | ||
495 | { | ||
496 | u32 *cmd = (u32 *) cmdbuf->buf; | ||
497 | int count, ret; | ||
498 | RING_LOCALS; | ||
499 | |||
500 | count=(cmd[0]>>16) & 0x3fff; | ||
501 | |||
502 | if (cmd[0] & 0x8000) { | ||
503 | u32 offset; | ||
504 | |||
505 | if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | ||
506 | | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { | ||
507 | offset = cmd[2] << 10; | ||
508 | ret = r300_check_offset(dev_priv, offset); | ||
509 | if (ret) { | ||
510 | DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); | ||
511 | return DRM_ERR(EINVAL); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && | ||
516 | (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { | ||
517 | offset = cmd[3] << 10; | ||
518 | ret = r300_check_offset(dev_priv, offset); | ||
519 | if (ret) { | ||
520 | DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); | ||
521 | return DRM_ERR(EINVAL); | ||
522 | } | ||
523 | |||
524 | } | ||
525 | } | ||
526 | |||
527 | BEGIN_RING(count+2); | ||
528 | OUT_RING(cmd[0]); | ||
529 | OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1); | ||
530 | ADVANCE_RING(); | ||
531 | |||
532 | cmdbuf->buf += (count+2)*4; | ||
533 | cmdbuf->bufsz -= (count+2)*4; | ||
534 | |||
535 | return 0; | ||
536 | } | ||
492 | 537 | ||
493 | static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, | 538 | static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, |
494 | drm_radeon_kcmd_buffer_t *cmdbuf) | 539 | drm_radeon_kcmd_buffer_t *cmdbuf) |
@@ -527,6 +572,9 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, | |||
527 | case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ | 572 | case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ |
528 | return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header); | 573 | return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header); |
529 | 574 | ||
575 | case RADEON_CNTL_BITBLT_MULTI: | ||
576 | return r300_emit_bitblt_multi(dev_priv, cmdbuf); | ||
577 | |||
530 | case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ | 578 | case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ |
531 | case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ | 579 | case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ |
532 | case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ | 580 | case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ |
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h index a0ed20e25221..d1e19954406b 100644 --- a/drivers/char/drm/r300_reg.h +++ b/drivers/char/drm/r300_reg.h | |||
@@ -451,6 +451,9 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
451 | /* END */ | 451 | /* END */ |
452 | 452 | ||
453 | /* gap */ | 453 | /* gap */ |
454 | /* Zero to flush caches. */ | ||
455 | #define R300_TX_CNTL 0x4100 | ||
456 | |||
454 | /* The upper enable bits are guessed, based on fglrx reported limits. */ | 457 | /* The upper enable bits are guessed, based on fglrx reported limits. */ |
455 | #define R300_TX_ENABLE 0x4104 | 458 | #define R300_TX_ENABLE 0x4104 |
456 | # define R300_TX_ENABLE_0 (1 << 0) | 459 | # define R300_TX_ENABLE_0 (1 << 0) |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 498b19b1d641..1f7d2ab8c4fc 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -90,9 +90,10 @@ | |||
90 | * 1.19- Add support for gart table in FB memory and PCIE r300 | 90 | * 1.19- Add support for gart table in FB memory and PCIE r300 |
91 | * 1.20- Add support for r300 texrect | 91 | * 1.20- Add support for r300 texrect |
92 | * 1.21- Add support for card type getparam | 92 | * 1.21- Add support for card type getparam |
93 | * 1.22- Add support for texture cache flushes (R300_TX_CNTL) | ||
93 | */ | 94 | */ |
94 | #define DRIVER_MAJOR 1 | 95 | #define DRIVER_MAJOR 1 |
95 | #define DRIVER_MINOR 21 | 96 | #define DRIVER_MINOR 22 |
96 | #define DRIVER_PATCHLEVEL 0 | 97 | #define DRIVER_PATCHLEVEL 0 |
97 | 98 | ||
98 | /* | 99 | /* |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 57539d8f9f7c..09dc4b01232c 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
@@ -150,17 +150,6 @@ static void rs_wait_until_sent(struct tty_struct *, int); | |||
150 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ | 150 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ |
151 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | 151 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) |
152 | 152 | ||
153 | /* | ||
154 | * tmp_buf is used as a temporary buffer by serial_write. We need to | ||
155 | * lock it in case the memcpy_fromfs blocks while swapping in a page, | ||
156 | * and some other program tries to do a serial write at the same time. | ||
157 | * Since the lock will only come under contention when the system is | ||
158 | * swapping and available memory is low, it makes sense to share one | ||
159 | * buffer across all the serial ports, since it significantly saves | ||
160 | * memory if large numbers of serial ports are open. | ||
161 | */ | ||
162 | static unsigned char *tmp_buf; | ||
163 | |||
164 | static inline int serial_paranoia_check(struct esp_struct *info, | 153 | static inline int serial_paranoia_check(struct esp_struct *info, |
165 | char *name, const char *routine) | 154 | char *name, const char *routine) |
166 | { | 155 | { |
@@ -1267,7 +1256,7 @@ static int rs_write(struct tty_struct * tty, | |||
1267 | if (serial_paranoia_check(info, tty->name, "rs_write")) | 1256 | if (serial_paranoia_check(info, tty->name, "rs_write")) |
1268 | return 0; | 1257 | return 0; |
1269 | 1258 | ||
1270 | if (!tty || !info->xmit_buf || !tmp_buf) | 1259 | if (!tty || !info->xmit_buf) |
1271 | return 0; | 1260 | return 0; |
1272 | 1261 | ||
1273 | while (1) { | 1262 | while (1) { |
@@ -2291,11 +2280,7 @@ static int esp_open(struct tty_struct *tty, struct file * filp) | |||
2291 | tty->driver_data = info; | 2280 | tty->driver_data = info; |
2292 | info->tty = tty; | 2281 | info->tty = tty; |
2293 | 2282 | ||
2294 | if (!tmp_buf) { | 2283 | spin_unlock_irqrestore(&info->lock, flags); |
2295 | tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL); | ||
2296 | if (!tmp_buf) | ||
2297 | return -ENOMEM; | ||
2298 | } | ||
2299 | 2284 | ||
2300 | /* | 2285 | /* |
2301 | * Start up serial port | 2286 | * Start up serial port |
@@ -2602,9 +2587,6 @@ static void __exit espserial_exit(void) | |||
2602 | free_pages((unsigned long)dma_buffer, | 2587 | free_pages((unsigned long)dma_buffer, |
2603 | get_order(DMA_BUFFER_SZ)); | 2588 | get_order(DMA_BUFFER_SZ)); |
2604 | 2589 | ||
2605 | if (tmp_buf) | ||
2606 | free_page((unsigned long)tmp_buf); | ||
2607 | |||
2608 | while (free_pio_buf) { | 2590 | while (free_pio_buf) { |
2609 | pio_buf = free_pio_buf->next; | 2591 | pio_buf = free_pio_buf->next; |
2610 | kfree(free_pio_buf); | 2592 | kfree(free_pio_buf); |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 66a2fee06eb9..ef140ebde117 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -956,22 +956,18 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
956 | } | 956 | } |
957 | } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { | 957 | } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { |
958 | struct acpi_resource_extended_irq *irqp; | 958 | struct acpi_resource_extended_irq *irqp; |
959 | int i; | 959 | int i, irq; |
960 | 960 | ||
961 | irqp = &res->data.extended_irq; | 961 | irqp = &res->data.extended_irq; |
962 | 962 | ||
963 | if (irqp->interrupt_count > 0) { | 963 | for (i = 0; i < irqp->interrupt_count; i++) { |
964 | hdp->hd_nirqs = irqp->interrupt_count; | 964 | irq = acpi_register_gsi(irqp->interrupts[i], |
965 | 965 | irqp->triggering, irqp->polarity); | |
966 | for (i = 0; i < hdp->hd_nirqs; i++) { | 966 | if (irq < 0) |
967 | int rc = | 967 | return AE_ERROR; |
968 | acpi_register_gsi(irqp->interrupts[i], | 968 | |
969 | irqp->triggering, | 969 | hdp->hd_irq[hdp->hd_nirqs] = irq; |
970 | irqp->polarity); | 970 | hdp->hd_nirqs++; |
971 | if (rc < 0) | ||
972 | return AE_ERROR; | ||
973 | hdp->hd_irq[i] = rc; | ||
974 | } | ||
975 | } | 971 | } |
976 | } | 972 | } |
977 | 973 | ||
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 1994a92d4733..f65b2e14a485 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -335,6 +335,8 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
335 | } /* else count == 0 */ | 335 | } /* else count == 0 */ |
336 | 336 | ||
337 | tty->driver_data = hp; | 337 | tty->driver_data = hp; |
338 | tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */ | ||
339 | |||
338 | hp->tty = tty; | 340 | hp->tty = tty; |
339 | /* Save for request_irq outside of spin_lock. */ | 341 | /* Save for request_irq outside of spin_lock. */ |
340 | irq = hp->irq; | 342 | irq = hp->irq; |
@@ -633,9 +635,6 @@ static int hvc_poll(struct hvc_struct *hp) | |||
633 | tty_insert_flip_char(tty, buf[i], 0); | 635 | tty_insert_flip_char(tty, buf[i], 0); |
634 | } | 636 | } |
635 | 637 | ||
636 | if (count) | ||
637 | tty_schedule_flip(tty); | ||
638 | |||
639 | /* | 638 | /* |
640 | * Account for the total amount read in one loop, and if above | 639 | * Account for the total amount read in one loop, and if above |
641 | * 64 bytes, we do a quick schedule loop to let the tty grok | 640 | * 64 bytes, we do a quick schedule loop to let the tty grok |
@@ -656,6 +655,9 @@ static int hvc_poll(struct hvc_struct *hp) | |||
656 | bail: | 655 | bail: |
657 | spin_unlock_irqrestore(&hp->lock, flags); | 656 | spin_unlock_irqrestore(&hp->lock, flags); |
658 | 657 | ||
658 | if (read_total) | ||
659 | tty_flip_buffer_push(tty); | ||
660 | |||
659 | return poll_mask; | 661 | return poll_mask; |
660 | } | 662 | } |
661 | 663 | ||
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c index b3bc2e37e616..29dc87e59020 100644 --- a/drivers/char/hw_random.c +++ b/drivers/char/hw_random.c | |||
@@ -131,7 +131,9 @@ enum { | |||
131 | rng_hw_none, | 131 | rng_hw_none, |
132 | rng_hw_intel, | 132 | rng_hw_intel, |
133 | rng_hw_amd, | 133 | rng_hw_amd, |
134 | #ifdef __i386__ | ||
134 | rng_hw_via, | 135 | rng_hw_via, |
136 | #endif | ||
135 | rng_hw_geode, | 137 | rng_hw_geode, |
136 | }; | 138 | }; |
137 | 139 | ||
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index c92378121b4c..1b05fa688996 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -675,7 +675,7 @@ static int __init mmtimer_init(void) | |||
675 | cnodeid_t node, maxn = -1; | 675 | cnodeid_t node, maxn = -1; |
676 | 676 | ||
677 | if (!ia64_platform_is("sn2")) | 677 | if (!ia64_platform_is("sn2")) |
678 | return -1; | 678 | return 0; |
679 | 679 | ||
680 | /* | 680 | /* |
681 | * Sanity check the cycles/sec variable | 681 | * Sanity check the cycles/sec variable |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 649677b5dc36..5fdf18515433 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -13,11 +13,12 @@ | |||
13 | * | 13 | * |
14 | * (C) 2000,2001,2002,2003,2004 Omnikey AG | 14 | * (C) 2000,2001,2002,2003,2004 Omnikey AG |
15 | * | 15 | * |
16 | * (C) 2005 Harald Welte <laforge@gnumonks.org> | 16 | * (C) 2005-2006 Harald Welte <laforge@gnumonks.org> |
17 | * - Adhere to Kernel CodingStyle | 17 | * - Adhere to Kernel CodingStyle |
18 | * - Port to 2.6.13 "new" style PCMCIA | 18 | * - Port to 2.6.13 "new" style PCMCIA |
19 | * - Check for copy_{from,to}_user return values | 19 | * - Check for copy_{from,to}_user return values |
20 | * - Use nonseekable_open() | 20 | * - Use nonseekable_open() |
21 | * - add class interface for udev device creation | ||
21 | * | 22 | * |
22 | * All rights reserved. Licensed under dual BSD/GPL license. | 23 | * All rights reserved. Licensed under dual BSD/GPL license. |
23 | */ | 24 | */ |
@@ -56,7 +57,7 @@ module_param(pc_debug, int, 0600); | |||
56 | #else | 57 | #else |
57 | #define DEBUGP(n, rdr, x, args...) | 58 | #define DEBUGP(n, rdr, x, args...) |
58 | #endif | 59 | #endif |
59 | static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte"; | 60 | static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte"; |
60 | 61 | ||
61 | #define T_1SEC (HZ) | 62 | #define T_1SEC (HZ) |
62 | #define T_10MSEC msecs_to_jiffies(10) | 63 | #define T_10MSEC msecs_to_jiffies(10) |
@@ -156,6 +157,7 @@ struct cm4000_dev { | |||
156 | /*queue*/ 4*sizeof(wait_queue_head_t)) | 157 | /*queue*/ 4*sizeof(wait_queue_head_t)) |
157 | 158 | ||
158 | static dev_link_t *dev_table[CM4000_MAX_DEV]; | 159 | static dev_link_t *dev_table[CM4000_MAX_DEV]; |
160 | static struct class *cmm_class; | ||
159 | 161 | ||
160 | /* This table doesn't use spaces after the comma between fields and thus | 162 | /* This table doesn't use spaces after the comma between fields and thus |
161 | * violates CodingStyle. However, I don't really think wrapping it around will | 163 | * violates CodingStyle. However, I don't really think wrapping it around will |
@@ -1937,6 +1939,9 @@ static int cm4000_attach(struct pcmcia_device *p_dev) | |||
1937 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 1939 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
1938 | cm4000_config(link, i); | 1940 | cm4000_config(link, i); |
1939 | 1941 | ||
1942 | class_device_create(cmm_class, NULL, MKDEV(major, i), NULL, | ||
1943 | "cmm%d", i); | ||
1944 | |||
1940 | return 0; | 1945 | return 0; |
1941 | } | 1946 | } |
1942 | 1947 | ||
@@ -1962,6 +1967,8 @@ static void cm4000_detach(struct pcmcia_device *p_dev) | |||
1962 | dev_table[devno] = NULL; | 1967 | dev_table[devno] = NULL; |
1963 | kfree(dev); | 1968 | kfree(dev); |
1964 | 1969 | ||
1970 | class_device_destroy(cmm_class, MKDEV(major, devno)); | ||
1971 | |||
1965 | return; | 1972 | return; |
1966 | } | 1973 | } |
1967 | 1974 | ||
@@ -1995,8 +2002,18 @@ static struct pcmcia_driver cm4000_driver = { | |||
1995 | 2002 | ||
1996 | static int __init cmm_init(void) | 2003 | static int __init cmm_init(void) |
1997 | { | 2004 | { |
2005 | int rc; | ||
2006 | |||
1998 | printk(KERN_INFO "%s\n", version); | 2007 | printk(KERN_INFO "%s\n", version); |
1999 | pcmcia_register_driver(&cm4000_driver); | 2008 | |
2009 | cmm_class = class_create(THIS_MODULE, "cardman_4000"); | ||
2010 | if (!cmm_class) | ||
2011 | return -1; | ||
2012 | |||
2013 | rc = pcmcia_register_driver(&cm4000_driver); | ||
2014 | if (rc < 0) | ||
2015 | return rc; | ||
2016 | |||
2000 | major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); | 2017 | major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); |
2001 | if (major < 0) { | 2018 | if (major < 0) { |
2002 | printk(KERN_WARNING MODULE_NAME | 2019 | printk(KERN_WARNING MODULE_NAME |
@@ -2012,6 +2029,7 @@ static void __exit cmm_exit(void) | |||
2012 | printk(KERN_INFO MODULE_NAME ": unloading\n"); | 2029 | printk(KERN_INFO MODULE_NAME ": unloading\n"); |
2013 | pcmcia_unregister_driver(&cm4000_driver); | 2030 | pcmcia_unregister_driver(&cm4000_driver); |
2014 | unregister_chrdev(major, DEVICE_NAME); | 2031 | unregister_chrdev(major, DEVICE_NAME); |
2032 | class_destroy(cmm_class); | ||
2015 | }; | 2033 | }; |
2016 | 2034 | ||
2017 | module_init(cmm_init); | 2035 | module_init(cmm_init); |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 46eb371bf17e..466e33bab029 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -3,12 +3,13 @@ | |||
3 | * | 3 | * |
4 | * (c) 2000-2004 Omnikey AG (http://www.omnikey.com/) | 4 | * (c) 2000-2004 Omnikey AG (http://www.omnikey.com/) |
5 | * | 5 | * |
6 | * (C) 2005 Harald Welte <laforge@gnumonks.org> | 6 | * (C) 2005-2006 Harald Welte <laforge@gnumonks.org> |
7 | * - add support for poll() | 7 | * - add support for poll() |
8 | * - driver cleanup | 8 | * - driver cleanup |
9 | * - add waitqueues | 9 | * - add waitqueues |
10 | * - adhere to linux kernel coding style and policies | 10 | * - adhere to linux kernel coding style and policies |
11 | * - support 2.6.13 "new style" pcmcia interface | 11 | * - support 2.6.13 "new style" pcmcia interface |
12 | * - add class interface for udev device creation | ||
12 | * | 13 | * |
13 | * The device basically is a USB CCID compliant device that has been | 14 | * The device basically is a USB CCID compliant device that has been |
14 | * attached to an I/O-Mapped FIFO. | 15 | * attached to an I/O-Mapped FIFO. |
@@ -53,7 +54,7 @@ module_param(pc_debug, int, 0600); | |||
53 | #endif | 54 | #endif |
54 | 55 | ||
55 | static char *version = | 56 | static char *version = |
56 | "OMNIKEY CardMan 4040 v1.1.0gm4 - All bugs added by Harald Welte"; | 57 | "OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte"; |
57 | 58 | ||
58 | #define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ) | 59 | #define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ) |
59 | #define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ) | 60 | #define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ) |
@@ -67,6 +68,7 @@ static char *version = | |||
67 | static void reader_release(dev_link_t *link); | 68 | static void reader_release(dev_link_t *link); |
68 | 69 | ||
69 | static int major; | 70 | static int major; |
71 | static struct class *cmx_class; | ||
70 | 72 | ||
71 | #define BS_READABLE 0x01 | 73 | #define BS_READABLE 0x01 |
72 | #define BS_WRITABLE 0x02 | 74 | #define BS_WRITABLE 0x02 |
@@ -696,6 +698,9 @@ static int reader_attach(struct pcmcia_device *p_dev) | |||
696 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 698 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
697 | reader_config(link, i); | 699 | reader_config(link, i); |
698 | 700 | ||
701 | class_device_create(cmx_class, NULL, MKDEV(major, i), NULL, | ||
702 | "cmx%d", i); | ||
703 | |||
699 | return 0; | 704 | return 0; |
700 | } | 705 | } |
701 | 706 | ||
@@ -721,6 +726,8 @@ static void reader_detach(struct pcmcia_device *p_dev) | |||
721 | dev_table[devno] = NULL; | 726 | dev_table[devno] = NULL; |
722 | kfree(dev); | 727 | kfree(dev); |
723 | 728 | ||
729 | class_device_destroy(cmx_class, MKDEV(major, devno)); | ||
730 | |||
724 | return; | 731 | return; |
725 | } | 732 | } |
726 | 733 | ||
@@ -755,8 +762,17 @@ static struct pcmcia_driver reader_driver = { | |||
755 | 762 | ||
756 | static int __init cm4040_init(void) | 763 | static int __init cm4040_init(void) |
757 | { | 764 | { |
765 | int rc; | ||
766 | |||
758 | printk(KERN_INFO "%s\n", version); | 767 | printk(KERN_INFO "%s\n", version); |
759 | pcmcia_register_driver(&reader_driver); | 768 | cmx_class = class_create(THIS_MODULE, "cardman_4040"); |
769 | if (!cmx_class) | ||
770 | return -1; | ||
771 | |||
772 | rc = pcmcia_register_driver(&reader_driver); | ||
773 | if (rc < 0) | ||
774 | return rc; | ||
775 | |||
760 | major = register_chrdev(0, DEVICE_NAME, &reader_fops); | 776 | major = register_chrdev(0, DEVICE_NAME, &reader_fops); |
761 | if (major < 0) { | 777 | if (major < 0) { |
762 | printk(KERN_WARNING MODULE_NAME | 778 | printk(KERN_WARNING MODULE_NAME |
@@ -771,6 +787,7 @@ static void __exit cm4040_exit(void) | |||
771 | printk(KERN_INFO MODULE_NAME ": unloading\n"); | 787 | printk(KERN_INFO MODULE_NAME ": unloading\n"); |
772 | pcmcia_unregister_driver(&reader_driver); | 788 | pcmcia_unregister_driver(&reader_driver); |
773 | unregister_chrdev(major, DEVICE_NAME); | 789 | unregister_chrdev(major, DEVICE_NAME); |
790 | class_destroy(cmx_class); | ||
774 | } | 791 | } |
775 | 792 | ||
776 | module_init(cm4040_init); | 793 | module_init(cm4040_init); |
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index 80a5b840e22f..fee68cc895f8 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c | |||
@@ -103,6 +103,7 @@ | |||
103 | 103 | ||
104 | #include <linux/serial.h> | 104 | #include <linux/serial.h> |
105 | #include <linux/generic_serial.h> | 105 | #include <linux/generic_serial.h> |
106 | #include <linux/tty_flip.h> | ||
106 | 107 | ||
107 | #include "ser_a2232.h" | 108 | #include "ser_a2232.h" |
108 | #include "ser_a2232fw.h" | 109 | #include "ser_a2232fw.h" |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index c2490e270f1f..a6b4f02bdceb 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -1095,17 +1095,17 @@ static inline void sx_receive_chars (struct sx_port *port) | |||
1095 | 1095 | ||
1096 | sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); | 1096 | sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); |
1097 | 1097 | ||
1098 | /* Don't copy past the end of the hardware receive buffer */ | ||
1099 | if (rx_op + c > 0x100) c = 0x100 - rx_op; | ||
1100 | |||
1101 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); | ||
1102 | |||
1098 | /* Don't copy more bytes than there is room for in the buffer */ | 1103 | /* Don't copy more bytes than there is room for in the buffer */ |
1099 | 1104 | ||
1100 | c = tty_prepare_flip_string(tty, &rp, c); | 1105 | c = tty_prepare_flip_string(tty, &rp, c); |
1101 | 1106 | ||
1102 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); | 1107 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); |
1103 | 1108 | ||
1104 | /* Don't copy past the end of the hardware receive buffer */ | ||
1105 | if (rx_op + c > 0x100) c = 0x100 - rx_op; | ||
1106 | |||
1107 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); | ||
1108 | |||
1109 | /* If for one reason or another, we can't copy more data, we're done! */ | 1109 | /* If for one reason or another, we can't copy more data, we're done! */ |
1110 | if (c == 0) break; | 1110 | if (c == 0) break; |
1111 | 1111 | ||
@@ -2173,15 +2173,17 @@ static int probe_si (struct sx_board *board) | |||
2173 | if ( IS_SI1_BOARD(board)) { | 2173 | if ( IS_SI1_BOARD(board)) { |
2174 | /* This should be an SI1 board, which has this | 2174 | /* This should be an SI1 board, which has this |
2175 | location writable... */ | 2175 | location writable... */ |
2176 | if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) | 2176 | if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) { |
2177 | func_exit (); | 2177 | func_exit (); |
2178 | return 0; | 2178 | return 0; |
2179 | } | ||
2179 | } else { | 2180 | } else { |
2180 | /* This should be an SI2 board, which has the bottom | 2181 | /* This should be an SI2 board, which has the bottom |
2181 | 3 bits non-writable... */ | 2182 | 3 bits non-writable... */ |
2182 | if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) | 2183 | if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) { |
2183 | func_exit (); | 2184 | func_exit (); |
2184 | return 0; | 2185 | return 0; |
2186 | } | ||
2185 | } | 2187 | } |
2186 | 2188 | ||
2187 | /* Now we're pretty much convinced that there is an SI board here, | 2189 | /* Now we're pretty much convinced that there is an SI board here, |
@@ -2192,15 +2194,17 @@ static int probe_si (struct sx_board *board) | |||
2192 | if ( IS_SI1_BOARD(board)) { | 2194 | if ( IS_SI1_BOARD(board)) { |
2193 | /* This should be an SI1 board, which has this | 2195 | /* This should be an SI1 board, which has this |
2194 | location writable... */ | 2196 | location writable... */ |
2195 | if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) | 2197 | if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) { |
2196 | func_exit(); | 2198 | func_exit(); |
2197 | return 0; | 2199 | return 0; |
2200 | } | ||
2198 | } else { | 2201 | } else { |
2199 | /* This should be an SI2 board, which has the bottom | 2202 | /* This should be an SI2 board, which has the bottom |
2200 | 3 bits non-writable... */ | 2203 | 3 bits non-writable... */ |
2201 | if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) | 2204 | if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) { |
2202 | func_exit (); | 2205 | func_exit (); |
2203 | return 0; | 2206 | return 0; |
2207 | } | ||
2204 | } | 2208 | } |
2205 | 2209 | ||
2206 | printheader (); | 2210 | printheader (); |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index a85a60a93deb..b046390cd256 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -306,7 +306,7 @@ struct slgt_info { | |||
306 | int tx_active; | 306 | int tx_active; |
307 | 307 | ||
308 | unsigned char signals; /* serial signal states */ | 308 | unsigned char signals; /* serial signal states */ |
309 | unsigned int init_error; /* initialization error */ | 309 | int init_error; /* initialization error */ |
310 | 310 | ||
311 | unsigned char *tx_buf; | 311 | unsigned char *tx_buf; |
312 | int tx_count; | 312 | int tx_count; |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 5765f672e853..d58f82318853 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -243,7 +243,7 @@ static struct sysrq_key_op sysrq_term_op = { | |||
243 | 243 | ||
244 | static void moom_callback(void *ignored) | 244 | static void moom_callback(void *ignored) |
245 | { | 245 | { |
246 | out_of_memory(GFP_KERNEL, 0); | 246 | out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL], GFP_KERNEL, 0); |
247 | } | 247 | } |
248 | 248 | ||
249 | static DECLARE_WORK(moom_work, moom_callback, NULL); | 249 | static DECLARE_WORK(moom_work, moom_callback, NULL); |
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 41a94bc79f67..eb2eb3e12d6a 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c | |||
@@ -250,12 +250,17 @@ tipar_open(struct inode *inode, struct file *file) | |||
250 | { | 250 | { |
251 | unsigned int minor = iminor(inode) - TIPAR_MINOR; | 251 | unsigned int minor = iminor(inode) - TIPAR_MINOR; |
252 | 252 | ||
253 | if (minor > tp_count - 1) | 253 | if (tp_count == 0 || minor > tp_count - 1) |
254 | return -ENXIO; | 254 | return -ENXIO; |
255 | 255 | ||
256 | if (test_and_set_bit(minor, &opened)) | 256 | if (test_and_set_bit(minor, &opened)) |
257 | return -EBUSY; | 257 | return -EBUSY; |
258 | 258 | ||
259 | if (!table[minor].dev) { | ||
260 | printk(KERN_ERR "%s: NULL device for minor %u\n", | ||
261 | __FUNCTION__, minor); | ||
262 | return -ENXIO; | ||
263 | } | ||
259 | parport_claim_or_block(table[minor].dev); | 264 | parport_claim_or_block(table[minor].dev); |
260 | init_ti_parallel(minor); | 265 | init_ti_parallel(minor); |
261 | parport_release(table[minor].dev); | 266 | parport_release(table[minor].dev); |
@@ -510,16 +515,20 @@ tipar_init_module(void) | |||
510 | err = PTR_ERR(tipar_class); | 515 | err = PTR_ERR(tipar_class); |
511 | goto out_chrdev; | 516 | goto out_chrdev; |
512 | } | 517 | } |
513 | if (parport_register_driver(&tipar_driver)) { | 518 | if (parport_register_driver(&tipar_driver) || tp_count == 0) { |
514 | printk(KERN_ERR "tipar: unable to register with parport\n"); | 519 | printk(KERN_ERR "tipar: unable to register with parport\n"); |
515 | err = -EIO; | 520 | err = -EIO; |
516 | goto out; | 521 | goto out_class; |
517 | } | 522 | } |
518 | 523 | ||
519 | err = 0; | 524 | err = 0; |
520 | goto out; | 525 | goto out; |
521 | 526 | ||
527 | out_class: | ||
528 | class_destroy(tipar_class); | ||
529 | |||
522 | out_chrdev: | 530 | out_chrdev: |
531 | devfs_remove("ticables/par"); | ||
523 | unregister_chrdev(TIPAR_MAJOR, "tipar"); | 532 | unregister_chrdev(TIPAR_MAJOR, "tipar"); |
524 | out: | 533 | out: |
525 | return err; | 534 | return err; |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index ec7590951af5..24095f6ee6da 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -33,6 +33,7 @@ | |||
33 | static int TPM_INF_DATA; | 33 | static int TPM_INF_DATA; |
34 | static int TPM_INF_ADDR; | 34 | static int TPM_INF_ADDR; |
35 | static int TPM_INF_BASE; | 35 | static int TPM_INF_BASE; |
36 | static int TPM_INF_ADDR_LEN; | ||
36 | static int TPM_INF_PORT_LEN; | 37 | static int TPM_INF_PORT_LEN; |
37 | 38 | ||
38 | /* TPM header definitions */ | 39 | /* TPM header definitions */ |
@@ -195,6 +196,7 @@ static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
195 | int i; | 196 | int i; |
196 | int ret; | 197 | int ret; |
197 | u32 size = 0; | 198 | u32 size = 0; |
199 | number_of_wtx = 0; | ||
198 | 200 | ||
199 | recv_begin: | 201 | recv_begin: |
200 | /* start receiving header */ | 202 | /* start receiving header */ |
@@ -378,24 +380,35 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
378 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && | 380 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && |
379 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { | 381 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { |
380 | TPM_INF_ADDR = pnp_port_start(dev, 0); | 382 | TPM_INF_ADDR = pnp_port_start(dev, 0); |
383 | TPM_INF_ADDR_LEN = pnp_port_len(dev, 0); | ||
381 | TPM_INF_DATA = (TPM_INF_ADDR + 1); | 384 | TPM_INF_DATA = (TPM_INF_ADDR + 1); |
382 | TPM_INF_BASE = pnp_port_start(dev, 1); | 385 | TPM_INF_BASE = pnp_port_start(dev, 1); |
383 | TPM_INF_PORT_LEN = pnp_port_len(dev, 1); | 386 | TPM_INF_PORT_LEN = pnp_port_len(dev, 1); |
384 | if (!TPM_INF_PORT_LEN) | 387 | if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) { |
385 | return -EINVAL; | 388 | rc = -EINVAL; |
389 | goto err_last; | ||
390 | } | ||
386 | dev_info(&dev->dev, "Found %s with ID %s\n", | 391 | dev_info(&dev->dev, "Found %s with ID %s\n", |
387 | dev->name, dev_id->id); | 392 | dev->name, dev_id->id); |
388 | if (!((TPM_INF_BASE >> 8) & 0xff)) | 393 | if (!((TPM_INF_BASE >> 8) & 0xff)) { |
389 | return -EINVAL; | 394 | rc = -EINVAL; |
395 | goto err_last; | ||
396 | } | ||
390 | /* publish my base address and request region */ | 397 | /* publish my base address and request region */ |
391 | tpm_inf.base = TPM_INF_BASE; | 398 | tpm_inf.base = TPM_INF_BASE; |
392 | if (request_region | 399 | if (request_region |
393 | (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { | 400 | (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { |
394 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | 401 | rc = -EINVAL; |
395 | return -EINVAL; | 402 | goto err_last; |
403 | } | ||
404 | if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN, | ||
405 | "tpm_infineon0") == NULL) { | ||
406 | rc = -EINVAL; | ||
407 | goto err_last; | ||
396 | } | 408 | } |
397 | } else { | 409 | } else { |
398 | return -EINVAL; | 410 | rc = -EINVAL; |
411 | goto err_last; | ||
399 | } | 412 | } |
400 | 413 | ||
401 | /* query chip for its vendor, its version number a.s.o. */ | 414 | /* query chip for its vendor, its version number a.s.o. */ |
@@ -443,8 +456,8 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
443 | dev_err(&dev->dev, | 456 | dev_err(&dev->dev, |
444 | "Could not set IO-ports to 0x%lx\n", | 457 | "Could not set IO-ports to 0x%lx\n", |
445 | tpm_inf.base); | 458 | tpm_inf.base); |
446 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | 459 | rc = -EIO; |
447 | return -EIO; | 460 | goto err_release_region; |
448 | } | 461 | } |
449 | 462 | ||
450 | /* activate register */ | 463 | /* activate register */ |
@@ -471,14 +484,21 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
471 | 484 | ||
472 | rc = tpm_register_hardware(&dev->dev, &tpm_inf); | 485 | rc = tpm_register_hardware(&dev->dev, &tpm_inf); |
473 | if (rc < 0) { | 486 | if (rc < 0) { |
474 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | 487 | rc = -ENODEV; |
475 | return -ENODEV; | 488 | goto err_release_region; |
476 | } | 489 | } |
477 | return 0; | 490 | return 0; |
478 | } else { | 491 | } else { |
479 | dev_info(&dev->dev, "No Infineon TPM found!\n"); | 492 | rc = -ENODEV; |
480 | return -ENODEV; | 493 | goto err_release_region; |
481 | } | 494 | } |
495 | |||
496 | err_release_region: | ||
497 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | ||
498 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | ||
499 | |||
500 | err_last: | ||
501 | return rc; | ||
482 | } | 502 | } |
483 | 503 | ||
484 | static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) | 504 | static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) |
@@ -518,5 +538,5 @@ module_exit(cleanup_inf); | |||
518 | 538 | ||
519 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 539 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
520 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 540 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
521 | MODULE_VERSION("1.6"); | 541 | MODULE_VERSION("1.7"); |
522 | MODULE_LICENSE("GPL"); | 542 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 076e07c1da38..53d3d066554e 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -268,6 +268,8 @@ static struct tty_buffer *tty_buffer_alloc(size_t size) | |||
268 | p->size = size; | 268 | p->size = size; |
269 | p->next = NULL; | 269 | p->next = NULL; |
270 | p->active = 0; | 270 | p->active = 0; |
271 | p->commit = 0; | ||
272 | p->read = 0; | ||
271 | p->char_buf_ptr = (char *)(p->data); | 273 | p->char_buf_ptr = (char *)(p->data); |
272 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | 274 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; |
273 | /* printk("Flip create %p\n", p); */ | 275 | /* printk("Flip create %p\n", p); */ |
@@ -298,8 +300,10 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | |||
298 | *tbh = t->next; | 300 | *tbh = t->next; |
299 | t->next = NULL; | 301 | t->next = NULL; |
300 | t->used = 0; | 302 | t->used = 0; |
303 | t->commit = 0; | ||
304 | t->read = 0; | ||
301 | /* DEBUG ONLY */ | 305 | /* DEBUG ONLY */ |
302 | memset(t->data, '*', size); | 306 | /* memset(t->data, '*', size); */ |
303 | /* printk("Flip recycle %p\n", t); */ | 307 | /* printk("Flip recycle %p\n", t); */ |
304 | return t; | 308 | return t; |
305 | } | 309 | } |
@@ -335,6 +339,7 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) | |||
335 | if (b != NULL) { | 339 | if (b != NULL) { |
336 | b->next = n; | 340 | b->next = n; |
337 | b->active = 0; | 341 | b->active = 0; |
342 | b->commit = b->used; | ||
338 | } else | 343 | } else |
339 | tty->buf.head = n; | 344 | tty->buf.head = n; |
340 | tty->buf.tail = n; | 345 | tty->buf.tail = n; |
@@ -1836,7 +1841,6 @@ static void release_dev(struct file * filp) | |||
1836 | tty_closing = tty->count <= 1; | 1841 | tty_closing = tty->count <= 1; |
1837 | o_tty_closing = o_tty && | 1842 | o_tty_closing = o_tty && |
1838 | (o_tty->count <= (pty_master ? 1 : 0)); | 1843 | (o_tty->count <= (pty_master ? 1 : 0)); |
1839 | up(&tty_sem); | ||
1840 | do_sleep = 0; | 1844 | do_sleep = 0; |
1841 | 1845 | ||
1842 | if (tty_closing) { | 1846 | if (tty_closing) { |
@@ -1864,6 +1868,7 @@ static void release_dev(struct file * filp) | |||
1864 | 1868 | ||
1865 | printk(KERN_WARNING "release_dev: %s: read/write wait queue " | 1869 | printk(KERN_WARNING "release_dev: %s: read/write wait queue " |
1866 | "active!\n", tty_name(tty, buf)); | 1870 | "active!\n", tty_name(tty, buf)); |
1871 | up(&tty_sem); | ||
1867 | schedule(); | 1872 | schedule(); |
1868 | } | 1873 | } |
1869 | 1874 | ||
@@ -1872,8 +1877,6 @@ static void release_dev(struct file * filp) | |||
1872 | * both sides, and we've completed the last operation that could | 1877 | * both sides, and we've completed the last operation that could |
1873 | * block, so it's safe to proceed with closing. | 1878 | * block, so it's safe to proceed with closing. |
1874 | */ | 1879 | */ |
1875 | |||
1876 | down(&tty_sem); | ||
1877 | if (pty_master) { | 1880 | if (pty_master) { |
1878 | if (--o_tty->count < 0) { | 1881 | if (--o_tty->count < 0) { |
1879 | printk(KERN_WARNING "release_dev: bad pty slave count " | 1882 | printk(KERN_WARNING "release_dev: bad pty slave count " |
@@ -1887,7 +1890,6 @@ static void release_dev(struct file * filp) | |||
1887 | tty->count, tty_name(tty, buf)); | 1890 | tty->count, tty_name(tty, buf)); |
1888 | tty->count = 0; | 1891 | tty->count = 0; |
1889 | } | 1892 | } |
1890 | up(&tty_sem); | ||
1891 | 1893 | ||
1892 | /* | 1894 | /* |
1893 | * We've decremented tty->count, so we need to remove this file | 1895 | * We've decremented tty->count, so we need to remove this file |
@@ -1932,6 +1934,8 @@ static void release_dev(struct file * filp) | |||
1932 | read_unlock(&tasklist_lock); | 1934 | read_unlock(&tasklist_lock); |
1933 | } | 1935 | } |
1934 | 1936 | ||
1937 | up(&tty_sem); | ||
1938 | |||
1935 | /* check whether both sides are closing ... */ | 1939 | /* check whether both sides are closing ... */ |
1936 | if (!tty_closing || (o_tty && !o_tty_closing)) | 1940 | if (!tty_closing || (o_tty && !o_tty_closing)) |
1937 | return; | 1941 | return; |
@@ -2752,6 +2756,9 @@ static void flush_to_ldisc(void *private_) | |||
2752 | unsigned long flags; | 2756 | unsigned long flags; |
2753 | struct tty_ldisc *disc; | 2757 | struct tty_ldisc *disc; |
2754 | struct tty_buffer *tbuf; | 2758 | struct tty_buffer *tbuf; |
2759 | int count; | ||
2760 | char *char_buf; | ||
2761 | unsigned char *flag_buf; | ||
2755 | 2762 | ||
2756 | disc = tty_ldisc_ref(tty); | 2763 | disc = tty_ldisc_ref(tty); |
2757 | if (disc == NULL) /* !TTY_LDISC */ | 2764 | if (disc == NULL) /* !TTY_LDISC */ |
@@ -2765,16 +2772,20 @@ static void flush_to_ldisc(void *private_) | |||
2765 | goto out; | 2772 | goto out; |
2766 | } | 2773 | } |
2767 | spin_lock_irqsave(&tty->buf.lock, flags); | 2774 | spin_lock_irqsave(&tty->buf.lock, flags); |
2768 | while((tbuf = tty->buf.head) != NULL && !tbuf->active) { | 2775 | while((tbuf = tty->buf.head) != NULL) { |
2776 | while ((count = tbuf->commit - tbuf->read) != 0) { | ||
2777 | char_buf = tbuf->char_buf_ptr + tbuf->read; | ||
2778 | flag_buf = tbuf->flag_buf_ptr + tbuf->read; | ||
2779 | tbuf->read += count; | ||
2780 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
2781 | disc->receive_buf(tty, char_buf, flag_buf, count); | ||
2782 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
2783 | } | ||
2784 | if (tbuf->active) | ||
2785 | break; | ||
2769 | tty->buf.head = tbuf->next; | 2786 | tty->buf.head = tbuf->next; |
2770 | if (tty->buf.head == NULL) | 2787 | if (tty->buf.head == NULL) |
2771 | tty->buf.tail = NULL; | 2788 | tty->buf.tail = NULL; |
2772 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
2773 | /* printk("Process buffer %p for %d\n", tbuf, tbuf->used); */ | ||
2774 | disc->receive_buf(tty, tbuf->char_buf_ptr, | ||
2775 | tbuf->flag_buf_ptr, | ||
2776 | tbuf->used); | ||
2777 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
2778 | tty_buffer_free(tty, tbuf); | 2789 | tty_buffer_free(tty, tbuf); |
2779 | } | 2790 | } |
2780 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 2791 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
@@ -2871,8 +2882,10 @@ void tty_flip_buffer_push(struct tty_struct *tty) | |||
2871 | { | 2882 | { |
2872 | unsigned long flags; | 2883 | unsigned long flags; |
2873 | spin_lock_irqsave(&tty->buf.lock, flags); | 2884 | spin_lock_irqsave(&tty->buf.lock, flags); |
2874 | if (tty->buf.tail != NULL) | 2885 | if (tty->buf.tail != NULL) { |
2875 | tty->buf.tail->active = 0; | 2886 | tty->buf.tail->active = 0; |
2887 | tty->buf.tail->commit = tty->buf.tail->used; | ||
2888 | } | ||
2876 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 2889 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
2877 | 2890 | ||
2878 | if (tty->low_latency) | 2891 | if (tty->low_latency) |
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c index 37c9e13ad3ac..8d6b249ad66b 100644 --- a/drivers/char/watchdog/pcwd.c +++ b/drivers/char/watchdog/pcwd.c | |||
@@ -49,29 +49,37 @@ | |||
49 | * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ | 49 | * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ |
50 | */ | 50 | */ |
51 | 51 | ||
52 | #include <linux/module.h> | 52 | #include <linux/config.h> /* For CONFIG_WATCHDOG_NOWAYOUT/... */ |
53 | #include <linux/moduleparam.h> | 53 | #include <linux/module.h> /* For module specific items */ |
54 | #include <linux/types.h> | 54 | #include <linux/moduleparam.h> /* For new moduleparam's */ |
55 | #include <linux/timer.h> | 55 | #include <linux/types.h> /* For standard types (like size_t) */ |
56 | #include <linux/jiffies.h> | 56 | #include <linux/errno.h> /* For the -ENODEV/... values */ |
57 | #include <linux/config.h> | 57 | #include <linux/kernel.h> /* For printk/panic/... */ |
58 | #include <linux/wait.h> | 58 | #include <linux/delay.h> /* For mdelay function */ |
59 | #include <linux/slab.h> | 59 | #include <linux/timer.h> /* For timer related operations */ |
60 | #include <linux/ioport.h> | 60 | #include <linux/jiffies.h> /* For jiffies stuff */ |
61 | #include <linux/delay.h> | 61 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ |
62 | #include <linux/fs.h> | 62 | #include <linux/watchdog.h> /* For the watchdog specific items */ |
63 | #include <linux/miscdevice.h> | 63 | #include <linux/notifier.h> /* For notifier support */ |
64 | #include <linux/watchdog.h> | 64 | #include <linux/reboot.h> /* For reboot_notifier stuff */ |
65 | #include <linux/notifier.h> | 65 | #include <linux/init.h> /* For __init/__exit/... */ |
66 | #include <linux/init.h> | 66 | #include <linux/fs.h> /* For file operations */ |
67 | #include <linux/spinlock.h> | 67 | #include <linux/ioport.h> /* For io-port access */ |
68 | #include <linux/reboot.h> | 68 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
69 | #include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */ | 69 | #include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */ |
70 | #include <asm/uaccess.h> | 70 | #include <linux/slab.h> /* For kmalloc */ |
71 | #include <asm/io.h> | ||
72 | 71 | ||
73 | #define WD_VER "1.16 (06/12/2004)" | 72 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ |
74 | #define PFX "pcwd: " | 73 | #include <asm/io.h> /* For inb/outb/... */ |
74 | |||
75 | /* Module and version information */ | ||
76 | #define WATCHDOG_VERSION "1.16" | ||
77 | #define WATCHDOG_DATE "03 Jan 2006" | ||
78 | #define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" | ||
79 | #define WATCHDOG_NAME "pcwd" | ||
80 | #define PFX WATCHDOG_NAME ": " | ||
81 | #define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION " (" WATCHDOG_DATE ")\n" | ||
82 | #define WD_VER WATCHDOG_VERSION " (" WATCHDOG_DATE ")" | ||
75 | 83 | ||
76 | /* | 84 | /* |
77 | * It should be noted that PCWD_REVISION_B was removed because A and B | 85 | * It should be noted that PCWD_REVISION_B was removed because A and B |
@@ -85,36 +93,38 @@ | |||
85 | 93 | ||
86 | /* | 94 | /* |
87 | * These are the defines that describe the control status bits for the | 95 | * These are the defines that describe the control status bits for the |
88 | * PC Watchdog card, revision A. | 96 | * PCI-PC Watchdog card. |
89 | */ | 97 | */ |
98 | /* Port 1 : Control Status #1 for the PC Watchdog card, revision A. */ | ||
90 | #define WD_WDRST 0x01 /* Previously reset state */ | 99 | #define WD_WDRST 0x01 /* Previously reset state */ |
91 | #define WD_T110 0x02 /* Temperature overheat sense */ | 100 | #define WD_T110 0x02 /* Temperature overheat sense */ |
92 | #define WD_HRTBT 0x04 /* Heartbeat sense */ | 101 | #define WD_HRTBT 0x04 /* Heartbeat sense */ |
93 | #define WD_RLY2 0x08 /* External relay triggered */ | 102 | #define WD_RLY2 0x08 /* External relay triggered */ |
94 | #define WD_SRLY2 0x80 /* Software external relay triggered */ | 103 | #define WD_SRLY2 0x80 /* Software external relay triggered */ |
95 | 104 | /* Port 1 : Control Status #1 for the PC Watchdog card, revision C. */ | |
96 | /* | ||
97 | * These are the defines that describe the control status bits for the | ||
98 | * PC Watchdog card, revision C. | ||
99 | */ | ||
100 | #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ | 105 | #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ |
101 | #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ | 106 | #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ |
102 | #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ | 107 | #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ |
108 | /* Port 2 : Control Status #2 */ | ||
109 | #define WD_WDIS 0x10 /* Watchdog Disabled */ | ||
110 | #define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ | ||
111 | #define WD_SSEL 0x40 /* Watchdog Switch Select (1:SW1 <-> 0:SW2) */ | ||
112 | #define WD_WCMD 0x80 /* Watchdog Command Mode */ | ||
103 | 113 | ||
104 | /* max. time we give an ISA watchdog card to process a command */ | 114 | /* max. time we give an ISA watchdog card to process a command */ |
105 | /* 500ms for each 4 bit response (according to spec.) */ | 115 | /* 500ms for each 4 bit response (according to spec.) */ |
106 | #define ISA_COMMAND_TIMEOUT 1000 | 116 | #define ISA_COMMAND_TIMEOUT 1000 |
107 | 117 | ||
108 | /* Watchdog's internal commands */ | 118 | /* Watchdog's internal commands */ |
109 | #define CMD_ISA_IDLE 0x00 | 119 | #define CMD_ISA_IDLE 0x00 |
110 | #define CMD_ISA_VERSION_INTEGER 0x01 | 120 | #define CMD_ISA_VERSION_INTEGER 0x01 |
111 | #define CMD_ISA_VERSION_TENTH 0x02 | 121 | #define CMD_ISA_VERSION_TENTH 0x02 |
112 | #define CMD_ISA_VERSION_HUNDRETH 0x03 | 122 | #define CMD_ISA_VERSION_HUNDRETH 0x03 |
113 | #define CMD_ISA_VERSION_MINOR 0x04 | 123 | #define CMD_ISA_VERSION_MINOR 0x04 |
114 | #define CMD_ISA_SWITCH_SETTINGS 0x05 | 124 | #define CMD_ISA_SWITCH_SETTINGS 0x05 |
115 | #define CMD_ISA_DELAY_TIME_2SECS 0x0A | 125 | #define CMD_ISA_DELAY_TIME_2SECS 0x0A |
116 | #define CMD_ISA_DELAY_TIME_4SECS 0x0B | 126 | #define CMD_ISA_DELAY_TIME_4SECS 0x0B |
117 | #define CMD_ISA_DELAY_TIME_8SECS 0x0C | 127 | #define CMD_ISA_DELAY_TIME_8SECS 0x0C |
118 | 128 | ||
119 | /* | 129 | /* |
120 | * We are using an kernel timer to do the pinging of the watchdog | 130 | * We are using an kernel timer to do the pinging of the watchdog |
@@ -130,15 +140,17 @@ static int cards_found; | |||
130 | /* internal variables */ | 140 | /* internal variables */ |
131 | static atomic_t open_allowed = ATOMIC_INIT(1); | 141 | static atomic_t open_allowed = ATOMIC_INIT(1); |
132 | static char expect_close; | 142 | static char expect_close; |
133 | static struct timer_list timer; | ||
134 | static unsigned long next_heartbeat; | ||
135 | static int temp_panic; | 143 | static int temp_panic; |
136 | static int revision; /* The card's revision */ | 144 | static struct { /* this is private data for each ISA-PC watchdog card */ |
137 | static int supports_temp; /* Wether or not the card has a temperature device */ | 145 | int revision; /* The card's revision */ |
138 | static int command_mode; /* Wether or not the card is in command mode */ | 146 | int supports_temp; /* Wether or not the card has a temperature device */ |
139 | static int initial_status; /* The card's boot status */ | 147 | int command_mode; /* Wether or not the card is in command mode */ |
140 | static int current_readport; /* The cards I/O address */ | 148 | int boot_status; /* The card's boot status */ |
141 | static spinlock_t io_lock; | 149 | int io_addr; /* The cards I/O address */ |
150 | spinlock_t io_lock; /* the lock for io operations */ | ||
151 | struct timer_list timer; /* The timer that pings the watchdog */ | ||
152 | unsigned long next_heartbeat; /* the next_heartbeat for the timer */ | ||
153 | } pcwd_private; | ||
142 | 154 | ||
143 | /* module parameters */ | 155 | /* module parameters */ |
144 | #define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ | 156 | #define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ |
@@ -161,14 +173,14 @@ static int send_isa_command(int cmd) | |||
161 | int port0, last_port0; /* Double read for stabilising */ | 173 | int port0, last_port0; /* Double read for stabilising */ |
162 | 174 | ||
163 | /* The WCMD bit must be 1 and the command is only 4 bits in size */ | 175 | /* The WCMD bit must be 1 and the command is only 4 bits in size */ |
164 | control_status = (cmd & 0x0F) | 0x80; | 176 | control_status = (cmd & 0x0F) | WD_WCMD; |
165 | outb_p(control_status, current_readport + 2); | 177 | outb_p(control_status, pcwd_private.io_addr + 2); |
166 | udelay(ISA_COMMAND_TIMEOUT); | 178 | udelay(ISA_COMMAND_TIMEOUT); |
167 | 179 | ||
168 | port0 = inb_p(current_readport); | 180 | port0 = inb_p(pcwd_private.io_addr); |
169 | for (i = 0; i < 25; ++i) { | 181 | for (i = 0; i < 25; ++i) { |
170 | last_port0 = port0; | 182 | last_port0 = port0; |
171 | port0 = inb_p(current_readport); | 183 | port0 = inb_p(pcwd_private.io_addr); |
172 | 184 | ||
173 | if (port0 == last_port0) | 185 | if (port0 == last_port0) |
174 | break; /* Data is stable */ | 186 | break; /* Data is stable */ |
@@ -184,7 +196,7 @@ static int set_command_mode(void) | |||
184 | int i, found=0, count=0; | 196 | int i, found=0, count=0; |
185 | 197 | ||
186 | /* Set the card into command mode */ | 198 | /* Set the card into command mode */ |
187 | spin_lock(&io_lock); | 199 | spin_lock(&pcwd_private.io_lock); |
188 | while ((!found) && (count < 3)) { | 200 | while ((!found) && (count < 3)) { |
189 | i = send_isa_command(CMD_ISA_IDLE); | 201 | i = send_isa_command(CMD_ISA_IDLE); |
190 | 202 | ||
@@ -192,15 +204,15 @@ static int set_command_mode(void) | |||
192 | found = 1; | 204 | found = 1; |
193 | else if (i == 0xF3) { | 205 | else if (i == 0xF3) { |
194 | /* Card does not like what we've done to it */ | 206 | /* Card does not like what we've done to it */ |
195 | outb_p(0x00, current_readport + 2); | 207 | outb_p(0x00, pcwd_private.io_addr + 2); |
196 | udelay(1200); /* Spec says wait 1ms */ | 208 | udelay(1200); /* Spec says wait 1ms */ |
197 | outb_p(0x00, current_readport + 2); | 209 | outb_p(0x00, pcwd_private.io_addr + 2); |
198 | udelay(ISA_COMMAND_TIMEOUT); | 210 | udelay(ISA_COMMAND_TIMEOUT); |
199 | } | 211 | } |
200 | count++; | 212 | count++; |
201 | } | 213 | } |
202 | spin_unlock(&io_lock); | 214 | spin_unlock(&pcwd_private.io_lock); |
203 | command_mode = found; | 215 | pcwd_private.command_mode = found; |
204 | 216 | ||
205 | return(found); | 217 | return(found); |
206 | } | 218 | } |
@@ -208,12 +220,95 @@ static int set_command_mode(void) | |||
208 | static void unset_command_mode(void) | 220 | static void unset_command_mode(void) |
209 | { | 221 | { |
210 | /* Set the card into normal mode */ | 222 | /* Set the card into normal mode */ |
211 | spin_lock(&io_lock); | 223 | spin_lock(&pcwd_private.io_lock); |
212 | outb_p(0x00, current_readport + 2); | 224 | outb_p(0x00, pcwd_private.io_addr + 2); |
213 | udelay(ISA_COMMAND_TIMEOUT); | 225 | udelay(ISA_COMMAND_TIMEOUT); |
214 | spin_unlock(&io_lock); | 226 | spin_unlock(&pcwd_private.io_lock); |
227 | |||
228 | pcwd_private.command_mode = 0; | ||
229 | } | ||
230 | |||
231 | static inline void pcwd_check_temperature_support(void) | ||
232 | { | ||
233 | if (inb(pcwd_private.io_addr) != 0xF0) | ||
234 | pcwd_private.supports_temp = 1; | ||
235 | } | ||
236 | |||
237 | static inline char *get_firmware(void) | ||
238 | { | ||
239 | int one, ten, hund, minor; | ||
240 | char *ret; | ||
241 | |||
242 | ret = kmalloc(6, GFP_KERNEL); | ||
243 | if(ret == NULL) | ||
244 | return NULL; | ||
245 | |||
246 | if (set_command_mode()) { | ||
247 | one = send_isa_command(CMD_ISA_VERSION_INTEGER); | ||
248 | ten = send_isa_command(CMD_ISA_VERSION_TENTH); | ||
249 | hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); | ||
250 | minor = send_isa_command(CMD_ISA_VERSION_MINOR); | ||
251 | sprintf(ret, "%c.%c%c%c", one, ten, hund, minor); | ||
252 | } | ||
253 | else | ||
254 | sprintf(ret, "ERROR"); | ||
255 | |||
256 | unset_command_mode(); | ||
257 | return(ret); | ||
258 | } | ||
259 | |||
260 | static inline int pcwd_get_option_switches(void) | ||
261 | { | ||
262 | int option_switches=0; | ||
263 | |||
264 | if (set_command_mode()) { | ||
265 | /* Get switch settings */ | ||
266 | option_switches = send_isa_command(CMD_ISA_SWITCH_SETTINGS); | ||
267 | } | ||
268 | |||
269 | unset_command_mode(); | ||
270 | return(option_switches); | ||
271 | } | ||
272 | |||
273 | static void pcwd_show_card_info(void) | ||
274 | { | ||
275 | char *firmware; | ||
276 | int option_switches; | ||
277 | |||
278 | /* Get some extra info from the hardware (in command/debug/diag mode) */ | ||
279 | if (pcwd_private.revision == PCWD_REVISION_A) | ||
280 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr); | ||
281 | else if (pcwd_private.revision == PCWD_REVISION_C) { | ||
282 | firmware = get_firmware(); | ||
283 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", | ||
284 | pcwd_private.io_addr, firmware); | ||
285 | kfree(firmware); | ||
286 | option_switches = pcwd_get_option_switches(); | ||
287 | printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", | ||
288 | option_switches, | ||
289 | ((option_switches & 0x10) ? "ON" : "OFF"), | ||
290 | ((option_switches & 0x08) ? "ON" : "OFF")); | ||
291 | |||
292 | /* Reprogram internal heartbeat to 2 seconds */ | ||
293 | if (set_command_mode()) { | ||
294 | send_isa_command(CMD_ISA_DELAY_TIME_2SECS); | ||
295 | unset_command_mode(); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | if (pcwd_private.supports_temp) | ||
300 | printk(KERN_INFO PFX "Temperature Option Detected\n"); | ||
301 | |||
302 | if (pcwd_private.boot_status & WDIOF_CARDRESET) | ||
303 | printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); | ||
304 | |||
305 | if (pcwd_private.boot_status & WDIOF_OVERHEAT) { | ||
306 | printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n"); | ||
307 | printk(KERN_EMERG PFX "CPU Overheat\n"); | ||
308 | } | ||
215 | 309 | ||
216 | command_mode = 0; | 310 | if (pcwd_private.boot_status == 0) |
311 | printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); | ||
217 | } | 312 | } |
218 | 313 | ||
219 | static void pcwd_timer_ping(unsigned long data) | 314 | static void pcwd_timer_ping(unsigned long data) |
@@ -222,25 +317,25 @@ static void pcwd_timer_ping(unsigned long data) | |||
222 | 317 | ||
223 | /* If we got a heartbeat pulse within the WDT_INTERVAL | 318 | /* If we got a heartbeat pulse within the WDT_INTERVAL |
224 | * we agree to ping the WDT */ | 319 | * we agree to ping the WDT */ |
225 | if(time_before(jiffies, next_heartbeat)) { | 320 | if(time_before(jiffies, pcwd_private.next_heartbeat)) { |
226 | /* Ping the watchdog */ | 321 | /* Ping the watchdog */ |
227 | spin_lock(&io_lock); | 322 | spin_lock(&pcwd_private.io_lock); |
228 | if (revision == PCWD_REVISION_A) { | 323 | if (pcwd_private.revision == PCWD_REVISION_A) { |
229 | /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */ | 324 | /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */ |
230 | wdrst_stat = inb_p(current_readport); | 325 | wdrst_stat = inb_p(pcwd_private.io_addr); |
231 | wdrst_stat &= 0x0F; | 326 | wdrst_stat &= 0x0F; |
232 | wdrst_stat |= WD_WDRST; | 327 | wdrst_stat |= WD_WDRST; |
233 | 328 | ||
234 | outb_p(wdrst_stat, current_readport + 1); | 329 | outb_p(wdrst_stat, pcwd_private.io_addr + 1); |
235 | } else { | 330 | } else { |
236 | /* Re-trigger watchdog by writing to port 0 */ | 331 | /* Re-trigger watchdog by writing to port 0 */ |
237 | outb_p(0x00, current_readport); | 332 | outb_p(0x00, pcwd_private.io_addr); |
238 | } | 333 | } |
239 | 334 | ||
240 | /* Re-set the timer interval */ | 335 | /* Re-set the timer interval */ |
241 | mod_timer(&timer, jiffies + WDT_INTERVAL); | 336 | mod_timer(&pcwd_private.timer, jiffies + WDT_INTERVAL); |
242 | 337 | ||
243 | spin_unlock(&io_lock); | 338 | spin_unlock(&pcwd_private.io_lock); |
244 | } else { | 339 | } else { |
245 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 340 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); |
246 | } | 341 | } |
@@ -250,19 +345,19 @@ static int pcwd_start(void) | |||
250 | { | 345 | { |
251 | int stat_reg; | 346 | int stat_reg; |
252 | 347 | ||
253 | next_heartbeat = jiffies + (heartbeat * HZ); | 348 | pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ); |
254 | 349 | ||
255 | /* Start the timer */ | 350 | /* Start the timer */ |
256 | mod_timer(&timer, jiffies + WDT_INTERVAL); | 351 | mod_timer(&pcwd_private.timer, jiffies + WDT_INTERVAL); |
257 | 352 | ||
258 | /* Enable the port */ | 353 | /* Enable the port */ |
259 | if (revision == PCWD_REVISION_C) { | 354 | if (pcwd_private.revision == PCWD_REVISION_C) { |
260 | spin_lock(&io_lock); | 355 | spin_lock(&pcwd_private.io_lock); |
261 | outb_p(0x00, current_readport + 3); | 356 | outb_p(0x00, pcwd_private.io_addr + 3); |
262 | udelay(ISA_COMMAND_TIMEOUT); | 357 | udelay(ISA_COMMAND_TIMEOUT); |
263 | stat_reg = inb_p(current_readport + 2); | 358 | stat_reg = inb_p(pcwd_private.io_addr + 2); |
264 | spin_unlock(&io_lock); | 359 | spin_unlock(&pcwd_private.io_lock); |
265 | if (stat_reg & 0x10) { | 360 | if (stat_reg & WD_WDIS) { |
266 | printk(KERN_INFO PFX "Could not start watchdog\n"); | 361 | printk(KERN_INFO PFX "Could not start watchdog\n"); |
267 | return -EIO; | 362 | return -EIO; |
268 | } | 363 | } |
@@ -275,18 +370,18 @@ static int pcwd_stop(void) | |||
275 | int stat_reg; | 370 | int stat_reg; |
276 | 371 | ||
277 | /* Stop the timer */ | 372 | /* Stop the timer */ |
278 | del_timer(&timer); | 373 | del_timer(&pcwd_private.timer); |
279 | 374 | ||
280 | /* Disable the board */ | 375 | /* Disable the board */ |
281 | if (revision == PCWD_REVISION_C) { | 376 | if (pcwd_private.revision == PCWD_REVISION_C) { |
282 | spin_lock(&io_lock); | 377 | spin_lock(&pcwd_private.io_lock); |
283 | outb_p(0xA5, current_readport + 3); | 378 | outb_p(0xA5, pcwd_private.io_addr + 3); |
284 | udelay(ISA_COMMAND_TIMEOUT); | 379 | udelay(ISA_COMMAND_TIMEOUT); |
285 | outb_p(0xA5, current_readport + 3); | 380 | outb_p(0xA5, pcwd_private.io_addr + 3); |
286 | udelay(ISA_COMMAND_TIMEOUT); | 381 | udelay(ISA_COMMAND_TIMEOUT); |
287 | stat_reg = inb_p(current_readport + 2); | 382 | stat_reg = inb_p(pcwd_private.io_addr + 2); |
288 | spin_unlock(&io_lock); | 383 | spin_unlock(&pcwd_private.io_lock); |
289 | if ((stat_reg & 0x10) == 0) { | 384 | if ((stat_reg & WD_WDIS) == 0) { |
290 | printk(KERN_INFO PFX "Could not stop watchdog\n"); | 385 | printk(KERN_INFO PFX "Could not stop watchdog\n"); |
291 | return -EIO; | 386 | return -EIO; |
292 | } | 387 | } |
@@ -297,7 +392,7 @@ static int pcwd_stop(void) | |||
297 | static int pcwd_keepalive(void) | 392 | static int pcwd_keepalive(void) |
298 | { | 393 | { |
299 | /* user land ping */ | 394 | /* user land ping */ |
300 | next_heartbeat = jiffies + (heartbeat * HZ); | 395 | pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ); |
301 | return 0; | 396 | return 0; |
302 | } | 397 | } |
303 | 398 | ||
@@ -315,23 +410,23 @@ static int pcwd_get_status(int *status) | |||
315 | int card_status; | 410 | int card_status; |
316 | 411 | ||
317 | *status=0; | 412 | *status=0; |
318 | spin_lock(&io_lock); | 413 | spin_lock(&pcwd_private.io_lock); |
319 | if (revision == PCWD_REVISION_A) | 414 | if (pcwd_private.revision == PCWD_REVISION_A) |
320 | /* Rev A cards return status information from | 415 | /* Rev A cards return status information from |
321 | * the base register, which is used for the | 416 | * the base register, which is used for the |
322 | * temperature in other cards. */ | 417 | * temperature in other cards. */ |
323 | card_status = inb(current_readport); | 418 | card_status = inb(pcwd_private.io_addr); |
324 | else { | 419 | else { |
325 | /* Rev C cards return card status in the base | 420 | /* Rev C cards return card status in the base |
326 | * address + 1 register. And use different bits | 421 | * address + 1 register. And use different bits |
327 | * to indicate a card initiated reset, and an | 422 | * to indicate a card initiated reset, and an |
328 | * over-temperature condition. And the reboot | 423 | * over-temperature condition. And the reboot |
329 | * status can be reset. */ | 424 | * status can be reset. */ |
330 | card_status = inb(current_readport + 1); | 425 | card_status = inb(pcwd_private.io_addr + 1); |
331 | } | 426 | } |
332 | spin_unlock(&io_lock); | 427 | spin_unlock(&pcwd_private.io_lock); |
333 | 428 | ||
334 | if (revision == PCWD_REVISION_A) { | 429 | if (pcwd_private.revision == PCWD_REVISION_A) { |
335 | if (card_status & WD_WDRST) | 430 | if (card_status & WD_WDRST) |
336 | *status |= WDIOF_CARDRESET; | 431 | *status |= WDIOF_CARDRESET; |
337 | 432 | ||
@@ -360,10 +455,10 @@ static int pcwd_get_status(int *status) | |||
360 | 455 | ||
361 | static int pcwd_clear_status(void) | 456 | static int pcwd_clear_status(void) |
362 | { | 457 | { |
363 | if (revision == PCWD_REVISION_C) { | 458 | if (pcwd_private.revision == PCWD_REVISION_C) { |
364 | spin_lock(&io_lock); | 459 | spin_lock(&pcwd_private.io_lock); |
365 | outb_p(0x00, current_readport + 1); /* clear reset status */ | 460 | outb_p(0x00, pcwd_private.io_addr + 1); /* clear reset status */ |
366 | spin_unlock(&io_lock); | 461 | spin_unlock(&pcwd_private.io_lock); |
367 | } | 462 | } |
368 | return 0; | 463 | return 0; |
369 | } | 464 | } |
@@ -371,20 +466,20 @@ static int pcwd_clear_status(void) | |||
371 | static int pcwd_get_temperature(int *temperature) | 466 | static int pcwd_get_temperature(int *temperature) |
372 | { | 467 | { |
373 | /* check that port 0 gives temperature info and no command results */ | 468 | /* check that port 0 gives temperature info and no command results */ |
374 | if (command_mode) | 469 | if (pcwd_private.command_mode) |
375 | return -1; | 470 | return -1; |
376 | 471 | ||
377 | *temperature = 0; | 472 | *temperature = 0; |
378 | if (!supports_temp) | 473 | if (!pcwd_private.supports_temp) |
379 | return -ENODEV; | 474 | return -ENODEV; |
380 | 475 | ||
381 | /* | 476 | /* |
382 | * Convert celsius to fahrenheit, since this was | 477 | * Convert celsius to fahrenheit, since this was |
383 | * the decided 'standard' for this return value. | 478 | * the decided 'standard' for this return value. |
384 | */ | 479 | */ |
385 | spin_lock(&io_lock); | 480 | spin_lock(&pcwd_private.io_lock); |
386 | *temperature = ((inb(current_readport)) * 9 / 5) + 32; | 481 | *temperature = ((inb(pcwd_private.io_addr)) * 9 / 5) + 32; |
387 | spin_unlock(&io_lock); | 482 | spin_unlock(&pcwd_private.io_lock); |
388 | 483 | ||
389 | return 0; | 484 | return 0; |
390 | } | 485 | } |
@@ -425,7 +520,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, | |||
425 | return put_user(status, argp); | 520 | return put_user(status, argp); |
426 | 521 | ||
427 | case WDIOC_GETBOOTSTATUS: | 522 | case WDIOC_GETBOOTSTATUS: |
428 | return put_user(initial_status, argp); | 523 | return put_user(pcwd_private.boot_status, argp); |
429 | 524 | ||
430 | case WDIOC_GETTEMP: | 525 | case WDIOC_GETTEMP: |
431 | if (pcwd_get_temperature(&temperature)) | 526 | if (pcwd_get_temperature(&temperature)) |
@@ -434,7 +529,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, | |||
434 | return put_user(temperature, argp); | 529 | return put_user(temperature, argp); |
435 | 530 | ||
436 | case WDIOC_SETOPTIONS: | 531 | case WDIOC_SETOPTIONS: |
437 | if (revision == PCWD_REVISION_C) | 532 | if (pcwd_private.revision == PCWD_REVISION_C) |
438 | { | 533 | { |
439 | if(copy_from_user(&rv, argp, sizeof(int))) | 534 | if(copy_from_user(&rv, argp, sizeof(int))) |
440 | return -EFAULT; | 535 | return -EFAULT; |
@@ -550,7 +645,7 @@ static ssize_t pcwd_temp_read(struct file *file, char __user *buf, size_t count, | |||
550 | 645 | ||
551 | static int pcwd_temp_open(struct inode *inode, struct file *file) | 646 | static int pcwd_temp_open(struct inode *inode, struct file *file) |
552 | { | 647 | { |
553 | if (!supports_temp) | 648 | if (!pcwd_private.supports_temp) |
554 | return -ENODEV; | 649 | return -ENODEV; |
555 | 650 | ||
556 | return nonseekable_open(inode, file); | 651 | return nonseekable_open(inode, file); |
@@ -616,68 +711,24 @@ static struct notifier_block pcwd_notifier = { | |||
616 | * Init & exit routines | 711 | * Init & exit routines |
617 | */ | 712 | */ |
618 | 713 | ||
619 | static inline void get_support(void) | ||
620 | { | ||
621 | if (inb(current_readport) != 0xF0) | ||
622 | supports_temp = 1; | ||
623 | } | ||
624 | |||
625 | static inline int get_revision(void) | 714 | static inline int get_revision(void) |
626 | { | 715 | { |
627 | int r = PCWD_REVISION_C; | 716 | int r = PCWD_REVISION_C; |
628 | 717 | ||
629 | spin_lock(&io_lock); | 718 | spin_lock(&pcwd_private.io_lock); |
630 | /* REV A cards use only 2 io ports; test | 719 | /* REV A cards use only 2 io ports; test |
631 | * presumes a floating bus reads as 0xff. */ | 720 | * presumes a floating bus reads as 0xff. */ |
632 | if ((inb(current_readport + 2) == 0xFF) || | 721 | if ((inb(pcwd_private.io_addr + 2) == 0xFF) || |
633 | (inb(current_readport + 3) == 0xFF)) | 722 | (inb(pcwd_private.io_addr + 3) == 0xFF)) |
634 | r=PCWD_REVISION_A; | 723 | r=PCWD_REVISION_A; |
635 | spin_unlock(&io_lock); | 724 | spin_unlock(&pcwd_private.io_lock); |
636 | 725 | ||
637 | return r; | 726 | return r; |
638 | } | 727 | } |
639 | 728 | ||
640 | static inline char *get_firmware(void) | ||
641 | { | ||
642 | int one, ten, hund, minor; | ||
643 | char *ret; | ||
644 | |||
645 | ret = kmalloc(6, GFP_KERNEL); | ||
646 | if(ret == NULL) | ||
647 | return NULL; | ||
648 | |||
649 | if (set_command_mode()) { | ||
650 | one = send_isa_command(CMD_ISA_VERSION_INTEGER); | ||
651 | ten = send_isa_command(CMD_ISA_VERSION_TENTH); | ||
652 | hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); | ||
653 | minor = send_isa_command(CMD_ISA_VERSION_MINOR); | ||
654 | sprintf(ret, "%c.%c%c%c", one, ten, hund, minor); | ||
655 | } | ||
656 | else | ||
657 | sprintf(ret, "ERROR"); | ||
658 | |||
659 | unset_command_mode(); | ||
660 | return(ret); | ||
661 | } | ||
662 | |||
663 | static inline int get_option_switches(void) | ||
664 | { | ||
665 | int rv=0; | ||
666 | |||
667 | if (set_command_mode()) { | ||
668 | /* Get switch settings */ | ||
669 | rv = send_isa_command(CMD_ISA_SWITCH_SETTINGS); | ||
670 | } | ||
671 | |||
672 | unset_command_mode(); | ||
673 | return(rv); | ||
674 | } | ||
675 | |||
676 | static int __devinit pcwatchdog_init(int base_addr) | 729 | static int __devinit pcwatchdog_init(int base_addr) |
677 | { | 730 | { |
678 | int ret; | 731 | int ret; |
679 | char *firmware; | ||
680 | int option_switches; | ||
681 | 732 | ||
682 | cards_found++; | 733 | cards_found++; |
683 | if (cards_found == 1) | 734 | if (cards_found == 1) |
@@ -692,104 +743,66 @@ static int __devinit pcwatchdog_init(int base_addr) | |||
692 | printk(KERN_ERR PFX "No I/O-Address for card detected\n"); | 743 | printk(KERN_ERR PFX "No I/O-Address for card detected\n"); |
693 | return -ENODEV; | 744 | return -ENODEV; |
694 | } | 745 | } |
695 | current_readport = base_addr; | 746 | pcwd_private.io_addr = base_addr; |
696 | 747 | ||
697 | /* Check card's revision */ | 748 | /* Check card's revision */ |
698 | revision = get_revision(); | 749 | pcwd_private.revision = get_revision(); |
699 | 750 | ||
700 | if (!request_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { | 751 | if (!request_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { |
701 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 752 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
702 | current_readport); | 753 | pcwd_private.io_addr); |
703 | current_readport = 0x0000; | 754 | pcwd_private.io_addr = 0x0000; |
704 | return -EIO; | 755 | return -EIO; |
705 | } | 756 | } |
706 | 757 | ||
707 | /* Initial variables */ | 758 | /* Initial variables */ |
708 | supports_temp = 0; | 759 | pcwd_private.supports_temp = 0; |
709 | temp_panic = 0; | 760 | temp_panic = 0; |
710 | initial_status = 0x0000; | 761 | pcwd_private.boot_status = 0x0000; |
711 | 762 | ||
712 | /* get the boot_status */ | 763 | /* get the boot_status */ |
713 | pcwd_get_status(&initial_status); | 764 | pcwd_get_status(&pcwd_private.boot_status); |
714 | 765 | ||
715 | /* clear the "card caused reboot" flag */ | 766 | /* clear the "card caused reboot" flag */ |
716 | pcwd_clear_status(); | 767 | pcwd_clear_status(); |
717 | 768 | ||
718 | init_timer(&timer); | 769 | init_timer(&pcwd_private.timer); |
719 | timer.function = pcwd_timer_ping; | 770 | pcwd_private.timer.function = pcwd_timer_ping; |
720 | timer.data = 0; | 771 | pcwd_private.timer.data = 0; |
721 | 772 | ||
722 | /* Disable the board */ | 773 | /* Disable the board */ |
723 | pcwd_stop(); | 774 | pcwd_stop(); |
724 | 775 | ||
725 | /* Check whether or not the card supports the temperature device */ | 776 | /* Check whether or not the card supports the temperature device */ |
726 | get_support(); | 777 | pcwd_check_temperature_support(); |
727 | |||
728 | /* Get some extra info from the hardware (in command/debug/diag mode) */ | ||
729 | if (revision == PCWD_REVISION_A) | ||
730 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", current_readport); | ||
731 | else if (revision == PCWD_REVISION_C) { | ||
732 | firmware = get_firmware(); | ||
733 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", | ||
734 | current_readport, firmware); | ||
735 | kfree(firmware); | ||
736 | option_switches = get_option_switches(); | ||
737 | printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", | ||
738 | option_switches, | ||
739 | ((option_switches & 0x10) ? "ON" : "OFF"), | ||
740 | ((option_switches & 0x08) ? "ON" : "OFF")); | ||
741 | |||
742 | /* Reprogram internal heartbeat to 2 seconds */ | ||
743 | if (set_command_mode()) { | ||
744 | send_isa_command(CMD_ISA_DELAY_TIME_2SECS); | ||
745 | unset_command_mode(); | ||
746 | } | ||
747 | } else { | ||
748 | /* Should NEVER happen, unless get_revision() fails. */ | ||
749 | printk(KERN_INFO PFX "Unable to get revision\n"); | ||
750 | release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); | ||
751 | current_readport = 0x0000; | ||
752 | return -1; | ||
753 | } | ||
754 | 778 | ||
755 | if (supports_temp) | 779 | /* Show info about the card itself */ |
756 | printk(KERN_INFO PFX "Temperature Option Detected\n"); | 780 | pcwd_show_card_info(); |
757 | |||
758 | if (initial_status & WDIOF_CARDRESET) | ||
759 | printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); | ||
760 | |||
761 | if (initial_status & WDIOF_OVERHEAT) { | ||
762 | printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n"); | ||
763 | printk(KERN_EMERG PFX "CPU Overheat\n"); | ||
764 | } | ||
765 | |||
766 | if (initial_status == 0) | ||
767 | printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); | ||
768 | 781 | ||
769 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 782 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ |
770 | if (pcwd_set_heartbeat(heartbeat)) { | 783 | if (pcwd_set_heartbeat(heartbeat)) { |
771 | pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); | 784 | pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); |
772 | printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", | 785 | printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", |
773 | WATCHDOG_HEARTBEAT); | 786 | WATCHDOG_HEARTBEAT); |
774 | } | 787 | } |
775 | 788 | ||
776 | ret = register_reboot_notifier(&pcwd_notifier); | 789 | ret = register_reboot_notifier(&pcwd_notifier); |
777 | if (ret) { | 790 | if (ret) { |
778 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 791 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", |
779 | ret); | 792 | ret); |
780 | release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); | 793 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); |
781 | current_readport = 0x0000; | 794 | pcwd_private.io_addr = 0x0000; |
782 | return ret; | 795 | return ret; |
783 | } | 796 | } |
784 | 797 | ||
785 | if (supports_temp) { | 798 | if (pcwd_private.supports_temp) { |
786 | ret = misc_register(&temp_miscdev); | 799 | ret = misc_register(&temp_miscdev); |
787 | if (ret) { | 800 | if (ret) { |
788 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 801 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", |
789 | TEMP_MINOR, ret); | 802 | TEMP_MINOR, ret); |
790 | unregister_reboot_notifier(&pcwd_notifier); | 803 | unregister_reboot_notifier(&pcwd_notifier); |
791 | release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); | 804 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); |
792 | current_readport = 0x0000; | 805 | pcwd_private.io_addr = 0x0000; |
793 | return ret; | 806 | return ret; |
794 | } | 807 | } |
795 | } | 808 | } |
@@ -798,11 +811,11 @@ static int __devinit pcwatchdog_init(int base_addr) | |||
798 | if (ret) { | 811 | if (ret) { |
799 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 812 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", |
800 | WATCHDOG_MINOR, ret); | 813 | WATCHDOG_MINOR, ret); |
801 | if (supports_temp) | 814 | if (pcwd_private.supports_temp) |
802 | misc_deregister(&temp_miscdev); | 815 | misc_deregister(&temp_miscdev); |
803 | unregister_reboot_notifier(&pcwd_notifier); | 816 | unregister_reboot_notifier(&pcwd_notifier); |
804 | release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); | 817 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); |
805 | current_readport = 0x0000; | 818 | pcwd_private.io_addr = 0x0000; |
806 | return ret; | 819 | return ret; |
807 | } | 820 | } |
808 | 821 | ||
@@ -820,11 +833,12 @@ static void __devexit pcwatchdog_exit(void) | |||
820 | 833 | ||
821 | /* Deregister */ | 834 | /* Deregister */ |
822 | misc_deregister(&pcwd_miscdev); | 835 | misc_deregister(&pcwd_miscdev); |
823 | if (supports_temp) | 836 | if (pcwd_private.supports_temp) |
824 | misc_deregister(&temp_miscdev); | 837 | misc_deregister(&temp_miscdev); |
825 | unregister_reboot_notifier(&pcwd_notifier); | 838 | unregister_reboot_notifier(&pcwd_notifier); |
826 | release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); | 839 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); |
827 | current_readport = 0x0000; | 840 | pcwd_private.io_addr = 0x0000; |
841 | cards_found--; | ||
828 | } | 842 | } |
829 | 843 | ||
830 | /* | 844 | /* |
@@ -887,7 +901,7 @@ static int __init pcwd_init_module(void) | |||
887 | { | 901 | { |
888 | int i, found = 0; | 902 | int i, found = 0; |
889 | 903 | ||
890 | spin_lock_init(&io_lock); | 904 | spin_lock_init(&pcwd_private.io_lock); |
891 | 905 | ||
892 | for (i = 0; pcwd_ioports[i] != 0; i++) { | 906 | for (i = 0; pcwd_ioports[i] != 0; i++) { |
893 | if (pcwd_checkcard(pcwd_ioports[i])) { | 907 | if (pcwd_checkcard(pcwd_ioports[i])) { |
@@ -906,7 +920,7 @@ static int __init pcwd_init_module(void) | |||
906 | 920 | ||
907 | static void __exit pcwd_cleanup_module(void) | 921 | static void __exit pcwd_cleanup_module(void) |
908 | { | 922 | { |
909 | if (current_readport) | 923 | if (pcwd_private.io_addr) |
910 | pcwatchdog_exit(); | 924 | pcwatchdog_exit(); |
911 | return; | 925 | return; |
912 | } | 926 | } |
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c index b474ea52d6e8..522a9370db94 100644 --- a/drivers/char/watchdog/sa1100_wdt.c +++ b/drivers/char/watchdog/sa1100_wdt.c | |||
@@ -93,23 +93,25 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file, | |||
93 | { | 93 | { |
94 | int ret = -ENOIOCTLCMD; | 94 | int ret = -ENOIOCTLCMD; |
95 | int time; | 95 | int time; |
96 | void __user *argp = (void __user *)arg; | ||
97 | int __user *p = argp; | ||
96 | 98 | ||
97 | switch (cmd) { | 99 | switch (cmd) { |
98 | case WDIOC_GETSUPPORT: | 100 | case WDIOC_GETSUPPORT: |
99 | ret = copy_to_user((struct watchdog_info __user *)arg, &ident, | 101 | ret = copy_to_user(argp, &ident, |
100 | sizeof(ident)) ? -EFAULT : 0; | 102 | sizeof(ident)) ? -EFAULT : 0; |
101 | break; | 103 | break; |
102 | 104 | ||
103 | case WDIOC_GETSTATUS: | 105 | case WDIOC_GETSTATUS: |
104 | ret = put_user(0, (int __user *)arg); | 106 | ret = put_user(0, p); |
105 | break; | 107 | break; |
106 | 108 | ||
107 | case WDIOC_GETBOOTSTATUS: | 109 | case WDIOC_GETBOOTSTATUS: |
108 | ret = put_user(boot_status, (int __user *)arg); | 110 | ret = put_user(boot_status, p); |
109 | break; | 111 | break; |
110 | 112 | ||
111 | case WDIOC_SETTIMEOUT: | 113 | case WDIOC_SETTIMEOUT: |
112 | ret = get_user(time, (int __user *)arg); | 114 | ret = get_user(time, p); |
113 | if (ret) | 115 | if (ret) |
114 | break; | 116 | break; |
115 | 117 | ||
@@ -123,7 +125,7 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file, | |||
123 | /*fall through*/ | 125 | /*fall through*/ |
124 | 126 | ||
125 | case WDIOC_GETTIMEOUT: | 127 | case WDIOC_GETTIMEOUT: |
126 | ret = put_user(pre_margin / OSCR_FREQ, (int __user *)arg); | 128 | ret = put_user(pre_margin / OSCR_FREQ, p); |
127 | break; | 129 | break; |
128 | 130 | ||
129 | case WDIOC_KEEPALIVE: | 131 | case WDIOC_KEEPALIVE: |
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c index 7a4dfb95d087..837b1ec3ffe3 100644 --- a/drivers/char/watchdog/sbc_epx_c3.c +++ b/drivers/char/watchdog/sbc_epx_c3.c | |||
@@ -92,7 +92,7 @@ static int epx_c3_release(struct inode *inode, struct file *file) | |||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static ssize_t epx_c3_write(struct file *file, const char *data, | 95 | static ssize_t epx_c3_write(struct file *file, const char __user *data, |
96 | size_t len, loff_t *ppos) | 96 | size_t len, loff_t *ppos) |
97 | { | 97 | { |
98 | /* Refresh the timer. */ | 98 | /* Refresh the timer. */ |
@@ -105,6 +105,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
105 | unsigned int cmd, unsigned long arg) | 105 | unsigned int cmd, unsigned long arg) |
106 | { | 106 | { |
107 | int options, retval = -EINVAL; | 107 | int options, retval = -EINVAL; |
108 | int __user *argp = (void __user *)arg; | ||
108 | static struct watchdog_info ident = { | 109 | static struct watchdog_info ident = { |
109 | .options = WDIOF_KEEPALIVEPING | | 110 | .options = WDIOF_KEEPALIVEPING | |
110 | WDIOF_MAGICCLOSE, | 111 | WDIOF_MAGICCLOSE, |
@@ -114,20 +115,19 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
114 | 115 | ||
115 | switch (cmd) { | 116 | switch (cmd) { |
116 | case WDIOC_GETSUPPORT: | 117 | case WDIOC_GETSUPPORT: |
117 | if (copy_to_user((struct watchdog_info *)arg, | 118 | if (copy_to_user(argp, &ident, sizeof(ident))) |
118 | &ident, sizeof(ident))) | ||
119 | return -EFAULT; | 119 | return -EFAULT; |
120 | return 0; | 120 | return 0; |
121 | case WDIOC_GETSTATUS: | 121 | case WDIOC_GETSTATUS: |
122 | case WDIOC_GETBOOTSTATUS: | 122 | case WDIOC_GETBOOTSTATUS: |
123 | return put_user(0,(int *)arg); | 123 | return put_user(0, argp); |
124 | case WDIOC_KEEPALIVE: | 124 | case WDIOC_KEEPALIVE: |
125 | epx_c3_pet(); | 125 | epx_c3_pet(); |
126 | return 0; | 126 | return 0; |
127 | case WDIOC_GETTIMEOUT: | 127 | case WDIOC_GETTIMEOUT: |
128 | return put_user(WATCHDOG_TIMEOUT,(int *)arg); | 128 | return put_user(WATCHDOG_TIMEOUT, argp); |
129 | case WDIOC_SETOPTIONS: { | 129 | case WDIOC_SETOPTIONS: |
130 | if (get_user(options, (int *)arg)) | 130 | if (get_user(options, argp)) |
131 | return -EFAULT; | 131 | return -EFAULT; |
132 | 132 | ||
133 | if (options & WDIOS_DISABLECARD) { | 133 | if (options & WDIOS_DISABLECARD) { |
@@ -141,7 +141,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
141 | } | 141 | } |
142 | 142 | ||
143 | return retval; | 143 | return retval; |
144 | } | ||
145 | default: | 144 | default: |
146 | return -ENOIOCTLCMD; | 145 | return -ENOIOCTLCMD; |
147 | } | 146 | } |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7a511479ae29..9582de1c9cad 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -35,8 +35,8 @@ | |||
35 | * level driver of CPUFreq support, and its spinlock. This lock | 35 | * level driver of CPUFreq support, and its spinlock. This lock |
36 | * also protects the cpufreq_cpu_data array. | 36 | * also protects the cpufreq_cpu_data array. |
37 | */ | 37 | */ |
38 | static struct cpufreq_driver *cpufreq_driver; | 38 | static struct cpufreq_driver *cpufreq_driver; |
39 | static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; | 39 | static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; |
40 | static DEFINE_SPINLOCK(cpufreq_driver_lock); | 40 | static DEFINE_SPINLOCK(cpufreq_driver_lock); |
41 | 41 | ||
42 | /* internal prototypes */ | 42 | /* internal prototypes */ |
@@ -50,15 +50,15 @@ static void handle_update(void *data); | |||
50 | * changes to devices when the CPU clock speed changes. | 50 | * changes to devices when the CPU clock speed changes. |
51 | * The mutex locks both lists. | 51 | * The mutex locks both lists. |
52 | */ | 52 | */ |
53 | static struct notifier_block *cpufreq_policy_notifier_list; | 53 | static struct notifier_block *cpufreq_policy_notifier_list; |
54 | static struct notifier_block *cpufreq_transition_notifier_list; | 54 | static struct notifier_block *cpufreq_transition_notifier_list; |
55 | static DECLARE_RWSEM (cpufreq_notifier_rwsem); | 55 | static DECLARE_RWSEM (cpufreq_notifier_rwsem); |
56 | 56 | ||
57 | 57 | ||
58 | static LIST_HEAD(cpufreq_governor_list); | 58 | static LIST_HEAD(cpufreq_governor_list); |
59 | static DEFINE_MUTEX (cpufreq_governor_mutex); | 59 | static DEFINE_MUTEX (cpufreq_governor_mutex); |
60 | 60 | ||
61 | struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu) | 61 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) |
62 | { | 62 | { |
63 | struct cpufreq_policy *data; | 63 | struct cpufreq_policy *data; |
64 | unsigned long flags; | 64 | unsigned long flags; |
@@ -85,20 +85,19 @@ struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu) | |||
85 | if (!kobject_get(&data->kobj)) | 85 | if (!kobject_get(&data->kobj)) |
86 | goto err_out_put_module; | 86 | goto err_out_put_module; |
87 | 87 | ||
88 | |||
89 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 88 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
90 | |||
91 | return data; | 89 | return data; |
92 | 90 | ||
93 | err_out_put_module: | 91 | err_out_put_module: |
94 | module_put(cpufreq_driver->owner); | 92 | module_put(cpufreq_driver->owner); |
95 | err_out_unlock: | 93 | err_out_unlock: |
96 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 94 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
97 | err_out: | 95 | err_out: |
98 | return NULL; | 96 | return NULL; |
99 | } | 97 | } |
100 | EXPORT_SYMBOL_GPL(cpufreq_cpu_get); | 98 | EXPORT_SYMBOL_GPL(cpufreq_cpu_get); |
101 | 99 | ||
100 | |||
102 | void cpufreq_cpu_put(struct cpufreq_policy *data) | 101 | void cpufreq_cpu_put(struct cpufreq_policy *data) |
103 | { | 102 | { |
104 | kobject_put(&data->kobj); | 103 | kobject_put(&data->kobj); |
@@ -229,44 +228,53 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) { | |||
229 | 228 | ||
230 | 229 | ||
231 | /** | 230 | /** |
232 | * cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition | 231 | * cpufreq_notify_transition - call notifier chain and adjust_jiffies |
232 | * on frequency transition. | ||
233 | * | 233 | * |
234 | * This function calls the transition notifiers and the "adjust_jiffies" function. It is called | 234 | * This function calls the transition notifiers and the "adjust_jiffies" |
235 | * twice on all CPU frequency changes that have external effects. | 235 | * function. It is called twice on all CPU frequency changes that have |
236 | * external effects. | ||
236 | */ | 237 | */ |
237 | void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) | 238 | void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) |
238 | { | 239 | { |
240 | struct cpufreq_policy *policy; | ||
241 | |||
239 | BUG_ON(irqs_disabled()); | 242 | BUG_ON(irqs_disabled()); |
240 | 243 | ||
241 | freqs->flags = cpufreq_driver->flags; | 244 | freqs->flags = cpufreq_driver->flags; |
242 | dprintk("notification %u of frequency transition to %u kHz\n", state, freqs->new); | 245 | dprintk("notification %u of frequency transition to %u kHz\n", |
246 | state, freqs->new); | ||
243 | 247 | ||
244 | down_read(&cpufreq_notifier_rwsem); | 248 | down_read(&cpufreq_notifier_rwsem); |
249 | |||
250 | policy = cpufreq_cpu_data[freqs->cpu]; | ||
245 | switch (state) { | 251 | switch (state) { |
252 | |||
246 | case CPUFREQ_PRECHANGE: | 253 | case CPUFREQ_PRECHANGE: |
247 | /* detect if the driver reported a value as "old frequency" which | 254 | /* detect if the driver reported a value as "old frequency" |
248 | * is not equal to what the cpufreq core thinks is "old frequency". | 255 | * which is not equal to what the cpufreq core thinks is |
256 | * "old frequency". | ||
249 | */ | 257 | */ |
250 | if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { | 258 | if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { |
251 | if ((likely(cpufreq_cpu_data[freqs->cpu])) && | 259 | if ((policy) && (policy->cpu == freqs->cpu) && |
252 | (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu)) && | 260 | (policy->cur) && (policy->cur != freqs->old)) { |
253 | (likely(cpufreq_cpu_data[freqs->cpu]->cur)) && | 261 | dprintk(KERN_WARNING "Warning: CPU frequency is" |
254 | (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur))) | 262 | " %u, cpufreq assumed %u kHz.\n", |
255 | { | 263 | freqs->old, policy->cur); |
256 | dprintk(KERN_WARNING "Warning: CPU frequency is %u, " | 264 | freqs->old = policy->cur; |
257 | "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur); | ||
258 | freqs->old = cpufreq_cpu_data[freqs->cpu]->cur; | ||
259 | } | 265 | } |
260 | } | 266 | } |
261 | notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_PRECHANGE, freqs); | 267 | notifier_call_chain(&cpufreq_transition_notifier_list, |
268 | CPUFREQ_PRECHANGE, freqs); | ||
262 | adjust_jiffies(CPUFREQ_PRECHANGE, freqs); | 269 | adjust_jiffies(CPUFREQ_PRECHANGE, freqs); |
263 | break; | 270 | break; |
271 | |||
264 | case CPUFREQ_POSTCHANGE: | 272 | case CPUFREQ_POSTCHANGE: |
265 | adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); | 273 | adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); |
266 | notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs); | 274 | notifier_call_chain(&cpufreq_transition_notifier_list, |
267 | if ((likely(cpufreq_cpu_data[freqs->cpu])) && | 275 | CPUFREQ_POSTCHANGE, freqs); |
268 | (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu))) | 276 | if (likely(policy) && likely(policy->cpu == freqs->cpu)) |
269 | cpufreq_cpu_data[freqs->cpu]->cur = freqs->new; | 277 | policy->cur = freqs->new; |
270 | break; | 278 | break; |
271 | } | 279 | } |
272 | up_read(&cpufreq_notifier_rwsem); | 280 | up_read(&cpufreq_notifier_rwsem); |
@@ -308,7 +316,7 @@ static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, | |||
308 | return 0; | 316 | return 0; |
309 | } | 317 | } |
310 | } | 318 | } |
311 | out: | 319 | out: |
312 | mutex_unlock(&cpufreq_governor_mutex); | 320 | mutex_unlock(&cpufreq_governor_mutex); |
313 | } | 321 | } |
314 | return -EINVAL; | 322 | return -EINVAL; |
@@ -415,7 +423,6 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy, | |||
415 | return -EINVAL; | 423 | return -EINVAL; |
416 | 424 | ||
417 | ret = cpufreq_set_policy(&new_policy); | 425 | ret = cpufreq_set_policy(&new_policy); |
418 | |||
419 | return ret ? ret : count; | 426 | return ret ? ret : count; |
420 | } | 427 | } |
421 | 428 | ||
@@ -446,7 +453,7 @@ static ssize_t show_scaling_available_governors (struct cpufreq_policy * policy, | |||
446 | goto out; | 453 | goto out; |
447 | i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name); | 454 | i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name); |
448 | } | 455 | } |
449 | out: | 456 | out: |
450 | i += sprintf(&buf[i], "\n"); | 457 | i += sprintf(&buf[i], "\n"); |
451 | return i; | 458 | return i; |
452 | } | 459 | } |
@@ -789,7 +796,6 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev) | |||
789 | kfree(data); | 796 | kfree(data); |
790 | 797 | ||
791 | cpufreq_debug_enable_ratelimit(); | 798 | cpufreq_debug_enable_ratelimit(); |
792 | |||
793 | return 0; | 799 | return 0; |
794 | } | 800 | } |
795 | 801 | ||
@@ -870,8 +876,7 @@ unsigned int cpufreq_get(unsigned int cpu) | |||
870 | 876 | ||
871 | ret = cpufreq_driver->get(cpu); | 877 | ret = cpufreq_driver->get(cpu); |
872 | 878 | ||
873 | if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) | 879 | if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { |
874 | { | ||
875 | /* verify no discrepancy between actual and saved value exists */ | 880 | /* verify no discrepancy between actual and saved value exists */ |
876 | if (unlikely(ret != policy->cur)) { | 881 | if (unlikely(ret != policy->cur)) { |
877 | cpufreq_out_of_sync(cpu, policy->cur, ret); | 882 | cpufreq_out_of_sync(cpu, policy->cur, ret); |
@@ -881,7 +886,7 @@ unsigned int cpufreq_get(unsigned int cpu) | |||
881 | 886 | ||
882 | mutex_unlock(&policy->lock); | 887 | mutex_unlock(&policy->lock); |
883 | 888 | ||
884 | out: | 889 | out: |
885 | cpufreq_cpu_put(policy); | 890 | cpufreq_cpu_put(policy); |
886 | 891 | ||
887 | return (ret); | 892 | return (ret); |
@@ -962,7 +967,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg) | |||
962 | cpu_policy->cur = cur_freq; | 967 | cpu_policy->cur = cur_freq; |
963 | } | 968 | } |
964 | 969 | ||
965 | out: | 970 | out: |
966 | cpufreq_cpu_put(cpu_policy); | 971 | cpufreq_cpu_put(cpu_policy); |
967 | return 0; | 972 | return 0; |
968 | } | 973 | } |
@@ -1169,7 +1174,6 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1169 | mutex_unlock(&policy->lock); | 1174 | mutex_unlock(&policy->lock); |
1170 | 1175 | ||
1171 | cpufreq_cpu_put(policy); | 1176 | cpufreq_cpu_put(policy); |
1172 | |||
1173 | return ret; | 1177 | return ret; |
1174 | } | 1178 | } |
1175 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); | 1179 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); |
@@ -1208,7 +1212,6 @@ int cpufreq_governor(unsigned int cpu, unsigned int event) | |||
1208 | mutex_unlock(&policy->lock); | 1212 | mutex_unlock(&policy->lock); |
1209 | 1213 | ||
1210 | cpufreq_cpu_put(policy); | 1214 | cpufreq_cpu_put(policy); |
1211 | |||
1212 | return ret; | 1215 | return ret; |
1213 | } | 1216 | } |
1214 | EXPORT_SYMBOL_GPL(cpufreq_governor); | 1217 | EXPORT_SYMBOL_GPL(cpufreq_governor); |
@@ -1232,7 +1235,6 @@ int cpufreq_register_governor(struct cpufreq_governor *governor) | |||
1232 | list_add(&governor->governor_list, &cpufreq_governor_list); | 1235 | list_add(&governor->governor_list, &cpufreq_governor_list); |
1233 | 1236 | ||
1234 | mutex_unlock(&cpufreq_governor_mutex); | 1237 | mutex_unlock(&cpufreq_governor_mutex); |
1235 | |||
1236 | return 0; | 1238 | return 0; |
1237 | } | 1239 | } |
1238 | EXPORT_SYMBOL_GPL(cpufreq_register_governor); | 1240 | EXPORT_SYMBOL_GPL(cpufreq_register_governor); |
@@ -1277,7 +1279,6 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) | |||
1277 | mutex_unlock(&cpu_policy->lock); | 1279 | mutex_unlock(&cpu_policy->lock); |
1278 | 1280 | ||
1279 | cpufreq_cpu_put(cpu_policy); | 1281 | cpufreq_cpu_put(cpu_policy); |
1280 | |||
1281 | return 0; | 1282 | return 0; |
1282 | } | 1283 | } |
1283 | EXPORT_SYMBOL(cpufreq_get_policy); | 1284 | EXPORT_SYMBOL(cpufreq_get_policy); |
@@ -1291,9 +1292,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli | |||
1291 | dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, | 1292 | dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, |
1292 | policy->min, policy->max); | 1293 | policy->min, policy->max); |
1293 | 1294 | ||
1294 | memcpy(&policy->cpuinfo, | 1295 | memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo)); |
1295 | &data->cpuinfo, | ||
1296 | sizeof(struct cpufreq_cpuinfo)); | ||
1297 | 1296 | ||
1298 | /* verify the cpu speed can be set within this limit */ | 1297 | /* verify the cpu speed can be set within this limit */ |
1299 | ret = cpufreq_driver->verify(policy); | 1298 | ret = cpufreq_driver->verify(policy); |
@@ -1324,8 +1323,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli | |||
1324 | 1323 | ||
1325 | up_read(&cpufreq_notifier_rwsem); | 1324 | up_read(&cpufreq_notifier_rwsem); |
1326 | 1325 | ||
1327 | data->min = policy->min; | 1326 | data->min = policy->min; |
1328 | data->max = policy->max; | 1327 | data->max = policy->max; |
1329 | 1328 | ||
1330 | dprintk("new min and max freqs are %u - %u kHz\n", data->min, data->max); | 1329 | dprintk("new min and max freqs are %u - %u kHz\n", data->min, data->max); |
1331 | 1330 | ||
@@ -1362,7 +1361,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli | |||
1362 | __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); | 1361 | __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); |
1363 | } | 1362 | } |
1364 | 1363 | ||
1365 | error_out: | 1364 | error_out: |
1366 | cpufreq_debug_enable_ratelimit(); | 1365 | cpufreq_debug_enable_ratelimit(); |
1367 | return ret; | 1366 | return ret; |
1368 | } | 1367 | } |
@@ -1421,9 +1420,7 @@ int cpufreq_update_policy(unsigned int cpu) | |||
1421 | mutex_lock(&data->lock); | 1420 | mutex_lock(&data->lock); |
1422 | 1421 | ||
1423 | dprintk("updating policy for CPU %u\n", cpu); | 1422 | dprintk("updating policy for CPU %u\n", cpu); |
1424 | memcpy(&policy, | 1423 | memcpy(&policy, data, sizeof(struct cpufreq_policy)); |
1425 | data, | ||
1426 | sizeof(struct cpufreq_policy)); | ||
1427 | policy.min = data->user_policy.min; | 1424 | policy.min = data->user_policy.min; |
1428 | policy.max = data->user_policy.max; | 1425 | policy.max = data->user_policy.max; |
1429 | policy.policy = data->user_policy.policy; | 1426 | policy.policy = data->user_policy.policy; |
@@ -1433,8 +1430,13 @@ int cpufreq_update_policy(unsigned int cpu) | |||
1433 | -> ask driver for current freq and notify governors about a change */ | 1430 | -> ask driver for current freq and notify governors about a change */ |
1434 | if (cpufreq_driver->get) { | 1431 | if (cpufreq_driver->get) { |
1435 | policy.cur = cpufreq_driver->get(cpu); | 1432 | policy.cur = cpufreq_driver->get(cpu); |
1436 | if (data->cur != policy.cur) | 1433 | if (!data->cur) { |
1437 | cpufreq_out_of_sync(cpu, data->cur, policy.cur); | 1434 | dprintk("Driver did not initialize current freq"); |
1435 | data->cur = policy.cur; | ||
1436 | } else { | ||
1437 | if (data->cur != policy.cur) | ||
1438 | cpufreq_out_of_sync(cpu, data->cur, policy.cur); | ||
1439 | } | ||
1438 | } | 1440 | } |
1439 | 1441 | ||
1440 | ret = __cpufreq_set_policy(data, &policy); | 1442 | ret = __cpufreq_set_policy(data, &policy); |
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 64819aa7cac4..0c08c58252be 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c | |||
@@ -348,10 +348,10 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t | |||
348 | break; | 348 | break; |
349 | 349 | ||
350 | case 32: | 350 | case 32: |
351 | E_KEY[4] = le32_to_cpu(in_key[4]); | 351 | E_KEY[4] = le32_to_cpu(key[4]); |
352 | E_KEY[5] = le32_to_cpu(in_key[5]); | 352 | E_KEY[5] = le32_to_cpu(key[5]); |
353 | E_KEY[6] = le32_to_cpu(in_key[6]); | 353 | E_KEY[6] = le32_to_cpu(key[6]); |
354 | t = E_KEY[7] = le32_to_cpu(in_key[7]); | 354 | t = E_KEY[7] = le32_to_cpu(key[7]); |
355 | for (i = 0; i < 7; ++i) | 355 | for (i = 0; i < 7; ++i) |
356 | loop8 (i); | 356 | loop8 (i); |
357 | break; | 357 | break; |
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index d94331c1e5b0..52f3eb45d2b9 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig | |||
@@ -6,18 +6,29 @@ | |||
6 | # $Id: Kconfig,v 1.4.2.7 2005/07/08 22:05:38 dsp_llnl Exp $ | 6 | # $Id: Kconfig,v 1.4.2.7 2005/07/08 22:05:38 dsp_llnl Exp $ |
7 | # | 7 | # |
8 | 8 | ||
9 | menu 'EDAC - error detection and reporting (RAS)' | 9 | menu 'EDAC - error detection and reporting (RAS) (EXPERIMENTAL)' |
10 | 10 | ||
11 | config EDAC | 11 | config EDAC |
12 | tristate "EDAC core system error reporting" | 12 | tristate "EDAC core system error reporting (EXPERIMENTAL)" |
13 | depends on X86 | 13 | depends on X86 && EXPERIMENTAL |
14 | default y | ||
15 | help | 14 | help |
16 | EDAC is designed to report errors in the core system. | 15 | EDAC is designed to report errors in the core system. |
17 | These are low-level errors that are reported in the CPU or | 16 | These are low-level errors that are reported in the CPU or |
18 | supporting chipset: memory errors, cache errors, PCI errors, | 17 | supporting chipset: memory errors, cache errors, PCI errors, |
19 | thermal throttling, etc.. If unsure, select 'Y'. | 18 | thermal throttling, etc.. If unsure, select 'Y'. |
20 | 19 | ||
20 | If this code is reporting problems on your system, please | ||
21 | see the EDAC project web pages for more information at: | ||
22 | |||
23 | <http://bluesmoke.sourceforge.net/> | ||
24 | |||
25 | and: | ||
26 | |||
27 | <http://buttersideup.com/edacwiki> | ||
28 | |||
29 | There is also a mailing list for the EDAC project, which can | ||
30 | be found via the sourceforge page. | ||
31 | |||
21 | 32 | ||
22 | comment "Reporting subsystems" | 33 | comment "Reporting subsystems" |
23 | depends on EDAC | 34 | depends on EDAC |
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index b10ee4698b1d..9c205274c1cb 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -38,6 +38,12 @@ | |||
38 | 38 | ||
39 | #define EDAC_MC_VERSION "edac_mc Ver: 2.0.0 " __DATE__ | 39 | #define EDAC_MC_VERSION "edac_mc Ver: 2.0.0 " __DATE__ |
40 | 40 | ||
41 | /* For now, disable the EDAC sysfs code. The sysfs interface that EDAC | ||
42 | * presents to user space needs more thought, and is likely to change | ||
43 | * substantially. | ||
44 | */ | ||
45 | #define DISABLE_EDAC_SYSFS | ||
46 | |||
41 | #ifdef CONFIG_EDAC_DEBUG | 47 | #ifdef CONFIG_EDAC_DEBUG |
42 | /* Values of 0 to 4 will generate output */ | 48 | /* Values of 0 to 4 will generate output */ |
43 | int edac_debug_level = 1; | 49 | int edac_debug_level = 1; |
@@ -47,7 +53,7 @@ EXPORT_SYMBOL(edac_debug_level); | |||
47 | /* EDAC Controls, setable by module parameter, and sysfs */ | 53 | /* EDAC Controls, setable by module parameter, and sysfs */ |
48 | static int log_ue = 1; | 54 | static int log_ue = 1; |
49 | static int log_ce = 1; | 55 | static int log_ce = 1; |
50 | static int panic_on_ue = 1; | 56 | static int panic_on_ue; |
51 | static int poll_msec = 1000; | 57 | static int poll_msec = 1000; |
52 | 58 | ||
53 | static int check_pci_parity = 0; /* default YES check PCI parity */ | 59 | static int check_pci_parity = 0; /* default YES check PCI parity */ |
@@ -77,6 +83,8 @@ static int pci_whitelist_count ; | |||
77 | 83 | ||
78 | /* START sysfs data and methods */ | 84 | /* START sysfs data and methods */ |
79 | 85 | ||
86 | #ifndef DISABLE_EDAC_SYSFS | ||
87 | |||
80 | static const char *mem_types[] = { | 88 | static const char *mem_types[] = { |
81 | [MEM_EMPTY] = "Empty", | 89 | [MEM_EMPTY] = "Empty", |
82 | [MEM_RESERVED] = "Reserved", | 90 | [MEM_RESERVED] = "Reserved", |
@@ -132,11 +140,13 @@ static struct kobject edac_pci_kobj; | |||
132 | * /sys/devices/system/edac/mc; | 140 | * /sys/devices/system/edac/mc; |
133 | * data structures and methods | 141 | * data structures and methods |
134 | */ | 142 | */ |
143 | #if 0 | ||
135 | static ssize_t memctrl_string_show(void *ptr, char *buffer) | 144 | static ssize_t memctrl_string_show(void *ptr, char *buffer) |
136 | { | 145 | { |
137 | char *value = (char*) ptr; | 146 | char *value = (char*) ptr; |
138 | return sprintf(buffer, "%s\n", value); | 147 | return sprintf(buffer, "%s\n", value); |
139 | } | 148 | } |
149 | #endif | ||
140 | 150 | ||
141 | static ssize_t memctrl_int_show(void *ptr, char *buffer) | 151 | static ssize_t memctrl_int_show(void *ptr, char *buffer) |
142 | { | 152 | { |
@@ -207,7 +217,9 @@ struct memctrl_dev_attribute attr_##_name = { \ | |||
207 | }; | 217 | }; |
208 | 218 | ||
209 | /* cwrow<id> attribute f*/ | 219 | /* cwrow<id> attribute f*/ |
220 | #if 0 | ||
210 | MEMCTRL_STRING_ATTR(mc_version,EDAC_MC_VERSION,S_IRUGO,memctrl_string_show,NULL); | 221 | MEMCTRL_STRING_ATTR(mc_version,EDAC_MC_VERSION,S_IRUGO,memctrl_string_show,NULL); |
222 | #endif | ||
211 | 223 | ||
212 | /* csrow<id> control files */ | 224 | /* csrow<id> control files */ |
213 | MEMCTRL_ATTR(panic_on_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store); | 225 | MEMCTRL_ATTR(panic_on_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store); |
@@ -222,7 +234,6 @@ static struct memctrl_dev_attribute *memctrl_attr[] = { | |||
222 | &attr_log_ue, | 234 | &attr_log_ue, |
223 | &attr_log_ce, | 235 | &attr_log_ce, |
224 | &attr_poll_msec, | 236 | &attr_poll_msec, |
225 | &attr_mc_version, | ||
226 | NULL, | 237 | NULL, |
227 | }; | 238 | }; |
228 | 239 | ||
@@ -238,6 +249,7 @@ static struct kobj_type ktype_memctrl = { | |||
238 | .default_attrs = (struct attribute **) memctrl_attr, | 249 | .default_attrs = (struct attribute **) memctrl_attr, |
239 | }; | 250 | }; |
240 | 251 | ||
252 | #endif /* DISABLE_EDAC_SYSFS */ | ||
241 | 253 | ||
242 | /* Initialize the main sysfs entries for edac: | 254 | /* Initialize the main sysfs entries for edac: |
243 | * /sys/devices/system/edac | 255 | * /sys/devices/system/edac |
@@ -248,6 +260,11 @@ static struct kobj_type ktype_memctrl = { | |||
248 | * !0 FAILURE | 260 | * !0 FAILURE |
249 | */ | 261 | */ |
250 | static int edac_sysfs_memctrl_setup(void) | 262 | static int edac_sysfs_memctrl_setup(void) |
263 | #ifdef DISABLE_EDAC_SYSFS | ||
264 | { | ||
265 | return 0; | ||
266 | } | ||
267 | #else | ||
251 | { | 268 | { |
252 | int err=0; | 269 | int err=0; |
253 | 270 | ||
@@ -280,6 +297,7 @@ static int edac_sysfs_memctrl_setup(void) | |||
280 | 297 | ||
281 | return err; | 298 | return err; |
282 | } | 299 | } |
300 | #endif /* DISABLE_EDAC_SYSFS */ | ||
283 | 301 | ||
284 | /* | 302 | /* |
285 | * MC teardown: | 303 | * MC teardown: |
@@ -287,6 +305,7 @@ static int edac_sysfs_memctrl_setup(void) | |||
287 | */ | 305 | */ |
288 | static void edac_sysfs_memctrl_teardown(void) | 306 | static void edac_sysfs_memctrl_teardown(void) |
289 | { | 307 | { |
308 | #ifndef DISABLE_EDAC_SYSFS | ||
290 | debugf0("MC: " __FILE__ ": %s()\n", __func__); | 309 | debugf0("MC: " __FILE__ ": %s()\n", __func__); |
291 | 310 | ||
292 | /* Unregister the MC's kobject */ | 311 | /* Unregister the MC's kobject */ |
@@ -297,8 +316,11 @@ static void edac_sysfs_memctrl_teardown(void) | |||
297 | 316 | ||
298 | /* Unregister the 'edac' object */ | 317 | /* Unregister the 'edac' object */ |
299 | sysdev_class_unregister(&edac_class); | 318 | sysdev_class_unregister(&edac_class); |
319 | #endif /* DISABLE_EDAC_SYSFS */ | ||
300 | } | 320 | } |
301 | 321 | ||
322 | #ifndef DISABLE_EDAC_SYSFS | ||
323 | |||
302 | /* | 324 | /* |
303 | * /sys/devices/system/edac/pci; | 325 | * /sys/devices/system/edac/pci; |
304 | * data structures and methods | 326 | * data structures and methods |
@@ -309,6 +331,8 @@ struct list_control { | |||
309 | int *count; | 331 | int *count; |
310 | }; | 332 | }; |
311 | 333 | ||
334 | |||
335 | #if 0 | ||
312 | /* Output the list as: vendor_id:device:id<,vendor_id:device_id> */ | 336 | /* Output the list as: vendor_id:device:id<,vendor_id:device_id> */ |
313 | static ssize_t edac_pci_list_string_show(void *ptr, char *buffer) | 337 | static ssize_t edac_pci_list_string_show(void *ptr, char *buffer) |
314 | { | 338 | { |
@@ -430,6 +454,7 @@ static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer, | |||
430 | return count; | 454 | return count; |
431 | } | 455 | } |
432 | 456 | ||
457 | #endif | ||
433 | static ssize_t edac_pci_int_show(void *ptr, char *buffer) | 458 | static ssize_t edac_pci_int_show(void *ptr, char *buffer) |
434 | { | 459 | { |
435 | int *value = ptr; | 460 | int *value = ptr; |
@@ -498,6 +523,7 @@ struct edac_pci_dev_attribute edac_pci_attr_##_name = { \ | |||
498 | .store = _store, \ | 523 | .store = _store, \ |
499 | }; | 524 | }; |
500 | 525 | ||
526 | #if 0 | ||
501 | static struct list_control pci_whitelist_control = { | 527 | static struct list_control pci_whitelist_control = { |
502 | .list = pci_whitelist, | 528 | .list = pci_whitelist, |
503 | .count = &pci_whitelist_count | 529 | .count = &pci_whitelist_count |
@@ -520,6 +546,7 @@ EDAC_PCI_STRING_ATTR(pci_parity_blacklist, | |||
520 | S_IRUGO|S_IWUSR, | 546 | S_IRUGO|S_IWUSR, |
521 | edac_pci_list_string_show, | 547 | edac_pci_list_string_show, |
522 | edac_pci_list_string_store); | 548 | edac_pci_list_string_store); |
549 | #endif | ||
523 | 550 | ||
524 | /* PCI Parity control files */ | 551 | /* PCI Parity control files */ |
525 | EDAC_PCI_ATTR(check_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store); | 552 | EDAC_PCI_ATTR(check_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store); |
@@ -531,8 +558,6 @@ static struct edac_pci_dev_attribute *edac_pci_attr[] = { | |||
531 | &edac_pci_attr_check_pci_parity, | 558 | &edac_pci_attr_check_pci_parity, |
532 | &edac_pci_attr_panic_on_pci_parity, | 559 | &edac_pci_attr_panic_on_pci_parity, |
533 | &edac_pci_attr_pci_parity_count, | 560 | &edac_pci_attr_pci_parity_count, |
534 | &edac_pci_attr_pci_parity_whitelist, | ||
535 | &edac_pci_attr_pci_parity_blacklist, | ||
536 | NULL, | 561 | NULL, |
537 | }; | 562 | }; |
538 | 563 | ||
@@ -548,11 +573,18 @@ static struct kobj_type ktype_edac_pci = { | |||
548 | .default_attrs = (struct attribute **) edac_pci_attr, | 573 | .default_attrs = (struct attribute **) edac_pci_attr, |
549 | }; | 574 | }; |
550 | 575 | ||
576 | #endif /* DISABLE_EDAC_SYSFS */ | ||
577 | |||
551 | /** | 578 | /** |
552 | * edac_sysfs_pci_setup() | 579 | * edac_sysfs_pci_setup() |
553 | * | 580 | * |
554 | */ | 581 | */ |
555 | static int edac_sysfs_pci_setup(void) | 582 | static int edac_sysfs_pci_setup(void) |
583 | #ifdef DISABLE_EDAC_SYSFS | ||
584 | { | ||
585 | return 0; | ||
586 | } | ||
587 | #else | ||
556 | { | 588 | { |
557 | int err; | 589 | int err; |
558 | 590 | ||
@@ -576,16 +608,20 @@ static int edac_sysfs_pci_setup(void) | |||
576 | } | 608 | } |
577 | return err; | 609 | return err; |
578 | } | 610 | } |
579 | 611 | #endif /* DISABLE_EDAC_SYSFS */ | |
580 | 612 | ||
581 | static void edac_sysfs_pci_teardown(void) | 613 | static void edac_sysfs_pci_teardown(void) |
582 | { | 614 | { |
615 | #ifndef DISABLE_EDAC_SYSFS | ||
583 | debugf0("MC: " __FILE__ ": %s()\n", __func__); | 616 | debugf0("MC: " __FILE__ ": %s()\n", __func__); |
584 | 617 | ||
585 | kobject_unregister(&edac_pci_kobj); | 618 | kobject_unregister(&edac_pci_kobj); |
586 | kobject_put(&edac_pci_kobj); | 619 | kobject_put(&edac_pci_kobj); |
620 | #endif | ||
587 | } | 621 | } |
588 | 622 | ||
623 | #ifndef DISABLE_EDAC_SYSFS | ||
624 | |||
589 | /* EDAC sysfs CSROW data structures and methods */ | 625 | /* EDAC sysfs CSROW data structures and methods */ |
590 | 626 | ||
591 | /* Set of more detailed csrow<id> attribute show/store functions */ | 627 | /* Set of more detailed csrow<id> attribute show/store functions */ |
@@ -1039,6 +1075,8 @@ static struct kobj_type ktype_mci = { | |||
1039 | .default_attrs = (struct attribute **) mci_attr, | 1075 | .default_attrs = (struct attribute **) mci_attr, |
1040 | }; | 1076 | }; |
1041 | 1077 | ||
1078 | #endif /* DISABLE_EDAC_SYSFS */ | ||
1079 | |||
1042 | #define EDAC_DEVICE_SYMLINK "device" | 1080 | #define EDAC_DEVICE_SYMLINK "device" |
1043 | 1081 | ||
1044 | /* | 1082 | /* |
@@ -1050,6 +1088,11 @@ static struct kobj_type ktype_mci = { | |||
1050 | * !0 Failure | 1088 | * !0 Failure |
1051 | */ | 1089 | */ |
1052 | static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) | 1090 | static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) |
1091 | #ifdef DISABLE_EDAC_SYSFS | ||
1092 | { | ||
1093 | return 0; | ||
1094 | } | ||
1095 | #else | ||
1053 | { | 1096 | { |
1054 | int i; | 1097 | int i; |
1055 | int err; | 1098 | int err; |
@@ -1118,12 +1161,14 @@ fail: | |||
1118 | 1161 | ||
1119 | return err; | 1162 | return err; |
1120 | } | 1163 | } |
1164 | #endif /* DISABLE_EDAC_SYSFS */ | ||
1121 | 1165 | ||
1122 | /* | 1166 | /* |
1123 | * remove a Memory Controller instance | 1167 | * remove a Memory Controller instance |
1124 | */ | 1168 | */ |
1125 | static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | 1169 | static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) |
1126 | { | 1170 | { |
1171 | #ifndef DISABLE_EDAC_SYSFS | ||
1127 | int i; | 1172 | int i; |
1128 | 1173 | ||
1129 | debugf0("MC: " __FILE__ ": %s()\n", __func__); | 1174 | debugf0("MC: " __FILE__ ": %s()\n", __func__); |
@@ -1140,6 +1185,7 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | |||
1140 | 1185 | ||
1141 | kobject_unregister(&mci->edac_mci_kobj); | 1186 | kobject_unregister(&mci->edac_mci_kobj); |
1142 | kobject_put(&mci->edac_mci_kobj); | 1187 | kobject_put(&mci->edac_mci_kobj); |
1188 | #endif /* DISABLE_EDAC_SYSFS */ | ||
1143 | } | 1189 | } |
1144 | 1190 | ||
1145 | /* END OF sysfs data and methods */ | 1191 | /* END OF sysfs data and methods */ |
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index 009c08fe5d69..1991f94af753 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c | |||
@@ -159,7 +159,7 @@ enum i82875p_chips { | |||
159 | 159 | ||
160 | struct i82875p_pvt { | 160 | struct i82875p_pvt { |
161 | struct pci_dev *ovrfl_pdev; | 161 | struct pci_dev *ovrfl_pdev; |
162 | void *ovrfl_window; | 162 | void __iomem *ovrfl_window; |
163 | }; | 163 | }; |
164 | 164 | ||
165 | 165 | ||
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c index 5c8943509cc1..66d03f242d3c 100644 --- a/drivers/fc4/fc.c +++ b/drivers/fc4/fc.c | |||
@@ -1053,7 +1053,7 @@ static int fc_do_els(fc_channel *fc, unsigned int alpa, void *data, int len) | |||
1053 | int i; | 1053 | int i; |
1054 | 1054 | ||
1055 | fcmd = &_fcmd; | 1055 | fcmd = &_fcmd; |
1056 | memset(fcmd, 0, sizeof(fcmd)); | 1056 | memset(fcmd, 0, sizeof(fcp_cmnd)); |
1057 | FCD(("PLOGI SID %d DID %d\n", fc->sid, alpa)) | 1057 | FCD(("PLOGI SID %d DID %d\n", fc->sid, alpa)) |
1058 | fch = &fcmd->fch; | 1058 | fch = &fcmd->fch; |
1059 | FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, alpa); | 1059 | FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, alpa); |
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index 8ed6ddbb9c5d..4652512f7d1a 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include "dcdbas.h" | 39 | #include "dcdbas.h" |
40 | 40 | ||
41 | #define DRIVER_NAME "dcdbas" | 41 | #define DRIVER_NAME "dcdbas" |
42 | #define DRIVER_VERSION "5.6.0-1" | 42 | #define DRIVER_VERSION "5.6.0-2" |
43 | #define DRIVER_DESCRIPTION "Dell Systems Management Base Driver" | 43 | #define DRIVER_DESCRIPTION "Dell Systems Management Base Driver" |
44 | 44 | ||
45 | static struct platform_device *dcdbas_pdev; | 45 | static struct platform_device *dcdbas_pdev; |
@@ -581,9 +581,13 @@ static int __init dcdbas_init(void) | |||
581 | */ | 581 | */ |
582 | static void __exit dcdbas_exit(void) | 582 | static void __exit dcdbas_exit(void) |
583 | { | 583 | { |
584 | platform_device_unregister(dcdbas_pdev); | 584 | /* |
585 | * make sure functions that use dcdbas_pdev are called | ||
586 | * before platform_device_unregister | ||
587 | */ | ||
585 | unregister_reboot_notifier(&dcdbas_reboot_nb); | 588 | unregister_reboot_notifier(&dcdbas_reboot_nb); |
586 | smi_data_buf_free(); | 589 | smi_data_buf_free(); |
590 | platform_device_unregister(dcdbas_pdev); | ||
587 | } | 591 | } |
588 | 592 | ||
589 | module_init(dcdbas_init); | 593 | module_init(dcdbas_init); |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c58295914365..7230d4e08196 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -113,6 +113,16 @@ config SENSORS_DS1621 | |||
113 | This driver can also be built as a module. If so, the module | 113 | This driver can also be built as a module. If so, the module |
114 | will be called ds1621. | 114 | will be called ds1621. |
115 | 115 | ||
116 | config SENSORS_F71805F | ||
117 | tristate "Fintek F71805F/FG" | ||
118 | depends on HWMON && EXPERIMENTAL | ||
119 | help | ||
120 | If you say yes here you get support for hardware monitoring | ||
121 | features of the Fintek F71805F/FG chips. | ||
122 | |||
123 | This driver can also be built as a module. If so, the module | ||
124 | will be called f71805f. | ||
125 | |||
116 | config SENSORS_FSCHER | 126 | config SENSORS_FSCHER |
117 | tristate "FSC Hermes" | 127 | tristate "FSC Hermes" |
118 | depends on HWMON && I2C && EXPERIMENTAL | 128 | depends on HWMON && I2C && EXPERIMENTAL |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 06d4a1d14105..fbdb8d911a72 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o | |||
18 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o | 18 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o |
19 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | 19 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o |
20 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | 20 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o |
21 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o | ||
21 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o | 22 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o |
22 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o | 23 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o |
23 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o | 24 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o |
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c new file mode 100644 index 000000000000..e029e0a94ecc --- /dev/null +++ b/drivers/hwmon/f71805f.c | |||
@@ -0,0 +1,908 @@ | |||
1 | /* | ||
2 | * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated | ||
3 | * hardware monitoring features | ||
4 | * Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> | ||
5 | * | ||
6 | * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates | ||
7 | * complete hardware monitoring features: voltage, fan and temperature | ||
8 | * sensors, and manual and automatic fan speed control. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/jiffies.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/hwmon.h> | ||
31 | #include <linux/hwmon-sysfs.h> | ||
32 | #include <linux/err.h> | ||
33 | #include <asm/io.h> | ||
34 | |||
35 | static struct platform_device *pdev; | ||
36 | |||
37 | #define DRVNAME "f71805f" | ||
38 | |||
39 | /* | ||
40 | * Super-I/O constants and functions | ||
41 | */ | ||
42 | |||
43 | #define F71805F_LD_HWM 0x04 | ||
44 | |||
45 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | ||
46 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | ||
47 | #define SIO_REG_DEVREV 0x22 /* Device revision */ | ||
48 | #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ | ||
49 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | ||
50 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | ||
51 | |||
52 | #define SIO_FINTEK_ID 0x1934 | ||
53 | #define SIO_F71805F_ID 0x0406 | ||
54 | |||
55 | static inline int | ||
56 | superio_inb(int base, int reg) | ||
57 | { | ||
58 | outb(reg, base); | ||
59 | return inb(base + 1); | ||
60 | } | ||
61 | |||
62 | static int | ||
63 | superio_inw(int base, int reg) | ||
64 | { | ||
65 | int val; | ||
66 | outb(reg++, base); | ||
67 | val = inb(base + 1) << 8; | ||
68 | outb(reg, base); | ||
69 | val |= inb(base + 1); | ||
70 | return val; | ||
71 | } | ||
72 | |||
73 | static inline void | ||
74 | superio_select(int base, int ld) | ||
75 | { | ||
76 | outb(SIO_REG_LDSEL, base); | ||
77 | outb(ld, base + 1); | ||
78 | } | ||
79 | |||
80 | static inline void | ||
81 | superio_enter(int base) | ||
82 | { | ||
83 | outb(0x87, base); | ||
84 | outb(0x87, base); | ||
85 | } | ||
86 | |||
87 | static inline void | ||
88 | superio_exit(int base) | ||
89 | { | ||
90 | outb(0xaa, base); | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * ISA constants | ||
95 | */ | ||
96 | |||
97 | #define REGION_LENGTH 2 | ||
98 | #define ADDR_REG_OFFSET 0 | ||
99 | #define DATA_REG_OFFSET 1 | ||
100 | |||
101 | static struct resource f71805f_resource __initdata = { | ||
102 | .flags = IORESOURCE_IO, | ||
103 | }; | ||
104 | |||
105 | /* | ||
106 | * Registers | ||
107 | */ | ||
108 | |||
109 | /* in nr from 0 to 8 (8-bit values) */ | ||
110 | #define F71805F_REG_IN(nr) (0x10 + (nr)) | ||
111 | #define F71805F_REG_IN_HIGH(nr) (0x40 + 2 * (nr)) | ||
112 | #define F71805F_REG_IN_LOW(nr) (0x41 + 2 * (nr)) | ||
113 | /* fan nr from 0 to 2 (12-bit values, two registers) */ | ||
114 | #define F71805F_REG_FAN(nr) (0x20 + 2 * (nr)) | ||
115 | #define F71805F_REG_FAN_LOW(nr) (0x28 + 2 * (nr)) | ||
116 | #define F71805F_REG_FAN_CTRL(nr) (0x60 + 16 * (nr)) | ||
117 | /* temp nr from 0 to 2 (8-bit values) */ | ||
118 | #define F71805F_REG_TEMP(nr) (0x1B + (nr)) | ||
119 | #define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) | ||
120 | #define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr)) | ||
121 | #define F71805F_REG_TEMP_MODE 0x01 | ||
122 | |||
123 | #define F71805F_REG_START 0x00 | ||
124 | /* status nr from 0 to 2 */ | ||
125 | #define F71805F_REG_STATUS(nr) (0x36 + (nr)) | ||
126 | |||
127 | /* | ||
128 | * Data structures and manipulation thereof | ||
129 | */ | ||
130 | |||
131 | struct f71805f_data { | ||
132 | unsigned short addr; | ||
133 | const char *name; | ||
134 | struct semaphore lock; | ||
135 | struct class_device *class_dev; | ||
136 | |||
137 | struct semaphore update_lock; | ||
138 | char valid; /* !=0 if following fields are valid */ | ||
139 | unsigned long last_updated; /* In jiffies */ | ||
140 | unsigned long last_limits; /* In jiffies */ | ||
141 | |||
142 | /* Register values */ | ||
143 | u8 in[9]; | ||
144 | u8 in_high[9]; | ||
145 | u8 in_low[9]; | ||
146 | u16 fan[3]; | ||
147 | u16 fan_low[3]; | ||
148 | u8 fan_enabled; /* Read once at init time */ | ||
149 | u8 temp[3]; | ||
150 | u8 temp_high[3]; | ||
151 | u8 temp_hyst[3]; | ||
152 | u8 temp_mode; | ||
153 | u8 alarms[3]; | ||
154 | }; | ||
155 | |||
156 | static inline long in_from_reg(u8 reg) | ||
157 | { | ||
158 | return (reg * 8); | ||
159 | } | ||
160 | |||
161 | /* The 2 least significant bits are not used */ | ||
162 | static inline u8 in_to_reg(long val) | ||
163 | { | ||
164 | if (val <= 0) | ||
165 | return 0; | ||
166 | if (val >= 2016) | ||
167 | return 0xfc; | ||
168 | return (((val + 16) / 32) << 2); | ||
169 | } | ||
170 | |||
171 | /* in0 is downscaled by a factor 2 internally */ | ||
172 | static inline long in0_from_reg(u8 reg) | ||
173 | { | ||
174 | return (reg * 16); | ||
175 | } | ||
176 | |||
177 | static inline u8 in0_to_reg(long val) | ||
178 | { | ||
179 | if (val <= 0) | ||
180 | return 0; | ||
181 | if (val >= 4032) | ||
182 | return 0xfc; | ||
183 | return (((val + 32) / 64) << 2); | ||
184 | } | ||
185 | |||
186 | /* The 4 most significant bits are not used */ | ||
187 | static inline long fan_from_reg(u16 reg) | ||
188 | { | ||
189 | reg &= 0xfff; | ||
190 | if (!reg || reg == 0xfff) | ||
191 | return 0; | ||
192 | return (1500000 / reg); | ||
193 | } | ||
194 | |||
195 | static inline u16 fan_to_reg(long rpm) | ||
196 | { | ||
197 | /* If the low limit is set below what the chip can measure, | ||
198 | store the largest possible 12-bit value in the registers, | ||
199 | so that no alarm will ever trigger. */ | ||
200 | if (rpm < 367) | ||
201 | return 0xfff; | ||
202 | return (1500000 / rpm); | ||
203 | } | ||
204 | |||
205 | static inline long temp_from_reg(u8 reg) | ||
206 | { | ||
207 | return (reg * 1000); | ||
208 | } | ||
209 | |||
210 | static inline u8 temp_to_reg(long val) | ||
211 | { | ||
212 | if (val < 0) | ||
213 | val = 0; | ||
214 | else if (val > 1000 * 0xff) | ||
215 | val = 0xff; | ||
216 | return ((val + 500) / 1000); | ||
217 | } | ||
218 | |||
219 | /* | ||
220 | * Device I/O access | ||
221 | */ | ||
222 | |||
223 | static u8 f71805f_read8(struct f71805f_data *data, u8 reg) | ||
224 | { | ||
225 | u8 val; | ||
226 | |||
227 | down(&data->lock); | ||
228 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
229 | val = inb(data->addr + DATA_REG_OFFSET); | ||
230 | up(&data->lock); | ||
231 | |||
232 | return val; | ||
233 | } | ||
234 | |||
235 | static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val) | ||
236 | { | ||
237 | down(&data->lock); | ||
238 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
239 | outb(val, data->addr + DATA_REG_OFFSET); | ||
240 | up(&data->lock); | ||
241 | } | ||
242 | |||
243 | /* It is important to read the MSB first, because doing so latches the | ||
244 | value of the LSB, so we are sure both bytes belong to the same value. */ | ||
245 | static u16 f71805f_read16(struct f71805f_data *data, u8 reg) | ||
246 | { | ||
247 | u16 val; | ||
248 | |||
249 | down(&data->lock); | ||
250 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
251 | val = inb(data->addr + DATA_REG_OFFSET) << 8; | ||
252 | outb(++reg, data->addr + ADDR_REG_OFFSET); | ||
253 | val |= inb(data->addr + DATA_REG_OFFSET); | ||
254 | up(&data->lock); | ||
255 | |||
256 | return val; | ||
257 | } | ||
258 | |||
259 | static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val) | ||
260 | { | ||
261 | down(&data->lock); | ||
262 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
263 | outb(val >> 8, data->addr + DATA_REG_OFFSET); | ||
264 | outb(++reg, data->addr + ADDR_REG_OFFSET); | ||
265 | outb(val & 0xff, data->addr + DATA_REG_OFFSET); | ||
266 | up(&data->lock); | ||
267 | } | ||
268 | |||
269 | static struct f71805f_data *f71805f_update_device(struct device *dev) | ||
270 | { | ||
271 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
272 | int nr; | ||
273 | |||
274 | down(&data->update_lock); | ||
275 | |||
276 | /* Limit registers cache is refreshed after 60 seconds */ | ||
277 | if (time_after(jiffies, data->last_updated + 60 * HZ) | ||
278 | || !data->valid) { | ||
279 | for (nr = 0; nr < 9; nr++) { | ||
280 | data->in_high[nr] = f71805f_read8(data, | ||
281 | F71805F_REG_IN_HIGH(nr)); | ||
282 | data->in_low[nr] = f71805f_read8(data, | ||
283 | F71805F_REG_IN_LOW(nr)); | ||
284 | } | ||
285 | for (nr = 0; nr < 3; nr++) { | ||
286 | if (data->fan_enabled & (1 << nr)) | ||
287 | data->fan_low[nr] = f71805f_read16(data, | ||
288 | F71805F_REG_FAN_LOW(nr)); | ||
289 | } | ||
290 | for (nr = 0; nr < 3; nr++) { | ||
291 | data->temp_high[nr] = f71805f_read8(data, | ||
292 | F71805F_REG_TEMP_HIGH(nr)); | ||
293 | data->temp_hyst[nr] = f71805f_read8(data, | ||
294 | F71805F_REG_TEMP_HYST(nr)); | ||
295 | } | ||
296 | data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE); | ||
297 | |||
298 | data->last_limits = jiffies; | ||
299 | } | ||
300 | |||
301 | /* Measurement registers cache is refreshed after 1 second */ | ||
302 | if (time_after(jiffies, data->last_updated + HZ) | ||
303 | || !data->valid) { | ||
304 | for (nr = 0; nr < 9; nr++) { | ||
305 | data->in[nr] = f71805f_read8(data, | ||
306 | F71805F_REG_IN(nr)); | ||
307 | } | ||
308 | for (nr = 0; nr < 3; nr++) { | ||
309 | if (data->fan_enabled & (1 << nr)) | ||
310 | data->fan[nr] = f71805f_read16(data, | ||
311 | F71805F_REG_FAN(nr)); | ||
312 | } | ||
313 | for (nr = 0; nr < 3; nr++) { | ||
314 | data->temp[nr] = f71805f_read8(data, | ||
315 | F71805F_REG_TEMP(nr)); | ||
316 | } | ||
317 | for (nr = 0; nr < 3; nr++) { | ||
318 | data->alarms[nr] = f71805f_read8(data, | ||
319 | F71805F_REG_STATUS(nr)); | ||
320 | } | ||
321 | |||
322 | data->last_updated = jiffies; | ||
323 | data->valid = 1; | ||
324 | } | ||
325 | |||
326 | up(&data->update_lock); | ||
327 | |||
328 | return data; | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * Sysfs interface | ||
333 | */ | ||
334 | |||
335 | static ssize_t show_in0(struct device *dev, struct device_attribute *devattr, | ||
336 | char *buf) | ||
337 | { | ||
338 | struct f71805f_data *data = f71805f_update_device(dev); | ||
339 | |||
340 | return sprintf(buf, "%ld\n", in0_from_reg(data->in[0])); | ||
341 | } | ||
342 | |||
343 | static ssize_t show_in0_max(struct device *dev, struct device_attribute | ||
344 | *devattr, char *buf) | ||
345 | { | ||
346 | struct f71805f_data *data = f71805f_update_device(dev); | ||
347 | |||
348 | return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[0])); | ||
349 | } | ||
350 | |||
351 | static ssize_t show_in0_min(struct device *dev, struct device_attribute | ||
352 | *devattr, char *buf) | ||
353 | { | ||
354 | struct f71805f_data *data = f71805f_update_device(dev); | ||
355 | |||
356 | return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[0])); | ||
357 | } | ||
358 | |||
359 | static ssize_t set_in0_max(struct device *dev, struct device_attribute | ||
360 | *devattr, const char *buf, size_t count) | ||
361 | { | ||
362 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
363 | long val = simple_strtol(buf, NULL, 10); | ||
364 | |||
365 | down(&data->update_lock); | ||
366 | data->in_high[0] = in0_to_reg(val); | ||
367 | f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]); | ||
368 | up(&data->update_lock); | ||
369 | |||
370 | return count; | ||
371 | } | ||
372 | |||
373 | static ssize_t set_in0_min(struct device *dev, struct device_attribute | ||
374 | *devattr, const char *buf, size_t count) | ||
375 | { | ||
376 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
377 | long val = simple_strtol(buf, NULL, 10); | ||
378 | |||
379 | down(&data->update_lock); | ||
380 | data->in_low[0] = in0_to_reg(val); | ||
381 | f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]); | ||
382 | up(&data->update_lock); | ||
383 | |||
384 | return count; | ||
385 | } | ||
386 | |||
387 | static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL); | ||
388 | static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max); | ||
389 | static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min); | ||
390 | |||
391 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, | ||
392 | char *buf) | ||
393 | { | ||
394 | struct f71805f_data *data = f71805f_update_device(dev); | ||
395 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
396 | int nr = attr->index; | ||
397 | |||
398 | return sprintf(buf, "%ld\n", in_from_reg(data->in[nr])); | ||
399 | } | ||
400 | |||
401 | static ssize_t show_in_max(struct device *dev, struct device_attribute | ||
402 | *devattr, char *buf) | ||
403 | { | ||
404 | struct f71805f_data *data = f71805f_update_device(dev); | ||
405 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
406 | int nr = attr->index; | ||
407 | |||
408 | return sprintf(buf, "%ld\n", in_from_reg(data->in_high[nr])); | ||
409 | } | ||
410 | |||
411 | static ssize_t show_in_min(struct device *dev, struct device_attribute | ||
412 | *devattr, char *buf) | ||
413 | { | ||
414 | struct f71805f_data *data = f71805f_update_device(dev); | ||
415 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
416 | int nr = attr->index; | ||
417 | |||
418 | return sprintf(buf, "%ld\n", in_from_reg(data->in_low[nr])); | ||
419 | } | ||
420 | |||
421 | static ssize_t set_in_max(struct device *dev, struct device_attribute | ||
422 | *devattr, const char *buf, size_t count) | ||
423 | { | ||
424 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
425 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
426 | int nr = attr->index; | ||
427 | long val = simple_strtol(buf, NULL, 10); | ||
428 | |||
429 | down(&data->update_lock); | ||
430 | data->in_high[nr] = in_to_reg(val); | ||
431 | f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]); | ||
432 | up(&data->update_lock); | ||
433 | |||
434 | return count; | ||
435 | } | ||
436 | |||
437 | static ssize_t set_in_min(struct device *dev, struct device_attribute | ||
438 | *devattr, const char *buf, size_t count) | ||
439 | { | ||
440 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
441 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
442 | int nr = attr->index; | ||
443 | long val = simple_strtol(buf, NULL, 10); | ||
444 | |||
445 | down(&data->update_lock); | ||
446 | data->in_low[nr] = in_to_reg(val); | ||
447 | f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]); | ||
448 | up(&data->update_lock); | ||
449 | |||
450 | return count; | ||
451 | } | ||
452 | |||
453 | #define sysfs_in(offset) \ | ||
454 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ | ||
455 | show_in, NULL, offset); \ | ||
456 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
457 | show_in_max, set_in_max, offset); \ | ||
458 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
459 | show_in_min, set_in_min, offset) | ||
460 | |||
461 | sysfs_in(1); | ||
462 | sysfs_in(2); | ||
463 | sysfs_in(3); | ||
464 | sysfs_in(4); | ||
465 | sysfs_in(5); | ||
466 | sysfs_in(6); | ||
467 | sysfs_in(7); | ||
468 | sysfs_in(8); | ||
469 | |||
470 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
471 | char *buf) | ||
472 | { | ||
473 | struct f71805f_data *data = f71805f_update_device(dev); | ||
474 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
475 | int nr = attr->index; | ||
476 | |||
477 | return sprintf(buf, "%ld\n", fan_from_reg(data->fan[nr])); | ||
478 | } | ||
479 | |||
480 | static ssize_t show_fan_min(struct device *dev, struct device_attribute | ||
481 | *devattr, char *buf) | ||
482 | { | ||
483 | struct f71805f_data *data = f71805f_update_device(dev); | ||
484 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
485 | int nr = attr->index; | ||
486 | |||
487 | return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr])); | ||
488 | } | ||
489 | |||
490 | static ssize_t set_fan_min(struct device *dev, struct device_attribute | ||
491 | *devattr, const char *buf, size_t count) | ||
492 | { | ||
493 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
494 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
495 | int nr = attr->index; | ||
496 | long val = simple_strtol(buf, NULL, 10); | ||
497 | |||
498 | down(&data->update_lock); | ||
499 | data->fan_low[nr] = fan_to_reg(val); | ||
500 | f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]); | ||
501 | up(&data->update_lock); | ||
502 | |||
503 | return count; | ||
504 | } | ||
505 | |||
506 | #define sysfs_fan(offset) \ | ||
507 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | ||
508 | show_fan, NULL, offset - 1); \ | ||
509 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
510 | show_fan_min, set_fan_min, offset - 1) | ||
511 | |||
512 | sysfs_fan(1); | ||
513 | sysfs_fan(2); | ||
514 | sysfs_fan(3); | ||
515 | |||
516 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
517 | char *buf) | ||
518 | { | ||
519 | struct f71805f_data *data = f71805f_update_device(dev); | ||
520 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
521 | int nr = attr->index; | ||
522 | |||
523 | return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr])); | ||
524 | } | ||
525 | |||
526 | static ssize_t show_temp_max(struct device *dev, struct device_attribute | ||
527 | *devattr, char *buf) | ||
528 | { | ||
529 | struct f71805f_data *data = f71805f_update_device(dev); | ||
530 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
531 | int nr = attr->index; | ||
532 | |||
533 | return sprintf(buf, "%ld\n", temp_from_reg(data->temp_high[nr])); | ||
534 | } | ||
535 | |||
536 | static ssize_t show_temp_hyst(struct device *dev, struct device_attribute | ||
537 | *devattr, char *buf) | ||
538 | { | ||
539 | struct f71805f_data *data = f71805f_update_device(dev); | ||
540 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
541 | int nr = attr->index; | ||
542 | |||
543 | return sprintf(buf, "%ld\n", temp_from_reg(data->temp_hyst[nr])); | ||
544 | } | ||
545 | |||
546 | static ssize_t show_temp_type(struct device *dev, struct device_attribute | ||
547 | *devattr, char *buf) | ||
548 | { | ||
549 | struct f71805f_data *data = f71805f_update_device(dev); | ||
550 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
551 | int nr = attr->index; | ||
552 | |||
553 | /* 3 is diode, 4 is thermistor */ | ||
554 | return sprintf(buf, "%u\n", (data->temp_mode & (1 << nr)) ? 3 : 4); | ||
555 | } | ||
556 | |||
557 | static ssize_t set_temp_max(struct device *dev, struct device_attribute | ||
558 | *devattr, const char *buf, size_t count) | ||
559 | { | ||
560 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
561 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
562 | int nr = attr->index; | ||
563 | long val = simple_strtol(buf, NULL, 10); | ||
564 | |||
565 | down(&data->update_lock); | ||
566 | data->temp_high[nr] = temp_to_reg(val); | ||
567 | f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]); | ||
568 | up(&data->update_lock); | ||
569 | |||
570 | return count; | ||
571 | } | ||
572 | |||
573 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute | ||
574 | *devattr, const char *buf, size_t count) | ||
575 | { | ||
576 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
577 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
578 | int nr = attr->index; | ||
579 | long val = simple_strtol(buf, NULL, 10); | ||
580 | |||
581 | down(&data->update_lock); | ||
582 | data->temp_hyst[nr] = temp_to_reg(val); | ||
583 | f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]); | ||
584 | up(&data->update_lock); | ||
585 | |||
586 | return count; | ||
587 | } | ||
588 | |||
589 | #define sysfs_temp(offset) \ | ||
590 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | ||
591 | show_temp, NULL, offset - 1); \ | ||
592 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | ||
593 | show_temp_max, set_temp_max, offset - 1); \ | ||
594 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ | ||
595 | show_temp_hyst, set_temp_hyst, offset - 1); \ | ||
596 | static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO, \ | ||
597 | show_temp_type, NULL, offset - 1) | ||
598 | |||
599 | sysfs_temp(1); | ||
600 | sysfs_temp(2); | ||
601 | sysfs_temp(3); | ||
602 | |||
603 | static ssize_t show_alarms_in(struct device *dev, struct device_attribute | ||
604 | *devattr, char *buf) | ||
605 | { | ||
606 | struct f71805f_data *data = f71805f_update_device(dev); | ||
607 | |||
608 | return sprintf(buf, "%d\n", data->alarms[0] | | ||
609 | ((data->alarms[1] & 0x01) << 8)); | ||
610 | } | ||
611 | |||
612 | static ssize_t show_alarms_fan(struct device *dev, struct device_attribute | ||
613 | *devattr, char *buf) | ||
614 | { | ||
615 | struct f71805f_data *data = f71805f_update_device(dev); | ||
616 | |||
617 | return sprintf(buf, "%d\n", data->alarms[2] & 0x07); | ||
618 | } | ||
619 | |||
620 | static ssize_t show_alarms_temp(struct device *dev, struct device_attribute | ||
621 | *devattr, char *buf) | ||
622 | { | ||
623 | struct f71805f_data *data = f71805f_update_device(dev); | ||
624 | |||
625 | return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07); | ||
626 | } | ||
627 | |||
628 | static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL); | ||
629 | static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL); | ||
630 | static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL); | ||
631 | |||
632 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
633 | *devattr, char *buf) | ||
634 | { | ||
635 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
636 | |||
637 | return sprintf(buf, "%s\n", data->name); | ||
638 | } | ||
639 | |||
640 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
641 | |||
642 | /* | ||
643 | * Device registration and initialization | ||
644 | */ | ||
645 | |||
646 | static void __devinit f71805f_init_device(struct f71805f_data *data) | ||
647 | { | ||
648 | u8 reg; | ||
649 | int i; | ||
650 | |||
651 | reg = f71805f_read8(data, F71805F_REG_START); | ||
652 | if ((reg & 0x41) != 0x01) { | ||
653 | printk(KERN_DEBUG DRVNAME ": Starting monitoring " | ||
654 | "operations\n"); | ||
655 | f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40); | ||
656 | } | ||
657 | |||
658 | /* Fan monitoring can be disabled. If it is, we won't be polling | ||
659 | the register values, and won't create the related sysfs files. */ | ||
660 | for (i = 0; i < 3; i++) { | ||
661 | reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(i)); | ||
662 | if (!(reg & 0x80)) | ||
663 | data->fan_enabled |= (1 << i); | ||
664 | } | ||
665 | } | ||
666 | |||
667 | static int __devinit f71805f_probe(struct platform_device *pdev) | ||
668 | { | ||
669 | struct f71805f_data *data; | ||
670 | struct resource *res; | ||
671 | int err; | ||
672 | |||
673 | if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) { | ||
674 | err = -ENOMEM; | ||
675 | printk(KERN_ERR DRVNAME ": Out of memory\n"); | ||
676 | goto exit; | ||
677 | } | ||
678 | |||
679 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
680 | data->addr = res->start; | ||
681 | init_MUTEX(&data->lock); | ||
682 | data->name = "f71805f"; | ||
683 | init_MUTEX(&data->update_lock); | ||
684 | |||
685 | platform_set_drvdata(pdev, data); | ||
686 | |||
687 | data->class_dev = hwmon_device_register(&pdev->dev); | ||
688 | if (IS_ERR(data->class_dev)) { | ||
689 | err = PTR_ERR(data->class_dev); | ||
690 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); | ||
691 | goto exit_free; | ||
692 | } | ||
693 | |||
694 | /* Initialize the F71805F chip */ | ||
695 | f71805f_init_device(data); | ||
696 | |||
697 | /* Register sysfs interface files */ | ||
698 | device_create_file(&pdev->dev, &dev_attr_in0_input); | ||
699 | device_create_file(&pdev->dev, &dev_attr_in0_max); | ||
700 | device_create_file(&pdev->dev, &dev_attr_in0_min); | ||
701 | device_create_file(&pdev->dev, &sensor_dev_attr_in1_input.dev_attr); | ||
702 | device_create_file(&pdev->dev, &sensor_dev_attr_in2_input.dev_attr); | ||
703 | device_create_file(&pdev->dev, &sensor_dev_attr_in3_input.dev_attr); | ||
704 | device_create_file(&pdev->dev, &sensor_dev_attr_in4_input.dev_attr); | ||
705 | device_create_file(&pdev->dev, &sensor_dev_attr_in5_input.dev_attr); | ||
706 | device_create_file(&pdev->dev, &sensor_dev_attr_in6_input.dev_attr); | ||
707 | device_create_file(&pdev->dev, &sensor_dev_attr_in7_input.dev_attr); | ||
708 | device_create_file(&pdev->dev, &sensor_dev_attr_in8_input.dev_attr); | ||
709 | device_create_file(&pdev->dev, &sensor_dev_attr_in1_max.dev_attr); | ||
710 | device_create_file(&pdev->dev, &sensor_dev_attr_in2_max.dev_attr); | ||
711 | device_create_file(&pdev->dev, &sensor_dev_attr_in3_max.dev_attr); | ||
712 | device_create_file(&pdev->dev, &sensor_dev_attr_in4_max.dev_attr); | ||
713 | device_create_file(&pdev->dev, &sensor_dev_attr_in5_max.dev_attr); | ||
714 | device_create_file(&pdev->dev, &sensor_dev_attr_in6_max.dev_attr); | ||
715 | device_create_file(&pdev->dev, &sensor_dev_attr_in7_max.dev_attr); | ||
716 | device_create_file(&pdev->dev, &sensor_dev_attr_in8_max.dev_attr); | ||
717 | device_create_file(&pdev->dev, &sensor_dev_attr_in1_min.dev_attr); | ||
718 | device_create_file(&pdev->dev, &sensor_dev_attr_in2_min.dev_attr); | ||
719 | device_create_file(&pdev->dev, &sensor_dev_attr_in3_min.dev_attr); | ||
720 | device_create_file(&pdev->dev, &sensor_dev_attr_in4_min.dev_attr); | ||
721 | device_create_file(&pdev->dev, &sensor_dev_attr_in5_min.dev_attr); | ||
722 | device_create_file(&pdev->dev, &sensor_dev_attr_in6_min.dev_attr); | ||
723 | device_create_file(&pdev->dev, &sensor_dev_attr_in7_min.dev_attr); | ||
724 | device_create_file(&pdev->dev, &sensor_dev_attr_in8_min.dev_attr); | ||
725 | if (data->fan_enabled & (1 << 0)) { | ||
726 | device_create_file(&pdev->dev, | ||
727 | &sensor_dev_attr_fan1_input.dev_attr); | ||
728 | device_create_file(&pdev->dev, | ||
729 | &sensor_dev_attr_fan1_min.dev_attr); | ||
730 | } | ||
731 | if (data->fan_enabled & (1 << 1)) { | ||
732 | device_create_file(&pdev->dev, | ||
733 | &sensor_dev_attr_fan2_input.dev_attr); | ||
734 | device_create_file(&pdev->dev, | ||
735 | &sensor_dev_attr_fan2_min.dev_attr); | ||
736 | } | ||
737 | if (data->fan_enabled & (1 << 2)) { | ||
738 | device_create_file(&pdev->dev, | ||
739 | &sensor_dev_attr_fan3_input.dev_attr); | ||
740 | device_create_file(&pdev->dev, | ||
741 | &sensor_dev_attr_fan3_min.dev_attr); | ||
742 | } | ||
743 | device_create_file(&pdev->dev, | ||
744 | &sensor_dev_attr_temp1_input.dev_attr); | ||
745 | device_create_file(&pdev->dev, | ||
746 | &sensor_dev_attr_temp2_input.dev_attr); | ||
747 | device_create_file(&pdev->dev, | ||
748 | &sensor_dev_attr_temp3_input.dev_attr); | ||
749 | device_create_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
750 | device_create_file(&pdev->dev, &sensor_dev_attr_temp2_max.dev_attr); | ||
751 | device_create_file(&pdev->dev, &sensor_dev_attr_temp3_max.dev_attr); | ||
752 | device_create_file(&pdev->dev, | ||
753 | &sensor_dev_attr_temp1_max_hyst.dev_attr); | ||
754 | device_create_file(&pdev->dev, | ||
755 | &sensor_dev_attr_temp2_max_hyst.dev_attr); | ||
756 | device_create_file(&pdev->dev, | ||
757 | &sensor_dev_attr_temp3_max_hyst.dev_attr); | ||
758 | device_create_file(&pdev->dev, &sensor_dev_attr_temp1_type.dev_attr); | ||
759 | device_create_file(&pdev->dev, &sensor_dev_attr_temp2_type.dev_attr); | ||
760 | device_create_file(&pdev->dev, &sensor_dev_attr_temp3_type.dev_attr); | ||
761 | device_create_file(&pdev->dev, &dev_attr_alarms_in); | ||
762 | device_create_file(&pdev->dev, &dev_attr_alarms_fan); | ||
763 | device_create_file(&pdev->dev, &dev_attr_alarms_temp); | ||
764 | device_create_file(&pdev->dev, &dev_attr_name); | ||
765 | |||
766 | return 0; | ||
767 | |||
768 | exit_free: | ||
769 | kfree(data); | ||
770 | exit: | ||
771 | return err; | ||
772 | } | ||
773 | |||
774 | static int __devexit f71805f_remove(struct platform_device *pdev) | ||
775 | { | ||
776 | struct f71805f_data *data = platform_get_drvdata(pdev); | ||
777 | |||
778 | platform_set_drvdata(pdev, NULL); | ||
779 | hwmon_device_unregister(data->class_dev); | ||
780 | kfree(data); | ||
781 | |||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | static struct platform_driver f71805f_driver = { | ||
786 | .driver = { | ||
787 | .owner = THIS_MODULE, | ||
788 | .name = DRVNAME, | ||
789 | }, | ||
790 | .probe = f71805f_probe, | ||
791 | .remove = __devexit_p(f71805f_remove), | ||
792 | }; | ||
793 | |||
794 | static int __init f71805f_device_add(unsigned short address) | ||
795 | { | ||
796 | int err; | ||
797 | |||
798 | pdev = platform_device_alloc(DRVNAME, address); | ||
799 | if (!pdev) { | ||
800 | err = -ENOMEM; | ||
801 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | ||
802 | goto exit; | ||
803 | } | ||
804 | |||
805 | f71805f_resource.start = address; | ||
806 | f71805f_resource.end = address + REGION_LENGTH - 1; | ||
807 | f71805f_resource.name = pdev->name; | ||
808 | err = platform_device_add_resources(pdev, &f71805f_resource, 1); | ||
809 | if (err) { | ||
810 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | ||
811 | "(%d)\n", err); | ||
812 | goto exit_device_put; | ||
813 | } | ||
814 | |||
815 | err = platform_device_add(pdev); | ||
816 | if (err) { | ||
817 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | ||
818 | err); | ||
819 | goto exit_device_put; | ||
820 | } | ||
821 | |||
822 | return 0; | ||
823 | |||
824 | exit_device_put: | ||
825 | platform_device_put(pdev); | ||
826 | exit: | ||
827 | return err; | ||
828 | } | ||
829 | |||
830 | static int __init f71805f_find(int sioaddr, unsigned short *address) | ||
831 | { | ||
832 | int err = -ENODEV; | ||
833 | u16 devid; | ||
834 | |||
835 | superio_enter(sioaddr); | ||
836 | |||
837 | devid = superio_inw(sioaddr, SIO_REG_MANID); | ||
838 | if (devid != SIO_FINTEK_ID) | ||
839 | goto exit; | ||
840 | |||
841 | devid = superio_inw(sioaddr, SIO_REG_DEVID); | ||
842 | if (devid != SIO_F71805F_ID) { | ||
843 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device, " | ||
844 | "skipping\n"); | ||
845 | goto exit; | ||
846 | } | ||
847 | |||
848 | superio_select(sioaddr, F71805F_LD_HWM); | ||
849 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | ||
850 | printk(KERN_WARNING DRVNAME ": Device not activated, " | ||
851 | "skipping\n"); | ||
852 | goto exit; | ||
853 | } | ||
854 | |||
855 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | ||
856 | if (*address == 0) { | ||
857 | printk(KERN_WARNING DRVNAME ": Base address not set, " | ||
858 | "skipping\n"); | ||
859 | goto exit; | ||
860 | } | ||
861 | |||
862 | err = 0; | ||
863 | printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n", | ||
864 | *address, superio_inb(sioaddr, SIO_REG_DEVREV)); | ||
865 | |||
866 | exit: | ||
867 | superio_exit(sioaddr); | ||
868 | return err; | ||
869 | } | ||
870 | |||
871 | static int __init f71805f_init(void) | ||
872 | { | ||
873 | int err; | ||
874 | unsigned short address; | ||
875 | |||
876 | if (f71805f_find(0x2e, &address) | ||
877 | && f71805f_find(0x4e, &address)) | ||
878 | return -ENODEV; | ||
879 | |||
880 | err = platform_driver_register(&f71805f_driver); | ||
881 | if (err) | ||
882 | goto exit; | ||
883 | |||
884 | /* Sets global pdev as a side effect */ | ||
885 | err = f71805f_device_add(address); | ||
886 | if (err) | ||
887 | goto exit_driver; | ||
888 | |||
889 | return 0; | ||
890 | |||
891 | exit_driver: | ||
892 | platform_driver_unregister(&f71805f_driver); | ||
893 | exit: | ||
894 | return err; | ||
895 | } | ||
896 | |||
897 | static void __exit f71805f_exit(void) | ||
898 | { | ||
899 | platform_device_unregister(pdev); | ||
900 | platform_driver_unregister(&f71805f_driver); | ||
901 | } | ||
902 | |||
903 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr>"); | ||
904 | MODULE_LICENSE("GPL"); | ||
905 | MODULE_DESCRIPTION("F71805F hardware monitoring driver"); | ||
906 | |||
907 | module_init(f71805f_init); | ||
908 | module_exit(f71805f_exit); | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 0da7c9c508c3..d7a9401600bb 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -45,8 +45,7 @@ | |||
45 | 45 | ||
46 | 46 | ||
47 | /* Addresses to scan */ | 47 | /* Addresses to scan */ |
48 | static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, | 48 | static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; |
49 | 0x2e, 0x2f, I2C_CLIENT_END }; | ||
50 | static unsigned short isa_address; | 49 | static unsigned short isa_address; |
51 | 50 | ||
52 | /* Insmod parameters */ | 51 | /* Insmod parameters */ |
@@ -830,6 +829,11 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
830 | if ((err = i2c_attach_client(new_client))) | 829 | if ((err = i2c_attach_client(new_client))) |
831 | goto ERROR2; | 830 | goto ERROR2; |
832 | 831 | ||
832 | if (!is_isa) | ||
833 | dev_info(&new_client->dev, "The I2C interface to IT87xxF " | ||
834 | "hardware monitoring chips is deprecated. Please " | ||
835 | "report if you still rely on it.\n"); | ||
836 | |||
833 | /* Check PWM configuration */ | 837 | /* Check PWM configuration */ |
834 | enable_pwm_interface = it87_check_pwm(new_client); | 838 | enable_pwm_interface = it87_check_pwm(new_client); |
835 | 839 | ||
@@ -1182,7 +1186,8 @@ static int __init sm_it87_init(void) | |||
1182 | 1186 | ||
1183 | static void __exit sm_it87_exit(void) | 1187 | static void __exit sm_it87_exit(void) |
1184 | { | 1188 | { |
1185 | i2c_isa_del_driver(&it87_isa_driver); | 1189 | if (isa_address) |
1190 | i2c_isa_del_driver(&it87_isa_driver); | ||
1186 | i2c_del_driver(&it87_driver); | 1191 | i2c_del_driver(&it87_driver); |
1187 | } | 1192 | } |
1188 | 1193 | ||
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index a2f420d01fb7..df9e02aaa70a 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c | |||
@@ -87,15 +87,15 @@ static struct i2c_driver lm77_driver = { | |||
87 | 87 | ||
88 | /* In the temperature registers, the low 3 bits are not part of the | 88 | /* In the temperature registers, the low 3 bits are not part of the |
89 | temperature values; they are the status bits. */ | 89 | temperature values; they are the status bits. */ |
90 | static inline u16 LM77_TEMP_TO_REG(int temp) | 90 | static inline s16 LM77_TEMP_TO_REG(int temp) |
91 | { | 91 | { |
92 | int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX); | 92 | int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX); |
93 | return (u16)((ntemp / 500) * 8); | 93 | return (ntemp / 500) * 8; |
94 | } | 94 | } |
95 | 95 | ||
96 | static inline int LM77_TEMP_FROM_REG(u16 reg) | 96 | static inline int LM77_TEMP_FROM_REG(s16 reg) |
97 | { | 97 | { |
98 | return ((int)reg / 8) * 500; | 98 | return (reg / 8) * 500; |
99 | } | 99 | } |
100 | 100 | ||
101 | /* sysfs stuff */ | 101 | /* sysfs stuff */ |
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 3eb08f004c0f..271e9cb9532c 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c | |||
@@ -437,12 +437,12 @@ static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | |||
437 | show_temp, NULL, offset - 1); \ | 437 | show_temp, NULL, offset - 1); \ |
438 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | 438 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ |
439 | show_temp_max, set_temp_max, offset - 1); \ | 439 | show_temp_max, set_temp_max, offset - 1); \ |
440 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ | 440 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ |
441 | show_temp_min, set_temp_min, offset - 1) | 441 | show_temp_min, set_temp_min, offset - 1) |
442 | 442 | ||
443 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp0, NULL); | 443 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp0, NULL); |
444 | static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp0_max, set_temp0_max); | 444 | static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp0_max, set_temp0_max); |
445 | static DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, show_temp0_min, set_temp0_min); | 445 | static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp0_min, set_temp0_min); |
446 | 446 | ||
447 | define_temperature_sysfs(2); | 447 | define_temperature_sysfs(2); |
448 | define_temperature_sysfs(3); | 448 | define_temperature_sysfs(3); |
@@ -451,7 +451,7 @@ define_temperature_sysfs(5); | |||
451 | define_temperature_sysfs(6); | 451 | define_temperature_sysfs(6); |
452 | 452 | ||
453 | #define CFG_INFO_TEMP(id) { &sensor_dev_attr_temp##id##_input.dev_attr, \ | 453 | #define CFG_INFO_TEMP(id) { &sensor_dev_attr_temp##id##_input.dev_attr, \ |
454 | &sensor_dev_attr_temp##id##_min.dev_attr, \ | 454 | &sensor_dev_attr_temp##id##_max_hyst.dev_attr, \ |
455 | &sensor_dev_attr_temp##id##_max.dev_attr } | 455 | &sensor_dev_attr_temp##id##_max.dev_attr } |
456 | #define CFG_INFO_VOLT(id) { &sensor_dev_attr_in##id##_input.dev_attr, \ | 456 | #define CFG_INFO_VOLT(id) { &sensor_dev_attr_in##id##_input.dev_attr, \ |
457 | &sensor_dev_attr_in##id##_min.dev_attr, \ | 457 | &sensor_dev_attr_in##id##_min.dev_attr, \ |
@@ -464,7 +464,7 @@ struct str_device_attr_table { | |||
464 | }; | 464 | }; |
465 | 465 | ||
466 | static struct str_device_attr_table cfg_info_temp[] = { | 466 | static struct str_device_attr_table cfg_info_temp[] = { |
467 | { &dev_attr_temp1_input, &dev_attr_temp1_min, &dev_attr_temp1_max }, | 467 | { &dev_attr_temp1_input, &dev_attr_temp1_max_hyst, &dev_attr_temp1_max }, |
468 | CFG_INFO_TEMP(2), | 468 | CFG_INFO_TEMP(2), |
469 | CFG_INFO_TEMP(3), | 469 | CFG_INFO_TEMP(3), |
470 | CFG_INFO_TEMP(4), | 470 | CFG_INFO_TEMP(4), |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 557114872f3c..64c1f8af5bb2 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -95,11 +95,16 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); | |||
95 | (0x39))) | 95 | (0x39))) |
96 | 96 | ||
97 | #define W83781D_REG_CONFIG 0x40 | 97 | #define W83781D_REG_CONFIG 0x40 |
98 | |||
99 | /* Interrupt status (W83781D, AS99127F) */ | ||
98 | #define W83781D_REG_ALARM1 0x41 | 100 | #define W83781D_REG_ALARM1 0x41 |
99 | #define W83781D_REG_ALARM2 0x42 | 101 | #define W83781D_REG_ALARM2 0x42 |
100 | #define W83781D_REG_ALARM3 0x450 /* not on W83781D */ | ||
101 | 102 | ||
102 | #define W83781D_REG_IRQ 0x4C | 103 | /* Real-time status (W83782D, W83783S, W83627HF) */ |
104 | #define W83782D_REG_ALARM1 0x459 | ||
105 | #define W83782D_REG_ALARM2 0x45A | ||
106 | #define W83782D_REG_ALARM3 0x45B | ||
107 | |||
103 | #define W83781D_REG_BEEP_CONFIG 0x4D | 108 | #define W83781D_REG_BEEP_CONFIG 0x4D |
104 | #define W83781D_REG_BEEP_INTS1 0x56 | 109 | #define W83781D_REG_BEEP_INTS1 0x56 |
105 | #define W83781D_REG_BEEP_INTS2 0x57 | 110 | #define W83781D_REG_BEEP_INTS2 0x57 |
@@ -1513,15 +1518,6 @@ w83781d_init_client(struct i2c_client *client) | |||
1513 | W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); | 1518 | W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); |
1514 | } | 1519 | } |
1515 | } | 1520 | } |
1516 | |||
1517 | if (type != w83781d) { | ||
1518 | /* enable comparator mode for temp2 and temp3 so | ||
1519 | alarm indication will work correctly */ | ||
1520 | i = w83781d_read_value(client, W83781D_REG_IRQ); | ||
1521 | if (!(i & 0x40)) | ||
1522 | w83781d_write_value(client, W83781D_REG_IRQ, | ||
1523 | i | 0x40); | ||
1524 | } | ||
1525 | } | 1521 | } |
1526 | 1522 | ||
1527 | /* Start monitoring */ | 1523 | /* Start monitoring */ |
@@ -1612,14 +1608,25 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1612 | data->fan_div[1] |= (i >> 4) & 0x04; | 1608 | data->fan_div[1] |= (i >> 4) & 0x04; |
1613 | data->fan_div[2] |= (i >> 5) & 0x04; | 1609 | data->fan_div[2] |= (i >> 5) & 0x04; |
1614 | } | 1610 | } |
1615 | data->alarms = | ||
1616 | w83781d_read_value(client, | ||
1617 | W83781D_REG_ALARM1) + | ||
1618 | (w83781d_read_value(client, W83781D_REG_ALARM2) << 8); | ||
1619 | if ((data->type == w83782d) || (data->type == w83627hf)) { | 1611 | if ((data->type == w83782d) || (data->type == w83627hf)) { |
1620 | data->alarms |= | 1612 | data->alarms = w83781d_read_value(client, |
1621 | w83781d_read_value(client, | 1613 | W83782D_REG_ALARM1) |
1622 | W83781D_REG_ALARM3) << 16; | 1614 | | (w83781d_read_value(client, |
1615 | W83782D_REG_ALARM2) << 8) | ||
1616 | | (w83781d_read_value(client, | ||
1617 | W83782D_REG_ALARM3) << 16); | ||
1618 | } else if (data->type == w83783s) { | ||
1619 | data->alarms = w83781d_read_value(client, | ||
1620 | W83782D_REG_ALARM1) | ||
1621 | | (w83781d_read_value(client, | ||
1622 | W83782D_REG_ALARM2) << 8); | ||
1623 | } else { | ||
1624 | /* No real-time status registers, fall back to | ||
1625 | interrupt status registers */ | ||
1626 | data->alarms = w83781d_read_value(client, | ||
1627 | W83781D_REG_ALARM1) | ||
1628 | | (w83781d_read_value(client, | ||
1629 | W83781D_REG_ALARM2) << 8); | ||
1623 | } | 1630 | } |
1624 | i = w83781d_read_value(client, W83781D_REG_BEEP_INTS2); | 1631 | i = w83781d_read_value(client, W83781D_REG_BEEP_INTS2); |
1625 | data->beep_enable = i >> 7; | 1632 | data->beep_enable = i >> 7; |
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index b176bf0c4c7b..a2f6bb676235 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -303,10 +303,6 @@ struct w83792d_data { | |||
303 | static int w83792d_attach_adapter(struct i2c_adapter *adapter); | 303 | static int w83792d_attach_adapter(struct i2c_adapter *adapter); |
304 | static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind); | 304 | static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind); |
305 | static int w83792d_detach_client(struct i2c_client *client); | 305 | static int w83792d_detach_client(struct i2c_client *client); |
306 | |||
307 | static int w83792d_read_value(struct i2c_client *client, u8 register); | ||
308 | static int w83792d_write_value(struct i2c_client *client, u8 register, | ||
309 | u8 value); | ||
310 | static struct w83792d_data *w83792d_update_device(struct device *dev); | 306 | static struct w83792d_data *w83792d_update_device(struct device *dev); |
311 | 307 | ||
312 | #ifdef DEBUG | 308 | #ifdef DEBUG |
@@ -329,6 +325,20 @@ static inline long in_count_from_reg(int nr, struct w83792d_data *data) | |||
329 | return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); | 325 | return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); |
330 | } | 326 | } |
331 | 327 | ||
328 | /* The SMBus locks itself. The Winbond W83792D chip has a bank register, | ||
329 | but the driver only accesses registers in bank 0, so we don't have | ||
330 | to switch banks and lock access between switches. */ | ||
331 | static inline int w83792d_read_value(struct i2c_client *client, u8 reg) | ||
332 | { | ||
333 | return i2c_smbus_read_byte_data(client, reg); | ||
334 | } | ||
335 | |||
336 | static inline int | ||
337 | w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
338 | { | ||
339 | return i2c_smbus_write_byte_data(client, reg, value); | ||
340 | } | ||
341 | |||
332 | /* following are the sysfs callback functions */ | 342 | /* following are the sysfs callback functions */ |
333 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | 343 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, |
334 | char *buf) | 344 | char *buf) |
@@ -1386,19 +1396,6 @@ w83792d_detach_client(struct i2c_client *client) | |||
1386 | return 0; | 1396 | return 0; |
1387 | } | 1397 | } |
1388 | 1398 | ||
1389 | /* The SMBus locks itself. The Winbond W83792D chip has a bank register, | ||
1390 | but the driver only accesses registers in bank 0, so we don't have | ||
1391 | to switch banks and lock access between switches. */ | ||
1392 | static int w83792d_read_value(struct i2c_client *client, u8 reg) | ||
1393 | { | ||
1394 | return i2c_smbus_read_byte_data(client, reg); | ||
1395 | } | ||
1396 | |||
1397 | static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
1398 | { | ||
1399 | return i2c_smbus_write_byte_data(client, reg, value); | ||
1400 | } | ||
1401 | |||
1402 | static void | 1399 | static void |
1403 | w83792d_init_client(struct i2c_client *client) | 1400 | w83792d_init_client(struct i2c_client *client) |
1404 | { | 1401 | { |
diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c index 938848ae162d..3df3f09995c2 100644 --- a/drivers/i2c/algos/i2c-algo-sibyte.c +++ b/drivers/i2c/algos/i2c-algo-sibyte.c | |||
@@ -202,7 +202,7 @@ EXPORT_SYMBOL(i2c_sibyte_del_bus); | |||
202 | #ifdef MODULE | 202 | #ifdef MODULE |
203 | MODULE_AUTHOR("Kip Walker, Broadcom Corp."); | 203 | MODULE_AUTHOR("Kip Walker, Broadcom Corp."); |
204 | MODULE_DESCRIPTION("SiByte I2C-Bus algorithm"); | 204 | MODULE_DESCRIPTION("SiByte I2C-Bus algorithm"); |
205 | MODULE_PARM(bit_scan, "i"); | 205 | module_param(bit_scan, int, 0); |
206 | MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); | 206 | MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); |
207 | MODULE_LICENSE("GPL"); | 207 | MODULE_LICENSE("GPL"); |
208 | 208 | ||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 08d5b8fed2dc..ff92735c7c85 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -124,6 +124,7 @@ config I2C_I801 | |||
124 | ICH6 | 124 | ICH6 |
125 | ICH7 | 125 | ICH7 |
126 | ESB2 | 126 | ESB2 |
127 | ICH8 | ||
127 | 128 | ||
128 | This driver can also be built as a module. If so, the module | 129 | This driver can also be built as a module. If so, the module |
129 | will be called i2c-i801. | 130 | will be called i2c-i801. |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 1c752ddc10e2..8e0f3158215f 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -32,6 +32,7 @@ | |||
32 | ICH6 266A | 32 | ICH6 266A |
33 | ICH7 27DA | 33 | ICH7 27DA |
34 | ESB2 269B | 34 | ESB2 269B |
35 | ICH8 283E | ||
35 | This driver supports several versions of Intel's I/O Controller Hubs (ICH). | 36 | This driver supports several versions of Intel's I/O Controller Hubs (ICH). |
36 | For SMBus support, they are similar to the PIIX4 and are part | 37 | For SMBus support, they are similar to the PIIX4 and are part |
37 | of Intel's '810' and other chipsets. | 38 | of Intel's '810' and other chipsets. |
@@ -527,6 +528,7 @@ static struct pci_device_id i801_ids[] = { | |||
527 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, | 528 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, |
528 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, | 529 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, |
529 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, | 530 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, |
531 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, | ||
530 | { 0, } | 532 | { 0, } |
531 | }; | 533 | }; |
532 | 534 | ||
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index 9f2ffef4d812..4344ae6b1fcb 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c | |||
@@ -72,16 +72,6 @@ static ssize_t show_adapter_name(struct device *dev, | |||
72 | } | 72 | } |
73 | static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); | 73 | static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); |
74 | 74 | ||
75 | static int i2c_isa_device_probe(struct device *dev) | ||
76 | { | ||
77 | return -ENODEV; | ||
78 | } | ||
79 | |||
80 | static int i2c_isa_device_remove(struct device *dev) | ||
81 | { | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | 75 | ||
86 | /* We implement an interface which resembles i2c_{add,del}_driver, | 76 | /* We implement an interface which resembles i2c_{add,del}_driver, |
87 | but for i2c-isa drivers. We don't have to remember and handle lists | 77 | but for i2c-isa drivers. We don't have to remember and handle lists |
@@ -93,8 +83,6 @@ int i2c_isa_add_driver(struct i2c_driver *driver) | |||
93 | 83 | ||
94 | /* Add the driver to the list of i2c drivers in the driver core */ | 84 | /* Add the driver to the list of i2c drivers in the driver core */ |
95 | driver->driver.bus = &i2c_bus_type; | 85 | driver->driver.bus = &i2c_bus_type; |
96 | driver->driver.probe = i2c_isa_device_probe; | ||
97 | driver->driver.remove = i2c_isa_device_remove; | ||
98 | res = driver_register(&driver->driver); | 86 | res = driver_register(&driver->driver); |
99 | if (res) | 87 | if (res) |
100 | return res; | 88 | return res; |
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c index 3e5eba9fcacb..c63025a4c861 100644 --- a/drivers/i2c/busses/i2c-parport-light.c +++ b/drivers/i2c/busses/i2c-parport-light.c | |||
@@ -121,14 +121,11 @@ static struct i2c_adapter parport_adapter = { | |||
121 | 121 | ||
122 | static int __init i2c_parport_init(void) | 122 | static int __init i2c_parport_init(void) |
123 | { | 123 | { |
124 | int type_count; | 124 | if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { |
125 | |||
126 | type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm); | ||
127 | if (type < 0 || type >= type_count) { | ||
128 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); | 125 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); |
129 | type = 0; | 126 | type = 0; |
130 | } | 127 | } |
131 | 128 | ||
132 | if (base == 0) { | 129 | if (base == 0) { |
133 | printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE); | 130 | printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE); |
134 | base = DEFAULT_BASE; | 131 | base = DEFAULT_BASE; |
@@ -152,7 +149,7 @@ static int __init i2c_parport_init(void) | |||
152 | release_region(base, 3); | 149 | release_region(base, 3); |
153 | return -ENODEV; | 150 | return -ENODEV; |
154 | } | 151 | } |
155 | 152 | ||
156 | return 0; | 153 | return 0; |
157 | } | 154 | } |
158 | 155 | ||
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 2854d858fc9b..7e2e8cd1c14a 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c | |||
@@ -241,14 +241,11 @@ static struct parport_driver i2c_parport_driver = { | |||
241 | 241 | ||
242 | static int __init i2c_parport_init(void) | 242 | static int __init i2c_parport_init(void) |
243 | { | 243 | { |
244 | int type_count; | 244 | if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { |
245 | |||
246 | type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm); | ||
247 | if (type < 0 || type >= type_count) { | ||
248 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); | 245 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); |
249 | type = 0; | 246 | type = 0; |
250 | } | 247 | } |
251 | 248 | ||
252 | return parport_register_driver(&i2c_parport_driver); | 249 | return parport_register_driver(&i2c_parport_driver); |
253 | } | 250 | } |
254 | 251 | ||
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 86e2234faf80..7579f4b256a8 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
@@ -861,7 +861,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *r | |||
861 | decode_ISR(isr); | 861 | decode_ISR(isr); |
862 | } | 862 | } |
863 | 863 | ||
864 | if (i2c->irqlogidx < sizeof(i2c->isrlog)/sizeof(u32)) | 864 | if (i2c->irqlogidx < ARRAY_SIZE(i2c->isrlog)) |
865 | i2c->isrlog[i2c->irqlogidx++] = isr; | 865 | i2c->isrlog[i2c->irqlogidx++] = isr; |
866 | 866 | ||
867 | show_state(i2c); | 867 | show_state(i2c); |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 0ce58b506046..1a2c9ab5d9e3 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -946,6 +946,20 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val | |||
946 | } | 946 | } |
947 | } | 947 | } |
948 | 948 | ||
949 | s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, | ||
950 | u8 length, u8 *values) | ||
951 | { | ||
952 | union i2c_smbus_data data; | ||
953 | |||
954 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
955 | length = I2C_SMBUS_BLOCK_MAX; | ||
956 | data.block[0] = length; | ||
957 | memcpy(data.block + 1, values, length); | ||
958 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
959 | I2C_SMBUS_WRITE, command, | ||
960 | I2C_SMBUS_I2C_BLOCK_DATA, &data); | ||
961 | } | ||
962 | |||
949 | /* Simulate a SMBus command using the i2c protocol | 963 | /* Simulate a SMBus command using the i2c protocol |
950 | No checking of parameters is done! */ | 964 | No checking of parameters is done! */ |
951 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, | 965 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, |
@@ -1150,6 +1164,7 @@ EXPORT_SYMBOL(i2c_smbus_read_word_data); | |||
1150 | EXPORT_SYMBOL(i2c_smbus_write_word_data); | 1164 | EXPORT_SYMBOL(i2c_smbus_write_word_data); |
1151 | EXPORT_SYMBOL(i2c_smbus_write_block_data); | 1165 | EXPORT_SYMBOL(i2c_smbus_write_block_data); |
1152 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); | 1166 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); |
1167 | EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); | ||
1153 | 1168 | ||
1154 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); | 1169 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); |
1155 | MODULE_DESCRIPTION("I2C-Bus main module"); | 1170 | MODULE_DESCRIPTION("I2C-Bus main module"); |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 6c60a9d2afd8..09086b8b6486 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -190,7 +190,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
190 | if (lba48) { | 190 | if (lba48) { |
191 | task_ioreg_t tasklets[10]; | 191 | task_ioreg_t tasklets[10]; |
192 | 192 | ||
193 | pr_debug("%s: LBA=0x%012llx\n", drive->name, block); | 193 | pr_debug("%s: LBA=0x%012llx\n", drive->name, |
194 | (unsigned long long)block); | ||
194 | 195 | ||
195 | tasklets[0] = 0; | 196 | tasklets[0] = 0; |
196 | tasklets[1] = 0; | 197 | tasklets[1] = 0; |
@@ -317,7 +318,8 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s | |||
317 | 318 | ||
318 | pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", | 319 | pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", |
319 | drive->name, rq_data_dir(rq) == READ ? "read" : "writ", | 320 | drive->name, rq_data_dir(rq) == READ ? "read" : "writ", |
320 | block, rq->nr_sectors, (unsigned long)rq->buffer); | 321 | (unsigned long long)block, rq->nr_sectors, |
322 | (unsigned long)rq->buffer); | ||
321 | 323 | ||
322 | if (hwif->rw_disk) | 324 | if (hwif->rw_disk) |
323 | hwif->rw_disk(drive, rq); | 325 | hwif->rw_disk(drive, rq); |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 9834dce4e20f..0606bd2f6020 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/timer.h> | 35 | #include <linux/timer.h> |
36 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
37 | #include <linux/sched.h> | ||
37 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
38 | #include <linux/major.h> | 39 | #include <linux/major.h> |
39 | #include <linux/errno.h> | 40 | #include <linux/errno.h> |
@@ -314,6 +315,8 @@ static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, | |||
314 | if (rq->bio) /* fs request */ | 315 | if (rq->bio) /* fs request */ |
315 | rq->errors = 0; | 316 | rq->errors = 0; |
316 | 317 | ||
318 | touch_softlockup_watchdog(); | ||
319 | |||
317 | switch (drive->hwif->data_phase) { | 320 | switch (drive->hwif->data_phase) { |
318 | case TASKFILE_MULTI_IN: | 321 | case TASKFILE_MULTI_IN: |
319 | case TASKFILE_MULTI_OUT: | 322 | case TASKFILE_MULTI_OUT: |
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 4c2af9020905..6213bd3caee5 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -445,6 +445,7 @@ static struct pcmcia_device_id ide_ids[] = { | |||
445 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), | 445 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), |
446 | PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), | 446 | PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), |
447 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), | 447 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), |
448 | PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), | ||
448 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), | 449 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), |
449 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), | 450 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), |
450 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), | 451 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), |
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 2b286e865163..43b96e298363 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
@@ -13,11 +13,6 @@ | |||
13 | * License along with this program; if not, write the Free Software | 13 | * License along with this program; if not, write the Free Software |
14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
15 | * | 15 | * |
16 | * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, | ||
17 | * Mountain View, CA 94043, or: | ||
18 | * | ||
19 | * http://www.sgi.com | ||
20 | * | ||
21 | * For further information regarding this notice, see: | 16 | * For further information regarding this notice, see: |
22 | * | 17 | * |
23 | * http://oss.sgi.com/projects/GenInfo/NoticeExplan | 18 | * http://oss.sgi.com/projects/GenInfo/NoticeExplan |
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 18d7eda38851..eca92eb475a1 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -137,15 +137,15 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device (default = 1)" | |||
137 | /* | 137 | /* |
138 | * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on | 138 | * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on |
139 | * if your sbp2 device is not properly handling the SCSI inquiry command. | 139 | * if your sbp2 device is not properly handling the SCSI inquiry command. |
140 | * This hack makes the inquiry look more like a typical MS Windows | 140 | * This hack makes the inquiry look more like a typical MS Windows inquiry |
141 | * inquiry. | 141 | * by enforcing 36 byte inquiry and avoiding access to mode_sense page 8. |
142 | * | 142 | * |
143 | * If force_inquiry_hack=1 is required for your device to work, | 143 | * If force_inquiry_hack=1 is required for your device to work, |
144 | * please submit the logged sbp2_firmware_revision value of this device to | 144 | * please submit the logged sbp2_firmware_revision value of this device to |
145 | * the linux1394-devel mailing list. | 145 | * the linux1394-devel mailing list. |
146 | */ | 146 | */ |
147 | static int force_inquiry_hack; | 147 | static int force_inquiry_hack; |
148 | module_param(force_inquiry_hack, int, 0444); | 148 | module_param(force_inquiry_hack, int, 0644); |
149 | MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)"); | 149 | MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)"); |
150 | 150 | ||
151 | /* | 151 | /* |
@@ -264,18 +264,17 @@ static struct hpsb_protocol_driver sbp2_driver = { | |||
264 | }, | 264 | }, |
265 | }; | 265 | }; |
266 | 266 | ||
267 | 267 | /* | |
268 | /* List of device firmware's that require a forced 36 byte inquiry. */ | 268 | * List of device firmwares that require the inquiry hack. |
269 | * Yields a few false positives but did not break other devices so far. | ||
270 | */ | ||
269 | static u32 sbp2_broken_inquiry_list[] = { | 271 | static u32 sbp2_broken_inquiry_list[] = { |
270 | 0x00002800, /* Stefan Richter <richtest@bauwesen.tu-cottbus.de> */ | 272 | 0x00002800, /* Stefan Richter <stefanr@s5r6.in-berlin.de> */ |
271 | /* DViCO Momobay CX-1 */ | 273 | /* DViCO Momobay CX-1 */ |
272 | 0x00000200 /* Andreas Plesch <plesch@fas.harvard.edu> */ | 274 | 0x00000200 /* Andreas Plesch <plesch@fas.harvard.edu> */ |
273 | /* QPS Fire DVDBurner */ | 275 | /* QPS Fire DVDBurner */ |
274 | }; | 276 | }; |
275 | 277 | ||
276 | #define NUM_BROKEN_INQUIRY_DEVS \ | ||
277 | (sizeof(sbp2_broken_inquiry_list)/sizeof(*sbp2_broken_inquiry_list)) | ||
278 | |||
279 | /************************************** | 278 | /************************************** |
280 | * General utility functions | 279 | * General utility functions |
281 | **************************************/ | 280 | **************************************/ |
@@ -643,9 +642,15 @@ static int sbp2_remove(struct device *dev) | |||
643 | if (!scsi_id) | 642 | if (!scsi_id) |
644 | return 0; | 643 | return 0; |
645 | 644 | ||
646 | /* Trigger shutdown functions in scsi's highlevel. */ | 645 | if (scsi_id->scsi_host) { |
647 | if (scsi_id->scsi_host) | 646 | /* Get rid of enqueued commands if there is no chance to |
647 | * send them. */ | ||
648 | if (!sbp2util_node_is_available(scsi_id)) | ||
649 | sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT); | ||
650 | /* scsi_remove_device() will trigger shutdown functions of SCSI | ||
651 | * highlevel drivers which would deadlock if blocked. */ | ||
648 | scsi_unblock_requests(scsi_id->scsi_host); | 652 | scsi_unblock_requests(scsi_id->scsi_host); |
653 | } | ||
649 | sdev = scsi_id->sdev; | 654 | sdev = scsi_id->sdev; |
650 | if (sdev) { | 655 | if (sdev) { |
651 | scsi_id->sdev = NULL; | 656 | scsi_id->sdev = NULL; |
@@ -742,11 +747,6 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud | |||
742 | hi->host = ud->ne->host; | 747 | hi->host = ud->ne->host; |
743 | INIT_LIST_HEAD(&hi->scsi_ids); | 748 | INIT_LIST_HEAD(&hi->scsi_ids); |
744 | 749 | ||
745 | /* Register our sbp2 status address space... */ | ||
746 | hpsb_register_addrspace(&sbp2_highlevel, ud->ne->host, &sbp2_ops, | ||
747 | SBP2_STATUS_FIFO_ADDRESS, | ||
748 | SBP2_STATUS_FIFO_ADDRESS + | ||
749 | SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(SBP2_MAX_UDS_PER_NODE+1)); | ||
750 | #ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA | 750 | #ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA |
751 | /* Handle data movement if physical dma is not | 751 | /* Handle data movement if physical dma is not |
752 | * enabled/supportedon host controller */ | 752 | * enabled/supportedon host controller */ |
@@ -759,6 +759,18 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud | |||
759 | 759 | ||
760 | list_add_tail(&scsi_id->scsi_list, &hi->scsi_ids); | 760 | list_add_tail(&scsi_id->scsi_list, &hi->scsi_ids); |
761 | 761 | ||
762 | /* Register the status FIFO address range. We could use the same FIFO | ||
763 | * for targets at different nodes. However we need different FIFOs per | ||
764 | * target in order to support multi-unit devices. */ | ||
765 | scsi_id->status_fifo_addr = hpsb_allocate_and_register_addrspace( | ||
766 | &sbp2_highlevel, ud->ne->host, &sbp2_ops, | ||
767 | sizeof(struct sbp2_status_block), sizeof(quadlet_t), | ||
768 | ~0ULL, ~0ULL); | ||
769 | if (!scsi_id->status_fifo_addr) { | ||
770 | SBP2_ERR("failed to allocate status FIFO address range"); | ||
771 | goto failed_alloc; | ||
772 | } | ||
773 | |||
762 | /* Register our host with the SCSI stack. */ | 774 | /* Register our host with the SCSI stack. */ |
763 | scsi_host = scsi_host_alloc(&scsi_driver_template, | 775 | scsi_host = scsi_host_alloc(&scsi_driver_template, |
764 | sizeof(unsigned long)); | 776 | sizeof(unsigned long)); |
@@ -997,6 +1009,10 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id) | |||
997 | SBP2_DMA_FREE("single query logins data"); | 1009 | SBP2_DMA_FREE("single query logins data"); |
998 | } | 1010 | } |
999 | 1011 | ||
1012 | if (scsi_id->status_fifo_addr) | ||
1013 | hpsb_unregister_addrspace(&sbp2_highlevel, hi->host, | ||
1014 | scsi_id->status_fifo_addr); | ||
1015 | |||
1000 | scsi_id->ud->device.driver_data = NULL; | 1016 | scsi_id->ud->device.driver_data = NULL; |
1001 | 1017 | ||
1002 | SBP2_DEBUG("SBP-2 device removed, SCSI ID = %d", scsi_id->ud->id); | 1018 | SBP2_DEBUG("SBP-2 device removed, SCSI ID = %d", scsi_id->ud->id); |
@@ -1075,11 +1091,10 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) | |||
1075 | ORB_SET_QUERY_LOGINS_RESP_LENGTH(sizeof(struct sbp2_query_logins_response)); | 1091 | ORB_SET_QUERY_LOGINS_RESP_LENGTH(sizeof(struct sbp2_query_logins_response)); |
1076 | SBP2_DEBUG("sbp2_query_logins: reserved_resp_length initialized"); | 1092 | SBP2_DEBUG("sbp2_query_logins: reserved_resp_length initialized"); |
1077 | 1093 | ||
1078 | scsi_id->query_logins_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + | 1094 | scsi_id->query_logins_orb->status_fifo_hi = |
1079 | SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); | 1095 | ORB_SET_STATUS_FIFO_HI(scsi_id->status_fifo_addr, hi->host->node_id); |
1080 | scsi_id->query_logins_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | | 1096 | scsi_id->query_logins_orb->status_fifo_lo = |
1081 | SBP2_STATUS_FIFO_ADDRESS_HI); | 1097 | ORB_SET_STATUS_FIFO_LO(scsi_id->status_fifo_addr); |
1082 | SBP2_DEBUG("sbp2_query_logins: status FIFO initialized"); | ||
1083 | 1098 | ||
1084 | sbp2util_cpu_to_be32_buffer(scsi_id->query_logins_orb, sizeof(struct sbp2_query_logins_orb)); | 1099 | sbp2util_cpu_to_be32_buffer(scsi_id->query_logins_orb, sizeof(struct sbp2_query_logins_orb)); |
1085 | 1100 | ||
@@ -1184,11 +1199,10 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) | |||
1184 | ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response)); | 1199 | ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response)); |
1185 | SBP2_DEBUG("sbp2_login_device: passwd_resp_lengths initialized"); | 1200 | SBP2_DEBUG("sbp2_login_device: passwd_resp_lengths initialized"); |
1186 | 1201 | ||
1187 | scsi_id->login_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + | 1202 | scsi_id->login_orb->status_fifo_hi = |
1188 | SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); | 1203 | ORB_SET_STATUS_FIFO_HI(scsi_id->status_fifo_addr, hi->host->node_id); |
1189 | scsi_id->login_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | | 1204 | scsi_id->login_orb->status_fifo_lo = |
1190 | SBP2_STATUS_FIFO_ADDRESS_HI); | 1205 | ORB_SET_STATUS_FIFO_LO(scsi_id->status_fifo_addr); |
1191 | SBP2_DEBUG("sbp2_login_device: status FIFO initialized"); | ||
1192 | 1206 | ||
1193 | /* | 1207 | /* |
1194 | * Byte swap ORB if necessary | 1208 | * Byte swap ORB if necessary |
@@ -1301,10 +1315,10 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id) | |||
1301 | scsi_id->logout_orb->login_ID_misc |= ORB_SET_NOTIFY(1); | 1315 | scsi_id->logout_orb->login_ID_misc |= ORB_SET_NOTIFY(1); |
1302 | 1316 | ||
1303 | scsi_id->logout_orb->reserved5 = 0x0; | 1317 | scsi_id->logout_orb->reserved5 = 0x0; |
1304 | scsi_id->logout_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + | 1318 | scsi_id->logout_orb->status_fifo_hi = |
1305 | SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); | 1319 | ORB_SET_STATUS_FIFO_HI(scsi_id->status_fifo_addr, hi->host->node_id); |
1306 | scsi_id->logout_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | | 1320 | scsi_id->logout_orb->status_fifo_lo = |
1307 | SBP2_STATUS_FIFO_ADDRESS_HI); | 1321 | ORB_SET_STATUS_FIFO_LO(scsi_id->status_fifo_addr); |
1308 | 1322 | ||
1309 | /* | 1323 | /* |
1310 | * Byte swap ORB if necessary | 1324 | * Byte swap ORB if necessary |
@@ -1366,10 +1380,10 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) | |||
1366 | scsi_id->reconnect_orb->login_ID_misc |= ORB_SET_NOTIFY(1); | 1380 | scsi_id->reconnect_orb->login_ID_misc |= ORB_SET_NOTIFY(1); |
1367 | 1381 | ||
1368 | scsi_id->reconnect_orb->reserved5 = 0x0; | 1382 | scsi_id->reconnect_orb->reserved5 = 0x0; |
1369 | scsi_id->reconnect_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + | 1383 | scsi_id->reconnect_orb->status_fifo_hi = |
1370 | SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); | 1384 | ORB_SET_STATUS_FIFO_HI(scsi_id->status_fifo_addr, hi->host->node_id); |
1371 | scsi_id->reconnect_orb->status_FIFO_hi = | 1385 | scsi_id->reconnect_orb->status_fifo_lo = |
1372 | (ORB_SET_NODE_ID(hi->host->node_id) | SBP2_STATUS_FIFO_ADDRESS_HI); | 1386 | ORB_SET_STATUS_FIFO_LO(scsi_id->status_fifo_addr); |
1373 | 1387 | ||
1374 | /* | 1388 | /* |
1375 | * Byte swap ORB if necessary | 1389 | * Byte swap ORB if necessary |
@@ -1560,7 +1574,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, | |||
1560 | /* Check for a blacklisted set of devices that require us to force | 1574 | /* Check for a blacklisted set of devices that require us to force |
1561 | * a 36 byte host inquiry. This can be overriden as a module param | 1575 | * a 36 byte host inquiry. This can be overriden as a module param |
1562 | * (to force all hosts). */ | 1576 | * (to force all hosts). */ |
1563 | for (i = 0; i < NUM_BROKEN_INQUIRY_DEVS; i++) { | 1577 | for (i = 0; i < ARRAY_SIZE(sbp2_broken_inquiry_list); i++) { |
1564 | if ((firmware_revision & 0xffff00) == | 1578 | if ((firmware_revision & 0xffff00) == |
1565 | sbp2_broken_inquiry_list[i]) { | 1579 | sbp2_broken_inquiry_list[i]) { |
1566 | SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround", | 1580 | SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround", |
@@ -2007,18 +2021,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, | |||
2007 | } | 2021 | } |
2008 | 2022 | ||
2009 | /* | 2023 | /* |
2010 | * The scsi stack sends down a request_bufflen which does not match the | ||
2011 | * length field in the scsi cdb. This causes some sbp2 devices to | ||
2012 | * reject this inquiry command. Fix the request_bufflen. | ||
2013 | */ | ||
2014 | if (*cmd == INQUIRY) { | ||
2015 | if (force_inquiry_hack || scsi_id->workarounds & SBP2_BREAKAGE_INQUIRY_HACK) | ||
2016 | request_bufflen = cmd[4] = 0x24; | ||
2017 | else | ||
2018 | request_bufflen = cmd[4]; | ||
2019 | } | ||
2020 | |||
2021 | /* | ||
2022 | * Now actually fill in the comamnd orb and sbp2 s/g list | 2024 | * Now actually fill in the comamnd orb and sbp2 s/g list |
2023 | */ | 2025 | */ |
2024 | sbp2_create_command_orb(scsi_id, command, cmd, SCpnt->use_sg, | 2026 | sbp2_create_command_orb(scsi_id, command, cmd, SCpnt->use_sg, |
@@ -2082,9 +2084,7 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, | |||
2082 | 2084 | ||
2083 | SBP2_DEBUG("sbp2_check_sbp2_response"); | 2085 | SBP2_DEBUG("sbp2_check_sbp2_response"); |
2084 | 2086 | ||
2085 | switch (SCpnt->cmnd[0]) { | 2087 | if (SCpnt->cmnd[0] == INQUIRY && (SCpnt->cmnd[1] & 3) == 0) { |
2086 | |||
2087 | case INQUIRY: | ||
2088 | /* | 2088 | /* |
2089 | * Make sure data length is ok. Minimum length is 36 bytes | 2089 | * Make sure data length is ok. Minimum length is 36 bytes |
2090 | */ | 2090 | */ |
@@ -2097,13 +2097,7 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, | |||
2097 | */ | 2097 | */ |
2098 | scsi_buf[2] |= 2; | 2098 | scsi_buf[2] |= 2; |
2099 | scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2; | 2099 | scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2; |
2100 | |||
2101 | break; | ||
2102 | |||
2103 | default: | ||
2104 | break; | ||
2105 | } | 2100 | } |
2106 | return; | ||
2107 | } | 2101 | } |
2108 | 2102 | ||
2109 | /* | 2103 | /* |
@@ -2114,7 +2108,6 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest | |||
2114 | { | 2108 | { |
2115 | struct sbp2scsi_host_info *hi; | 2109 | struct sbp2scsi_host_info *hi; |
2116 | struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp; | 2110 | struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp; |
2117 | u32 id; | ||
2118 | struct scsi_cmnd *SCpnt = NULL; | 2111 | struct scsi_cmnd *SCpnt = NULL; |
2119 | u32 scsi_status = SBP2_SCSI_STATUS_GOOD; | 2112 | u32 scsi_status = SBP2_SCSI_STATUS_GOOD; |
2120 | struct sbp2_command_info *command; | 2113 | struct sbp2_command_info *command; |
@@ -2137,12 +2130,12 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest | |||
2137 | } | 2130 | } |
2138 | 2131 | ||
2139 | /* | 2132 | /* |
2140 | * Find our scsi_id structure by looking at the status fifo address written to by | 2133 | * Find our scsi_id structure by looking at the status fifo address |
2141 | * the sbp2 device. | 2134 | * written to by the sbp2 device. |
2142 | */ | 2135 | */ |
2143 | id = SBP2_STATUS_FIFO_OFFSET_TO_ENTRY((u32)(addr - SBP2_STATUS_FIFO_ADDRESS)); | ||
2144 | list_for_each_entry(scsi_id_tmp, &hi->scsi_ids, scsi_list) { | 2136 | list_for_each_entry(scsi_id_tmp, &hi->scsi_ids, scsi_list) { |
2145 | if (scsi_id_tmp->ne->nodeid == nodeid && scsi_id_tmp->ud->id == id) { | 2137 | if (scsi_id_tmp->ne->nodeid == nodeid && |
2138 | scsi_id_tmp->status_fifo_addr == addr) { | ||
2146 | scsi_id = scsi_id_tmp; | 2139 | scsi_id = scsi_id_tmp; |
2147 | break; | 2140 | break; |
2148 | } | 2141 | } |
@@ -2483,7 +2476,16 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, | |||
2483 | 2476 | ||
2484 | static int sbp2scsi_slave_alloc(struct scsi_device *sdev) | 2477 | static int sbp2scsi_slave_alloc(struct scsi_device *sdev) |
2485 | { | 2478 | { |
2486 | ((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = sdev; | 2479 | struct scsi_id_instance_data *scsi_id = |
2480 | (struct scsi_id_instance_data *)sdev->host->hostdata[0]; | ||
2481 | |||
2482 | scsi_id->sdev = sdev; | ||
2483 | |||
2484 | if (force_inquiry_hack || | ||
2485 | scsi_id->workarounds & SBP2_BREAKAGE_INQUIRY_HACK) { | ||
2486 | sdev->inquiry_len = 36; | ||
2487 | sdev->skip_ms_page_8 = 1; | ||
2488 | } | ||
2487 | return 0; | 2489 | return 0; |
2488 | } | 2490 | } |
2489 | 2491 | ||
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index 900ea1d25e71..e2d357a9ea3a 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h | |||
@@ -33,15 +33,17 @@ | |||
33 | #define ORB_DIRECTION_NO_DATA_TRANSFER 0x2 | 33 | #define ORB_DIRECTION_NO_DATA_TRANSFER 0x2 |
34 | 34 | ||
35 | #define ORB_SET_NULL_PTR(value) ((value & 0x1) << 31) | 35 | #define ORB_SET_NULL_PTR(value) ((value & 0x1) << 31) |
36 | #define ORB_SET_NOTIFY(value) ((value & 0x1) << 31) | 36 | #define ORB_SET_NOTIFY(value) ((value & 0x1) << 31) |
37 | #define ORB_SET_RQ_FMT(value) ((value & 0x3) << 29) /* unused ? */ | 37 | #define ORB_SET_RQ_FMT(value) ((value & 0x3) << 29) /* unused ? */ |
38 | #define ORB_SET_NODE_ID(value) ((value & 0xffff) << 16) | 38 | #define ORB_SET_NODE_ID(value) ((value & 0xffff) << 16) |
39 | #define ORB_SET_DATA_SIZE(value) (value & 0xffff) | 39 | #define ORB_SET_STATUS_FIFO_HI(value, id) (value >> 32 | ORB_SET_NODE_ID(id)) |
40 | #define ORB_SET_PAGE_SIZE(value) ((value & 0x7) << 16) | 40 | #define ORB_SET_STATUS_FIFO_LO(value) (value & 0xffffffff) |
41 | #define ORB_SET_PAGE_TABLE_PRESENT(value) ((value & 0x1) << 19) | 41 | #define ORB_SET_DATA_SIZE(value) (value & 0xffff) |
42 | #define ORB_SET_MAX_PAYLOAD(value) ((value & 0xf) << 20) | 42 | #define ORB_SET_PAGE_SIZE(value) ((value & 0x7) << 16) |
43 | #define ORB_SET_SPEED(value) ((value & 0x7) << 24) | 43 | #define ORB_SET_PAGE_TABLE_PRESENT(value) ((value & 0x1) << 19) |
44 | #define ORB_SET_DIRECTION(value) ((value & 0x1) << 27) | 44 | #define ORB_SET_MAX_PAYLOAD(value) ((value & 0xf) << 20) |
45 | #define ORB_SET_SPEED(value) ((value & 0x7) << 24) | ||
46 | #define ORB_SET_DIRECTION(value) ((value & 0x1) << 27) | ||
45 | 47 | ||
46 | struct sbp2_command_orb { | 48 | struct sbp2_command_orb { |
47 | volatile u32 next_ORB_hi; | 49 | volatile u32 next_ORB_hi; |
@@ -76,8 +78,8 @@ struct sbp2_login_orb { | |||
76 | u32 login_response_lo; | 78 | u32 login_response_lo; |
77 | u32 lun_misc; | 79 | u32 lun_misc; |
78 | u32 passwd_resp_lengths; | 80 | u32 passwd_resp_lengths; |
79 | u32 status_FIFO_hi; | 81 | u32 status_fifo_hi; |
80 | u32 status_FIFO_lo; | 82 | u32 status_fifo_lo; |
81 | }; | 83 | }; |
82 | 84 | ||
83 | #define RESPONSE_GET_LOGIN_ID(value) (value & 0xffff) | 85 | #define RESPONSE_GET_LOGIN_ID(value) (value & 0xffff) |
@@ -102,8 +104,8 @@ struct sbp2_query_logins_orb { | |||
102 | u32 query_response_lo; | 104 | u32 query_response_lo; |
103 | u32 lun_misc; | 105 | u32 lun_misc; |
104 | u32 reserved_resp_length; | 106 | u32 reserved_resp_length; |
105 | u32 status_FIFO_hi; | 107 | u32 status_fifo_hi; |
106 | u32 status_FIFO_lo; | 108 | u32 status_fifo_lo; |
107 | }; | 109 | }; |
108 | 110 | ||
109 | #define RESPONSE_GET_MAX_LOGINS(value) (value & 0xffff) | 111 | #define RESPONSE_GET_MAX_LOGINS(value) (value & 0xffff) |
@@ -123,8 +125,8 @@ struct sbp2_reconnect_orb { | |||
123 | u32 reserved4; | 125 | u32 reserved4; |
124 | u32 login_ID_misc; | 126 | u32 login_ID_misc; |
125 | u32 reserved5; | 127 | u32 reserved5; |
126 | u32 status_FIFO_hi; | 128 | u32 status_fifo_hi; |
127 | u32 status_FIFO_lo; | 129 | u32 status_fifo_lo; |
128 | }; | 130 | }; |
129 | 131 | ||
130 | struct sbp2_logout_orb { | 132 | struct sbp2_logout_orb { |
@@ -134,8 +136,8 @@ struct sbp2_logout_orb { | |||
134 | u32 reserved4; | 136 | u32 reserved4; |
135 | u32 login_ID_misc; | 137 | u32 login_ID_misc; |
136 | u32 reserved5; | 138 | u32 reserved5; |
137 | u32 status_FIFO_hi; | 139 | u32 status_fifo_hi; |
138 | u32 status_FIFO_lo; | 140 | u32 status_fifo_lo; |
139 | }; | 141 | }; |
140 | 142 | ||
141 | #define PAGE_TABLE_SET_SEGMENT_BASE_HI(value) (value & 0xffff) | 143 | #define PAGE_TABLE_SET_SEGMENT_BASE_HI(value) (value & 0xffff) |
@@ -195,30 +197,6 @@ struct sbp2_status_block { | |||
195 | * Miscellaneous SBP2 related config rom defines | 197 | * Miscellaneous SBP2 related config rom defines |
196 | */ | 198 | */ |
197 | 199 | ||
198 | /* The status fifo address definition below is used as a base for each | ||
199 | * node, which a chunk seperately assigned to each unit directory in the | ||
200 | * node. For example, 0xfffe00000000ULL is used for the first sbp2 device | ||
201 | * detected on node 0, 0xfffe00000020ULL for the next sbp2 device on node | ||
202 | * 0, and so on. | ||
203 | * | ||
204 | * Note: We could use a single status fifo address for all sbp2 devices, | ||
205 | * and figure out which sbp2 device the status belongs to by looking at | ||
206 | * the source node id of the status write... but, using separate addresses | ||
207 | * for each sbp2 unit directory allows for better code and the ability to | ||
208 | * support multiple luns within a single 1394 node. | ||
209 | * | ||
210 | * Also note that we choose the address range below as it is a region | ||
211 | * specified for write posting, where the ohci controller will | ||
212 | * automatically send an ack_complete when the status is written by the | ||
213 | * sbp2 device... saving a split transaction. =) | ||
214 | */ | ||
215 | #define SBP2_STATUS_FIFO_ADDRESS 0xfffe00000000ULL | ||
216 | #define SBP2_STATUS_FIFO_ADDRESS_HI 0xfffe | ||
217 | #define SBP2_STATUS_FIFO_ADDRESS_LO 0x0 | ||
218 | |||
219 | #define SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(entry) ((entry) << 5) | ||
220 | #define SBP2_STATUS_FIFO_OFFSET_TO_ENTRY(offset) ((offset) >> 5) | ||
221 | |||
222 | #define SBP2_UNIT_DIRECTORY_OFFSET_KEY 0xd1 | 200 | #define SBP2_UNIT_DIRECTORY_OFFSET_KEY 0xd1 |
223 | #define SBP2_CSR_OFFSET_KEY 0x54 | 201 | #define SBP2_CSR_OFFSET_KEY 0x54 |
224 | #define SBP2_UNIT_SPEC_ID_KEY 0x12 | 202 | #define SBP2_UNIT_SPEC_ID_KEY 0x12 |
@@ -258,7 +236,6 @@ struct sbp2_status_block { | |||
258 | */ | 236 | */ |
259 | 237 | ||
260 | #define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 | 238 | #define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 |
261 | #define SBP2_MAX_UDS_PER_NODE 16 /* Maximum scsi devices per node */ | ||
262 | #define SBP2_MAX_SECTORS 255 /* Max sectors supported */ | 239 | #define SBP2_MAX_SECTORS 255 /* Max sectors supported */ |
263 | #define SBP2_MAX_CMDS 8 /* This should be safe */ | 240 | #define SBP2_MAX_CMDS 8 /* This should be safe */ |
264 | 241 | ||
@@ -338,6 +315,11 @@ struct scsi_id_instance_data { | |||
338 | u32 sbp2_firmware_revision; | 315 | u32 sbp2_firmware_revision; |
339 | 316 | ||
340 | /* | 317 | /* |
318 | * Address for the device to write status blocks to | ||
319 | */ | ||
320 | u64 status_fifo_addr; | ||
321 | |||
322 | /* | ||
341 | * Variable used for logins, reconnects, logouts, query logins | 323 | * Variable used for logins, reconnects, logouts, query logins |
342 | */ | 324 | */ |
343 | atomic_t sbp2_login_complete; | 325 | atomic_t sbp2_login_complete; |
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 39fb88309e8e..216dbbf1dc8e 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c | |||
@@ -744,7 +744,7 @@ static int __video1394_ioctl(struct file *file, | |||
744 | if (i == ISO_CHANNELS) { | 744 | if (i == ISO_CHANNELS) { |
745 | PRINT(KERN_ERR, ohci->host->id, | 745 | PRINT(KERN_ERR, ohci->host->id, |
746 | "No free channel found"); | 746 | "No free channel found"); |
747 | return EAGAIN; | 747 | return -EAGAIN; |
748 | } | 748 | } |
749 | if (!(ohci->ISO_channel_usage & mask)) { | 749 | if (!(ohci->ISO_channel_usage & mask)) { |
750 | v.channel = i; | 750 | v.channel = i; |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index d393b504bf26..c82f47a66e48 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -665,7 +665,15 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
665 | struct ib_wc mad_wc; | 665 | struct ib_wc mad_wc; |
666 | struct ib_send_wr *send_wr = &mad_send_wr->send_wr; | 666 | struct ib_send_wr *send_wr = &mad_send_wr->send_wr; |
667 | 667 | ||
668 | if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) { | 668 | /* |
669 | * Directed route handling starts if the initial LID routed part of | ||
670 | * a request or the ending LID routed part of a response is empty. | ||
671 | * If we are at the start of the LID routed part, don't update the | ||
672 | * hop_ptr or hop_cnt. See section 14.2.2, Vol 1 IB spec. | ||
673 | */ | ||
674 | if ((ib_get_smp_direction(smp) ? smp->dr_dlid : smp->dr_slid) == | ||
675 | IB_LID_PERMISSIVE && | ||
676 | !smi_handle_dr_smp_send(smp, device->node_type, port_num)) { | ||
669 | ret = -EINVAL; | 677 | ret = -EINVAL; |
670 | printk(KERN_ERR PFX "Invalid directed route\n"); | 678 | printk(KERN_ERR PFX "Invalid directed route\n"); |
671 | goto out; | 679 | goto out; |
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index e95c4293a496..f6a05965a4e8 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
@@ -1319,15 +1319,6 @@ static struct class ucm_class = { | |||
1319 | .release = ib_ucm_release_class_dev | 1319 | .release = ib_ucm_release_class_dev |
1320 | }; | 1320 | }; |
1321 | 1321 | ||
1322 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | ||
1323 | { | ||
1324 | struct ib_ucm_device *dev; | ||
1325 | |||
1326 | dev = container_of(class_dev, struct ib_ucm_device, class_dev); | ||
1327 | return print_dev_t(buf, dev->dev.dev); | ||
1328 | } | ||
1329 | static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); | ||
1330 | |||
1331 | static ssize_t show_ibdev(struct class_device *class_dev, char *buf) | 1322 | static ssize_t show_ibdev(struct class_device *class_dev, char *buf) |
1332 | { | 1323 | { |
1333 | struct ib_ucm_device *dev; | 1324 | struct ib_ucm_device *dev; |
@@ -1364,15 +1355,13 @@ static void ib_ucm_add_one(struct ib_device *device) | |||
1364 | 1355 | ||
1365 | ucm_dev->class_dev.class = &ucm_class; | 1356 | ucm_dev->class_dev.class = &ucm_class; |
1366 | ucm_dev->class_dev.dev = device->dma_device; | 1357 | ucm_dev->class_dev.dev = device->dma_device; |
1358 | ucm_dev->class_dev.devt = ucm_dev->dev.dev; | ||
1367 | snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", | 1359 | snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", |
1368 | ucm_dev->devnum); | 1360 | ucm_dev->devnum); |
1369 | if (class_device_register(&ucm_dev->class_dev)) | 1361 | if (class_device_register(&ucm_dev->class_dev)) |
1370 | goto err_cdev; | 1362 | goto err_cdev; |
1371 | 1363 | ||
1372 | if (class_device_create_file(&ucm_dev->class_dev, | 1364 | if (class_device_create_file(&ucm_dev->class_dev, |
1373 | &class_device_attr_dev)) | ||
1374 | goto err_class; | ||
1375 | if (class_device_create_file(&ucm_dev->class_dev, | ||
1376 | &class_device_attr_ibdev)) | 1365 | &class_device_attr_ibdev)) |
1377 | goto err_class; | 1366 | goto err_class; |
1378 | 1367 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index f9b9b93dc501..2825615ce81c 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -1029,25 +1029,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, | |||
1029 | MTHCA_GET(size, outbox, QUERY_DEV_LIM_UAR_ENTRY_SZ_OFFSET); | 1029 | MTHCA_GET(size, outbox, QUERY_DEV_LIM_UAR_ENTRY_SZ_OFFSET); |
1030 | dev_lim->uar_scratch_entry_sz = size; | 1030 | dev_lim->uar_scratch_entry_sz = size; |
1031 | 1031 | ||
1032 | mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n", | ||
1033 | dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz); | ||
1034 | mthca_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n", | ||
1035 | dev_lim->max_srqs, dev_lim->reserved_srqs, dev_lim->srq_entry_sz); | ||
1036 | mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", | ||
1037 | dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz); | ||
1038 | mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n", | ||
1039 | dev_lim->max_eqs, dev_lim->reserved_eqs, dev_lim->eqc_entry_sz); | ||
1040 | mthca_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", | ||
1041 | dev_lim->reserved_mrws, dev_lim->reserved_mtts); | ||
1042 | mthca_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", | ||
1043 | dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars); | ||
1044 | mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n", | ||
1045 | dev_lim->max_pds, dev_lim->reserved_mgms); | ||
1046 | mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", | ||
1047 | dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz); | ||
1048 | |||
1049 | mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); | ||
1050 | |||
1051 | if (mthca_is_memfree(dev)) { | 1032 | if (mthca_is_memfree(dev)) { |
1052 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); | 1033 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); |
1053 | dev_lim->max_srq_sz = 1 << field; | 1034 | dev_lim->max_srq_sz = 1 << field; |
@@ -1093,6 +1074,25 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, | |||
1093 | dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; | 1074 | dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; |
1094 | } | 1075 | } |
1095 | 1076 | ||
1077 | mthca_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n", | ||
1078 | dev_lim->max_qps, dev_lim->reserved_qps, dev_lim->qpc_entry_sz); | ||
1079 | mthca_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n", | ||
1080 | dev_lim->max_srqs, dev_lim->reserved_srqs, dev_lim->srq_entry_sz); | ||
1081 | mthca_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", | ||
1082 | dev_lim->max_cqs, dev_lim->reserved_cqs, dev_lim->cqc_entry_sz); | ||
1083 | mthca_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n", | ||
1084 | dev_lim->max_eqs, dev_lim->reserved_eqs, dev_lim->eqc_entry_sz); | ||
1085 | mthca_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", | ||
1086 | dev_lim->reserved_mrws, dev_lim->reserved_mtts); | ||
1087 | mthca_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", | ||
1088 | dev_lim->max_pds, dev_lim->reserved_pds, dev_lim->reserved_uars); | ||
1089 | mthca_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n", | ||
1090 | dev_lim->max_pds, dev_lim->reserved_mgms); | ||
1091 | mthca_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", | ||
1092 | dev_lim->max_cq_sz, dev_lim->max_qp_sz, dev_lim->max_srq_sz); | ||
1093 | |||
1094 | mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); | ||
1095 | |||
1096 | out: | 1096 | out: |
1097 | mthca_free_mailbox(dev, mailbox); | 1097 | mthca_free_mailbox(dev, mailbox); |
1098 | return err; | 1098 | return err; |
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 2a165fd06e57..e481037288d6 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h | |||
@@ -53,8 +53,8 @@ | |||
53 | 53 | ||
54 | #define DRV_NAME "ib_mthca" | 54 | #define DRV_NAME "ib_mthca" |
55 | #define PFX DRV_NAME ": " | 55 | #define PFX DRV_NAME ": " |
56 | #define DRV_VERSION "0.06" | 56 | #define DRV_VERSION "0.07" |
57 | #define DRV_RELDATE "June 23, 2005" | 57 | #define DRV_RELDATE "February 13, 2006" |
58 | 58 | ||
59 | enum { | 59 | enum { |
60 | MTHCA_FLAG_DDR_HIDDEN = 1 << 1, | 60 | MTHCA_FLAG_DDR_HIDDEN = 1 << 1, |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index e0a5412b7e68..2f85a9a831b1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -78,6 +78,7 @@ enum { | |||
78 | IPOIB_FLAG_SUBINTERFACE = 4, | 78 | IPOIB_FLAG_SUBINTERFACE = 4, |
79 | IPOIB_MCAST_RUN = 5, | 79 | IPOIB_MCAST_RUN = 5, |
80 | IPOIB_STOP_REAPER = 6, | 80 | IPOIB_STOP_REAPER = 6, |
81 | IPOIB_MCAST_STARTED = 7, | ||
81 | 82 | ||
82 | IPOIB_MAX_BACKOFF_SECONDS = 16, | 83 | IPOIB_MAX_BACKOFF_SECONDS = 16, |
83 | 84 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index ccaa0c387076..a2408d7ec598 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -533,8 +533,10 @@ void ipoib_mcast_join_task(void *dev_ptr) | |||
533 | } | 533 | } |
534 | 534 | ||
535 | if (!priv->broadcast) { | 535 | if (!priv->broadcast) { |
536 | priv->broadcast = ipoib_mcast_alloc(dev, 1); | 536 | struct ipoib_mcast *broadcast; |
537 | if (!priv->broadcast) { | 537 | |
538 | broadcast = ipoib_mcast_alloc(dev, 1); | ||
539 | if (!broadcast) { | ||
538 | ipoib_warn(priv, "failed to allocate broadcast group\n"); | 540 | ipoib_warn(priv, "failed to allocate broadcast group\n"); |
539 | mutex_lock(&mcast_mutex); | 541 | mutex_lock(&mcast_mutex); |
540 | if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) | 542 | if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) |
@@ -544,10 +546,11 @@ void ipoib_mcast_join_task(void *dev_ptr) | |||
544 | return; | 546 | return; |
545 | } | 547 | } |
546 | 548 | ||
547 | memcpy(priv->broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4, | 549 | spin_lock_irq(&priv->lock); |
550 | memcpy(broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4, | ||
548 | sizeof (union ib_gid)); | 551 | sizeof (union ib_gid)); |
552 | priv->broadcast = broadcast; | ||
549 | 553 | ||
550 | spin_lock_irq(&priv->lock); | ||
551 | __ipoib_mcast_add(dev, priv->broadcast); | 554 | __ipoib_mcast_add(dev, priv->broadcast); |
552 | spin_unlock_irq(&priv->lock); | 555 | spin_unlock_irq(&priv->lock); |
553 | } | 556 | } |
@@ -601,6 +604,10 @@ int ipoib_mcast_start_thread(struct net_device *dev) | |||
601 | queue_work(ipoib_workqueue, &priv->mcast_task); | 604 | queue_work(ipoib_workqueue, &priv->mcast_task); |
602 | mutex_unlock(&mcast_mutex); | 605 | mutex_unlock(&mcast_mutex); |
603 | 606 | ||
607 | spin_lock_irq(&priv->lock); | ||
608 | set_bit(IPOIB_MCAST_STARTED, &priv->flags); | ||
609 | spin_unlock_irq(&priv->lock); | ||
610 | |||
604 | return 0; | 611 | return 0; |
605 | } | 612 | } |
606 | 613 | ||
@@ -611,6 +618,10 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush) | |||
611 | 618 | ||
612 | ipoib_dbg_mcast(priv, "stopping multicast thread\n"); | 619 | ipoib_dbg_mcast(priv, "stopping multicast thread\n"); |
613 | 620 | ||
621 | spin_lock_irq(&priv->lock); | ||
622 | clear_bit(IPOIB_MCAST_STARTED, &priv->flags); | ||
623 | spin_unlock_irq(&priv->lock); | ||
624 | |||
614 | mutex_lock(&mcast_mutex); | 625 | mutex_lock(&mcast_mutex); |
615 | clear_bit(IPOIB_MCAST_RUN, &priv->flags); | 626 | clear_bit(IPOIB_MCAST_RUN, &priv->flags); |
616 | cancel_delayed_work(&priv->mcast_task); | 627 | cancel_delayed_work(&priv->mcast_task); |
@@ -693,6 +704,14 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, | |||
693 | */ | 704 | */ |
694 | spin_lock(&priv->lock); | 705 | spin_lock(&priv->lock); |
695 | 706 | ||
707 | if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) || | ||
708 | !priv->broadcast || | ||
709 | !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { | ||
710 | ++priv->stats.tx_dropped; | ||
711 | dev_kfree_skb_any(skb); | ||
712 | goto unlock; | ||
713 | } | ||
714 | |||
696 | mcast = __ipoib_mcast_find(dev, mgid); | 715 | mcast = __ipoib_mcast_find(dev, mgid); |
697 | if (!mcast) { | 716 | if (!mcast) { |
698 | /* Let's create a new send only group now */ | 717 | /* Let's create a new send only group now */ |
@@ -754,6 +773,7 @@ out: | |||
754 | ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); | 773 | ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); |
755 | } | 774 | } |
756 | 775 | ||
776 | unlock: | ||
757 | spin_unlock(&priv->lock); | 777 | spin_unlock(&priv->lock); |
758 | } | 778 | } |
759 | 779 | ||
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 2d2d4ac3525a..960dae5c87d1 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -1155,6 +1155,12 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func) | |||
1155 | 1155 | ||
1156 | spin_lock_irq(target->scsi_host->host_lock); | 1156 | spin_lock_irq(target->scsi_host->host_lock); |
1157 | 1157 | ||
1158 | if (target->state == SRP_TARGET_DEAD || | ||
1159 | target->state == SRP_TARGET_REMOVED) { | ||
1160 | scmnd->result = DID_BAD_TARGET << 16; | ||
1161 | goto out; | ||
1162 | } | ||
1163 | |||
1158 | if (scmnd->host_scribble == (void *) -1L) | 1164 | if (scmnd->host_scribble == (void *) -1L) |
1159 | goto out; | 1165 | goto out; |
1160 | 1166 | ||
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 6e0afbb22383..2708167ba175 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -11,7 +11,6 @@ obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o | |||
11 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | 11 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o |
12 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o | 12 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o |
13 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o | 13 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o |
14 | obj-$(CONFIG_KEYBOARD_98KBD) += 98kbd.o | ||
15 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o | 14 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o |
16 | obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o | 15 | obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o |
17 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 16 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 184c4129470d..415c49178985 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -7,7 +7,6 @@ | |||
7 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | 7 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o |
8 | obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o | 8 | obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o |
9 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o | 9 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o |
10 | obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o | ||
11 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 10 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o |
12 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | 11 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o |
13 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 12 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index d448bb5e4869..3a6ae85cd69c 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/interrupt.h> | ||
22 | #include <asm/hardware.h> | 23 | #include <asm/hardware.h> |
23 | 24 | ||
24 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | 25 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index c88520d3d13c..40333d61093c 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -232,6 +232,7 @@ static struct ps2pp_info *get_model_info(unsigned char model) | |||
232 | { 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, | 232 | { 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, |
233 | { 96, 0, 0 }, | 233 | { 96, 0, 0 }, |
234 | { 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL }, | 234 | { 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL }, |
235 | { 99, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, | ||
235 | { 100, PS2PP_KIND_MX, /* MX510 */ | 236 | { 100, PS2PP_KIND_MX, /* MX510 */ |
236 | PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | | 237 | PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | |
237 | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, | 238 | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 19b1b0121726..ad6217467676 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -58,7 +58,7 @@ static unsigned int psmouse_resetafter = 5; | |||
58 | module_param_named(resetafter, psmouse_resetafter, uint, 0644); | 58 | module_param_named(resetafter, psmouse_resetafter, uint, 0644); |
59 | MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); | 59 | MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); |
60 | 60 | ||
61 | static unsigned int psmouse_resync_time = 5; | 61 | static unsigned int psmouse_resync_time; |
62 | module_param_named(resync_time, psmouse_resync_time, uint, 0644); | 62 | module_param_named(resync_time, psmouse_resync_time, uint, 0644); |
63 | MODULE_PARM_DESC(resync_time, "How long can mouse stay idle before forcing resync (in seconds, 0 = never)."); | 63 | MODULE_PARM_DESC(resync_time, "How long can mouse stay idle before forcing resync (in seconds, 0 = never)."); |
64 | 64 | ||
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index b4898d8a68e2..6d9ec9ab1b90 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -68,15 +68,19 @@ struct trackpoint_attr_data { | |||
68 | size_t field_offset; | 68 | size_t field_offset; |
69 | unsigned char command; | 69 | unsigned char command; |
70 | unsigned char mask; | 70 | unsigned char mask; |
71 | unsigned char inverted; | ||
71 | }; | 72 | }; |
72 | 73 | ||
73 | static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf) | 74 | static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf) |
74 | { | 75 | { |
75 | struct trackpoint_data *tp = psmouse->private; | 76 | struct trackpoint_data *tp = psmouse->private; |
76 | struct trackpoint_attr_data *attr = data; | 77 | struct trackpoint_attr_data *attr = data; |
77 | unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); | 78 | unsigned char value = *(unsigned char *)((char *)tp + attr->field_offset); |
79 | |||
80 | if (attr->inverted) | ||
81 | value = !value; | ||
78 | 82 | ||
79 | return sprintf(buf, "%u\n", *field); | 83 | return sprintf(buf, "%u\n", value); |
80 | } | 84 | } |
81 | 85 | ||
82 | static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, | 86 | static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, |
@@ -120,6 +124,9 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, | |||
120 | if (*rest || value > 1) | 124 | if (*rest || value > 1) |
121 | return -EINVAL; | 125 | return -EINVAL; |
122 | 126 | ||
127 | if (attr->inverted) | ||
128 | value = !value; | ||
129 | |||
123 | if (*field != value) { | 130 | if (*field != value) { |
124 | *field = value; | 131 | *field = value; |
125 | trackpoint_toggle_bit(&psmouse->ps2dev, attr->command, attr->mask); | 132 | trackpoint_toggle_bit(&psmouse->ps2dev, attr->command, attr->mask); |
@@ -129,11 +136,12 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, | |||
129 | } | 136 | } |
130 | 137 | ||
131 | 138 | ||
132 | #define TRACKPOINT_BIT_ATTR(_name, _command, _mask) \ | 139 | #define TRACKPOINT_BIT_ATTR(_name, _command, _mask, _inv) \ |
133 | static struct trackpoint_attr_data trackpoint_attr_##_name = { \ | 140 | static struct trackpoint_attr_data trackpoint_attr_##_name = { \ |
134 | .field_offset = offsetof(struct trackpoint_data, _name), \ | 141 | .field_offset = offsetof(struct trackpoint_data, _name), \ |
135 | .command = _command, \ | 142 | .command = _command, \ |
136 | .mask = _mask, \ | 143 | .mask = _mask, \ |
144 | .inverted = _inv, \ | ||
137 | }; \ | 145 | }; \ |
138 | PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \ | 146 | PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \ |
139 | &trackpoint_attr_##_name, \ | 147 | &trackpoint_attr_##_name, \ |
@@ -150,9 +158,9 @@ TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH); | |||
150 | TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME); | 158 | TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME); |
151 | TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV); | 159 | TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV); |
152 | 160 | ||
153 | TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON); | 161 | TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0); |
154 | TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK); | 162 | TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, 0); |
155 | TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV); | 163 | TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, 1); |
156 | 164 | ||
157 | static struct attribute *trackpoint_attrs[] = { | 165 | static struct attribute *trackpoint_attrs[] = { |
158 | &psmouse_attr_sensitivity.dattr.attr, | 166 | &psmouse_attr_sensitivity.dattr.attr, |
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index 9857d8b6ad66..050298b1a09d 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h | |||
@@ -78,7 +78,7 @@ | |||
78 | 78 | ||
79 | #define TP_TOGGLE_MB 0x23 /* Disable/Enable Middle Button */ | 79 | #define TP_TOGGLE_MB 0x23 /* Disable/Enable Middle Button */ |
80 | #define TP_MASK_MB 0x01 | 80 | #define TP_MASK_MB 0x01 |
81 | #define TP_TOGGLE_EXT_DEV 0x23 /* Toggle external device */ | 81 | #define TP_TOGGLE_EXT_DEV 0x23 /* Disable external device */ |
82 | #define TP_MASK_EXT_DEV 0x02 | 82 | #define TP_MASK_EXT_DEV 0x02 |
83 | #define TP_TOGGLE_DRIFT 0x23 /* Drift Correction */ | 83 | #define TP_TOGGLE_DRIFT 0x23 /* Drift Correction */ |
84 | #define TP_MASK_DRIFT 0x80 | 84 | #define TP_MASK_DRIFT 0x80 |
@@ -125,7 +125,7 @@ | |||
125 | #define TP_DEF_MB 0x00 | 125 | #define TP_DEF_MB 0x00 |
126 | #define TP_DEF_PTSON 0x00 | 126 | #define TP_DEF_PTSON 0x00 |
127 | #define TP_DEF_SKIPBACK 0x00 | 127 | #define TP_DEF_SKIPBACK 0x00 |
128 | #define TP_DEF_EXT_DEV 0x01 | 128 | #define TP_DEF_EXT_DEV 0x00 /* 0 means enabled */ |
129 | 129 | ||
130 | #define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd)) | 130 | #define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd)) |
131 | 131 | ||
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 678a8599f9ff..4155197867a3 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile | |||
@@ -13,7 +13,6 @@ obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o | |||
13 | obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o | 13 | obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o |
14 | obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o | 14 | obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o |
15 | obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o | 15 | obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o |
16 | obj-$(CONFIG_SERIO_98KBD) += 98kbd-io.o | ||
17 | obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o | 16 | obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o |
18 | obj-$(CONFIG_HP_SDC) += hp_sdc.o | 17 | obj-$(CONFIG_HP_SDC) += hp_sdc.o |
19 | obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o | 18 | obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index b45a45ca7cc9..8c12a974b411 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -48,10 +48,13 @@ | |||
48 | 48 | ||
49 | #define TS_POLL_PERIOD msecs_to_jiffies(10) | 49 | #define TS_POLL_PERIOD msecs_to_jiffies(10) |
50 | 50 | ||
51 | /* this driver doesn't aim at the peak continuous sample rate */ | ||
52 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) | ||
53 | |||
51 | struct ts_event { | 54 | struct ts_event { |
52 | /* For portability, we can't read 12 bit values using SPI (which | 55 | /* For portability, we can't read 12 bit values using SPI (which |
53 | * would make the controller deliver them as native byteorder u16 | 56 | * would make the controller deliver them as native byteorder u16 |
54 | * with msbs zeroed). Instead, we read them as two 8-byte values, | 57 | * with msbs zeroed). Instead, we read them as two 8-bit values, |
55 | * which need byteswapping then range adjustment. | 58 | * which need byteswapping then range adjustment. |
56 | */ | 59 | */ |
57 | __be16 x; | 60 | __be16 x; |
@@ -60,7 +63,7 @@ struct ts_event { | |||
60 | }; | 63 | }; |
61 | 64 | ||
62 | struct ads7846 { | 65 | struct ads7846 { |
63 | struct input_dev input; | 66 | struct input_dev *input; |
64 | char phys[32]; | 67 | char phys[32]; |
65 | 68 | ||
66 | struct spi_device *spi; | 69 | struct spi_device *spi; |
@@ -68,6 +71,7 @@ struct ads7846 { | |||
68 | u16 vref_delay_usecs; | 71 | u16 vref_delay_usecs; |
69 | u16 x_plate_ohms; | 72 | u16 x_plate_ohms; |
70 | 73 | ||
74 | u8 read_x, read_y, read_z1, read_z2; | ||
71 | struct ts_event tc; | 75 | struct ts_event tc; |
72 | 76 | ||
73 | struct spi_transfer xfer[8]; | 77 | struct spi_transfer xfer[8]; |
@@ -117,10 +121,10 @@ struct ads7846 { | |||
117 | #define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \ | 121 | #define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \ |
118 | | ADS_12_BIT | ADS_DFR) | 122 | | ADS_12_BIT | ADS_DFR) |
119 | 123 | ||
120 | static const u8 read_y = READ_12BIT_DFR(y) | ADS_PD10_ADC_ON; | 124 | #define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON) |
121 | static const u8 read_z1 = READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON; | 125 | #define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON) |
122 | static const u8 read_z2 = READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON; | 126 | #define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON) |
123 | static const u8 read_x = READ_12BIT_DFR(x) | ADS_PD10_PDOWN; /* LAST */ | 127 | #define READ_X (READ_12BIT_DFR(x) | ADS_PD10_PDOWN) /* LAST */ |
124 | 128 | ||
125 | /* single-ended samples need to first power up reference voltage; | 129 | /* single-ended samples need to first power up reference voltage; |
126 | * we leave both ADC and VREF powered | 130 | * we leave both ADC and VREF powered |
@@ -128,8 +132,8 @@ static const u8 read_x = READ_12BIT_DFR(x) | ADS_PD10_PDOWN; /* LAST */ | |||
128 | #define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \ | 132 | #define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \ |
129 | | ADS_12_BIT | ADS_SER) | 133 | | ADS_12_BIT | ADS_SER) |
130 | 134 | ||
131 | static const u8 ref_on = READ_12BIT_DFR(x) | ADS_PD10_ALL_ON; | 135 | #define REF_ON (READ_12BIT_DFR(x) | ADS_PD10_ALL_ON) |
132 | static const u8 ref_off = READ_12BIT_DFR(y) | ADS_PD10_PDOWN; | 136 | #define REF_OFF (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) |
133 | 137 | ||
134 | /*--------------------------------------------------------------------------*/ | 138 | /*--------------------------------------------------------------------------*/ |
135 | 139 | ||
@@ -138,7 +142,9 @@ static const u8 ref_off = READ_12BIT_DFR(y) | ADS_PD10_PDOWN; | |||
138 | */ | 142 | */ |
139 | 143 | ||
140 | struct ser_req { | 144 | struct ser_req { |
145 | u8 ref_on; | ||
141 | u8 command; | 146 | u8 command; |
147 | u8 ref_off; | ||
142 | u16 scratch; | 148 | u16 scratch; |
143 | __be16 sample; | 149 | __be16 sample; |
144 | struct spi_message msg; | 150 | struct spi_message msg; |
@@ -152,7 +158,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
152 | struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL); | 158 | struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL); |
153 | int status; | 159 | int status; |
154 | int sample; | 160 | int sample; |
155 | int i; | 161 | int i; |
156 | 162 | ||
157 | if (!req) | 163 | if (!req) |
158 | return -ENOMEM; | 164 | return -ENOMEM; |
@@ -160,7 +166,8 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
160 | INIT_LIST_HEAD(&req->msg.transfers); | 166 | INIT_LIST_HEAD(&req->msg.transfers); |
161 | 167 | ||
162 | /* activate reference, so it has time to settle; */ | 168 | /* activate reference, so it has time to settle; */ |
163 | req->xfer[0].tx_buf = &ref_on; | 169 | req->ref_on = REF_ON; |
170 | req->xfer[0].tx_buf = &req->ref_on; | ||
164 | req->xfer[0].len = 1; | 171 | req->xfer[0].len = 1; |
165 | req->xfer[1].rx_buf = &req->scratch; | 172 | req->xfer[1].rx_buf = &req->scratch; |
166 | req->xfer[1].len = 2; | 173 | req->xfer[1].len = 2; |
@@ -182,7 +189,8 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
182 | /* REVISIT: take a few more samples, and compare ... */ | 189 | /* REVISIT: take a few more samples, and compare ... */ |
183 | 190 | ||
184 | /* turn off reference */ | 191 | /* turn off reference */ |
185 | req->xfer[4].tx_buf = &ref_off; | 192 | req->ref_off = REF_OFF; |
193 | req->xfer[4].tx_buf = &req->ref_off; | ||
186 | req->xfer[4].len = 1; | 194 | req->xfer[4].len = 1; |
187 | req->xfer[5].rx_buf = &req->scratch; | 195 | req->xfer[5].rx_buf = &req->scratch; |
188 | req->xfer[5].len = 2; | 196 | req->xfer[5].len = 2; |
@@ -236,11 +244,12 @@ SHOW(vbatt) | |||
236 | 244 | ||
237 | static void ads7846_rx(void *ads) | 245 | static void ads7846_rx(void *ads) |
238 | { | 246 | { |
239 | struct ads7846 *ts = ads; | 247 | struct ads7846 *ts = ads; |
240 | unsigned Rt; | 248 | struct input_dev *input_dev = ts->input; |
241 | unsigned sync = 0; | 249 | unsigned Rt; |
242 | u16 x, y, z1, z2; | 250 | unsigned sync = 0; |
243 | unsigned long flags; | 251 | u16 x, y, z1, z2; |
252 | unsigned long flags; | ||
244 | 253 | ||
245 | /* adjust: 12 bit samples (left aligned), built from | 254 | /* adjust: 12 bit samples (left aligned), built from |
246 | * two 8 bit values writen msb-first. | 255 | * two 8 bit values writen msb-first. |
@@ -276,21 +285,21 @@ static void ads7846_rx(void *ads) | |||
276 | * won't notice that, even if nPENIRQ never fires ... | 285 | * won't notice that, even if nPENIRQ never fires ... |
277 | */ | 286 | */ |
278 | if (!ts->pendown && Rt != 0) { | 287 | if (!ts->pendown && Rt != 0) { |
279 | input_report_key(&ts->input, BTN_TOUCH, 1); | 288 | input_report_key(input_dev, BTN_TOUCH, 1); |
280 | sync = 1; | 289 | sync = 1; |
281 | } else if (ts->pendown && Rt == 0) { | 290 | } else if (ts->pendown && Rt == 0) { |
282 | input_report_key(&ts->input, BTN_TOUCH, 0); | 291 | input_report_key(input_dev, BTN_TOUCH, 0); |
283 | sync = 1; | 292 | sync = 1; |
284 | } | 293 | } |
285 | 294 | ||
286 | if (Rt) { | 295 | if (Rt) { |
287 | input_report_abs(&ts->input, ABS_X, x); | 296 | input_report_abs(input_dev, ABS_X, x); |
288 | input_report_abs(&ts->input, ABS_Y, y); | 297 | input_report_abs(input_dev, ABS_Y, y); |
289 | input_report_abs(&ts->input, ABS_PRESSURE, Rt); | 298 | input_report_abs(input_dev, ABS_PRESSURE, Rt); |
290 | sync = 1; | 299 | sync = 1; |
291 | } | 300 | } |
292 | if (sync) | 301 | if (sync) |
293 | input_sync(&ts->input); | 302 | input_sync(input_dev); |
294 | 303 | ||
295 | #ifdef VERBOSE | 304 | #ifdef VERBOSE |
296 | if (Rt || ts->pendown) | 305 | if (Rt || ts->pendown) |
@@ -396,9 +405,10 @@ static int ads7846_resume(struct spi_device *spi) | |||
396 | static int __devinit ads7846_probe(struct spi_device *spi) | 405 | static int __devinit ads7846_probe(struct spi_device *spi) |
397 | { | 406 | { |
398 | struct ads7846 *ts; | 407 | struct ads7846 *ts; |
408 | struct input_dev *input_dev; | ||
399 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 409 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
400 | struct spi_transfer *x; | 410 | struct spi_transfer *x; |
401 | int i; | 411 | int err; |
402 | 412 | ||
403 | if (!spi->irq) { | 413 | if (!spi->irq) { |
404 | dev_dbg(&spi->dev, "no IRQ?\n"); | 414 | dev_dbg(&spi->dev, "no IRQ?\n"); |
@@ -411,9 +421,9 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
411 | } | 421 | } |
412 | 422 | ||
413 | /* don't exceed max specified sample rate */ | 423 | /* don't exceed max specified sample rate */ |
414 | if (spi->max_speed_hz > (125000 * 16)) { | 424 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { |
415 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | 425 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", |
416 | (spi->max_speed_hz/16)/1000); | 426 | (spi->max_speed_hz/SAMPLE_BITS)/1000); |
417 | return -EINVAL; | 427 | return -EINVAL; |
418 | } | 428 | } |
419 | 429 | ||
@@ -423,13 +433,18 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
423 | * to discard the four garbage LSBs. | 433 | * to discard the four garbage LSBs. |
424 | */ | 434 | */ |
425 | 435 | ||
426 | if (!(ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL))) | 436 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); |
427 | return -ENOMEM; | 437 | input_dev = input_allocate_device(); |
438 | if (!ts || !input_dev) { | ||
439 | err = -ENOMEM; | ||
440 | goto err_free_mem; | ||
441 | } | ||
428 | 442 | ||
429 | dev_set_drvdata(&spi->dev, ts); | 443 | dev_set_drvdata(&spi->dev, ts); |
444 | spi->dev.power.power_state = PMSG_ON; | ||
430 | 445 | ||
431 | ts->spi = spi; | 446 | ts->spi = spi; |
432 | spi->dev.power.power_state = PMSG_ON; | 447 | ts->input = input_dev; |
433 | 448 | ||
434 | init_timer(&ts->timer); | 449 | init_timer(&ts->timer); |
435 | ts->timer.data = (unsigned long) ts; | 450 | ts->timer.data = (unsigned long) ts; |
@@ -439,70 +454,80 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
439 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | 454 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; |
440 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | 455 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; |
441 | 456 | ||
442 | init_input_dev(&ts->input); | 457 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); |
443 | 458 | ||
444 | ts->input.dev = &spi->dev; | 459 | input_dev->name = "ADS784x Touchscreen"; |
445 | ts->input.name = "ADS784x Touchscreen"; | 460 | input_dev->phys = ts->phys; |
446 | snprintf(ts->phys, sizeof ts->phys, "%s/input0", spi->dev.bus_id); | 461 | input_dev->cdev.dev = &spi->dev; |
447 | ts->input.phys = ts->phys; | ||
448 | 462 | ||
449 | ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 463 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
450 | ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 464 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
451 | input_set_abs_params(&ts->input, ABS_X, | 465 | input_set_abs_params(input_dev, ABS_X, |
452 | pdata->x_min ? : 0, | 466 | pdata->x_min ? : 0, |
453 | pdata->x_max ? : MAX_12BIT, | 467 | pdata->x_max ? : MAX_12BIT, |
454 | 0, 0); | 468 | 0, 0); |
455 | input_set_abs_params(&ts->input, ABS_Y, | 469 | input_set_abs_params(input_dev, ABS_Y, |
456 | pdata->y_min ? : 0, | 470 | pdata->y_min ? : 0, |
457 | pdata->y_max ? : MAX_12BIT, | 471 | pdata->y_max ? : MAX_12BIT, |
458 | 0, 0); | 472 | 0, 0); |
459 | input_set_abs_params(&ts->input, ABS_PRESSURE, | 473 | input_set_abs_params(input_dev, ABS_PRESSURE, |
460 | pdata->pressure_min, pdata->pressure_max, 0, 0); | 474 | pdata->pressure_min, pdata->pressure_max, 0, 0); |
461 | 475 | ||
462 | input_register_device(&ts->input); | ||
463 | |||
464 | /* set up the transfers to read touchscreen state; this assumes we | 476 | /* set up the transfers to read touchscreen state; this assumes we |
465 | * use formula #2 for pressure, not #3. | 477 | * use formula #2 for pressure, not #3. |
466 | */ | 478 | */ |
479 | INIT_LIST_HEAD(&ts->msg.transfers); | ||
467 | x = ts->xfer; | 480 | x = ts->xfer; |
468 | 481 | ||
469 | /* y- still on; turn on only y+ (and ADC) */ | 482 | /* y- still on; turn on only y+ (and ADC) */ |
470 | x->tx_buf = &read_y; | 483 | ts->read_y = READ_Y; |
484 | x->tx_buf = &ts->read_y; | ||
471 | x->len = 1; | 485 | x->len = 1; |
486 | spi_message_add_tail(x, &ts->msg); | ||
487 | |||
472 | x++; | 488 | x++; |
473 | x->rx_buf = &ts->tc.y; | 489 | x->rx_buf = &ts->tc.y; |
474 | x->len = 2; | 490 | x->len = 2; |
475 | x++; | 491 | spi_message_add_tail(x, &ts->msg); |
476 | 492 | ||
477 | /* turn y+ off, x- on; we'll use formula #2 */ | 493 | /* turn y+ off, x- on; we'll use formula #2 */ |
478 | if (ts->model == 7846) { | 494 | if (ts->model == 7846) { |
479 | x->tx_buf = &read_z1; | 495 | x++; |
496 | ts->read_z1 = READ_Z1; | ||
497 | x->tx_buf = &ts->read_z1; | ||
480 | x->len = 1; | 498 | x->len = 1; |
499 | spi_message_add_tail(x, &ts->msg); | ||
500 | |||
481 | x++; | 501 | x++; |
482 | x->rx_buf = &ts->tc.z1; | 502 | x->rx_buf = &ts->tc.z1; |
483 | x->len = 2; | 503 | x->len = 2; |
484 | x++; | 504 | spi_message_add_tail(x, &ts->msg); |
485 | 505 | ||
486 | x->tx_buf = &read_z2; | 506 | x++; |
507 | ts->read_z2 = READ_Z2; | ||
508 | x->tx_buf = &ts->read_z2; | ||
487 | x->len = 1; | 509 | x->len = 1; |
510 | spi_message_add_tail(x, &ts->msg); | ||
511 | |||
488 | x++; | 512 | x++; |
489 | x->rx_buf = &ts->tc.z2; | 513 | x->rx_buf = &ts->tc.z2; |
490 | x->len = 2; | 514 | x->len = 2; |
491 | x++; | 515 | spi_message_add_tail(x, &ts->msg); |
492 | } | 516 | } |
493 | 517 | ||
494 | /* turn y- off, x+ on, then leave in lowpower */ | 518 | /* turn y- off, x+ on, then leave in lowpower */ |
495 | x->tx_buf = &read_x; | 519 | x++; |
520 | ts->read_x = READ_X; | ||
521 | x->tx_buf = &ts->read_x; | ||
496 | x->len = 1; | 522 | x->len = 1; |
523 | spi_message_add_tail(x, &ts->msg); | ||
524 | |||
497 | x++; | 525 | x++; |
498 | x->rx_buf = &ts->tc.x; | 526 | x->rx_buf = &ts->tc.x; |
499 | x->len = 2; | 527 | x->len = 2; |
500 | x++; | 528 | CS_CHANGE(*x); |
501 | 529 | spi_message_add_tail(x, &ts->msg); | |
502 | CS_CHANGE(x[-1]); | ||
503 | 530 | ||
504 | for (i = 0; i < x - ts->xfer; i++) | ||
505 | spi_message_add_tail(&ts->xfer[i], &ts->msg); | ||
506 | ts->msg.complete = ads7846_rx; | 531 | ts->msg.complete = ads7846_rx; |
507 | ts->msg.context = ts; | 532 | ts->msg.context = ts; |
508 | 533 | ||
@@ -510,9 +535,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
510 | SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, | 535 | SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, |
511 | spi->dev.bus_id, ts)) { | 536 | spi->dev.bus_id, ts)) { |
512 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 537 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); |
513 | input_unregister_device(&ts->input); | 538 | err = -EBUSY; |
514 | kfree(ts); | 539 | goto err_free_mem; |
515 | return -EBUSY; | ||
516 | } | 540 | } |
517 | 541 | ||
518 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); | 542 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); |
@@ -534,7 +558,18 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
534 | device_create_file(&spi->dev, &dev_attr_vbatt); | 558 | device_create_file(&spi->dev, &dev_attr_vbatt); |
535 | device_create_file(&spi->dev, &dev_attr_vaux); | 559 | device_create_file(&spi->dev, &dev_attr_vaux); |
536 | 560 | ||
561 | err = input_register_device(input_dev); | ||
562 | if (err) | ||
563 | goto err_free_irq; | ||
564 | |||
537 | return 0; | 565 | return 0; |
566 | |||
567 | err_free_irq: | ||
568 | free_irq(spi->irq, ts); | ||
569 | err_free_mem: | ||
570 | input_free_device(input_dev); | ||
571 | kfree(ts); | ||
572 | return err; | ||
538 | } | 573 | } |
539 | 574 | ||
540 | static int __devexit ads7846_remove(struct spi_device *spi) | 575 | static int __devexit ads7846_remove(struct spi_device *spi) |
@@ -554,7 +589,7 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
554 | device_remove_file(&spi->dev, &dev_attr_vbatt); | 589 | device_remove_file(&spi->dev, &dev_attr_vbatt); |
555 | device_remove_file(&spi->dev, &dev_attr_vaux); | 590 | device_remove_file(&spi->dev, &dev_attr_vaux); |
556 | 591 | ||
557 | input_unregister_device(&ts->input); | 592 | input_unregister_device(ts->input); |
558 | kfree(ts); | 593 | kfree(ts); |
559 | 594 | ||
560 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); | 595 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); |
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index 0ef560144be3..6dfc94122dd9 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig | |||
@@ -351,7 +351,7 @@ config HISAX_ENTERNOW_PCI | |||
351 | 351 | ||
352 | config HISAX_AMD7930 | 352 | config HISAX_AMD7930 |
353 | bool "Am7930 (EXPERIMENTAL)" | 353 | bool "Am7930 (EXPERIMENTAL)" |
354 | depends on EXPERIMENTAL && SPARC | 354 | depends on EXPERIMENTAL && SPARC && BROKEN |
355 | help | 355 | help |
356 | This enables HiSax support for the AMD7930 chips on some SPARCs. | 356 | This enables HiSax support for the AMD7930 chips on some SPARCs. |
357 | This code is not finished yet. | 357 | This code is not finished yet. |
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 8159bcecd0c2..df9d65201819 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c | |||
@@ -1929,6 +1929,8 @@ static struct pci_device_id hisax_pci_tbl[] __initdata = { | |||
1929 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, PCI_ANY_ID, PCI_ANY_ID}, | 1929 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, PCI_ANY_ID, PCI_ANY_ID}, |
1930 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, PCI_ANY_ID, PCI_ANY_ID}, | 1930 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, PCI_ANY_ID, PCI_ANY_ID}, |
1931 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, PCI_ANY_ID, PCI_ANY_ID}, | 1931 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, PCI_ANY_ID, PCI_ANY_ID}, |
1932 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, PCI_ANY_ID, PCI_ANY_ID}, | ||
1933 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, PCI_ANY_ID, PCI_ANY_ID}, | ||
1932 | {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, PCI_ANY_ID, PCI_ANY_ID}, | 1934 | {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, PCI_ANY_ID, PCI_ANY_ID}, |
1933 | {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, PCI_ANY_ID, PCI_ANY_ID}, | 1935 | {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, PCI_ANY_ID, PCI_ANY_ID}, |
1934 | {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, PCI_ANY_ID, PCI_ANY_ID}, | 1936 | {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, PCI_ANY_ID, PCI_ANY_ID}, |
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 4866fc32d8d9..91d25acb5ede 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c | |||
@@ -51,6 +51,8 @@ static const PCI_ENTRY id_list[] = | |||
51 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"}, | 51 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"}, |
52 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"}, | 52 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"}, |
53 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"}, | 53 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"}, |
54 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, "Primux II S0", "B700"}, | ||
55 | {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, "Primux II S0 NT", "B701"}, | ||
54 | {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"}, | 56 | {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"}, |
55 | {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"}, | 57 | {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"}, |
56 | {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"}, | 58 | {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"}, |
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index ca5b4a3b683e..262c44127419 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * hfc_usb.c | 2 | * hfc_usb.c |
3 | * | 3 | * |
4 | * $Id: hfc_usb.c,v 4.36 2005/04/08 09:55:13 martinb1 Exp $ | 4 | * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $ |
5 | * | 5 | * |
6 | * modular HiSax ISDN driver for Colognechip HFC-S USB chip | 6 | * modular HiSax ISDN driver for Colognechip HFC-S USB chip |
7 | * | 7 | * |
@@ -45,7 +45,7 @@ | |||
45 | #include "hfc_usb.h" | 45 | #include "hfc_usb.h" |
46 | 46 | ||
47 | static const char *hfcusb_revision = | 47 | static const char *hfcusb_revision = |
48 | "$Revision: 4.36 $ $Date: 2005/04/08 09:55:13 $ "; | 48 | "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ "; |
49 | 49 | ||
50 | /* Hisax debug support | 50 | /* Hisax debug support |
51 | * use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG | 51 | * use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG |
@@ -219,7 +219,7 @@ symbolic(struct hfcusb_symbolic_list list[], const int num) | |||
219 | for (i = 0; list[i].name != NULL; i++) | 219 | for (i = 0; list[i].name != NULL; i++) |
220 | if (list[i].num == num) | 220 | if (list[i].num == num) |
221 | return (list[i].name); | 221 | return (list[i].name); |
222 | return "<unkown ERROR>"; | 222 | return "<unknown ERROR>"; |
223 | } | 223 | } |
224 | 224 | ||
225 | 225 | ||
@@ -235,9 +235,9 @@ ctrl_start_transfer(hfcusb_data * hfc) | |||
235 | hfc->ctrl_urb->transfer_buffer = NULL; | 235 | hfc->ctrl_urb->transfer_buffer = NULL; |
236 | hfc->ctrl_urb->transfer_buffer_length = 0; | 236 | hfc->ctrl_urb->transfer_buffer_length = 0; |
237 | hfc->ctrl_write.wIndex = | 237 | hfc->ctrl_write.wIndex = |
238 | hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg; | 238 | cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg); |
239 | hfc->ctrl_write.wValue = | 239 | hfc->ctrl_write.wValue = |
240 | hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val; | 240 | cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val); |
241 | 241 | ||
242 | usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC); /* start transfer */ | 242 | usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC); /* start transfer */ |
243 | } | 243 | } |
@@ -1282,7 +1282,7 @@ usb_init(hfcusb_data * hfc) | |||
1282 | /* init the background machinery for control requests */ | 1282 | /* init the background machinery for control requests */ |
1283 | hfc->ctrl_read.bRequestType = 0xc0; | 1283 | hfc->ctrl_read.bRequestType = 0xc0; |
1284 | hfc->ctrl_read.bRequest = 1; | 1284 | hfc->ctrl_read.bRequest = 1; |
1285 | hfc->ctrl_read.wLength = 1; | 1285 | hfc->ctrl_read.wLength = cpu_to_le16(1); |
1286 | hfc->ctrl_write.bRequestType = 0x40; | 1286 | hfc->ctrl_write.bRequestType = 0x40; |
1287 | hfc->ctrl_write.bRequest = 0; | 1287 | hfc->ctrl_write.bRequest = 0; |
1288 | hfc->ctrl_write.wLength = 0; | 1288 | hfc->ctrl_write.wLength = 0; |
@@ -1373,9 +1373,8 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1373 | 1373 | ||
1374 | vend_idx = 0xffff; | 1374 | vend_idx = 0xffff; |
1375 | for (i = 0; hfcusb_idtab[i].idVendor; i++) { | 1375 | for (i = 0; hfcusb_idtab[i].idVendor; i++) { |
1376 | if (dev->descriptor.idVendor == hfcusb_idtab[i].idVendor | 1376 | if ((le16_to_cpu(dev->descriptor.idVendor) == hfcusb_idtab[i].idVendor) |
1377 | && dev->descriptor.idProduct == | 1377 | && (le16_to_cpu(dev->descriptor.idProduct) == hfcusb_idtab[i].idProduct)) { |
1378 | hfcusb_idtab[i].idProduct) { | ||
1379 | vend_idx = i; | 1378 | vend_idx = i; |
1380 | continue; | 1379 | continue; |
1381 | } | 1380 | } |
@@ -1516,8 +1515,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1516 | usb_transfer_mode | 1515 | usb_transfer_mode |
1517 | = USB_INT; | 1516 | = USB_INT; |
1518 | packet_size = | 1517 | packet_size = |
1519 | ep->desc. | 1518 | le16_to_cpu(ep->desc.wMaxPacketSize); |
1520 | wMaxPacketSize; | ||
1521 | break; | 1519 | break; |
1522 | case USB_ENDPOINT_XFER_BULK: | 1520 | case USB_ENDPOINT_XFER_BULK: |
1523 | if (ep_addr & 0x80) | 1521 | if (ep_addr & 0x80) |
@@ -1545,8 +1543,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1545 | usb_transfer_mode | 1543 | usb_transfer_mode |
1546 | = USB_BULK; | 1544 | = USB_BULK; |
1547 | packet_size = | 1545 | packet_size = |
1548 | ep->desc. | 1546 | le16_to_cpu(ep->desc.wMaxPacketSize); |
1549 | wMaxPacketSize; | ||
1550 | break; | 1547 | break; |
1551 | case USB_ENDPOINT_XFER_ISOC: | 1548 | case USB_ENDPOINT_XFER_ISOC: |
1552 | if (ep_addr & 0x80) | 1549 | if (ep_addr & 0x80) |
@@ -1574,8 +1571,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1574 | usb_transfer_mode | 1571 | usb_transfer_mode |
1575 | = USB_ISOC; | 1572 | = USB_ISOC; |
1576 | iso_packet_size = | 1573 | iso_packet_size = |
1577 | ep->desc. | 1574 | le16_to_cpu(ep->desc.wMaxPacketSize); |
1578 | wMaxPacketSize; | ||
1579 | break; | 1575 | break; |
1580 | default: | 1576 | default: |
1581 | context-> | 1577 | context-> |
@@ -1588,10 +1584,8 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1588 | fifonum = cidx; | 1584 | fifonum = cidx; |
1589 | context->fifos[cidx].hfc = | 1585 | context->fifos[cidx].hfc = |
1590 | context; | 1586 | context; |
1591 | context->fifos[cidx]. | 1587 | context->fifos[cidx].usb_packet_maxlen = |
1592 | usb_packet_maxlen = | 1588 | le16_to_cpu(ep->desc.wMaxPacketSize); |
1593 | ep->desc. | ||
1594 | wMaxPacketSize; | ||
1595 | context->fifos[cidx]. | 1589 | context->fifos[cidx]. |
1596 | intervall = | 1590 | intervall = |
1597 | ep->desc.bInterval; | 1591 | ep->desc.bInterval; |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index f190a99604f0..aeaa1db74bd8 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -1682,6 +1682,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) | |||
1682 | #ifdef ISDN_DEBUG_MODEM_OPEN | 1682 | #ifdef ISDN_DEBUG_MODEM_OPEN |
1683 | printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n"); | 1683 | printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n"); |
1684 | #endif | 1684 | #endif |
1685 | module_put(info->owner); | ||
1685 | return; | 1686 | return; |
1686 | } | 1687 | } |
1687 | info->flags |= ISDN_ASYNC_CLOSING; | 1688 | info->flags |= ISDN_ASYNC_CLOSING; |
@@ -2359,8 +2360,8 @@ isdn_tty_at_cout(char *msg, modem_info * info) | |||
2359 | 2360 | ||
2360 | /* use queue instead of direct, if online and */ | 2361 | /* use queue instead of direct, if online and */ |
2361 | /* data is in queue or buffer is full */ | 2362 | /* data is in queue or buffer is full */ |
2362 | if ((info->online && tty_buffer_request_room(tty, l) < l) || | 2363 | if (info->online && ((tty_buffer_request_room(tty, l) < l) || |
2363 | (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { | 2364 | !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { |
2364 | skb = alloc_skb(l, GFP_ATOMIC); | 2365 | skb = alloc_skb(l, GFP_ATOMIC); |
2365 | if (!skb) { | 2366 | if (!skb) { |
2366 | spin_unlock_irqrestore(&info->readlock, flags); | 2367 | spin_unlock_irqrestore(&info->readlock, flags); |
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 7d4a0ac28c06..12ad462737ba 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig | |||
@@ -187,6 +187,14 @@ config WINDFARM_PM91 | |||
187 | This driver provides thermal control for the PowerMac9,1 | 187 | This driver provides thermal control for the PowerMac9,1 |
188 | which is the recent (SMU based) single CPU desktop G5 | 188 | which is the recent (SMU based) single CPU desktop G5 |
189 | 189 | ||
190 | config WINDFARM_PM112 | ||
191 | tristate "Support for thermal management on PowerMac11,2" | ||
192 | depends on WINDFARM && I2C && PMAC_SMU | ||
193 | select I2C_POWERMAC | ||
194 | help | ||
195 | This driver provides thermal control for the PowerMac11,2 | ||
196 | which are the recent dual and quad G5 machines using the | ||
197 | 970MP dual-core processor. | ||
190 | 198 | ||
191 | config ANSLCD | 199 | config ANSLCD |
192 | tristate "Support for ANS LCD display" | 200 | tristate "Support for ANS LCD display" |
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index f4657aa81fb0..6081acdea404 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile | |||
@@ -35,3 +35,8 @@ obj-$(CONFIG_WINDFARM_PM91) += windfarm_smu_controls.o \ | |||
35 | windfarm_smu_sensors.o \ | 35 | windfarm_smu_sensors.o \ |
36 | windfarm_lm75_sensor.o windfarm_pid.o \ | 36 | windfarm_lm75_sensor.o windfarm_pid.o \ |
37 | windfarm_cpufreq_clamp.o windfarm_pm91.o | 37 | windfarm_cpufreq_clamp.o windfarm_pm91.o |
38 | obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \ | ||
39 | windfarm_smu_controls.o \ | ||
40 | windfarm_smu_sensors.o \ | ||
41 | windfarm_max6690_sensor.o \ | ||
42 | windfarm_lm75_sensor.o windfarm_pid.o | ||
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 6eb93e45fcd3..4a478eb0e27d 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -825,7 +825,7 @@ proc_get_info(char *page, char **start, off_t off, | |||
825 | p += sprintf(p, "PMU driver version : %d\n", PMU_DRIVER_VERSION); | 825 | p += sprintf(p, "PMU driver version : %d\n", PMU_DRIVER_VERSION); |
826 | p += sprintf(p, "PMU firmware version : %02x\n", pmu_version); | 826 | p += sprintf(p, "PMU firmware version : %02x\n", pmu_version); |
827 | p += sprintf(p, "AC Power : %d\n", | 827 | p += sprintf(p, "AC Power : %d\n", |
828 | ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0)); | 828 | ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0) || pmu_battery_count == 0); |
829 | p += sprintf(p, "Battery count : %d\n", pmu_battery_count); | 829 | p += sprintf(p, "Battery count : %d\n", pmu_battery_count); |
830 | 830 | ||
831 | return p - page; | 831 | return p - page; |
diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h index 3f0cb0312ea3..7a2482cc26a7 100644 --- a/drivers/macintosh/windfarm.h +++ b/drivers/macintosh/windfarm.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/notifier.h> | 16 | #include <linux/notifier.h> |
17 | #include <linux/device.h> | ||
17 | 18 | ||
18 | /* Display a 16.16 fixed point value */ | 19 | /* Display a 16.16 fixed point value */ |
19 | #define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16) | 20 | #define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16) |
@@ -39,6 +40,7 @@ struct wf_control { | |||
39 | char *name; | 40 | char *name; |
40 | int type; | 41 | int type; |
41 | struct kref ref; | 42 | struct kref ref; |
43 | struct device_attribute attr; | ||
42 | }; | 44 | }; |
43 | 45 | ||
44 | #define WF_CONTROL_TYPE_GENERIC 0 | 46 | #define WF_CONTROL_TYPE_GENERIC 0 |
@@ -87,6 +89,7 @@ struct wf_sensor { | |||
87 | struct wf_sensor_ops *ops; | 89 | struct wf_sensor_ops *ops; |
88 | char *name; | 90 | char *name; |
89 | struct kref ref; | 91 | struct kref ref; |
92 | struct device_attribute attr; | ||
90 | }; | 93 | }; |
91 | 94 | ||
92 | /* Same lifetime rules as controls */ | 95 | /* Same lifetime rules as controls */ |
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index 6c2a471ea6c0..6c0ba04bc57a 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c | |||
@@ -33,6 +33,9 @@ | |||
33 | #include <linux/reboot.h> | 33 | #include <linux/reboot.h> |
34 | #include <linux/device.h> | 34 | #include <linux/device.h> |
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/mutex.h> | ||
37 | |||
38 | #include <asm/prom.h> | ||
36 | 39 | ||
37 | #include "windfarm.h" | 40 | #include "windfarm.h" |
38 | 41 | ||
@@ -48,13 +51,17 @@ | |||
48 | 51 | ||
49 | static LIST_HEAD(wf_controls); | 52 | static LIST_HEAD(wf_controls); |
50 | static LIST_HEAD(wf_sensors); | 53 | static LIST_HEAD(wf_sensors); |
51 | static DECLARE_MUTEX(wf_lock); | 54 | static DEFINE_MUTEX(wf_lock); |
52 | static struct notifier_block *wf_client_list; | 55 | static struct notifier_block *wf_client_list; |
53 | static int wf_client_count; | 56 | static int wf_client_count; |
54 | static unsigned int wf_overtemp; | 57 | static unsigned int wf_overtemp; |
55 | static unsigned int wf_overtemp_counter; | 58 | static unsigned int wf_overtemp_counter; |
56 | struct task_struct *wf_thread; | 59 | struct task_struct *wf_thread; |
57 | 60 | ||
61 | static struct platform_device wf_platform_device = { | ||
62 | .name = "windfarm", | ||
63 | }; | ||
64 | |||
58 | /* | 65 | /* |
59 | * Utilities & tick thread | 66 | * Utilities & tick thread |
60 | */ | 67 | */ |
@@ -156,26 +163,67 @@ static void wf_control_release(struct kref *kref) | |||
156 | kfree(ct); | 163 | kfree(ct); |
157 | } | 164 | } |
158 | 165 | ||
166 | static ssize_t wf_show_control(struct device *dev, | ||
167 | struct device_attribute *attr, char *buf) | ||
168 | { | ||
169 | struct wf_control *ctrl = container_of(attr, struct wf_control, attr); | ||
170 | s32 val = 0; | ||
171 | int err; | ||
172 | |||
173 | err = ctrl->ops->get_value(ctrl, &val); | ||
174 | if (err < 0) | ||
175 | return err; | ||
176 | return sprintf(buf, "%d\n", val); | ||
177 | } | ||
178 | |||
179 | /* This is really only for debugging... */ | ||
180 | static ssize_t wf_store_control(struct device *dev, | ||
181 | struct device_attribute *attr, | ||
182 | const char *buf, size_t count) | ||
183 | { | ||
184 | struct wf_control *ctrl = container_of(attr, struct wf_control, attr); | ||
185 | int val; | ||
186 | int err; | ||
187 | char *endp; | ||
188 | |||
189 | val = simple_strtoul(buf, &endp, 0); | ||
190 | while (endp < buf + count && (*endp == ' ' || *endp == '\n')) | ||
191 | ++endp; | ||
192 | if (endp - buf < count) | ||
193 | return -EINVAL; | ||
194 | err = ctrl->ops->set_value(ctrl, val); | ||
195 | if (err < 0) | ||
196 | return err; | ||
197 | return count; | ||
198 | } | ||
199 | |||
159 | int wf_register_control(struct wf_control *new_ct) | 200 | int wf_register_control(struct wf_control *new_ct) |
160 | { | 201 | { |
161 | struct wf_control *ct; | 202 | struct wf_control *ct; |
162 | 203 | ||
163 | down(&wf_lock); | 204 | mutex_lock(&wf_lock); |
164 | list_for_each_entry(ct, &wf_controls, link) { | 205 | list_for_each_entry(ct, &wf_controls, link) { |
165 | if (!strcmp(ct->name, new_ct->name)) { | 206 | if (!strcmp(ct->name, new_ct->name)) { |
166 | printk(KERN_WARNING "windfarm: trying to register" | 207 | printk(KERN_WARNING "windfarm: trying to register" |
167 | " duplicate control %s\n", ct->name); | 208 | " duplicate control %s\n", ct->name); |
168 | up(&wf_lock); | 209 | mutex_unlock(&wf_lock); |
169 | return -EEXIST; | 210 | return -EEXIST; |
170 | } | 211 | } |
171 | } | 212 | } |
172 | kref_init(&new_ct->ref); | 213 | kref_init(&new_ct->ref); |
173 | list_add(&new_ct->link, &wf_controls); | 214 | list_add(&new_ct->link, &wf_controls); |
174 | 215 | ||
216 | new_ct->attr.attr.name = new_ct->name; | ||
217 | new_ct->attr.attr.owner = THIS_MODULE; | ||
218 | new_ct->attr.attr.mode = 0644; | ||
219 | new_ct->attr.show = wf_show_control; | ||
220 | new_ct->attr.store = wf_store_control; | ||
221 | device_create_file(&wf_platform_device.dev, &new_ct->attr); | ||
222 | |||
175 | DBG("wf: Registered control %s\n", new_ct->name); | 223 | DBG("wf: Registered control %s\n", new_ct->name); |
176 | 224 | ||
177 | wf_notify(WF_EVENT_NEW_CONTROL, new_ct); | 225 | wf_notify(WF_EVENT_NEW_CONTROL, new_ct); |
178 | up(&wf_lock); | 226 | mutex_unlock(&wf_lock); |
179 | 227 | ||
180 | return 0; | 228 | return 0; |
181 | } | 229 | } |
@@ -183,9 +231,9 @@ EXPORT_SYMBOL_GPL(wf_register_control); | |||
183 | 231 | ||
184 | void wf_unregister_control(struct wf_control *ct) | 232 | void wf_unregister_control(struct wf_control *ct) |
185 | { | 233 | { |
186 | down(&wf_lock); | 234 | mutex_lock(&wf_lock); |
187 | list_del(&ct->link); | 235 | list_del(&ct->link); |
188 | up(&wf_lock); | 236 | mutex_unlock(&wf_lock); |
189 | 237 | ||
190 | DBG("wf: Unregistered control %s\n", ct->name); | 238 | DBG("wf: Unregistered control %s\n", ct->name); |
191 | 239 | ||
@@ -197,16 +245,16 @@ struct wf_control * wf_find_control(const char *name) | |||
197 | { | 245 | { |
198 | struct wf_control *ct; | 246 | struct wf_control *ct; |
199 | 247 | ||
200 | down(&wf_lock); | 248 | mutex_lock(&wf_lock); |
201 | list_for_each_entry(ct, &wf_controls, link) { | 249 | list_for_each_entry(ct, &wf_controls, link) { |
202 | if (!strcmp(ct->name, name)) { | 250 | if (!strcmp(ct->name, name)) { |
203 | if (wf_get_control(ct)) | 251 | if (wf_get_control(ct)) |
204 | ct = NULL; | 252 | ct = NULL; |
205 | up(&wf_lock); | 253 | mutex_unlock(&wf_lock); |
206 | return ct; | 254 | return ct; |
207 | } | 255 | } |
208 | } | 256 | } |
209 | up(&wf_lock); | 257 | mutex_unlock(&wf_lock); |
210 | return NULL; | 258 | return NULL; |
211 | } | 259 | } |
212 | EXPORT_SYMBOL_GPL(wf_find_control); | 260 | EXPORT_SYMBOL_GPL(wf_find_control); |
@@ -246,26 +294,46 @@ static void wf_sensor_release(struct kref *kref) | |||
246 | kfree(sr); | 294 | kfree(sr); |
247 | } | 295 | } |
248 | 296 | ||
297 | static ssize_t wf_show_sensor(struct device *dev, | ||
298 | struct device_attribute *attr, char *buf) | ||
299 | { | ||
300 | struct wf_sensor *sens = container_of(attr, struct wf_sensor, attr); | ||
301 | s32 val = 0; | ||
302 | int err; | ||
303 | |||
304 | err = sens->ops->get_value(sens, &val); | ||
305 | if (err < 0) | ||
306 | return err; | ||
307 | return sprintf(buf, "%d.%03d\n", FIX32TOPRINT(val)); | ||
308 | } | ||
309 | |||
249 | int wf_register_sensor(struct wf_sensor *new_sr) | 310 | int wf_register_sensor(struct wf_sensor *new_sr) |
250 | { | 311 | { |
251 | struct wf_sensor *sr; | 312 | struct wf_sensor *sr; |
252 | 313 | ||
253 | down(&wf_lock); | 314 | mutex_lock(&wf_lock); |
254 | list_for_each_entry(sr, &wf_sensors, link) { | 315 | list_for_each_entry(sr, &wf_sensors, link) { |
255 | if (!strcmp(sr->name, new_sr->name)) { | 316 | if (!strcmp(sr->name, new_sr->name)) { |
256 | printk(KERN_WARNING "windfarm: trying to register" | 317 | printk(KERN_WARNING "windfarm: trying to register" |
257 | " duplicate sensor %s\n", sr->name); | 318 | " duplicate sensor %s\n", sr->name); |
258 | up(&wf_lock); | 319 | mutex_unlock(&wf_lock); |
259 | return -EEXIST; | 320 | return -EEXIST; |
260 | } | 321 | } |
261 | } | 322 | } |
262 | kref_init(&new_sr->ref); | 323 | kref_init(&new_sr->ref); |
263 | list_add(&new_sr->link, &wf_sensors); | 324 | list_add(&new_sr->link, &wf_sensors); |
264 | 325 | ||
326 | new_sr->attr.attr.name = new_sr->name; | ||
327 | new_sr->attr.attr.owner = THIS_MODULE; | ||
328 | new_sr->attr.attr.mode = 0444; | ||
329 | new_sr->attr.show = wf_show_sensor; | ||
330 | new_sr->attr.store = NULL; | ||
331 | device_create_file(&wf_platform_device.dev, &new_sr->attr); | ||
332 | |||
265 | DBG("wf: Registered sensor %s\n", new_sr->name); | 333 | DBG("wf: Registered sensor %s\n", new_sr->name); |
266 | 334 | ||
267 | wf_notify(WF_EVENT_NEW_SENSOR, new_sr); | 335 | wf_notify(WF_EVENT_NEW_SENSOR, new_sr); |
268 | up(&wf_lock); | 336 | mutex_unlock(&wf_lock); |
269 | 337 | ||
270 | return 0; | 338 | return 0; |
271 | } | 339 | } |
@@ -273,9 +341,9 @@ EXPORT_SYMBOL_GPL(wf_register_sensor); | |||
273 | 341 | ||
274 | void wf_unregister_sensor(struct wf_sensor *sr) | 342 | void wf_unregister_sensor(struct wf_sensor *sr) |
275 | { | 343 | { |
276 | down(&wf_lock); | 344 | mutex_lock(&wf_lock); |
277 | list_del(&sr->link); | 345 | list_del(&sr->link); |
278 | up(&wf_lock); | 346 | mutex_unlock(&wf_lock); |
279 | 347 | ||
280 | DBG("wf: Unregistered sensor %s\n", sr->name); | 348 | DBG("wf: Unregistered sensor %s\n", sr->name); |
281 | 349 | ||
@@ -287,16 +355,16 @@ struct wf_sensor * wf_find_sensor(const char *name) | |||
287 | { | 355 | { |
288 | struct wf_sensor *sr; | 356 | struct wf_sensor *sr; |
289 | 357 | ||
290 | down(&wf_lock); | 358 | mutex_lock(&wf_lock); |
291 | list_for_each_entry(sr, &wf_sensors, link) { | 359 | list_for_each_entry(sr, &wf_sensors, link) { |
292 | if (!strcmp(sr->name, name)) { | 360 | if (!strcmp(sr->name, name)) { |
293 | if (wf_get_sensor(sr)) | 361 | if (wf_get_sensor(sr)) |
294 | sr = NULL; | 362 | sr = NULL; |
295 | up(&wf_lock); | 363 | mutex_unlock(&wf_lock); |
296 | return sr; | 364 | return sr; |
297 | } | 365 | } |
298 | } | 366 | } |
299 | up(&wf_lock); | 367 | mutex_unlock(&wf_lock); |
300 | return NULL; | 368 | return NULL; |
301 | } | 369 | } |
302 | EXPORT_SYMBOL_GPL(wf_find_sensor); | 370 | EXPORT_SYMBOL_GPL(wf_find_sensor); |
@@ -329,7 +397,7 @@ int wf_register_client(struct notifier_block *nb) | |||
329 | struct wf_control *ct; | 397 | struct wf_control *ct; |
330 | struct wf_sensor *sr; | 398 | struct wf_sensor *sr; |
331 | 399 | ||
332 | down(&wf_lock); | 400 | mutex_lock(&wf_lock); |
333 | rc = notifier_chain_register(&wf_client_list, nb); | 401 | rc = notifier_chain_register(&wf_client_list, nb); |
334 | if (rc != 0) | 402 | if (rc != 0) |
335 | goto bail; | 403 | goto bail; |
@@ -341,19 +409,19 @@ int wf_register_client(struct notifier_block *nb) | |||
341 | if (wf_client_count == 1) | 409 | if (wf_client_count == 1) |
342 | wf_start_thread(); | 410 | wf_start_thread(); |
343 | bail: | 411 | bail: |
344 | up(&wf_lock); | 412 | mutex_unlock(&wf_lock); |
345 | return rc; | 413 | return rc; |
346 | } | 414 | } |
347 | EXPORT_SYMBOL_GPL(wf_register_client); | 415 | EXPORT_SYMBOL_GPL(wf_register_client); |
348 | 416 | ||
349 | int wf_unregister_client(struct notifier_block *nb) | 417 | int wf_unregister_client(struct notifier_block *nb) |
350 | { | 418 | { |
351 | down(&wf_lock); | 419 | mutex_lock(&wf_lock); |
352 | notifier_chain_unregister(&wf_client_list, nb); | 420 | notifier_chain_unregister(&wf_client_list, nb); |
353 | wf_client_count++; | 421 | wf_client_count++; |
354 | if (wf_client_count == 0) | 422 | if (wf_client_count == 0) |
355 | wf_stop_thread(); | 423 | wf_stop_thread(); |
356 | up(&wf_lock); | 424 | mutex_unlock(&wf_lock); |
357 | 425 | ||
358 | return 0; | 426 | return 0; |
359 | } | 427 | } |
@@ -361,23 +429,23 @@ EXPORT_SYMBOL_GPL(wf_unregister_client); | |||
361 | 429 | ||
362 | void wf_set_overtemp(void) | 430 | void wf_set_overtemp(void) |
363 | { | 431 | { |
364 | down(&wf_lock); | 432 | mutex_lock(&wf_lock); |
365 | wf_overtemp++; | 433 | wf_overtemp++; |
366 | if (wf_overtemp == 1) { | 434 | if (wf_overtemp == 1) { |
367 | printk(KERN_WARNING "windfarm: Overtemp condition detected !\n"); | 435 | printk(KERN_WARNING "windfarm: Overtemp condition detected !\n"); |
368 | wf_overtemp_counter = 0; | 436 | wf_overtemp_counter = 0; |
369 | wf_notify(WF_EVENT_OVERTEMP, NULL); | 437 | wf_notify(WF_EVENT_OVERTEMP, NULL); |
370 | } | 438 | } |
371 | up(&wf_lock); | 439 | mutex_unlock(&wf_lock); |
372 | } | 440 | } |
373 | EXPORT_SYMBOL_GPL(wf_set_overtemp); | 441 | EXPORT_SYMBOL_GPL(wf_set_overtemp); |
374 | 442 | ||
375 | void wf_clear_overtemp(void) | 443 | void wf_clear_overtemp(void) |
376 | { | 444 | { |
377 | down(&wf_lock); | 445 | mutex_lock(&wf_lock); |
378 | WARN_ON(wf_overtemp == 0); | 446 | WARN_ON(wf_overtemp == 0); |
379 | if (wf_overtemp == 0) { | 447 | if (wf_overtemp == 0) { |
380 | up(&wf_lock); | 448 | mutex_unlock(&wf_lock); |
381 | return; | 449 | return; |
382 | } | 450 | } |
383 | wf_overtemp--; | 451 | wf_overtemp--; |
@@ -385,7 +453,7 @@ void wf_clear_overtemp(void) | |||
385 | printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n"); | 453 | printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n"); |
386 | wf_notify(WF_EVENT_NORMALTEMP, NULL); | 454 | wf_notify(WF_EVENT_NORMALTEMP, NULL); |
387 | } | 455 | } |
388 | up(&wf_lock); | 456 | mutex_unlock(&wf_lock); |
389 | } | 457 | } |
390 | EXPORT_SYMBOL_GPL(wf_clear_overtemp); | 458 | EXPORT_SYMBOL_GPL(wf_clear_overtemp); |
391 | 459 | ||
@@ -395,14 +463,15 @@ int wf_is_overtemp(void) | |||
395 | } | 463 | } |
396 | EXPORT_SYMBOL_GPL(wf_is_overtemp); | 464 | EXPORT_SYMBOL_GPL(wf_is_overtemp); |
397 | 465 | ||
398 | static struct platform_device wf_platform_device = { | ||
399 | .name = "windfarm", | ||
400 | }; | ||
401 | |||
402 | static int __init windfarm_core_init(void) | 466 | static int __init windfarm_core_init(void) |
403 | { | 467 | { |
404 | DBG("wf: core loaded\n"); | 468 | DBG("wf: core loaded\n"); |
405 | 469 | ||
470 | /* Don't register on old machines that use therm_pm72 for now */ | ||
471 | if (machine_is_compatible("PowerMac7,2") || | ||
472 | machine_is_compatible("PowerMac7,3") || | ||
473 | machine_is_compatible("RackMac3,1")) | ||
474 | return -ENODEV; | ||
406 | platform_device_register(&wf_platform_device); | 475 | platform_device_register(&wf_platform_device); |
407 | return 0; | 476 | return 0; |
408 | } | 477 | } |
diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c index 607dbaca69c9..81337cd16e80 100644 --- a/drivers/macintosh/windfarm_cpufreq_clamp.c +++ b/drivers/macintosh/windfarm_cpufreq_clamp.c | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <linux/wait.h> | 8 | #include <linux/wait.h> |
9 | #include <linux/cpufreq.h> | 9 | #include <linux/cpufreq.h> |
10 | 10 | ||
11 | #include <asm/prom.h> | ||
12 | |||
11 | #include "windfarm.h" | 13 | #include "windfarm.h" |
12 | 14 | ||
13 | #define VERSION "0.3" | 15 | #define VERSION "0.3" |
@@ -74,6 +76,12 @@ static int __init wf_cpufreq_clamp_init(void) | |||
74 | { | 76 | { |
75 | struct wf_control *clamp; | 77 | struct wf_control *clamp; |
76 | 78 | ||
79 | /* Don't register on old machines that use therm_pm72 for now */ | ||
80 | if (machine_is_compatible("PowerMac7,2") || | ||
81 | machine_is_compatible("PowerMac7,3") || | ||
82 | machine_is_compatible("RackMac3,1")) | ||
83 | return -ENODEV; | ||
84 | |||
77 | clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL); | 85 | clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL); |
78 | if (clamp == NULL) | 86 | if (clamp == NULL) |
79 | return -ENOMEM; | 87 | return -ENOMEM; |
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index 906d3ecae6e6..423bfa2432c0 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include "windfarm.h" | 26 | #include "windfarm.h" |
27 | 27 | ||
28 | #define VERSION "0.1" | 28 | #define VERSION "0.2" |
29 | 29 | ||
30 | #undef DEBUG | 30 | #undef DEBUG |
31 | 31 | ||
@@ -113,6 +113,7 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, | |||
113 | const char *loc) | 113 | const char *loc) |
114 | { | 114 | { |
115 | struct wf_lm75_sensor *lm; | 115 | struct wf_lm75_sensor *lm; |
116 | int rc; | ||
116 | 117 | ||
117 | DBG("wf_lm75: creating %s device at address 0x%02x\n", | 118 | DBG("wf_lm75: creating %s device at address 0x%02x\n", |
118 | ds1775 ? "ds1775" : "lm75", addr); | 119 | ds1775 ? "ds1775" : "lm75", addr); |
@@ -139,9 +140,11 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, | |||
139 | lm->i2c.driver = &wf_lm75_driver; | 140 | lm->i2c.driver = &wf_lm75_driver; |
140 | strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1); | 141 | strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1); |
141 | 142 | ||
142 | if (i2c_attach_client(&lm->i2c)) { | 143 | rc = i2c_attach_client(&lm->i2c); |
143 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n", | 144 | if (rc) { |
144 | ds1775 ? "ds1775" : "lm75", lm->i2c.name); | 145 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c," |
146 | " err %d\n", ds1775 ? "ds1775" : "lm75", | ||
147 | lm->i2c.name, rc); | ||
145 | goto fail; | 148 | goto fail; |
146 | } | 149 | } |
147 | 150 | ||
@@ -175,16 +178,22 @@ static int wf_lm75_attach(struct i2c_adapter *adapter) | |||
175 | (dev = of_get_next_child(busnode, dev)) != NULL;) { | 178 | (dev = of_get_next_child(busnode, dev)) != NULL;) { |
176 | const char *loc = | 179 | const char *loc = |
177 | get_property(dev, "hwsensor-location", NULL); | 180 | get_property(dev, "hwsensor-location", NULL); |
178 | u32 *reg = (u32 *)get_property(dev, "reg", NULL); | 181 | u8 addr; |
179 | DBG(" dev: %s... (loc: %p, reg: %p)\n", dev->name, loc, reg); | 182 | |
180 | if (loc == NULL || reg == NULL) | 183 | /* We must re-match the adapter in order to properly check |
184 | * the channel on multibus setups | ||
185 | */ | ||
186 | if (!pmac_i2c_match_adapter(dev, adapter)) | ||
187 | continue; | ||
188 | addr = pmac_i2c_get_dev_addr(dev); | ||
189 | if (loc == NULL || addr == 0) | ||
181 | continue; | 190 | continue; |
182 | /* real lm75 */ | 191 | /* real lm75 */ |
183 | if (device_is_compatible(dev, "lm75")) | 192 | if (device_is_compatible(dev, "lm75")) |
184 | wf_lm75_create(adapter, *reg, 0, loc); | 193 | wf_lm75_create(adapter, addr, 0, loc); |
185 | /* ds1775 (compatible, better resolution */ | 194 | /* ds1775 (compatible, better resolution */ |
186 | else if (device_is_compatible(dev, "ds1775")) | 195 | else if (device_is_compatible(dev, "ds1775")) |
187 | wf_lm75_create(adapter, *reg, 1, loc); | 196 | wf_lm75_create(adapter, addr, 1, loc); |
188 | } | 197 | } |
189 | return 0; | 198 | return 0; |
190 | } | 199 | } |
@@ -206,6 +215,11 @@ static int wf_lm75_detach(struct i2c_client *client) | |||
206 | 215 | ||
207 | static int __init wf_lm75_sensor_init(void) | 216 | static int __init wf_lm75_sensor_init(void) |
208 | { | 217 | { |
218 | /* Don't register on old machines that use therm_pm72 for now */ | ||
219 | if (machine_is_compatible("PowerMac7,2") || | ||
220 | machine_is_compatible("PowerMac7,3") || | ||
221 | machine_is_compatible("RackMac3,1")) | ||
222 | return -ENODEV; | ||
209 | return i2c_add_driver(&wf_lm75_driver); | 223 | return i2c_add_driver(&wf_lm75_driver); |
210 | } | 224 | } |
211 | 225 | ||
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c new file mode 100644 index 000000000000..8e99d408fddd --- /dev/null +++ b/drivers/macintosh/windfarm_max6690_sensor.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * Windfarm PowerMac thermal control. MAX6690 sensor. | ||
3 | * | ||
4 | * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> | ||
5 | * | ||
6 | * Use and redistribute under the terms of the GNU GPL v2. | ||
7 | */ | ||
8 | #include <linux/types.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/i2c-dev.h> | ||
15 | #include <asm/prom.h> | ||
16 | #include <asm/pmac_low_i2c.h> | ||
17 | |||
18 | #include "windfarm.h" | ||
19 | |||
20 | #define VERSION "0.2" | ||
21 | |||
22 | /* This currently only exports the external temperature sensor, | ||
23 | since that's all the control loops need. */ | ||
24 | |||
25 | /* Some MAX6690 register numbers */ | ||
26 | #define MAX6690_INTERNAL_TEMP 0 | ||
27 | #define MAX6690_EXTERNAL_TEMP 1 | ||
28 | |||
29 | struct wf_6690_sensor { | ||
30 | struct i2c_client i2c; | ||
31 | struct wf_sensor sens; | ||
32 | }; | ||
33 | |||
34 | #define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) | ||
35 | #define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c) | ||
36 | |||
37 | static int wf_max6690_attach(struct i2c_adapter *adapter); | ||
38 | static int wf_max6690_detach(struct i2c_client *client); | ||
39 | |||
40 | static struct i2c_driver wf_max6690_driver = { | ||
41 | .driver = { | ||
42 | .name = "wf_max6690", | ||
43 | }, | ||
44 | .attach_adapter = wf_max6690_attach, | ||
45 | .detach_client = wf_max6690_detach, | ||
46 | }; | ||
47 | |||
48 | static int wf_max6690_get(struct wf_sensor *sr, s32 *value) | ||
49 | { | ||
50 | struct wf_6690_sensor *max = wf_to_6690(sr); | ||
51 | s32 data; | ||
52 | |||
53 | if (max->i2c.adapter == NULL) | ||
54 | return -ENODEV; | ||
55 | |||
56 | /* chip gets initialized by firmware */ | ||
57 | data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP); | ||
58 | if (data < 0) | ||
59 | return data; | ||
60 | *value = data << 16; | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static void wf_max6690_release(struct wf_sensor *sr) | ||
65 | { | ||
66 | struct wf_6690_sensor *max = wf_to_6690(sr); | ||
67 | |||
68 | if (max->i2c.adapter) { | ||
69 | i2c_detach_client(&max->i2c); | ||
70 | max->i2c.adapter = NULL; | ||
71 | } | ||
72 | kfree(max); | ||
73 | } | ||
74 | |||
75 | static struct wf_sensor_ops wf_max6690_ops = { | ||
76 | .get_value = wf_max6690_get, | ||
77 | .release = wf_max6690_release, | ||
78 | .owner = THIS_MODULE, | ||
79 | }; | ||
80 | |||
81 | static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr) | ||
82 | { | ||
83 | struct wf_6690_sensor *max; | ||
84 | char *name = "backside-temp"; | ||
85 | |||
86 | max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); | ||
87 | if (max == NULL) { | ||
88 | printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " | ||
89 | "no memory\n", name); | ||
90 | return; | ||
91 | } | ||
92 | |||
93 | max->sens.ops = &wf_max6690_ops; | ||
94 | max->sens.name = name; | ||
95 | max->i2c.addr = addr >> 1; | ||
96 | max->i2c.adapter = adapter; | ||
97 | max->i2c.driver = &wf_max6690_driver; | ||
98 | strncpy(max->i2c.name, name, I2C_NAME_SIZE-1); | ||
99 | |||
100 | if (i2c_attach_client(&max->i2c)) { | ||
101 | printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n"); | ||
102 | goto fail; | ||
103 | } | ||
104 | |||
105 | if (wf_register_sensor(&max->sens)) { | ||
106 | i2c_detach_client(&max->i2c); | ||
107 | goto fail; | ||
108 | } | ||
109 | |||
110 | return; | ||
111 | |||
112 | fail: | ||
113 | kfree(max); | ||
114 | } | ||
115 | |||
116 | static int wf_max6690_attach(struct i2c_adapter *adapter) | ||
117 | { | ||
118 | struct device_node *busnode, *dev = NULL; | ||
119 | struct pmac_i2c_bus *bus; | ||
120 | const char *loc; | ||
121 | |||
122 | bus = pmac_i2c_adapter_to_bus(adapter); | ||
123 | if (bus == NULL) | ||
124 | return -ENODEV; | ||
125 | busnode = pmac_i2c_get_bus_node(bus); | ||
126 | |||
127 | while ((dev = of_get_next_child(busnode, dev)) != NULL) { | ||
128 | u8 addr; | ||
129 | |||
130 | /* We must re-match the adapter in order to properly check | ||
131 | * the channel on multibus setups | ||
132 | */ | ||
133 | if (!pmac_i2c_match_adapter(dev, adapter)) | ||
134 | continue; | ||
135 | if (!device_is_compatible(dev, "max6690")) | ||
136 | continue; | ||
137 | addr = pmac_i2c_get_dev_addr(dev); | ||
138 | loc = get_property(dev, "hwsensor-location", NULL); | ||
139 | if (loc == NULL || addr == 0) | ||
140 | continue; | ||
141 | printk("found max6690, loc=%s addr=0x%02x\n", loc, addr); | ||
142 | if (strcmp(loc, "BACKSIDE")) | ||
143 | continue; | ||
144 | wf_max6690_create(adapter, addr); | ||
145 | } | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int wf_max6690_detach(struct i2c_client *client) | ||
151 | { | ||
152 | struct wf_6690_sensor *max = i2c_to_6690(client); | ||
153 | |||
154 | max->i2c.adapter = NULL; | ||
155 | wf_unregister_sensor(&max->sens); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int __init wf_max6690_sensor_init(void) | ||
161 | { | ||
162 | /* Don't register on old machines that use therm_pm72 for now */ | ||
163 | if (machine_is_compatible("PowerMac7,2") || | ||
164 | machine_is_compatible("PowerMac7,3") || | ||
165 | machine_is_compatible("RackMac3,1")) | ||
166 | return -ENODEV; | ||
167 | return i2c_add_driver(&wf_max6690_driver); | ||
168 | } | ||
169 | |||
170 | static void __exit wf_max6690_sensor_exit(void) | ||
171 | { | ||
172 | i2c_del_driver(&wf_max6690_driver); | ||
173 | } | ||
174 | |||
175 | module_init(wf_max6690_sensor_init); | ||
176 | module_exit(wf_max6690_sensor_exit); | ||
177 | |||
178 | MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); | ||
179 | MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control"); | ||
180 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/macintosh/windfarm_pid.c b/drivers/macintosh/windfarm_pid.c index 2e803b368757..f10efb28cae4 100644 --- a/drivers/macintosh/windfarm_pid.c +++ b/drivers/macintosh/windfarm_pid.c | |||
@@ -88,8 +88,8 @@ EXPORT_SYMBOL_GPL(wf_cpu_pid_init); | |||
88 | 88 | ||
89 | s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) | 89 | s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) |
90 | { | 90 | { |
91 | s64 error, integ, deriv, prop; | 91 | s64 integ, deriv, prop; |
92 | s32 target, sval, adj; | 92 | s32 error, target, sval, adj; |
93 | int i, hlen = st->param.history_len; | 93 | int i, hlen = st->param.history_len; |
94 | 94 | ||
95 | /* Calculate error term */ | 95 | /* Calculate error term */ |
@@ -117,7 +117,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) | |||
117 | integ += st->errors[(st->index + hlen - i) % hlen]; | 117 | integ += st->errors[(st->index + hlen - i) % hlen]; |
118 | integ *= st->param.interval; | 118 | integ *= st->param.interval; |
119 | integ *= st->param.gr; | 119 | integ *= st->param.gr; |
120 | sval = st->param.tmax - ((integ >> 20) & 0xffffffff); | 120 | sval = st->param.tmax - (s32)(integ >> 20); |
121 | adj = min(st->param.ttarget, sval); | 121 | adj = min(st->param.ttarget, sval); |
122 | 122 | ||
123 | DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj); | 123 | DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj); |
@@ -129,7 +129,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) | |||
129 | deriv *= st->param.gd; | 129 | deriv *= st->param.gd; |
130 | 130 | ||
131 | /* Calculate proportional term */ | 131 | /* Calculate proportional term */ |
132 | prop = (new_temp - adj); | 132 | prop = st->last_delta = (new_temp - adj); |
133 | prop *= st->param.gp; | 133 | prop *= st->param.gp; |
134 | 134 | ||
135 | DBG("deriv: %lx, prop: %lx\n", deriv, prop); | 135 | DBG("deriv: %lx, prop: %lx\n", deriv, prop); |
@@ -143,3 +143,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) | |||
143 | return st->target; | 143 | return st->target; |
144 | } | 144 | } |
145 | EXPORT_SYMBOL_GPL(wf_cpu_pid_run); | 145 | EXPORT_SYMBOL_GPL(wf_cpu_pid_run); |
146 | |||
147 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); | ||
148 | MODULE_DESCRIPTION("PID algorithm for PowerMacs thermal control"); | ||
149 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/macintosh/windfarm_pid.h b/drivers/macintosh/windfarm_pid.h index a364c2a2499c..bbccc22d42b8 100644 --- a/drivers/macintosh/windfarm_pid.h +++ b/drivers/macintosh/windfarm_pid.h | |||
@@ -72,6 +72,7 @@ struct wf_cpu_pid_state { | |||
72 | int index; /* index of current power */ | 72 | int index; /* index of current power */ |
73 | int tindex; /* index of current temp */ | 73 | int tindex; /* index of current temp */ |
74 | s32 target; /* current target value */ | 74 | s32 target; /* current target value */ |
75 | s32 last_delta; /* last Tactual - Ttarget */ | ||
75 | s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */ | 76 | s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */ |
76 | s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ | 77 | s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ |
77 | s32 temps[2]; /* temp. history buffer */ | 78 | s32 temps[2]; /* temp. history buffer */ |
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c new file mode 100644 index 000000000000..ef66bf2778ec --- /dev/null +++ b/drivers/macintosh/windfarm_pm112.c | |||
@@ -0,0 +1,700 @@ | |||
1 | /* | ||
2 | * Windfarm PowerMac thermal control. | ||
3 | * Control loops for machines with SMU and PPC970MP processors. | ||
4 | * | ||
5 | * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> | ||
6 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
7 | * | ||
8 | * Use and redistribute under the terms of the GNU GPL v2. | ||
9 | */ | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/reboot.h> | ||
16 | #include <asm/prom.h> | ||
17 | #include <asm/smu.h> | ||
18 | |||
19 | #include "windfarm.h" | ||
20 | #include "windfarm_pid.h" | ||
21 | |||
22 | #define VERSION "0.2" | ||
23 | |||
24 | #define DEBUG | ||
25 | #undef LOTSA_DEBUG | ||
26 | |||
27 | #ifdef DEBUG | ||
28 | #define DBG(args...) printk(args) | ||
29 | #else | ||
30 | #define DBG(args...) do { } while(0) | ||
31 | #endif | ||
32 | |||
33 | #ifdef LOTSA_DEBUG | ||
34 | #define DBG_LOTS(args...) printk(args) | ||
35 | #else | ||
36 | #define DBG_LOTS(args...) do { } while(0) | ||
37 | #endif | ||
38 | |||
39 | /* define this to force CPU overtemp to 60 degree, useful for testing | ||
40 | * the overtemp code | ||
41 | */ | ||
42 | #undef HACKED_OVERTEMP | ||
43 | |||
44 | /* We currently only handle 2 chips, 4 cores... */ | ||
45 | #define NR_CHIPS 2 | ||
46 | #define NR_CORES 4 | ||
47 | #define NR_CPU_FANS 3 * NR_CHIPS | ||
48 | |||
49 | /* Controls and sensors */ | ||
50 | static struct wf_sensor *sens_cpu_temp[NR_CORES]; | ||
51 | static struct wf_sensor *sens_cpu_power[NR_CORES]; | ||
52 | static struct wf_sensor *hd_temp; | ||
53 | static struct wf_sensor *slots_power; | ||
54 | static struct wf_sensor *u4_temp; | ||
55 | |||
56 | static struct wf_control *cpu_fans[NR_CPU_FANS]; | ||
57 | static char *cpu_fan_names[NR_CPU_FANS] = { | ||
58 | "cpu-rear-fan-0", | ||
59 | "cpu-rear-fan-1", | ||
60 | "cpu-front-fan-0", | ||
61 | "cpu-front-fan-1", | ||
62 | "cpu-pump-0", | ||
63 | "cpu-pump-1", | ||
64 | }; | ||
65 | static struct wf_control *cpufreq_clamp; | ||
66 | |||
67 | /* Second pump isn't required (and isn't actually present) */ | ||
68 | #define CPU_FANS_REQD (NR_CPU_FANS - 2) | ||
69 | #define FIRST_PUMP 4 | ||
70 | #define LAST_PUMP 5 | ||
71 | |||
72 | /* We keep a temperature history for average calculation of 180s */ | ||
73 | #define CPU_TEMP_HIST_SIZE 180 | ||
74 | |||
75 | /* Scale factor for fan speed, *100 */ | ||
76 | static int cpu_fan_scale[NR_CPU_FANS] = { | ||
77 | 100, | ||
78 | 100, | ||
79 | 97, /* inlet fans run at 97% of exhaust fan */ | ||
80 | 97, | ||
81 | 100, /* updated later */ | ||
82 | 100, /* updated later */ | ||
83 | }; | ||
84 | |||
85 | static struct wf_control *backside_fan; | ||
86 | static struct wf_control *slots_fan; | ||
87 | static struct wf_control *drive_bay_fan; | ||
88 | |||
89 | /* PID loop state */ | ||
90 | static struct wf_cpu_pid_state cpu_pid[NR_CORES]; | ||
91 | static u32 cpu_thist[CPU_TEMP_HIST_SIZE]; | ||
92 | static int cpu_thist_pt; | ||
93 | static s64 cpu_thist_total; | ||
94 | static s32 cpu_all_tmax = 100 << 16; | ||
95 | static int cpu_last_target; | ||
96 | static struct wf_pid_state backside_pid; | ||
97 | static int backside_tick; | ||
98 | static struct wf_pid_state slots_pid; | ||
99 | static int slots_started; | ||
100 | static struct wf_pid_state drive_bay_pid; | ||
101 | static int drive_bay_tick; | ||
102 | |||
103 | static int nr_cores; | ||
104 | static int have_all_controls; | ||
105 | static int have_all_sensors; | ||
106 | static int started; | ||
107 | |||
108 | static int failure_state; | ||
109 | #define FAILURE_SENSOR 1 | ||
110 | #define FAILURE_FAN 2 | ||
111 | #define FAILURE_PERM 4 | ||
112 | #define FAILURE_LOW_OVERTEMP 8 | ||
113 | #define FAILURE_HIGH_OVERTEMP 16 | ||
114 | |||
115 | /* Overtemp values */ | ||
116 | #define LOW_OVER_AVERAGE 0 | ||
117 | #define LOW_OVER_IMMEDIATE (10 << 16) | ||
118 | #define LOW_OVER_CLEAR ((-10) << 16) | ||
119 | #define HIGH_OVER_IMMEDIATE (14 << 16) | ||
120 | #define HIGH_OVER_AVERAGE (10 << 16) | ||
121 | #define HIGH_OVER_IMMEDIATE (14 << 16) | ||
122 | |||
123 | |||
124 | /* Implementation... */ | ||
125 | static int create_cpu_loop(int cpu) | ||
126 | { | ||
127 | int chip = cpu / 2; | ||
128 | int core = cpu & 1; | ||
129 | struct smu_sdbp_header *hdr; | ||
130 | struct smu_sdbp_cpupiddata *piddata; | ||
131 | struct wf_cpu_pid_param pid; | ||
132 | struct wf_control *main_fan = cpu_fans[0]; | ||
133 | s32 tmax; | ||
134 | int fmin; | ||
135 | |||
136 | /* Get PID params from the appropriate SAT */ | ||
137 | hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL); | ||
138 | if (hdr == NULL) { | ||
139 | printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n"); | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | piddata = (struct smu_sdbp_cpupiddata *)&hdr[1]; | ||
143 | |||
144 | /* Get FVT params to get Tmax; if not found, assume default */ | ||
145 | hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL); | ||
146 | if (hdr) { | ||
147 | struct smu_sdbp_fvt *fvt = (struct smu_sdbp_fvt *)&hdr[1]; | ||
148 | tmax = fvt->maxtemp << 16; | ||
149 | } else | ||
150 | tmax = 95 << 16; /* default to 95 degrees C */ | ||
151 | |||
152 | /* We keep a global tmax for overtemp calculations */ | ||
153 | if (tmax < cpu_all_tmax) | ||
154 | cpu_all_tmax = tmax; | ||
155 | |||
156 | /* | ||
157 | * Darwin has a minimum fan speed of 1000 rpm for the 4-way and | ||
158 | * 515 for the 2-way. That appears to be overkill, so for now, | ||
159 | * impose a minimum of 750 or 515. | ||
160 | */ | ||
161 | fmin = (nr_cores > 2) ? 750 : 515; | ||
162 | |||
163 | /* Initialize PID loop */ | ||
164 | pid.interval = 1; /* seconds */ | ||
165 | pid.history_len = piddata->history_len; | ||
166 | pid.gd = piddata->gd; | ||
167 | pid.gp = piddata->gp; | ||
168 | pid.gr = piddata->gr / piddata->history_len; | ||
169 | pid.pmaxadj = (piddata->max_power << 16) - (piddata->power_adj << 8); | ||
170 | pid.ttarget = tmax - (piddata->target_temp_delta << 16); | ||
171 | pid.tmax = tmax; | ||
172 | pid.min = main_fan->ops->get_min(main_fan); | ||
173 | pid.max = main_fan->ops->get_max(main_fan); | ||
174 | if (pid.min < fmin) | ||
175 | pid.min = fmin; | ||
176 | |||
177 | wf_cpu_pid_init(&cpu_pid[cpu], &pid); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static void cpu_max_all_fans(void) | ||
182 | { | ||
183 | int i; | ||
184 | |||
185 | /* We max all CPU fans in case of a sensor error. We also do the | ||
186 | * cpufreq clamping now, even if it's supposedly done later by the | ||
187 | * generic code anyway, we do it earlier here to react faster | ||
188 | */ | ||
189 | if (cpufreq_clamp) | ||
190 | wf_control_set_max(cpufreq_clamp); | ||
191 | for (i = 0; i < NR_CPU_FANS; ++i) | ||
192 | if (cpu_fans[i]) | ||
193 | wf_control_set_max(cpu_fans[i]); | ||
194 | } | ||
195 | |||
196 | static int cpu_check_overtemp(s32 temp) | ||
197 | { | ||
198 | int new_state = 0; | ||
199 | s32 t_avg, t_old; | ||
200 | |||
201 | /* First check for immediate overtemps */ | ||
202 | if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) { | ||
203 | new_state |= FAILURE_LOW_OVERTEMP; | ||
204 | if ((failure_state & FAILURE_LOW_OVERTEMP) == 0) | ||
205 | printk(KERN_ERR "windfarm: Overtemp due to immediate CPU" | ||
206 | " temperature !\n"); | ||
207 | } | ||
208 | if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) { | ||
209 | new_state |= FAILURE_HIGH_OVERTEMP; | ||
210 | if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0) | ||
211 | printk(KERN_ERR "windfarm: Critical overtemp due to" | ||
212 | " immediate CPU temperature !\n"); | ||
213 | } | ||
214 | |||
215 | /* We calculate a history of max temperatures and use that for the | ||
216 | * overtemp management | ||
217 | */ | ||
218 | t_old = cpu_thist[cpu_thist_pt]; | ||
219 | cpu_thist[cpu_thist_pt] = temp; | ||
220 | cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE; | ||
221 | cpu_thist_total -= t_old; | ||
222 | cpu_thist_total += temp; | ||
223 | t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE; | ||
224 | |||
225 | DBG_LOTS("t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n", | ||
226 | FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp)); | ||
227 | |||
228 | /* Now check for average overtemps */ | ||
229 | if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) { | ||
230 | new_state |= FAILURE_LOW_OVERTEMP; | ||
231 | if ((failure_state & FAILURE_LOW_OVERTEMP) == 0) | ||
232 | printk(KERN_ERR "windfarm: Overtemp due to average CPU" | ||
233 | " temperature !\n"); | ||
234 | } | ||
235 | if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) { | ||
236 | new_state |= FAILURE_HIGH_OVERTEMP; | ||
237 | if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0) | ||
238 | printk(KERN_ERR "windfarm: Critical overtemp due to" | ||
239 | " average CPU temperature !\n"); | ||
240 | } | ||
241 | |||
242 | /* Now handle overtemp conditions. We don't currently use the windfarm | ||
243 | * overtemp handling core as it's not fully suited to the needs of those | ||
244 | * new machine. This will be fixed later. | ||
245 | */ | ||
246 | if (new_state) { | ||
247 | /* High overtemp -> immediate shutdown */ | ||
248 | if (new_state & FAILURE_HIGH_OVERTEMP) | ||
249 | machine_power_off(); | ||
250 | if ((failure_state & new_state) != new_state) | ||
251 | cpu_max_all_fans(); | ||
252 | failure_state |= new_state; | ||
253 | } else if ((failure_state & FAILURE_LOW_OVERTEMP) && | ||
254 | (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) { | ||
255 | printk(KERN_ERR "windfarm: Overtemp condition cleared !\n"); | ||
256 | failure_state &= ~FAILURE_LOW_OVERTEMP; | ||
257 | } | ||
258 | |||
259 | return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP); | ||
260 | } | ||
261 | |||
262 | static void cpu_fans_tick(void) | ||
263 | { | ||
264 | int err, cpu; | ||
265 | s32 greatest_delta = 0; | ||
266 | s32 temp, power, t_max = 0; | ||
267 | int i, t, target = 0; | ||
268 | struct wf_sensor *sr; | ||
269 | struct wf_control *ct; | ||
270 | struct wf_cpu_pid_state *sp; | ||
271 | |||
272 | DBG_LOTS(KERN_DEBUG); | ||
273 | for (cpu = 0; cpu < nr_cores; ++cpu) { | ||
274 | /* Get CPU core temperature */ | ||
275 | sr = sens_cpu_temp[cpu]; | ||
276 | err = sr->ops->get_value(sr, &temp); | ||
277 | if (err) { | ||
278 | DBG("\n"); | ||
279 | printk(KERN_WARNING "windfarm: CPU %d temperature " | ||
280 | "sensor error %d\n", cpu, err); | ||
281 | failure_state |= FAILURE_SENSOR; | ||
282 | cpu_max_all_fans(); | ||
283 | return; | ||
284 | } | ||
285 | |||
286 | /* Keep track of highest temp */ | ||
287 | t_max = max(t_max, temp); | ||
288 | |||
289 | /* Get CPU power */ | ||
290 | sr = sens_cpu_power[cpu]; | ||
291 | err = sr->ops->get_value(sr, &power); | ||
292 | if (err) { | ||
293 | DBG("\n"); | ||
294 | printk(KERN_WARNING "windfarm: CPU %d power " | ||
295 | "sensor error %d\n", cpu, err); | ||
296 | failure_state |= FAILURE_SENSOR; | ||
297 | cpu_max_all_fans(); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | /* Run PID */ | ||
302 | sp = &cpu_pid[cpu]; | ||
303 | t = wf_cpu_pid_run(sp, power, temp); | ||
304 | |||
305 | if (cpu == 0 || sp->last_delta > greatest_delta) { | ||
306 | greatest_delta = sp->last_delta; | ||
307 | target = t; | ||
308 | } | ||
309 | DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ", | ||
310 | cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp)); | ||
311 | } | ||
312 | DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max)); | ||
313 | |||
314 | /* Darwin limits decrease to 20 per iteration */ | ||
315 | if (target < (cpu_last_target - 20)) | ||
316 | target = cpu_last_target - 20; | ||
317 | cpu_last_target = target; | ||
318 | for (cpu = 0; cpu < nr_cores; ++cpu) | ||
319 | cpu_pid[cpu].target = target; | ||
320 | |||
321 | /* Handle possible overtemps */ | ||
322 | if (cpu_check_overtemp(t_max)) | ||
323 | return; | ||
324 | |||
325 | /* Set fans */ | ||
326 | for (i = 0; i < NR_CPU_FANS; ++i) { | ||
327 | ct = cpu_fans[i]; | ||
328 | if (ct == NULL) | ||
329 | continue; | ||
330 | err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100); | ||
331 | if (err) { | ||
332 | printk(KERN_WARNING "windfarm: fan %s reports " | ||
333 | "error %d\n", ct->name, err); | ||
334 | failure_state |= FAILURE_FAN; | ||
335 | break; | ||
336 | } | ||
337 | } | ||
338 | } | ||
339 | |||
340 | /* Backside/U4 fan */ | ||
341 | static struct wf_pid_param backside_param = { | ||
342 | .interval = 5, | ||
343 | .history_len = 2, | ||
344 | .gd = 48 << 20, | ||
345 | .gp = 5 << 20, | ||
346 | .gr = 0, | ||
347 | .itarget = 64 << 16, | ||
348 | .additive = 1, | ||
349 | }; | ||
350 | |||
351 | static void backside_fan_tick(void) | ||
352 | { | ||
353 | s32 temp; | ||
354 | int speed; | ||
355 | int err; | ||
356 | |||
357 | if (!backside_fan || !u4_temp) | ||
358 | return; | ||
359 | if (!backside_tick) { | ||
360 | /* first time; initialize things */ | ||
361 | printk(KERN_INFO "windfarm: Backside control loop started.\n"); | ||
362 | backside_param.min = backside_fan->ops->get_min(backside_fan); | ||
363 | backside_param.max = backside_fan->ops->get_max(backside_fan); | ||
364 | wf_pid_init(&backside_pid, &backside_param); | ||
365 | backside_tick = 1; | ||
366 | } | ||
367 | if (--backside_tick > 0) | ||
368 | return; | ||
369 | backside_tick = backside_pid.param.interval; | ||
370 | |||
371 | err = u4_temp->ops->get_value(u4_temp, &temp); | ||
372 | if (err) { | ||
373 | printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n", | ||
374 | err); | ||
375 | failure_state |= FAILURE_SENSOR; | ||
376 | wf_control_set_max(backside_fan); | ||
377 | return; | ||
378 | } | ||
379 | speed = wf_pid_run(&backside_pid, temp); | ||
380 | DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n", | ||
381 | FIX32TOPRINT(temp), speed); | ||
382 | |||
383 | err = backside_fan->ops->set_value(backside_fan, speed); | ||
384 | if (err) { | ||
385 | printk(KERN_WARNING "windfarm: backside fan error %d\n", err); | ||
386 | failure_state |= FAILURE_FAN; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | /* Drive bay fan */ | ||
391 | static struct wf_pid_param drive_bay_prm = { | ||
392 | .interval = 5, | ||
393 | .history_len = 2, | ||
394 | .gd = 30 << 20, | ||
395 | .gp = 5 << 20, | ||
396 | .gr = 0, | ||
397 | .itarget = 40 << 16, | ||
398 | .additive = 1, | ||
399 | }; | ||
400 | |||
401 | static void drive_bay_fan_tick(void) | ||
402 | { | ||
403 | s32 temp; | ||
404 | int speed; | ||
405 | int err; | ||
406 | |||
407 | if (!drive_bay_fan || !hd_temp) | ||
408 | return; | ||
409 | if (!drive_bay_tick) { | ||
410 | /* first time; initialize things */ | ||
411 | printk(KERN_INFO "windfarm: Drive bay control loop started.\n"); | ||
412 | drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan); | ||
413 | drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan); | ||
414 | wf_pid_init(&drive_bay_pid, &drive_bay_prm); | ||
415 | drive_bay_tick = 1; | ||
416 | } | ||
417 | if (--drive_bay_tick > 0) | ||
418 | return; | ||
419 | drive_bay_tick = drive_bay_pid.param.interval; | ||
420 | |||
421 | err = hd_temp->ops->get_value(hd_temp, &temp); | ||
422 | if (err) { | ||
423 | printk(KERN_WARNING "windfarm: drive bay temp sensor " | ||
424 | "error %d\n", err); | ||
425 | failure_state |= FAILURE_SENSOR; | ||
426 | wf_control_set_max(drive_bay_fan); | ||
427 | return; | ||
428 | } | ||
429 | speed = wf_pid_run(&drive_bay_pid, temp); | ||
430 | DBG_LOTS("drive_bay PID temp=%d.%.3d speed=%d\n", | ||
431 | FIX32TOPRINT(temp), speed); | ||
432 | |||
433 | err = drive_bay_fan->ops->set_value(drive_bay_fan, speed); | ||
434 | if (err) { | ||
435 | printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err); | ||
436 | failure_state |= FAILURE_FAN; | ||
437 | } | ||
438 | } | ||
439 | |||
440 | /* PCI slots area fan */ | ||
441 | /* This makes the fan speed proportional to the power consumed */ | ||
442 | static struct wf_pid_param slots_param = { | ||
443 | .interval = 1, | ||
444 | .history_len = 2, | ||
445 | .gd = 0, | ||
446 | .gp = 0, | ||
447 | .gr = 0x1277952, | ||
448 | .itarget = 0, | ||
449 | .min = 1560, | ||
450 | .max = 3510, | ||
451 | }; | ||
452 | |||
453 | static void slots_fan_tick(void) | ||
454 | { | ||
455 | s32 power; | ||
456 | int speed; | ||
457 | int err; | ||
458 | |||
459 | if (!slots_fan || !slots_power) | ||
460 | return; | ||
461 | if (!slots_started) { | ||
462 | /* first time; initialize things */ | ||
463 | printk(KERN_INFO "windfarm: Slots control loop started.\n"); | ||
464 | wf_pid_init(&slots_pid, &slots_param); | ||
465 | slots_started = 1; | ||
466 | } | ||
467 | |||
468 | err = slots_power->ops->get_value(slots_power, &power); | ||
469 | if (err) { | ||
470 | printk(KERN_WARNING "windfarm: slots power sensor error %d\n", | ||
471 | err); | ||
472 | failure_state |= FAILURE_SENSOR; | ||
473 | wf_control_set_max(slots_fan); | ||
474 | return; | ||
475 | } | ||
476 | speed = wf_pid_run(&slots_pid, power); | ||
477 | DBG_LOTS("slots PID power=%d.%.3d speed=%d\n", | ||
478 | FIX32TOPRINT(power), speed); | ||
479 | |||
480 | err = slots_fan->ops->set_value(slots_fan, speed); | ||
481 | if (err) { | ||
482 | printk(KERN_WARNING "windfarm: slots fan error %d\n", err); | ||
483 | failure_state |= FAILURE_FAN; | ||
484 | } | ||
485 | } | ||
486 | |||
487 | static void set_fail_state(void) | ||
488 | { | ||
489 | int i; | ||
490 | |||
491 | if (cpufreq_clamp) | ||
492 | wf_control_set_max(cpufreq_clamp); | ||
493 | for (i = 0; i < NR_CPU_FANS; ++i) | ||
494 | if (cpu_fans[i]) | ||
495 | wf_control_set_max(cpu_fans[i]); | ||
496 | if (backside_fan) | ||
497 | wf_control_set_max(backside_fan); | ||
498 | if (slots_fan) | ||
499 | wf_control_set_max(slots_fan); | ||
500 | if (drive_bay_fan) | ||
501 | wf_control_set_max(drive_bay_fan); | ||
502 | } | ||
503 | |||
504 | static void pm112_tick(void) | ||
505 | { | ||
506 | int i, last_failure; | ||
507 | |||
508 | if (!started) { | ||
509 | started = 1; | ||
510 | printk(KERN_INFO "windfarm: CPUs control loops started.\n"); | ||
511 | for (i = 0; i < nr_cores; ++i) { | ||
512 | if (create_cpu_loop(i) < 0) { | ||
513 | failure_state = FAILURE_PERM; | ||
514 | set_fail_state(); | ||
515 | break; | ||
516 | } | ||
517 | } | ||
518 | DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax)); | ||
519 | |||
520 | #ifdef HACKED_OVERTEMP | ||
521 | cpu_all_tmax = 60 << 16; | ||
522 | #endif | ||
523 | } | ||
524 | |||
525 | /* Permanent failure, bail out */ | ||
526 | if (failure_state & FAILURE_PERM) | ||
527 | return; | ||
528 | /* Clear all failure bits except low overtemp which will be eventually | ||
529 | * cleared by the control loop itself | ||
530 | */ | ||
531 | last_failure = failure_state; | ||
532 | failure_state &= FAILURE_LOW_OVERTEMP; | ||
533 | cpu_fans_tick(); | ||
534 | backside_fan_tick(); | ||
535 | slots_fan_tick(); | ||
536 | drive_bay_fan_tick(); | ||
537 | |||
538 | DBG_LOTS("last_failure: 0x%x, failure_state: %x\n", | ||
539 | last_failure, failure_state); | ||
540 | |||
541 | /* Check for failures. Any failure causes cpufreq clamping */ | ||
542 | if (failure_state && last_failure == 0 && cpufreq_clamp) | ||
543 | wf_control_set_max(cpufreq_clamp); | ||
544 | if (failure_state == 0 && last_failure && cpufreq_clamp) | ||
545 | wf_control_set_min(cpufreq_clamp); | ||
546 | |||
547 | /* That's it for now, we might want to deal with other failures | ||
548 | * differently in the future though | ||
549 | */ | ||
550 | } | ||
551 | |||
552 | static void pm112_new_control(struct wf_control *ct) | ||
553 | { | ||
554 | int i, max_exhaust; | ||
555 | |||
556 | if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { | ||
557 | if (wf_get_control(ct) == 0) | ||
558 | cpufreq_clamp = ct; | ||
559 | } | ||
560 | |||
561 | for (i = 0; i < NR_CPU_FANS; ++i) { | ||
562 | if (!strcmp(ct->name, cpu_fan_names[i])) { | ||
563 | if (cpu_fans[i] == NULL && wf_get_control(ct) == 0) | ||
564 | cpu_fans[i] = ct; | ||
565 | break; | ||
566 | } | ||
567 | } | ||
568 | if (i >= NR_CPU_FANS) { | ||
569 | /* not a CPU fan, try the others */ | ||
570 | if (!strcmp(ct->name, "backside-fan")) { | ||
571 | if (backside_fan == NULL && wf_get_control(ct) == 0) | ||
572 | backside_fan = ct; | ||
573 | } else if (!strcmp(ct->name, "slots-fan")) { | ||
574 | if (slots_fan == NULL && wf_get_control(ct) == 0) | ||
575 | slots_fan = ct; | ||
576 | } else if (!strcmp(ct->name, "drive-bay-fan")) { | ||
577 | if (drive_bay_fan == NULL && wf_get_control(ct) == 0) | ||
578 | drive_bay_fan = ct; | ||
579 | } | ||
580 | return; | ||
581 | } | ||
582 | |||
583 | for (i = 0; i < CPU_FANS_REQD; ++i) | ||
584 | if (cpu_fans[i] == NULL) | ||
585 | return; | ||
586 | |||
587 | /* work out pump scaling factors */ | ||
588 | max_exhaust = cpu_fans[0]->ops->get_max(cpu_fans[0]); | ||
589 | for (i = FIRST_PUMP; i <= LAST_PUMP; ++i) | ||
590 | if ((ct = cpu_fans[i]) != NULL) | ||
591 | cpu_fan_scale[i] = | ||
592 | ct->ops->get_max(ct) * 100 / max_exhaust; | ||
593 | |||
594 | have_all_controls = 1; | ||
595 | } | ||
596 | |||
597 | static void pm112_new_sensor(struct wf_sensor *sr) | ||
598 | { | ||
599 | unsigned int i; | ||
600 | |||
601 | if (!strncmp(sr->name, "cpu-temp-", 9)) { | ||
602 | i = sr->name[9] - '0'; | ||
603 | if (sr->name[10] == 0 && i < NR_CORES && | ||
604 | sens_cpu_temp[i] == NULL && wf_get_sensor(sr) == 0) | ||
605 | sens_cpu_temp[i] = sr; | ||
606 | |||
607 | } else if (!strncmp(sr->name, "cpu-power-", 10)) { | ||
608 | i = sr->name[10] - '0'; | ||
609 | if (sr->name[11] == 0 && i < NR_CORES && | ||
610 | sens_cpu_power[i] == NULL && wf_get_sensor(sr) == 0) | ||
611 | sens_cpu_power[i] = sr; | ||
612 | } else if (!strcmp(sr->name, "hd-temp")) { | ||
613 | if (hd_temp == NULL && wf_get_sensor(sr) == 0) | ||
614 | hd_temp = sr; | ||
615 | } else if (!strcmp(sr->name, "slots-power")) { | ||
616 | if (slots_power == NULL && wf_get_sensor(sr) == 0) | ||
617 | slots_power = sr; | ||
618 | } else if (!strcmp(sr->name, "backside-temp")) { | ||
619 | if (u4_temp == NULL && wf_get_sensor(sr) == 0) | ||
620 | u4_temp = sr; | ||
621 | } else | ||
622 | return; | ||
623 | |||
624 | /* check if we have all the sensors we need */ | ||
625 | for (i = 0; i < nr_cores; ++i) | ||
626 | if (sens_cpu_temp[i] == NULL || sens_cpu_power[i] == NULL) | ||
627 | return; | ||
628 | |||
629 | have_all_sensors = 1; | ||
630 | } | ||
631 | |||
632 | static int pm112_wf_notify(struct notifier_block *self, | ||
633 | unsigned long event, void *data) | ||
634 | { | ||
635 | switch (event) { | ||
636 | case WF_EVENT_NEW_SENSOR: | ||
637 | pm112_new_sensor(data); | ||
638 | break; | ||
639 | case WF_EVENT_NEW_CONTROL: | ||
640 | pm112_new_control(data); | ||
641 | break; | ||
642 | case WF_EVENT_TICK: | ||
643 | if (have_all_controls && have_all_sensors) | ||
644 | pm112_tick(); | ||
645 | } | ||
646 | return 0; | ||
647 | } | ||
648 | |||
649 | static struct notifier_block pm112_events = { | ||
650 | .notifier_call = pm112_wf_notify, | ||
651 | }; | ||
652 | |||
653 | static int wf_pm112_probe(struct device *dev) | ||
654 | { | ||
655 | wf_register_client(&pm112_events); | ||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | static int wf_pm112_remove(struct device *dev) | ||
660 | { | ||
661 | wf_unregister_client(&pm112_events); | ||
662 | /* should release all sensors and controls */ | ||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static struct device_driver wf_pm112_driver = { | ||
667 | .name = "windfarm", | ||
668 | .bus = &platform_bus_type, | ||
669 | .probe = wf_pm112_probe, | ||
670 | .remove = wf_pm112_remove, | ||
671 | }; | ||
672 | |||
673 | static int __init wf_pm112_init(void) | ||
674 | { | ||
675 | struct device_node *cpu; | ||
676 | |||
677 | if (!machine_is_compatible("PowerMac11,2")) | ||
678 | return -ENODEV; | ||
679 | |||
680 | /* Count the number of CPU cores */ | ||
681 | nr_cores = 0; | ||
682 | for (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; ) | ||
683 | ++nr_cores; | ||
684 | |||
685 | printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n"); | ||
686 | driver_register(&wf_pm112_driver); | ||
687 | return 0; | ||
688 | } | ||
689 | |||
690 | static void __exit wf_pm112_exit(void) | ||
691 | { | ||
692 | driver_unregister(&wf_pm112_driver); | ||
693 | } | ||
694 | |||
695 | module_init(wf_pm112_init); | ||
696 | module_exit(wf_pm112_exit); | ||
697 | |||
698 | MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); | ||
699 | MODULE_DESCRIPTION("Thermal control for PowerMac11,2"); | ||
700 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index eb69a601e765..f1df6efcbe68 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c | |||
@@ -538,45 +538,6 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st) | |||
538 | } | 538 | } |
539 | } | 539 | } |
540 | 540 | ||
541 | |||
542 | /* | ||
543 | * ****** Attributes ****** | ||
544 | * | ||
545 | */ | ||
546 | |||
547 | #define BUILD_SHOW_FUNC_FIX(name, data) \ | ||
548 | static ssize_t show_##name(struct device *dev, \ | ||
549 | struct device_attribute *attr, \ | ||
550 | char *buf) \ | ||
551 | { \ | ||
552 | ssize_t r; \ | ||
553 | s32 val = 0; \ | ||
554 | data->ops->get_value(data, &val); \ | ||
555 | r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \ | ||
556 | return r; \ | ||
557 | } \ | ||
558 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
559 | |||
560 | |||
561 | #define BUILD_SHOW_FUNC_INT(name, data) \ | ||
562 | static ssize_t show_##name(struct device *dev, \ | ||
563 | struct device_attribute *attr, \ | ||
564 | char *buf) \ | ||
565 | { \ | ||
566 | s32 val = 0; \ | ||
567 | data->ops->get_value(data, &val); \ | ||
568 | return sprintf(buf, "%d", val); \ | ||
569 | } \ | ||
570 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
571 | |||
572 | BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main); | ||
573 | BUILD_SHOW_FUNC_INT(sys_fan, fan_system); | ||
574 | BUILD_SHOW_FUNC_INT(hd_fan, fan_hd); | ||
575 | |||
576 | BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp); | ||
577 | BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power); | ||
578 | BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp); | ||
579 | |||
580 | /* | 541 | /* |
581 | * ****** Setup / Init / Misc ... ****** | 542 | * ****** Setup / Init / Misc ... ****** |
582 | * | 543 | * |
@@ -654,17 +615,13 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
654 | return; | 615 | return; |
655 | 616 | ||
656 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) { | 617 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) { |
657 | if (wf_get_control(ct) == 0) { | 618 | if (wf_get_control(ct) == 0) |
658 | fan_cpu_main = ct; | 619 | fan_cpu_main = ct; |
659 | device_create_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
660 | } | ||
661 | } | 620 | } |
662 | 621 | ||
663 | if (fan_system == NULL && !strcmp(ct->name, "system-fan")) { | 622 | if (fan_system == NULL && !strcmp(ct->name, "system-fan")) { |
664 | if (wf_get_control(ct) == 0) { | 623 | if (wf_get_control(ct) == 0) |
665 | fan_system = ct; | 624 | fan_system = ct; |
666 | device_create_file(wf_smu_dev, &dev_attr_sys_fan); | ||
667 | } | ||
668 | } | 625 | } |
669 | 626 | ||
670 | if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { | 627 | if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { |
@@ -683,10 +640,8 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
683 | } | 640 | } |
684 | 641 | ||
685 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { | 642 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { |
686 | if (wf_get_control(ct) == 0) { | 643 | if (wf_get_control(ct) == 0) |
687 | fan_hd = ct; | 644 | fan_hd = ct; |
688 | device_create_file(wf_smu_dev, &dev_attr_hd_fan); | ||
689 | } | ||
690 | } | 645 | } |
691 | 646 | ||
692 | if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp) | 647 | if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp) |
@@ -699,24 +654,18 @@ static void wf_smu_new_sensor(struct wf_sensor *sr) | |||
699 | return; | 654 | return; |
700 | 655 | ||
701 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { | 656 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { |
702 | if (wf_get_sensor(sr) == 0) { | 657 | if (wf_get_sensor(sr) == 0) |
703 | sensor_cpu_power = sr; | 658 | sensor_cpu_power = sr; |
704 | device_create_file(wf_smu_dev, &dev_attr_cpu_power); | ||
705 | } | ||
706 | } | 659 | } |
707 | 660 | ||
708 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { | 661 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { |
709 | if (wf_get_sensor(sr) == 0) { | 662 | if (wf_get_sensor(sr) == 0) |
710 | sensor_cpu_temp = sr; | 663 | sensor_cpu_temp = sr; |
711 | device_create_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
712 | } | ||
713 | } | 664 | } |
714 | 665 | ||
715 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { | 666 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { |
716 | if (wf_get_sensor(sr) == 0) { | 667 | if (wf_get_sensor(sr) == 0) |
717 | sensor_hd_temp = sr; | 668 | sensor_hd_temp = sr; |
718 | device_create_file(wf_smu_dev, &dev_attr_hd_temp); | ||
719 | } | ||
720 | } | 669 | } |
721 | 670 | ||
722 | if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp) | 671 | if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp) |
@@ -794,32 +743,20 @@ static int wf_smu_remove(struct device *ddev) | |||
794 | * with that except by adding locks all over... I'll do that | 743 | * with that except by adding locks all over... I'll do that |
795 | * eventually but heh, who ever rmmod this module anyway ? | 744 | * eventually but heh, who ever rmmod this module anyway ? |
796 | */ | 745 | */ |
797 | if (sensor_cpu_power) { | 746 | if (sensor_cpu_power) |
798 | device_remove_file(wf_smu_dev, &dev_attr_cpu_power); | ||
799 | wf_put_sensor(sensor_cpu_power); | 747 | wf_put_sensor(sensor_cpu_power); |
800 | } | 748 | if (sensor_cpu_temp) |
801 | if (sensor_cpu_temp) { | ||
802 | device_remove_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
803 | wf_put_sensor(sensor_cpu_temp); | 749 | wf_put_sensor(sensor_cpu_temp); |
804 | } | 750 | if (sensor_hd_temp) |
805 | if (sensor_hd_temp) { | ||
806 | device_remove_file(wf_smu_dev, &dev_attr_hd_temp); | ||
807 | wf_put_sensor(sensor_hd_temp); | 751 | wf_put_sensor(sensor_hd_temp); |
808 | } | ||
809 | 752 | ||
810 | /* Release all controls */ | 753 | /* Release all controls */ |
811 | if (fan_cpu_main) { | 754 | if (fan_cpu_main) |
812 | device_remove_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
813 | wf_put_control(fan_cpu_main); | 755 | wf_put_control(fan_cpu_main); |
814 | } | 756 | if (fan_hd) |
815 | if (fan_hd) { | ||
816 | device_remove_file(wf_smu_dev, &dev_attr_hd_fan); | ||
817 | wf_put_control(fan_hd); | 757 | wf_put_control(fan_hd); |
818 | } | 758 | if (fan_system) |
819 | if (fan_system) { | ||
820 | device_remove_file(wf_smu_dev, &dev_attr_sys_fan); | ||
821 | wf_put_control(fan_system); | 759 | wf_put_control(fan_system); |
822 | } | ||
823 | if (cpufreq_clamp) | 760 | if (cpufreq_clamp) |
824 | wf_put_control(cpufreq_clamp); | 761 | wf_put_control(cpufreq_clamp); |
825 | 762 | ||
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 43243cf7410b..0d6372e96d32 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c | |||
@@ -458,45 +458,6 @@ static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st) | |||
458 | 458 | ||
459 | 459 | ||
460 | /* | 460 | /* |
461 | * ****** Attributes ****** | ||
462 | * | ||
463 | */ | ||
464 | |||
465 | #define BUILD_SHOW_FUNC_FIX(name, data) \ | ||
466 | static ssize_t show_##name(struct device *dev, \ | ||
467 | struct device_attribute *attr, \ | ||
468 | char *buf) \ | ||
469 | { \ | ||
470 | ssize_t r; \ | ||
471 | s32 val = 0; \ | ||
472 | data->ops->get_value(data, &val); \ | ||
473 | r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \ | ||
474 | return r; \ | ||
475 | } \ | ||
476 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
477 | |||
478 | |||
479 | #define BUILD_SHOW_FUNC_INT(name, data) \ | ||
480 | static ssize_t show_##name(struct device *dev, \ | ||
481 | struct device_attribute *attr, \ | ||
482 | char *buf) \ | ||
483 | { \ | ||
484 | s32 val = 0; \ | ||
485 | data->ops->get_value(data, &val); \ | ||
486 | return sprintf(buf, "%d", val); \ | ||
487 | } \ | ||
488 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
489 | |||
490 | BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main); | ||
491 | BUILD_SHOW_FUNC_INT(hd_fan, fan_hd); | ||
492 | BUILD_SHOW_FUNC_INT(slots_fan, fan_slots); | ||
493 | |||
494 | BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp); | ||
495 | BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power); | ||
496 | BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp); | ||
497 | BUILD_SHOW_FUNC_FIX(slots_power, sensor_slots_power); | ||
498 | |||
499 | /* | ||
500 | * ****** Setup / Init / Misc ... ****** | 461 | * ****** Setup / Init / Misc ... ****** |
501 | * | 462 | * |
502 | */ | 463 | */ |
@@ -581,10 +542,8 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
581 | return; | 542 | return; |
582 | 543 | ||
583 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) { | 544 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) { |
584 | if (wf_get_control(ct) == 0) { | 545 | if (wf_get_control(ct) == 0) |
585 | fan_cpu_main = ct; | 546 | fan_cpu_main = ct; |
586 | device_create_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
587 | } | ||
588 | } | 547 | } |
589 | 548 | ||
590 | if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) { | 549 | if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) { |
@@ -603,17 +562,13 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
603 | } | 562 | } |
604 | 563 | ||
605 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { | 564 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { |
606 | if (wf_get_control(ct) == 0) { | 565 | if (wf_get_control(ct) == 0) |
607 | fan_hd = ct; | 566 | fan_hd = ct; |
608 | device_create_file(wf_smu_dev, &dev_attr_hd_fan); | ||
609 | } | ||
610 | } | 567 | } |
611 | 568 | ||
612 | if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) { | 569 | if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) { |
613 | if (wf_get_control(ct) == 0) { | 570 | if (wf_get_control(ct) == 0) |
614 | fan_slots = ct; | 571 | fan_slots = ct; |
615 | device_create_file(wf_smu_dev, &dev_attr_slots_fan); | ||
616 | } | ||
617 | } | 572 | } |
618 | 573 | ||
619 | if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd && | 574 | if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd && |
@@ -627,31 +582,23 @@ static void wf_smu_new_sensor(struct wf_sensor *sr) | |||
627 | return; | 582 | return; |
628 | 583 | ||
629 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { | 584 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { |
630 | if (wf_get_sensor(sr) == 0) { | 585 | if (wf_get_sensor(sr) == 0) |
631 | sensor_cpu_power = sr; | 586 | sensor_cpu_power = sr; |
632 | device_create_file(wf_smu_dev, &dev_attr_cpu_power); | ||
633 | } | ||
634 | } | 587 | } |
635 | 588 | ||
636 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { | 589 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { |
637 | if (wf_get_sensor(sr) == 0) { | 590 | if (wf_get_sensor(sr) == 0) |
638 | sensor_cpu_temp = sr; | 591 | sensor_cpu_temp = sr; |
639 | device_create_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
640 | } | ||
641 | } | 592 | } |
642 | 593 | ||
643 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { | 594 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { |
644 | if (wf_get_sensor(sr) == 0) { | 595 | if (wf_get_sensor(sr) == 0) |
645 | sensor_hd_temp = sr; | 596 | sensor_hd_temp = sr; |
646 | device_create_file(wf_smu_dev, &dev_attr_hd_temp); | ||
647 | } | ||
648 | } | 597 | } |
649 | 598 | ||
650 | if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) { | 599 | if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) { |
651 | if (wf_get_sensor(sr) == 0) { | 600 | if (wf_get_sensor(sr) == 0) |
652 | sensor_slots_power = sr; | 601 | sensor_slots_power = sr; |
653 | device_create_file(wf_smu_dev, &dev_attr_slots_power); | ||
654 | } | ||
655 | } | 602 | } |
656 | 603 | ||
657 | if (sensor_cpu_power && sensor_cpu_temp && | 604 | if (sensor_cpu_power && sensor_cpu_temp && |
@@ -720,40 +667,26 @@ static int wf_smu_remove(struct device *ddev) | |||
720 | * with that except by adding locks all over... I'll do that | 667 | * with that except by adding locks all over... I'll do that |
721 | * eventually but heh, who ever rmmod this module anyway ? | 668 | * eventually but heh, who ever rmmod this module anyway ? |
722 | */ | 669 | */ |
723 | if (sensor_cpu_power) { | 670 | if (sensor_cpu_power) |
724 | device_remove_file(wf_smu_dev, &dev_attr_cpu_power); | ||
725 | wf_put_sensor(sensor_cpu_power); | 671 | wf_put_sensor(sensor_cpu_power); |
726 | } | 672 | if (sensor_cpu_temp) |
727 | if (sensor_cpu_temp) { | ||
728 | device_remove_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
729 | wf_put_sensor(sensor_cpu_temp); | 673 | wf_put_sensor(sensor_cpu_temp); |
730 | } | 674 | if (sensor_hd_temp) |
731 | if (sensor_hd_temp) { | ||
732 | device_remove_file(wf_smu_dev, &dev_attr_hd_temp); | ||
733 | wf_put_sensor(sensor_hd_temp); | 675 | wf_put_sensor(sensor_hd_temp); |
734 | } | 676 | if (sensor_slots_power) |
735 | if (sensor_slots_power) { | ||
736 | device_remove_file(wf_smu_dev, &dev_attr_slots_power); | ||
737 | wf_put_sensor(sensor_slots_power); | 677 | wf_put_sensor(sensor_slots_power); |
738 | } | ||
739 | 678 | ||
740 | /* Release all controls */ | 679 | /* Release all controls */ |
741 | if (fan_cpu_main) { | 680 | if (fan_cpu_main) |
742 | device_remove_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
743 | wf_put_control(fan_cpu_main); | 681 | wf_put_control(fan_cpu_main); |
744 | } | ||
745 | if (fan_cpu_second) | 682 | if (fan_cpu_second) |
746 | wf_put_control(fan_cpu_second); | 683 | wf_put_control(fan_cpu_second); |
747 | if (fan_cpu_third) | 684 | if (fan_cpu_third) |
748 | wf_put_control(fan_cpu_third); | 685 | wf_put_control(fan_cpu_third); |
749 | if (fan_hd) { | 686 | if (fan_hd) |
750 | device_remove_file(wf_smu_dev, &dev_attr_hd_fan); | ||
751 | wf_put_control(fan_hd); | 687 | wf_put_control(fan_hd); |
752 | } | 688 | if (fan_slots) |
753 | if (fan_slots) { | ||
754 | device_remove_file(wf_smu_dev, &dev_attr_slots_fan); | ||
755 | wf_put_control(fan_slots); | 689 | wf_put_control(fan_slots); |
756 | } | ||
757 | if (cpufreq_clamp) | 690 | if (cpufreq_clamp) |
758 | wf_put_control(cpufreq_clamp); | 691 | wf_put_control(cpufreq_clamp); |
759 | 692 | ||
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c index 4d811600bdab..a9e88edc0c72 100644 --- a/drivers/macintosh/windfarm_smu_controls.c +++ b/drivers/macintosh/windfarm_smu_controls.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include "windfarm.h" | 25 | #include "windfarm.h" |
26 | 26 | ||
27 | #define VERSION "0.3" | 27 | #define VERSION "0.4" |
28 | 28 | ||
29 | #undef DEBUG | 29 | #undef DEBUG |
30 | 30 | ||
@@ -34,6 +34,8 @@ | |||
34 | #define DBG(args...) do { } while(0) | 34 | #define DBG(args...) do { } while(0) |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | static int smu_supports_new_fans_ops = 1; | ||
38 | |||
37 | /* | 39 | /* |
38 | * SMU fans control object | 40 | * SMU fans control object |
39 | */ | 41 | */ |
@@ -59,23 +61,49 @@ static int smu_set_fan(int pwm, u8 id, u16 value) | |||
59 | 61 | ||
60 | /* Fill SMU command structure */ | 62 | /* Fill SMU command structure */ |
61 | cmd.cmd = SMU_CMD_FAN_COMMAND; | 63 | cmd.cmd = SMU_CMD_FAN_COMMAND; |
62 | cmd.data_len = 14; | 64 | |
65 | /* The SMU has an "old" and a "new" way of setting the fan speed | ||
66 | * Unfortunately, I found no reliable way to know which one works | ||
67 | * on a given machine model. After some investigations it appears | ||
68 | * that MacOS X just tries the new one, and if it fails fallbacks | ||
69 | * to the old ones ... Ugh. | ||
70 | */ | ||
71 | retry: | ||
72 | if (smu_supports_new_fans_ops) { | ||
73 | buffer[0] = 0x30; | ||
74 | buffer[1] = id; | ||
75 | *((u16 *)(&buffer[2])) = value; | ||
76 | cmd.data_len = 4; | ||
77 | } else { | ||
78 | if (id > 7) | ||
79 | return -EINVAL; | ||
80 | /* Fill argument buffer */ | ||
81 | memset(buffer, 0, 16); | ||
82 | buffer[0] = pwm ? 0x10 : 0x00; | ||
83 | buffer[1] = 0x01 << id; | ||
84 | *((u16 *)&buffer[2 + id * 2]) = value; | ||
85 | cmd.data_len = 14; | ||
86 | } | ||
87 | |||
63 | cmd.reply_len = 16; | 88 | cmd.reply_len = 16; |
64 | cmd.data_buf = cmd.reply_buf = buffer; | 89 | cmd.data_buf = cmd.reply_buf = buffer; |
65 | cmd.status = 0; | 90 | cmd.status = 0; |
66 | cmd.done = smu_done_complete; | 91 | cmd.done = smu_done_complete; |
67 | cmd.misc = ∁ | 92 | cmd.misc = ∁ |
68 | 93 | ||
69 | /* Fill argument buffer */ | ||
70 | memset(buffer, 0, 16); | ||
71 | buffer[0] = pwm ? 0x10 : 0x00; | ||
72 | buffer[1] = 0x01 << id; | ||
73 | *((u16 *)&buffer[2 + id * 2]) = value; | ||
74 | |||
75 | rc = smu_queue_cmd(&cmd); | 94 | rc = smu_queue_cmd(&cmd); |
76 | if (rc) | 95 | if (rc) |
77 | return rc; | 96 | return rc; |
78 | wait_for_completion(&comp); | 97 | wait_for_completion(&comp); |
98 | |||
99 | /* Handle fallback (see coment above) */ | ||
100 | if (cmd.status != 0 && smu_supports_new_fans_ops) { | ||
101 | printk(KERN_WARNING "windfarm: SMU failed new fan command " | ||
102 | "falling back to old method\n"); | ||
103 | smu_supports_new_fans_ops = 0; | ||
104 | goto retry; | ||
105 | } | ||
106 | |||
79 | return cmd.status; | 107 | return cmd.status; |
80 | } | 108 | } |
81 | 109 | ||
@@ -158,19 +186,29 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node, | |||
158 | 186 | ||
159 | /* Names used on desktop models */ | 187 | /* Names used on desktop models */ |
160 | if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") || | 188 | if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") || |
161 | !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan")) | 189 | !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan") || |
190 | !strcmp(l, "CPU A EXHAUST")) | ||
162 | fct->ctrl.name = "cpu-rear-fan-0"; | 191 | fct->ctrl.name = "cpu-rear-fan-0"; |
163 | else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1")) | 192 | else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1") || |
193 | !strcmp(l, "CPU B EXHAUST")) | ||
164 | fct->ctrl.name = "cpu-rear-fan-1"; | 194 | fct->ctrl.name = "cpu-rear-fan-1"; |
165 | else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") || | 195 | else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") || |
166 | !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan")) | 196 | !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan") || |
197 | !strcmp(l, "CPU A INTAKE")) | ||
167 | fct->ctrl.name = "cpu-front-fan-0"; | 198 | fct->ctrl.name = "cpu-front-fan-0"; |
168 | else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1")) | 199 | else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1") || |
200 | !strcmp(l, "CPU B INTAKE")) | ||
169 | fct->ctrl.name = "cpu-front-fan-1"; | 201 | fct->ctrl.name = "cpu-front-fan-1"; |
170 | else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan")) | 202 | else if (!strcmp(l, "CPU A PUMP")) |
203 | fct->ctrl.name = "cpu-pump-0"; | ||
204 | else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") || | ||
205 | !strcmp(l, "EXPANSION SLOTS INTAKE")) | ||
171 | fct->ctrl.name = "slots-fan"; | 206 | fct->ctrl.name = "slots-fan"; |
172 | else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay")) | 207 | else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay") || |
208 | !strcmp(l, "DRIVE BAY A INTAKE")) | ||
173 | fct->ctrl.name = "drive-bay-fan"; | 209 | fct->ctrl.name = "drive-bay-fan"; |
210 | else if (!strcmp(l, "BACKSIDE")) | ||
211 | fct->ctrl.name = "backside-fan"; | ||
174 | 212 | ||
175 | /* Names used on iMac models */ | 213 | /* Names used on iMac models */ |
176 | if (!strcmp(l, "System Fan") || !strcmp(l, "System fan")) | 214 | if (!strcmp(l, "System Fan") || !strcmp(l, "System fan")) |
@@ -223,7 +261,8 @@ static int __init smu_controls_init(void) | |||
223 | 261 | ||
224 | /* Look for RPM fans */ | 262 | /* Look for RPM fans */ |
225 | for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;) | 263 | for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;) |
226 | if (!strcmp(fans->name, "rpm-fans")) | 264 | if (!strcmp(fans->name, "rpm-fans") || |
265 | device_is_compatible(fans, "smu-rpm-fans")) | ||
227 | break; | 266 | break; |
228 | for (fan = NULL; | 267 | for (fan = NULL; |
229 | fans && (fan = of_get_next_child(fans, fan)) != NULL;) { | 268 | fans && (fan = of_get_next_child(fans, fan)) != NULL;) { |
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c new file mode 100644 index 000000000000..24e51d5e97fc --- /dev/null +++ b/drivers/macintosh/windfarm_smu_sat.c | |||
@@ -0,0 +1,419 @@ | |||
1 | /* | ||
2 | * Windfarm PowerMac thermal control. SMU "satellite" controller sensors. | ||
3 | * | ||
4 | * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> | ||
5 | * | ||
6 | * Released under the terms of the GNU GPL v2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/types.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/wait.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/i2c-dev.h> | ||
17 | #include <asm/semaphore.h> | ||
18 | #include <asm/prom.h> | ||
19 | #include <asm/smu.h> | ||
20 | #include <asm/pmac_low_i2c.h> | ||
21 | |||
22 | #include "windfarm.h" | ||
23 | |||
24 | #define VERSION "0.2" | ||
25 | |||
26 | #define DEBUG | ||
27 | |||
28 | #ifdef DEBUG | ||
29 | #define DBG(args...) printk(args) | ||
30 | #else | ||
31 | #define DBG(args...) do { } while(0) | ||
32 | #endif | ||
33 | |||
34 | /* If the cache is older than 800ms we'll refetch it */ | ||
35 | #define MAX_AGE msecs_to_jiffies(800) | ||
36 | |||
37 | struct wf_sat { | ||
38 | int nr; | ||
39 | atomic_t refcnt; | ||
40 | struct semaphore mutex; | ||
41 | unsigned long last_read; /* jiffies when cache last updated */ | ||
42 | u8 cache[16]; | ||
43 | struct i2c_client i2c; | ||
44 | struct device_node *node; | ||
45 | }; | ||
46 | |||
47 | static struct wf_sat *sats[2]; | ||
48 | |||
49 | struct wf_sat_sensor { | ||
50 | int index; | ||
51 | int index2; /* used for power sensors */ | ||
52 | int shift; | ||
53 | struct wf_sat *sat; | ||
54 | struct wf_sensor sens; | ||
55 | }; | ||
56 | |||
57 | #define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) | ||
58 | #define i2c_to_sat(c) container_of(c, struct wf_sat, i2c) | ||
59 | |||
60 | static int wf_sat_attach(struct i2c_adapter *adapter); | ||
61 | static int wf_sat_detach(struct i2c_client *client); | ||
62 | |||
63 | static struct i2c_driver wf_sat_driver = { | ||
64 | .driver = { | ||
65 | .name = "wf_smu_sat", | ||
66 | }, | ||
67 | .attach_adapter = wf_sat_attach, | ||
68 | .detach_client = wf_sat_detach, | ||
69 | }; | ||
70 | |||
71 | /* | ||
72 | * XXX i2c_smbus_read_i2c_block_data doesn't pass the requested | ||
73 | * length down to the low-level driver, so we use this, which | ||
74 | * works well enough with the SMU i2c driver code... | ||
75 | */ | ||
76 | static int sat_read_block(struct i2c_client *client, u8 command, | ||
77 | u8 *values, int len) | ||
78 | { | ||
79 | union i2c_smbus_data data; | ||
80 | int err; | ||
81 | |||
82 | data.block[0] = len; | ||
83 | err = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
84 | I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA, | ||
85 | &data); | ||
86 | if (!err) | ||
87 | memcpy(values, data.block, len); | ||
88 | return err; | ||
89 | } | ||
90 | |||
91 | struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, | ||
92 | unsigned int *size) | ||
93 | { | ||
94 | struct wf_sat *sat; | ||
95 | int err; | ||
96 | unsigned int i, len; | ||
97 | u8 *buf; | ||
98 | u8 data[4]; | ||
99 | |||
100 | /* TODO: Add the resulting partition to the device-tree */ | ||
101 | |||
102 | if (sat_id > 1 || (sat = sats[sat_id]) == NULL) | ||
103 | return NULL; | ||
104 | |||
105 | err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8); | ||
106 | if (err) { | ||
107 | printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); | ||
108 | return NULL; | ||
109 | } | ||
110 | |||
111 | len = i2c_smbus_read_word_data(&sat->i2c, 9); | ||
112 | if (len < 0) { | ||
113 | printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); | ||
114 | return NULL; | ||
115 | } | ||
116 | if (len == 0) { | ||
117 | printk(KERN_ERR "smu_sat_get_sdb_part no partition %x\n", id); | ||
118 | return NULL; | ||
119 | } | ||
120 | |||
121 | len = le16_to_cpu(len); | ||
122 | len = (len + 3) & ~3; | ||
123 | buf = kmalloc(len, GFP_KERNEL); | ||
124 | if (buf == NULL) | ||
125 | return NULL; | ||
126 | |||
127 | for (i = 0; i < len; i += 4) { | ||
128 | err = sat_read_block(&sat->i2c, 0xa, data, 4); | ||
129 | if (err) { | ||
130 | printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", | ||
131 | err); | ||
132 | goto fail; | ||
133 | } | ||
134 | buf[i] = data[1]; | ||
135 | buf[i+1] = data[0]; | ||
136 | buf[i+2] = data[3]; | ||
137 | buf[i+3] = data[2]; | ||
138 | } | ||
139 | #ifdef DEBUG | ||
140 | DBG(KERN_DEBUG "sat %d partition %x:", sat_id, id); | ||
141 | for (i = 0; i < len; ++i) | ||
142 | DBG(" %x", buf[i]); | ||
143 | DBG("\n"); | ||
144 | #endif | ||
145 | |||
146 | if (size) | ||
147 | *size = len; | ||
148 | return (struct smu_sdbp_header *) buf; | ||
149 | |||
150 | fail: | ||
151 | kfree(buf); | ||
152 | return NULL; | ||
153 | } | ||
154 | EXPORT_SYMBOL_GPL(smu_sat_get_sdb_partition); | ||
155 | |||
156 | /* refresh the cache */ | ||
157 | static int wf_sat_read_cache(struct wf_sat *sat) | ||
158 | { | ||
159 | int err; | ||
160 | |||
161 | err = sat_read_block(&sat->i2c, 0x3f, sat->cache, 16); | ||
162 | if (err) | ||
163 | return err; | ||
164 | sat->last_read = jiffies; | ||
165 | #ifdef LOTSA_DEBUG | ||
166 | { | ||
167 | int i; | ||
168 | DBG(KERN_DEBUG "wf_sat_get: data is"); | ||
169 | for (i = 0; i < 16; ++i) | ||
170 | DBG(" %.2x", sat->cache[i]); | ||
171 | DBG("\n"); | ||
172 | } | ||
173 | #endif | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int wf_sat_get(struct wf_sensor *sr, s32 *value) | ||
178 | { | ||
179 | struct wf_sat_sensor *sens = wf_to_sat(sr); | ||
180 | struct wf_sat *sat = sens->sat; | ||
181 | int i, err; | ||
182 | s32 val; | ||
183 | |||
184 | if (sat->i2c.adapter == NULL) | ||
185 | return -ENODEV; | ||
186 | |||
187 | down(&sat->mutex); | ||
188 | if (time_after(jiffies, (sat->last_read + MAX_AGE))) { | ||
189 | err = wf_sat_read_cache(sat); | ||
190 | if (err) | ||
191 | goto fail; | ||
192 | } | ||
193 | |||
194 | i = sens->index * 2; | ||
195 | val = ((sat->cache[i] << 8) + sat->cache[i+1]) << sens->shift; | ||
196 | if (sens->index2 >= 0) { | ||
197 | i = sens->index2 * 2; | ||
198 | /* 4.12 * 8.8 -> 12.20; shift right 4 to get 16.16 */ | ||
199 | val = (val * ((sat->cache[i] << 8) + sat->cache[i+1])) >> 4; | ||
200 | } | ||
201 | |||
202 | *value = val; | ||
203 | err = 0; | ||
204 | |||
205 | fail: | ||
206 | up(&sat->mutex); | ||
207 | return err; | ||
208 | } | ||
209 | |||
210 | static void wf_sat_release(struct wf_sensor *sr) | ||
211 | { | ||
212 | struct wf_sat_sensor *sens = wf_to_sat(sr); | ||
213 | struct wf_sat *sat = sens->sat; | ||
214 | |||
215 | if (atomic_dec_and_test(&sat->refcnt)) { | ||
216 | if (sat->i2c.adapter) { | ||
217 | i2c_detach_client(&sat->i2c); | ||
218 | sat->i2c.adapter = NULL; | ||
219 | } | ||
220 | if (sat->nr >= 0) | ||
221 | sats[sat->nr] = NULL; | ||
222 | kfree(sat); | ||
223 | } | ||
224 | kfree(sens); | ||
225 | } | ||
226 | |||
227 | static struct wf_sensor_ops wf_sat_ops = { | ||
228 | .get_value = wf_sat_get, | ||
229 | .release = wf_sat_release, | ||
230 | .owner = THIS_MODULE, | ||
231 | }; | ||
232 | |||
233 | static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) | ||
234 | { | ||
235 | struct wf_sat *sat; | ||
236 | struct wf_sat_sensor *sens; | ||
237 | u32 *reg; | ||
238 | char *loc, *type; | ||
239 | u8 addr, chip, core; | ||
240 | struct device_node *child; | ||
241 | int shift, cpu, index; | ||
242 | char *name; | ||
243 | int vsens[2], isens[2]; | ||
244 | |||
245 | reg = (u32 *) get_property(dev, "reg", NULL); | ||
246 | if (reg == NULL) | ||
247 | return; | ||
248 | addr = *reg; | ||
249 | DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr); | ||
250 | |||
251 | sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); | ||
252 | if (sat == NULL) | ||
253 | return; | ||
254 | sat->nr = -1; | ||
255 | sat->node = of_node_get(dev); | ||
256 | atomic_set(&sat->refcnt, 0); | ||
257 | init_MUTEX(&sat->mutex); | ||
258 | sat->i2c.addr = (addr >> 1) & 0x7f; | ||
259 | sat->i2c.adapter = adapter; | ||
260 | sat->i2c.driver = &wf_sat_driver; | ||
261 | strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1); | ||
262 | |||
263 | if (i2c_attach_client(&sat->i2c)) { | ||
264 | printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n"); | ||
265 | goto fail; | ||
266 | } | ||
267 | |||
268 | vsens[0] = vsens[1] = -1; | ||
269 | isens[0] = isens[1] = -1; | ||
270 | child = NULL; | ||
271 | while ((child = of_get_next_child(dev, child)) != NULL) { | ||
272 | reg = (u32 *) get_property(child, "reg", NULL); | ||
273 | type = get_property(child, "device_type", NULL); | ||
274 | loc = get_property(child, "location", NULL); | ||
275 | if (reg == NULL || loc == NULL) | ||
276 | continue; | ||
277 | |||
278 | /* the cooked sensors are between 0x30 and 0x37 */ | ||
279 | if (*reg < 0x30 || *reg > 0x37) | ||
280 | continue; | ||
281 | index = *reg - 0x30; | ||
282 | |||
283 | /* expect location to be CPU [AB][01] ... */ | ||
284 | if (strncmp(loc, "CPU ", 4) != 0) | ||
285 | continue; | ||
286 | chip = loc[4] - 'A'; | ||
287 | core = loc[5] - '0'; | ||
288 | if (chip > 1 || core > 1) { | ||
289 | printk(KERN_ERR "wf_sat_create: don't understand " | ||
290 | "location %s for %s\n", loc, child->full_name); | ||
291 | continue; | ||
292 | } | ||
293 | cpu = 2 * chip + core; | ||
294 | if (sat->nr < 0) | ||
295 | sat->nr = chip; | ||
296 | else if (sat->nr != chip) { | ||
297 | printk(KERN_ERR "wf_sat_create: can't cope with " | ||
298 | "multiple CPU chips on one SAT (%s)\n", loc); | ||
299 | continue; | ||
300 | } | ||
301 | |||
302 | if (strcmp(type, "voltage-sensor") == 0) { | ||
303 | name = "cpu-voltage"; | ||
304 | shift = 4; | ||
305 | vsens[core] = index; | ||
306 | } else if (strcmp(type, "current-sensor") == 0) { | ||
307 | name = "cpu-current"; | ||
308 | shift = 8; | ||
309 | isens[core] = index; | ||
310 | } else if (strcmp(type, "temp-sensor") == 0) { | ||
311 | name = "cpu-temp"; | ||
312 | shift = 10; | ||
313 | } else | ||
314 | continue; /* hmmm shouldn't happen */ | ||
315 | |||
316 | /* the +16 is enough for "cpu-voltage-n" */ | ||
317 | sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL); | ||
318 | if (sens == NULL) { | ||
319 | printk(KERN_ERR "wf_sat_create: couldn't create " | ||
320 | "%s sensor %d (no memory)\n", name, cpu); | ||
321 | continue; | ||
322 | } | ||
323 | sens->index = index; | ||
324 | sens->index2 = -1; | ||
325 | sens->shift = shift; | ||
326 | sens->sat = sat; | ||
327 | atomic_inc(&sat->refcnt); | ||
328 | sens->sens.ops = &wf_sat_ops; | ||
329 | sens->sens.name = (char *) (sens + 1); | ||
330 | snprintf(sens->sens.name, 16, "%s-%d", name, cpu); | ||
331 | |||
332 | if (wf_register_sensor(&sens->sens)) { | ||
333 | atomic_dec(&sat->refcnt); | ||
334 | kfree(sens); | ||
335 | } | ||
336 | } | ||
337 | |||
338 | /* make the power sensors */ | ||
339 | for (core = 0; core < 2; ++core) { | ||
340 | if (vsens[core] < 0 || isens[core] < 0) | ||
341 | continue; | ||
342 | cpu = 2 * sat->nr + core; | ||
343 | sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL); | ||
344 | if (sens == NULL) { | ||
345 | printk(KERN_ERR "wf_sat_create: couldn't create power " | ||
346 | "sensor %d (no memory)\n", cpu); | ||
347 | continue; | ||
348 | } | ||
349 | sens->index = vsens[core]; | ||
350 | sens->index2 = isens[core]; | ||
351 | sens->shift = 0; | ||
352 | sens->sat = sat; | ||
353 | atomic_inc(&sat->refcnt); | ||
354 | sens->sens.ops = &wf_sat_ops; | ||
355 | sens->sens.name = (char *) (sens + 1); | ||
356 | snprintf(sens->sens.name, 16, "cpu-power-%d", cpu); | ||
357 | |||
358 | if (wf_register_sensor(&sens->sens)) { | ||
359 | atomic_dec(&sat->refcnt); | ||
360 | kfree(sens); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | if (sat->nr >= 0) | ||
365 | sats[sat->nr] = sat; | ||
366 | |||
367 | return; | ||
368 | |||
369 | fail: | ||
370 | kfree(sat); | ||
371 | } | ||
372 | |||
373 | static int wf_sat_attach(struct i2c_adapter *adapter) | ||
374 | { | ||
375 | struct device_node *busnode, *dev = NULL; | ||
376 | struct pmac_i2c_bus *bus; | ||
377 | |||
378 | bus = pmac_i2c_adapter_to_bus(adapter); | ||
379 | if (bus == NULL) | ||
380 | return -ENODEV; | ||
381 | busnode = pmac_i2c_get_bus_node(bus); | ||
382 | |||
383 | while ((dev = of_get_next_child(busnode, dev)) != NULL) | ||
384 | if (device_is_compatible(dev, "smu-sat")) | ||
385 | wf_sat_create(adapter, dev); | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static int wf_sat_detach(struct i2c_client *client) | ||
390 | { | ||
391 | struct wf_sat *sat = i2c_to_sat(client); | ||
392 | |||
393 | /* XXX TODO */ | ||
394 | |||
395 | sat->i2c.adapter = NULL; | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | static int __init sat_sensors_init(void) | ||
400 | { | ||
401 | int err; | ||
402 | |||
403 | err = i2c_add_driver(&wf_sat_driver); | ||
404 | if (err < 0) | ||
405 | return err; | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | static void __exit sat_sensors_exit(void) | ||
410 | { | ||
411 | i2c_del_driver(&wf_sat_driver); | ||
412 | } | ||
413 | |||
414 | module_init(sat_sensors_init); | ||
415 | /*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */ | ||
416 | |||
417 | MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); | ||
418 | MODULE_DESCRIPTION("SMU satellite sensors for PowerMac thermal control"); | ||
419 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c index 1a00d9c75a23..bed25dcf8a1e 100644 --- a/drivers/macintosh/windfarm_smu_sensors.c +++ b/drivers/macintosh/windfarm_smu_sensors.c | |||
@@ -220,14 +220,29 @@ static struct smu_ad_sensor *smu_ads_create(struct device_node *node) | |||
220 | !strcmp(l, "CPU T-Diode")) { | 220 | !strcmp(l, "CPU T-Diode")) { |
221 | ads->sens.ops = &smu_cputemp_ops; | 221 | ads->sens.ops = &smu_cputemp_ops; |
222 | ads->sens.name = "cpu-temp"; | 222 | ads->sens.name = "cpu-temp"; |
223 | if (cpudiode == NULL) { | ||
224 | DBG("wf: cpudiode partition (%02x) not found\n", | ||
225 | SMU_SDB_CPUDIODE_ID); | ||
226 | goto fail; | ||
227 | } | ||
223 | } else if (!strcmp(c, "current-sensor") && | 228 | } else if (!strcmp(c, "current-sensor") && |
224 | !strcmp(l, "CPU Current")) { | 229 | !strcmp(l, "CPU Current")) { |
225 | ads->sens.ops = &smu_cpuamp_ops; | 230 | ads->sens.ops = &smu_cpuamp_ops; |
226 | ads->sens.name = "cpu-current"; | 231 | ads->sens.name = "cpu-current"; |
232 | if (cpuvcp == NULL) { | ||
233 | DBG("wf: cpuvcp partition (%02x) not found\n", | ||
234 | SMU_SDB_CPUVCP_ID); | ||
235 | goto fail; | ||
236 | } | ||
227 | } else if (!strcmp(c, "voltage-sensor") && | 237 | } else if (!strcmp(c, "voltage-sensor") && |
228 | !strcmp(l, "CPU Voltage")) { | 238 | !strcmp(l, "CPU Voltage")) { |
229 | ads->sens.ops = &smu_cpuvolt_ops; | 239 | ads->sens.ops = &smu_cpuvolt_ops; |
230 | ads->sens.name = "cpu-voltage"; | 240 | ads->sens.name = "cpu-voltage"; |
241 | if (cpuvcp == NULL) { | ||
242 | DBG("wf: cpuvcp partition (%02x) not found\n", | ||
243 | SMU_SDB_CPUVCP_ID); | ||
244 | goto fail; | ||
245 | } | ||
231 | } else if (!strcmp(c, "power-sensor") && | 246 | } else if (!strcmp(c, "power-sensor") && |
232 | !strcmp(l, "Slots Power")) { | 247 | !strcmp(l, "Slots Power")) { |
233 | ads->sens.ops = &smu_slotspow_ops; | 248 | ads->sens.ops = &smu_slotspow_ops; |
@@ -365,29 +380,22 @@ smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps) | |||
365 | return NULL; | 380 | return NULL; |
366 | } | 381 | } |
367 | 382 | ||
368 | static int smu_fetch_param_partitions(void) | 383 | static void smu_fetch_param_partitions(void) |
369 | { | 384 | { |
370 | struct smu_sdbp_header *hdr; | 385 | struct smu_sdbp_header *hdr; |
371 | 386 | ||
372 | /* Get CPU voltage/current/power calibration data */ | 387 | /* Get CPU voltage/current/power calibration data */ |
373 | hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL); | 388 | hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL); |
374 | if (hdr == NULL) { | 389 | if (hdr != NULL) { |
375 | DBG("wf: cpuvcp partition (%02x) not found\n", | 390 | cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1]; |
376 | SMU_SDB_CPUVCP_ID); | 391 | /* Keep version around */ |
377 | return -ENODEV; | 392 | cpuvcp_version = hdr->version; |
378 | } | 393 | } |
379 | cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1]; | ||
380 | /* Keep version around */ | ||
381 | cpuvcp_version = hdr->version; | ||
382 | 394 | ||
383 | /* Get CPU diode calibration data */ | 395 | /* Get CPU diode calibration data */ |
384 | hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL); | 396 | hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL); |
385 | if (hdr == NULL) { | 397 | if (hdr != NULL) |
386 | DBG("wf: cpudiode partition (%02x) not found\n", | 398 | cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1]; |
387 | SMU_SDB_CPUDIODE_ID); | ||
388 | return -ENODEV; | ||
389 | } | ||
390 | cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1]; | ||
391 | 399 | ||
392 | /* Get slots power calibration data if any */ | 400 | /* Get slots power calibration data if any */ |
393 | hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL); | 401 | hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL); |
@@ -398,23 +406,18 @@ static int smu_fetch_param_partitions(void) | |||
398 | hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL); | 406 | hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL); |
399 | if (hdr != NULL) | 407 | if (hdr != NULL) |
400 | debugswitches = (u8 *)&hdr[1]; | 408 | debugswitches = (u8 *)&hdr[1]; |
401 | |||
402 | return 0; | ||
403 | } | 409 | } |
404 | 410 | ||
405 | static int __init smu_sensors_init(void) | 411 | static int __init smu_sensors_init(void) |
406 | { | 412 | { |
407 | struct device_node *smu, *sensors, *s; | 413 | struct device_node *smu, *sensors, *s; |
408 | struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL; | 414 | struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL; |
409 | int rc; | ||
410 | 415 | ||
411 | if (!smu_present()) | 416 | if (!smu_present()) |
412 | return -ENODEV; | 417 | return -ENODEV; |
413 | 418 | ||
414 | /* Get parameters partitions */ | 419 | /* Get parameters partitions */ |
415 | rc = smu_fetch_param_partitions(); | 420 | smu_fetch_param_partitions(); |
416 | if (rc) | ||
417 | return rc; | ||
418 | 421 | ||
419 | smu = of_find_node_by_type(NULL, "smu"); | 422 | smu = of_find_node_by_type(NULL, "smu"); |
420 | if (smu == NULL) | 423 | if (smu == NULL) |
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index ab89278a56bf..697aacafb02a 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c | |||
@@ -103,9 +103,15 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
103 | return -EINVAL; | 103 | return -EINVAL; |
104 | } | 104 | } |
105 | 105 | ||
106 | if (((uint32_t)ti->len) & (chunk_size - 1)) { | ||
107 | ti->error = "dm-stripe: Target length not divisible by " | ||
108 | "chunk size"; | ||
109 | return -EINVAL; | ||
110 | } | ||
111 | |||
106 | width = ti->len; | 112 | width = ti->len; |
107 | if (sector_div(width, stripes)) { | 113 | if (sector_div(width, stripes)) { |
108 | ti->error = "dm-stripe: Target length not divisable by " | 114 | ti->error = "dm-stripe: Target length not divisible by " |
109 | "number of stripes"; | 115 | "number of stripes"; |
110 | return -EINVAL; | 116 | return -EINVAL; |
111 | } | 117 | } |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index e9adeb9d172f..745ca1f67b14 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -849,10 +849,16 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) | |||
849 | 849 | ||
850 | static void free_dev(struct mapped_device *md) | 850 | static void free_dev(struct mapped_device *md) |
851 | { | 851 | { |
852 | free_minor(md->disk->first_minor); | 852 | unsigned int minor = md->disk->first_minor; |
853 | |||
854 | if (md->suspended_bdev) { | ||
855 | thaw_bdev(md->suspended_bdev, NULL); | ||
856 | bdput(md->suspended_bdev); | ||
857 | } | ||
853 | mempool_destroy(md->tio_pool); | 858 | mempool_destroy(md->tio_pool); |
854 | mempool_destroy(md->io_pool); | 859 | mempool_destroy(md->io_pool); |
855 | del_gendisk(md->disk); | 860 | del_gendisk(md->disk); |
861 | free_minor(minor); | ||
856 | put_disk(md->disk); | 862 | put_disk(md->disk); |
857 | blk_put_queue(md->queue); | 863 | blk_put_queue(md->queue); |
858 | kfree(md); | 864 | kfree(md); |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index d39f584cd8b3..5d88329e3c7a 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -306,6 +306,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
306 | r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); | 306 | r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); |
307 | int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state); | 307 | int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state); |
308 | conf_t *conf = mddev_to_conf(r1_bio->mddev); | 308 | conf_t *conf = mddev_to_conf(r1_bio->mddev); |
309 | struct bio *to_put = NULL; | ||
309 | 310 | ||
310 | if (bio->bi_size) | 311 | if (bio->bi_size) |
311 | return 1; | 312 | return 1; |
@@ -323,6 +324,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
323 | * this branch is our 'one mirror IO has finished' event handler: | 324 | * this branch is our 'one mirror IO has finished' event handler: |
324 | */ | 325 | */ |
325 | r1_bio->bios[mirror] = NULL; | 326 | r1_bio->bios[mirror] = NULL; |
327 | to_put = bio; | ||
326 | if (!uptodate) { | 328 | if (!uptodate) { |
327 | md_error(r1_bio->mddev, conf->mirrors[mirror].rdev); | 329 | md_error(r1_bio->mddev, conf->mirrors[mirror].rdev); |
328 | /* an I/O failed, we can't clear the bitmap */ | 330 | /* an I/O failed, we can't clear the bitmap */ |
@@ -375,7 +377,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
375 | /* Don't dec_pending yet, we want to hold | 377 | /* Don't dec_pending yet, we want to hold |
376 | * the reference over the retry | 378 | * the reference over the retry |
377 | */ | 379 | */ |
378 | return 0; | 380 | goto out; |
379 | } | 381 | } |
380 | if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { | 382 | if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { |
381 | /* free extra copy of the data pages */ | 383 | /* free extra copy of the data pages */ |
@@ -392,10 +394,11 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
392 | raid_end_bio_io(r1_bio); | 394 | raid_end_bio_io(r1_bio); |
393 | } | 395 | } |
394 | 396 | ||
395 | if (r1_bio->bios[mirror]==NULL) | ||
396 | bio_put(bio); | ||
397 | |||
398 | rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); | 397 | rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); |
398 | out: | ||
399 | if (to_put) | ||
400 | bio_put(to_put); | ||
401 | |||
399 | return 0; | 402 | return 0; |
400 | } | 403 | } |
401 | 404 | ||
@@ -857,7 +860,7 @@ static int make_request(request_queue_t *q, struct bio * bio) | |||
857 | atomic_set(&r1_bio->remaining, 0); | 860 | atomic_set(&r1_bio->remaining, 0); |
858 | atomic_set(&r1_bio->behind_remaining, 0); | 861 | atomic_set(&r1_bio->behind_remaining, 0); |
859 | 862 | ||
860 | do_barriers = bio->bi_rw & BIO_RW_BARRIER; | 863 | do_barriers = bio_barrier(bio); |
861 | if (do_barriers) | 864 | if (do_barriers) |
862 | set_bit(R1BIO_Barrier, &r1_bio->state); | 865 | set_bit(R1BIO_Barrier, &r1_bio->state); |
863 | 866 | ||
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig index 2583a865a58e..2963605c0ecc 100644 --- a/drivers/media/dvb/b2c2/Kconfig +++ b/drivers/media/dvb/b2c2/Kconfig | |||
@@ -4,7 +4,7 @@ config DVB_B2C2_FLEXCOP | |||
4 | select DVB_STV0299 | 4 | select DVB_STV0299 |
5 | select DVB_MT352 | 5 | select DVB_MT352 |
6 | select DVB_MT312 | 6 | select DVB_MT312 |
7 | select DVB_NXT2002 | 7 | select DVB_NXT200X |
8 | select DVB_STV0297 | 8 | select DVB_STV0297 |
9 | select DVB_BCM3510 | 9 | select DVB_BCM3510 |
10 | select DVB_LGDT330X | 10 | select DVB_LGDT330X |
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h index 344a3c898460..7d7e1613c5a7 100644 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ b/drivers/media/dvb/b2c2/flexcop-common.h | |||
@@ -116,11 +116,9 @@ void flexcop_dma_free(struct flexcop_dma *dma); | |||
116 | 116 | ||
117 | int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); | 117 | int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); |
118 | int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); | 118 | int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); |
119 | int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); | ||
120 | int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx); | 119 | int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx); |
121 | int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff); | 120 | int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff); |
122 | int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles); | 121 | int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles); |
123 | int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets); | ||
124 | 122 | ||
125 | /* from flexcop-eeprom.c */ | 123 | /* from flexcop-eeprom.c */ |
126 | /* the PCI part uses this call to get the MAC address, the USB part has its own */ | 124 | /* the PCI part uses this call to get the MAC address, the USB part has its own */ |
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c index cf4ed1df6086..6f592bc32d22 100644 --- a/drivers/media/dvb/b2c2/flexcop-dma.c +++ b/drivers/media/dvb/b2c2/flexcop-dma.c | |||
@@ -169,38 +169,3 @@ int flexcop_dma_config_timer(struct flexcop_device *fc, | |||
169 | } | 169 | } |
170 | EXPORT_SYMBOL(flexcop_dma_config_timer); | 170 | EXPORT_SYMBOL(flexcop_dma_config_timer); |
171 | 171 | ||
172 | /* packet IRQ does not exist in FCII or FCIIb - according to data book and tests */ | ||
173 | int flexcop_dma_control_packet_irq(struct flexcop_device *fc, | ||
174 | flexcop_dma_index_t no, | ||
175 | int onoff) | ||
176 | { | ||
177 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); | ||
178 | |||
179 | deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw); | ||
180 | if (no & FC_DMA_1) | ||
181 | v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff; | ||
182 | |||
183 | if (no & FC_DMA_2) | ||
184 | v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff; | ||
185 | |||
186 | fc->write_ibi_reg(fc,ctrl_208,v); | ||
187 | deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw); | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | EXPORT_SYMBOL(flexcop_dma_control_packet_irq); | ||
192 | |||
193 | int flexcop_dma_config_packet_count(struct flexcop_device *fc, | ||
194 | flexcop_dma_index_t dma_idx, | ||
195 | u8 packets) | ||
196 | { | ||
197 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; | ||
198 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
199 | |||
200 | flexcop_dma_remap(fc,dma_idx,1); | ||
201 | |||
202 | v.dma_0x4_remap.DMA_maxpackets = packets; | ||
203 | fc->write_ibi_reg(fc,r,v); | ||
204 | return 0; | ||
205 | } | ||
206 | EXPORT_SYMBOL(flexcop_dma_config_packet_count); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 0b940e152b79..9c7f122826e0 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | #include "stv0299.h" | 10 | #include "stv0299.h" |
11 | #include "mt352.h" | 11 | #include "mt352.h" |
12 | #include "nxt2002.h" | 12 | #include "nxt200x.h" |
13 | #include "bcm3510.h" | 13 | #include "bcm3510.h" |
14 | #include "stv0297.h" | 14 | #include "stv0297.h" |
15 | #include "mt312.h" | 15 | #include "mt312.h" |
@@ -343,9 +343,10 @@ static struct lgdt330x_config air2pc_atsc_hd5000_config = { | |||
343 | .clock_polarity_flip = 1, | 343 | .clock_polarity_flip = 1, |
344 | }; | 344 | }; |
345 | 345 | ||
346 | static struct nxt2002_config samsung_tbmv_config = { | 346 | static struct nxt200x_config samsung_tbmv_config = { |
347 | .demod_address = 0x0a, | 347 | .demod_address = 0x0a, |
348 | .request_firmware = flexcop_fe_request_firmware, | 348 | .pll_address = 0xc2, |
349 | .pll_desc = &dvb_pll_samsung_tbmv, | ||
349 | }; | 350 | }; |
350 | 351 | ||
351 | static struct bcm3510_config air2pc_atsc_first_gen_config = { | 352 | static struct bcm3510_config air2pc_atsc_first_gen_config = { |
@@ -505,7 +506,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
505 | info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); | 506 | info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); |
506 | } else | 507 | } else |
507 | /* try the air atsc 2nd generation (nxt2002) */ | 508 | /* try the air atsc 2nd generation (nxt2002) */ |
508 | if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { | 509 | if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { |
509 | fc->dev_type = FC_AIR_ATSC2; | 510 | fc->dev_type = FC_AIR_ATSC2; |
510 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); | 511 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); |
511 | } else | 512 | } else |
@@ -525,7 +526,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
525 | info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); | 526 | info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); |
526 | } else | 527 | } else |
527 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ | 528 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ |
528 | if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { | 529 | if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { |
529 | ops = fc->fe->ops; | 530 | ops = fc->fe->ops; |
530 | 531 | ||
531 | ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; | 532 | ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; |
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c index 62282d8dbfa8..167583bf0621 100644 --- a/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/drivers/media/dvb/b2c2/flexcop-misc.c | |||
@@ -36,14 +36,14 @@ void flexcop_determine_revision(struct flexcop_device *fc) | |||
36 | /* bus parts have to decide if hw pid filtering is used or not. */ | 36 | /* bus parts have to decide if hw pid filtering is used or not. */ |
37 | } | 37 | } |
38 | 38 | ||
39 | const char *flexcop_revision_names[] = { | 39 | static const char *flexcop_revision_names[] = { |
40 | "Unkown chip", | 40 | "Unkown chip", |
41 | "FlexCopII", | 41 | "FlexCopII", |
42 | "FlexCopIIb", | 42 | "FlexCopIIb", |
43 | "FlexCopIII", | 43 | "FlexCopIII", |
44 | }; | 44 | }; |
45 | 45 | ||
46 | const char *flexcop_device_names[] = { | 46 | static const char *flexcop_device_names[] = { |
47 | "Unkown device", | 47 | "Unkown device", |
48 | "Air2PC/AirStar 2 DVB-T", | 48 | "Air2PC/AirStar 2 DVB-T", |
49 | "Air2PC/AirStar 2 ATSC 1st generation", | 49 | "Air2PC/AirStar 2 ATSC 1st generation", |
@@ -54,7 +54,7 @@ const char *flexcop_device_names[] = { | |||
54 | "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", | 54 | "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", |
55 | }; | 55 | }; |
56 | 56 | ||
57 | const char *flexcop_bus_names[] = { | 57 | static const char *flexcop_bus_names[] = { |
58 | "USB", | 58 | "USB", |
59 | "PCI", | 59 | "PCI", |
60 | }; | 60 | }; |
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index 2f76eb3fea40..9bc40bdcc282 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c | |||
@@ -161,8 +161,10 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
161 | fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; | 161 | fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; |
162 | u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; | 162 | u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; |
163 | 163 | ||
164 | deb_irq("%u irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ", | 164 | deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ", |
165 | jiffies_to_usecs(jiffies - fc_pci->last_irq),v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos); | 165 | jiffies_to_usecs(jiffies - fc_pci->last_irq), |
166 | v.raw, (unsigned long long)cur_addr, cur_pos, | ||
167 | fc_pci->last_dma1_cur_pos); | ||
166 | fc_pci->last_irq = jiffies; | 168 | fc_pci->last_irq = jiffies; |
167 | 169 | ||
168 | /* buffer end was reached, restarted from the beginning | 170 | /* buffer end was reached, restarted from the beginning |
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h index 3153f9513c63..491f9bd6e195 100644 --- a/drivers/media/dvb/b2c2/flexcop-reg.h +++ b/drivers/media/dvb/b2c2/flexcop-reg.h | |||
@@ -16,8 +16,6 @@ typedef enum { | |||
16 | FLEXCOP_III, | 16 | FLEXCOP_III, |
17 | } flexcop_revision_t; | 17 | } flexcop_revision_t; |
18 | 18 | ||
19 | extern const char *flexcop_revision_names[]; | ||
20 | |||
21 | typedef enum { | 19 | typedef enum { |
22 | FC_UNK = 0, | 20 | FC_UNK = 0, |
23 | FC_AIR_DVB, | 21 | FC_AIR_DVB, |
@@ -34,8 +32,6 @@ typedef enum { | |||
34 | FC_PCI, | 32 | FC_PCI, |
35 | } flexcop_bus_t; | 33 | } flexcop_bus_t; |
36 | 34 | ||
37 | extern const char *flexcop_device_names[]; | ||
38 | |||
39 | /* FlexCop IBI Registers */ | 35 | /* FlexCop IBI Registers */ |
40 | #if defined(__LITTLE_ENDIAN) | 36 | #if defined(__LITTLE_ENDIAN) |
41 | #include "flexcop_ibi_value_le.h" | 37 | #include "flexcop_ibi_value_le.h" |
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index a04bb61f21f4..356f447ee2ab 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c | |||
@@ -381,6 +381,23 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet * | |||
381 | 381 | ||
382 | EXPORT_SYMBOL(bt878_device_control); | 382 | EXPORT_SYMBOL(bt878_device_control); |
383 | 383 | ||
384 | |||
385 | static struct cards card_list[] __devinitdata = { | ||
386 | |||
387 | { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, | ||
388 | { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, | ||
389 | { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" }, | ||
390 | { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, | ||
391 | { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" }, | ||
392 | { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, | ||
393 | { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, | ||
394 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, | ||
395 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, | ||
396 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, | ||
397 | { 0, -1, NULL } | ||
398 | }; | ||
399 | |||
400 | |||
384 | /***********************/ | 401 | /***********************/ |
385 | /* PCI device handling */ | 402 | /* PCI device handling */ |
386 | /***********************/ | 403 | /***********************/ |
@@ -388,18 +405,41 @@ EXPORT_SYMBOL(bt878_device_control); | |||
388 | static int __devinit bt878_probe(struct pci_dev *dev, | 405 | static int __devinit bt878_probe(struct pci_dev *dev, |
389 | const struct pci_device_id *pci_id) | 406 | const struct pci_device_id *pci_id) |
390 | { | 407 | { |
391 | int result; | 408 | int result = 0, has_dvb = 0, i; |
392 | unsigned char lat; | 409 | unsigned char lat; |
393 | struct bt878 *bt; | 410 | struct bt878 *bt; |
394 | #if defined(__powerpc__) | 411 | #if defined(__powerpc__) |
395 | unsigned int cmd; | 412 | unsigned int cmd; |
396 | #endif | 413 | #endif |
414 | unsigned int cardid; | ||
415 | unsigned short id; | ||
416 | struct cards *dvb_cards; | ||
397 | 417 | ||
398 | printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", | 418 | printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", |
399 | bt878_num); | 419 | bt878_num); |
400 | if (pci_enable_device(dev)) | 420 | if (pci_enable_device(dev)) |
401 | return -EIO; | 421 | return -EIO; |
402 | 422 | ||
423 | pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &id); | ||
424 | cardid = id << 16; | ||
425 | pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &id); | ||
426 | cardid |= id; | ||
427 | |||
428 | for (i = 0, dvb_cards = card_list; i < ARRAY_SIZE(card_list); i++, dvb_cards++) { | ||
429 | if (cardid == dvb_cards->pci_id) { | ||
430 | printk("%s: card id=[0x%x],[ %s ] has DVB functions.\n", | ||
431 | __func__, cardid, dvb_cards->name); | ||
432 | has_dvb = 1; | ||
433 | } | ||
434 | } | ||
435 | |||
436 | if (!has_dvb) { | ||
437 | printk("%s: card id=[0x%x], Unknown card.\nExiting..\n", __func__, cardid); | ||
438 | result = -EINVAL; | ||
439 | |||
440 | goto fail0; | ||
441 | } | ||
442 | |||
403 | bt = &bt878[bt878_num]; | 443 | bt = &bt878[bt878_num]; |
404 | bt->dev = dev; | 444 | bt->dev = dev; |
405 | bt->nr = bt878_num; | 445 | bt->nr = bt878_num; |
@@ -416,6 +456,8 @@ static int __devinit bt878_probe(struct pci_dev *dev, | |||
416 | 456 | ||
417 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision); | 457 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision); |
418 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); | 458 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); |
459 | |||
460 | |||
419 | printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ", | 461 | printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ", |
420 | bt878_num, bt->id, bt->revision, dev->bus->number, | 462 | bt878_num, bt->id, bt->revision, dev->bus->number, |
421 | PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | 463 | PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); |
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h index a73baf00ca39..9faf93770d08 100644 --- a/drivers/media/dvb/bt8xx/bt878.h +++ b/drivers/media/dvb/bt8xx/bt878.h | |||
@@ -88,6 +88,23 @@ | |||
88 | 88 | ||
89 | #define BT878_RISC_SYNC_MASK (1 << 15) | 89 | #define BT878_RISC_SYNC_MASK (1 << 15) |
90 | 90 | ||
91 | |||
92 | #define BTTV_BOARD_UNKNOWN 0x00 | ||
93 | #define BTTV_BOARD_PINNACLESAT 0x5e | ||
94 | #define BTTV_BOARD_NEBULA_DIGITV 0x68 | ||
95 | #define BTTV_BOARD_PC_HDTV 0x70 | ||
96 | #define BTTV_BOARD_TWINHAN_DST 0x71 | ||
97 | #define BTTV_BOARD_AVDVBT_771 0x7b | ||
98 | #define BTTV_BOARD_AVDVBT_761 0x7c | ||
99 | #define BTTV_BOARD_DVICO_DVBT_LITE 0x80 | ||
100 | #define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 | ||
101 | |||
102 | struct cards { | ||
103 | __u32 pci_id; | ||
104 | __u16 card_id; | ||
105 | char *name; | ||
106 | }; | ||
107 | |||
91 | extern int bt878_num; | 108 | extern int bt878_num; |
92 | 109 | ||
93 | struct bt878 { | 110 | struct bt878 { |
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 3a2ff1cc24b7..0310e3dd07e6 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -602,7 +602,7 @@ static int dst_type_print(u8 type) | |||
602 | 602 | ||
603 | */ | 603 | */ |
604 | 604 | ||
605 | struct dst_types dst_tlist[] = { | 605 | static struct dst_types dst_tlist[] = { |
606 | { | 606 | { |
607 | .device_id = "200103A", | 607 | .device_id = "200103A", |
608 | .offset = 0, | 608 | .offset = 0, |
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h index 9f025825b2d2..0c1d87c5227a 100644 --- a/drivers/media/dvb/dvb-core/demux.h +++ b/drivers/media/dvb/dvb-core/demux.h | |||
@@ -216,7 +216,7 @@ struct dmx_frontend { | |||
216 | /*--------------------------------------------------------------------------*/ | 216 | /*--------------------------------------------------------------------------*/ |
217 | 217 | ||
218 | /* | 218 | /* |
219 | * Flags OR'ed in the capabilites field of struct dmx_demux. | 219 | * Flags OR'ed in the capabilities field of struct dmx_demux. |
220 | */ | 220 | */ |
221 | 221 | ||
222 | #define DMX_TS_FILTERING 1 | 222 | #define DMX_TS_FILTERING 1 |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 90a69d343b79..d3df12039b06 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -83,12 +83,18 @@ config DVB_USB_UMT_010 | |||
83 | Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. | 83 | Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. |
84 | 84 | ||
85 | config DVB_USB_CXUSB | 85 | config DVB_USB_CXUSB |
86 | tristate "Medion MD95700 hybrid USB2.0 (Conexant) support" | 86 | tristate "Conexant USB2.0 hybrid reference design support" |
87 | depends on DVB_USB | 87 | depends on DVB_USB |
88 | select DVB_CX22702 | 88 | select DVB_CX22702 |
89 | select DVB_LGDT330X | ||
90 | select DVB_MT352 | ||
89 | help | 91 | help |
90 | Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently | 92 | Say Y here to support the Conexant USB2.0 hybrid reference design. |
91 | only the DVB-T part is supported. | 93 | Currently, only DVB and ATSC modes are supported, analog mode |
94 | shall be added in the future. Devices that require this module: | ||
95 | |||
96 | Medion MD95700 hybrid USB2.0 device. | ||
97 | DViCO FusionHDTV (Bluebird) USB2.0 devices | ||
92 | 98 | ||
93 | config DVB_USB_DIGITV | 99 | config DVB_USB_DIGITV |
94 | tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" | 100 | tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index a7fb06f4cd34..162f9795cd89 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -184,7 +184,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
184 | return 0; | 184 | return 0; |
185 | } | 185 | } |
186 | 186 | ||
187 | struct dvb_usb_rc_key dvico_mce_rc_keys[] = { | 187 | static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { |
188 | { 0xfe, 0x02, KEY_TV }, | 188 | { 0xfe, 0x02, KEY_TV }, |
189 | { 0xfe, 0x0e, KEY_MP3 }, | 189 | { 0xfe, 0x0e, KEY_MP3 }, |
190 | { 0xfe, 0x1a, KEY_DVD }, | 190 | { 0xfe, 0x1a, KEY_DVD }, |
@@ -234,7 +234,7 @@ struct dvb_usb_rc_key dvico_mce_rc_keys[] = { | |||
234 | 234 | ||
235 | static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) | 235 | static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) |
236 | { | 236 | { |
237 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; | 237 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; |
238 | static u8 reset [] = { RESET, 0x80 }; | 238 | static u8 reset [] = { RESET, 0x80 }; |
239 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | 239 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; |
240 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; | 240 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; |
@@ -255,7 +255,7 @@ static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) | |||
255 | 255 | ||
256 | static int cxusb_mt352_demod_init(struct dvb_frontend* fe) | 256 | static int cxusb_mt352_demod_init(struct dvb_frontend* fe) |
257 | { /* used in both lgz201 and th7579 */ | 257 | { /* used in both lgz201 and th7579 */ |
258 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 }; | 258 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 }; |
259 | static u8 reset [] = { RESET, 0x80 }; | 259 | static u8 reset [] = { RESET, 0x80 }; |
260 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | 260 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; |
261 | static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; | 261 | static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; |
@@ -273,7 +273,7 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe) | |||
273 | return 0; | 273 | return 0; |
274 | } | 274 | } |
275 | 275 | ||
276 | struct cx22702_config cxusb_cx22702_config = { | 276 | static struct cx22702_config cxusb_cx22702_config = { |
277 | .demod_address = 0x63, | 277 | .demod_address = 0x63, |
278 | 278 | ||
279 | .output_mode = CX22702_PARALLEL_OUTPUT, | 279 | .output_mode = CX22702_PARALLEL_OUTPUT, |
@@ -282,13 +282,13 @@ struct cx22702_config cxusb_cx22702_config = { | |||
282 | .pll_set = dvb_usb_pll_set_i2c, | 282 | .pll_set = dvb_usb_pll_set_i2c, |
283 | }; | 283 | }; |
284 | 284 | ||
285 | struct lgdt330x_config cxusb_lgdt330x_config = { | 285 | static struct lgdt330x_config cxusb_lgdt3303_config = { |
286 | .demod_address = 0x0e, | 286 | .demod_address = 0x0e, |
287 | .demod_chip = LGDT3303, | 287 | .demod_chip = LGDT3303, |
288 | .pll_set = dvb_usb_pll_set_i2c, | 288 | .pll_set = dvb_usb_pll_set_i2c, |
289 | }; | 289 | }; |
290 | 290 | ||
291 | struct mt352_config cxusb_dee1601_config = { | 291 | static struct mt352_config cxusb_dee1601_config = { |
292 | .demod_address = 0x0f, | 292 | .demod_address = 0x0f, |
293 | .demod_init = cxusb_dee1601_demod_init, | 293 | .demod_init = cxusb_dee1601_demod_init, |
294 | .pll_set = dvb_usb_pll_set, | 294 | .pll_set = dvb_usb_pll_set, |
@@ -357,14 +357,14 @@ static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d) | |||
357 | return -EIO; | 357 | return -EIO; |
358 | } | 358 | } |
359 | 359 | ||
360 | static int cxusb_lgdt330x_frontend_attach(struct dvb_usb_device *d) | 360 | static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_device *d) |
361 | { | 361 | { |
362 | if (usb_set_interface(d->udev,0,7) < 0) | 362 | if (usb_set_interface(d->udev,0,7) < 0) |
363 | err("set interface failed"); | 363 | err("set interface failed"); |
364 | 364 | ||
365 | cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); | 365 | cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); |
366 | 366 | ||
367 | if ((d->fe = lgdt330x_attach(&cxusb_lgdt330x_config, &d->i2c_adap)) != NULL) | 367 | if ((d->fe = lgdt330x_attach(&cxusb_lgdt3303_config, &d->i2c_adap)) != NULL) |
368 | return 0; | 368 | return 0; |
369 | 369 | ||
370 | return -EIO; | 370 | return -EIO; |
@@ -506,7 +506,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = { | |||
506 | 506 | ||
507 | .streaming_ctrl = cxusb_streaming_ctrl, | 507 | .streaming_ctrl = cxusb_streaming_ctrl, |
508 | .power_ctrl = cxusb_power_ctrl, | 508 | .power_ctrl = cxusb_power_ctrl, |
509 | .frontend_attach = cxusb_lgdt330x_frontend_attach, | 509 | .frontend_attach = cxusb_lgdt3303_frontend_attach, |
510 | .tuner_attach = cxusb_lgh064f_tuner_attach, | 510 | .tuner_attach = cxusb_lgh064f_tuner_attach, |
511 | 511 | ||
512 | .i2c_algo = &cxusb_i2c_algo, | 512 | .i2c_algo = &cxusb_i2c_algo, |
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index e6c55c9c9417..caa1346e3063 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
@@ -175,11 +175,13 @@ static int digitv_probe(struct usb_interface *intf, | |||
175 | if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) { | 175 | if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) { |
176 | u8 b[4] = { 0 }; | 176 | u8 b[4] = { 0 }; |
177 | 177 | ||
178 | b[0] = 1; | 178 | if (d != NULL) { /* do that only when the firmware is loaded */ |
179 | digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0); | 179 | b[0] = 1; |
180 | digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0); | ||
180 | 181 | ||
181 | b[0] = 0; | 182 | b[0] = 0; |
182 | digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0); | 183 | digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0); |
184 | } | ||
183 | } | 185 | } |
184 | return ret; | 186 | return ret; |
185 | } | 187 | } |
@@ -194,7 +196,7 @@ static struct dvb_usb_properties digitv_properties = { | |||
194 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 196 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
195 | 197 | ||
196 | .usb_ctrl = CYPRESS_FX2, | 198 | .usb_ctrl = CYPRESS_FX2, |
197 | .firmware = "dvb-usb-digitv-01.fw", | 199 | .firmware = "dvb-usb-digitv-02.fw", |
198 | 200 | ||
199 | .size_of_priv = 0, | 201 | .size_of_priv = 0, |
200 | 202 | ||
@@ -229,6 +231,7 @@ static struct dvb_usb_properties digitv_properties = { | |||
229 | { &digitv_table[0], NULL }, | 231 | { &digitv_table[0], NULL }, |
230 | { NULL }, | 232 | { NULL }, |
231 | }, | 233 | }, |
234 | { NULL }, | ||
232 | } | 235 | } |
233 | }; | 236 | }; |
234 | 237 | ||
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index 130ea7f21f5e..12ebaf8bddca 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c | |||
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = { | |||
151 | .cold_ids = { &dtt200u_usb_table[0], NULL }, | 151 | .cold_ids = { &dtt200u_usb_table[0], NULL }, |
152 | .warm_ids = { &dtt200u_usb_table[1], NULL }, | 152 | .warm_ids = { &dtt200u_usb_table[1], NULL }, |
153 | }, | 153 | }, |
154 | { 0 }, | 154 | { NULL }, |
155 | } | 155 | } |
156 | }; | 156 | }; |
157 | 157 | ||
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = { | |||
192 | .cold_ids = { &dtt200u_usb_table[2], NULL }, | 192 | .cold_ids = { &dtt200u_usb_table[2], NULL }, |
193 | .warm_ids = { &dtt200u_usb_table[3], NULL }, | 193 | .warm_ids = { &dtt200u_usb_table[3], NULL }, |
194 | }, | 194 | }, |
195 | { 0 }, | 195 | { NULL }, |
196 | } | 196 | } |
197 | }; | 197 | }; |
198 | 198 | ||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c index 8535895819fb..9222b0a81f74 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c | |||
@@ -24,6 +24,9 @@ static struct usb_cypress_controller cypress[] = { | |||
24 | { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, | 24 | { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, | ||
28 | int *pos); | ||
29 | |||
27 | /* | 30 | /* |
28 | * load a firmware packet to the device | 31 | * load a firmware packet to the device |
29 | */ | 32 | */ |
@@ -112,7 +115,8 @@ int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties | |||
112 | return ret; | 115 | return ret; |
113 | } | 116 | } |
114 | 117 | ||
115 | int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos) | 118 | static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, |
119 | int *pos) | ||
116 | { | 120 | { |
117 | u8 *b = (u8 *) &fw->data[*pos]; | 121 | u8 *b = (u8 *) &fw->data[*pos]; |
118 | int data_offs = 4; | 122 | int data_offs = 4; |
@@ -142,5 +146,3 @@ int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos) | |||
142 | 146 | ||
143 | return *pos; | 147 | return *pos; |
144 | } | 148 | } |
145 | EXPORT_SYMBOL(dvb_usb_get_hexline); | ||
146 | |||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index 716f8bf528cd..ce34a55e5c24 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c | |||
@@ -47,7 +47,7 @@ static int dvb_usb_init(struct dvb_usb_device *d) | |||
47 | 47 | ||
48 | d->state = DVB_USB_STATE_INIT; | 48 | d->state = DVB_USB_STATE_INIT; |
49 | 49 | ||
50 | /* check the capabilites and set appropriate variables */ | 50 | /* check the capabilities and set appropriate variables */ |
51 | 51 | ||
52 | /* speed - when running at FULL speed we need a HW PID filter */ | 52 | /* speed - when running at FULL speed we need a HW PID filter */ |
53 | if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) { | 53 | if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) { |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index dd568396e594..d4909e5c67e0 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
@@ -87,7 +87,7 @@ struct dvb_usb_device; | |||
87 | 87 | ||
88 | /** | 88 | /** |
89 | * struct dvb_usb_properties - properties of a dvb-usb-device | 89 | * struct dvb_usb_properties - properties of a dvb-usb-device |
90 | * @caps: capabilites of the DVB USB device. | 90 | * @caps: capabilities of the DVB USB device. |
91 | * @pid_filter_count: number of PID filter position in the optional hardware | 91 | * @pid_filter_count: number of PID filter position in the optional hardware |
92 | * PID-filter. | 92 | * PID-filter. |
93 | * | 93 | * |
@@ -341,7 +341,6 @@ struct hexline { | |||
341 | u8 data[255]; | 341 | u8 data[255]; |
342 | u8 chk; | 342 | u8 chk; |
343 | }; | 343 | }; |
344 | extern int dvb_usb_get_hexline(const struct firmware *, struct hexline *, int *); | ||
345 | extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type); | 344 | extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type); |
346 | 345 | ||
347 | #endif | 346 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c index afa00fdb5ec0..4a95eca81c5c 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.c +++ b/drivers/media/dvb/dvb-usb/vp702x.c | |||
@@ -53,7 +53,8 @@ int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 | |||
53 | return ret; | 53 | return ret; |
54 | } | 54 | } |
55 | 55 | ||
56 | int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) | 56 | static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, |
57 | u16 index, u8 *b, int blen) | ||
57 | { | 58 | { |
58 | deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index); | 59 | deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index); |
59 | debug_dump(b,blen,deb_xfer); | 60 | debug_dump(b,blen,deb_xfer); |
@@ -88,7 +89,8 @@ unlock: | |||
88 | return ret; | 89 | return ret; |
89 | } | 90 | } |
90 | 91 | ||
91 | int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec) | 92 | static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, |
93 | int olen, u8 *i, int ilen, int msec) | ||
92 | { | 94 | { |
93 | u8 bout[olen+2]; | 95 | u8 bout[olen+2]; |
94 | u8 bin[ilen+1]; | 96 | u8 bin[ilen+1]; |
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h index a808d48e7bf2..c2f97f96c21f 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.h +++ b/drivers/media/dvb/dvb-usb/vp702x.h | |||
@@ -101,8 +101,6 @@ extern int dvb_usb_vp702x_debug; | |||
101 | extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); | 101 | extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); |
102 | 102 | ||
103 | extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); | 103 | extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); |
104 | extern int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec); | ||
105 | extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); | 104 | extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); |
106 | extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); | ||
107 | 105 | ||
108 | #endif | 106 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c index 5242cca5db4a..9999336aeeb6 100644 --- a/drivers/media/dvb/dvb-usb/vp7045-fe.c +++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c | |||
@@ -23,10 +23,11 @@ | |||
23 | 23 | ||
24 | struct vp7045_fe_state { | 24 | struct vp7045_fe_state { |
25 | struct dvb_frontend fe; | 25 | struct dvb_frontend fe; |
26 | struct dvb_frontend_ops ops; | ||
27 | |||
26 | struct dvb_usb_device *d; | 28 | struct dvb_usb_device *d; |
27 | }; | 29 | }; |
28 | 30 | ||
29 | |||
30 | static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) | 31 | static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) |
31 | { | 32 | { |
32 | struct vp7045_fe_state *state = fe->demodulator_priv; | 33 | struct vp7045_fe_state *state = fe->demodulator_priv; |
@@ -150,7 +151,8 @@ struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d) | |||
150 | goto error; | 151 | goto error; |
151 | 152 | ||
152 | s->d = d; | 153 | s->d = d; |
153 | s->fe.ops = &vp7045_fe_ops; | 154 | memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops)); |
155 | s->fe.ops = &s->ops; | ||
154 | s->fe.demodulator_priv = s; | 156 | s->fe.demodulator_priv = s; |
155 | 157 | ||
156 | goto success; | 158 | goto success; |
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 028204956bb0..3835235b68df 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c | |||
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = { | |||
247 | .cold_ids = { &vp7045_usb_table[2], NULL }, | 247 | .cold_ids = { &vp7045_usb_table[2], NULL }, |
248 | .warm_ids = { &vp7045_usb_table[3], NULL }, | 248 | .warm_ids = { &vp7045_usb_table[3], NULL }, |
249 | }, | 249 | }, |
250 | { 0 }, | 250 | { NULL }, |
251 | } | 251 | } |
252 | }; | 252 | }; |
253 | 253 | ||
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index db3a8b40031e..c676b1e23ab0 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -28,14 +28,8 @@ config DVB_TDA8083 | |||
28 | help | 28 | help |
29 | A DVB-S tuner module. Say Y when you want to support this frontend. | 29 | A DVB-S tuner module. Say Y when you want to support this frontend. |
30 | 30 | ||
31 | config DVB_TDA80XX | ||
32 | tristate "Philips TDA8044 or TDA8083 based" | ||
33 | depends on DVB_CORE | ||
34 | help | ||
35 | A DVB-S tuner module. Say Y when you want to support this frontend. | ||
36 | |||
37 | config DVB_MT312 | 31 | config DVB_MT312 |
38 | tristate "Zarlink MT312 based" | 32 | tristate "Zarlink VP310/MT312 based" |
39 | depends on DVB_CORE | 33 | depends on DVB_CORE |
40 | help | 34 | help |
41 | A DVB-S tuner module. Say Y when you want to support this frontend. | 35 | A DVB-S tuner module. Say Y when you want to support this frontend. |
@@ -139,12 +133,6 @@ config DVB_DIB3000MC | |||
139 | comment "DVB-C (cable) frontends" | 133 | comment "DVB-C (cable) frontends" |
140 | depends on DVB_CORE | 134 | depends on DVB_CORE |
141 | 135 | ||
142 | config DVB_ATMEL_AT76C651 | ||
143 | tristate "Atmel AT76C651 based" | ||
144 | depends on DVB_CORE | ||
145 | help | ||
146 | A DVB-C tuner module. Say Y when you want to support this frontend. | ||
147 | |||
148 | config DVB_VES1820 | 136 | config DVB_VES1820 |
149 | tristate "VLSI VES1820 based" | 137 | tristate "VLSI VES1820 based" |
150 | depends on DVB_CORE | 138 | depends on DVB_CORE |
@@ -166,18 +154,6 @@ config DVB_STV0297 | |||
166 | comment "ATSC (North American/Korean Terresterial DTV) frontends" | 154 | comment "ATSC (North American/Korean Terresterial DTV) frontends" |
167 | depends on DVB_CORE | 155 | depends on DVB_CORE |
168 | 156 | ||
169 | config DVB_NXT2002 | ||
170 | tristate "Nxt2002 based" | ||
171 | depends on DVB_CORE | ||
172 | select FW_LOADER | ||
173 | help | ||
174 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. | ||
175 | |||
176 | This driver needs external firmware. Please use the command | ||
177 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to | ||
178 | download/extract it, and then copy it to /usr/lib/hotplug/firmware | ||
179 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
180 | |||
181 | config DVB_NXT200X | 157 | config DVB_NXT200X |
182 | tristate "Nextwave NXT2002/NXT2004 based" | 158 | tristate "Nextwave NXT2002/NXT2004 based" |
183 | depends on DVB_CORE | 159 | depends on DVB_CORE |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 615ec830e1c9..1af769cd90c0 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -8,7 +8,6 @@ obj-$(CONFIG_DVB_CORE) += dvb-pll.o | |||
8 | obj-$(CONFIG_DVB_STV0299) += stv0299.o | 8 | obj-$(CONFIG_DVB_STV0299) += stv0299.o |
9 | obj-$(CONFIG_DVB_SP8870) += sp8870.o | 9 | obj-$(CONFIG_DVB_SP8870) += sp8870.o |
10 | obj-$(CONFIG_DVB_CX22700) += cx22700.o | 10 | obj-$(CONFIG_DVB_CX22700) += cx22700.o |
11 | obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o | ||
12 | obj-$(CONFIG_DVB_CX24110) += cx24110.o | 11 | obj-$(CONFIG_DVB_CX24110) += cx24110.o |
13 | obj-$(CONFIG_DVB_TDA8083) += tda8083.o | 12 | obj-$(CONFIG_DVB_TDA8083) += tda8083.o |
14 | obj-$(CONFIG_DVB_L64781) += l64781.o | 13 | obj-$(CONFIG_DVB_L64781) += l64781.o |
@@ -22,10 +21,8 @@ obj-$(CONFIG_DVB_SP887X) += sp887x.o | |||
22 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o | 21 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o |
23 | obj-$(CONFIG_DVB_MT352) += mt352.o | 22 | obj-$(CONFIG_DVB_MT352) += mt352.o |
24 | obj-$(CONFIG_DVB_CX22702) += cx22702.o | 23 | obj-$(CONFIG_DVB_CX22702) += cx22702.o |
25 | obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o | ||
26 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o | 24 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o |
27 | obj-$(CONFIG_DVB_STV0297) += stv0297.o | 25 | obj-$(CONFIG_DVB_STV0297) += stv0297.o |
28 | obj-$(CONFIG_DVB_NXT2002) += nxt2002.o | ||
29 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o | 26 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o |
30 | obj-$(CONFIG_DVB_OR51211) += or51211.o | 27 | obj-$(CONFIG_DVB_OR51211) += or51211.o |
31 | obj-$(CONFIG_DVB_OR51132) += or51132.o | 28 | obj-$(CONFIG_DVB_OR51132) += or51132.o |
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c deleted file mode 100644 index 8e0f4b3a1417..000000000000 --- a/drivers/media/dvb/frontends/at76c651.c +++ /dev/null | |||
@@ -1,450 +0,0 @@ | |||
1 | /* | ||
2 | * at76c651.c | ||
3 | * | ||
4 | * Atmel DVB-C Frontend Driver (at76c651/tua6010xs) | ||
5 | * | ||
6 | * Copyright (C) 2001 fnbrd <fnbrd@gmx.de> | ||
7 | * & 2002-2004 Andreas Oberritter <obi@linuxtv.org> | ||
8 | * & 2003 Wolfram Joost <dbox2@frokaschwei.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * AT76C651 | ||
25 | * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf | ||
26 | * http://www.atmel.com/atmel/acrobat/doc1320.pdf | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/moduleparam.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/bitops.h> | ||
36 | #include "dvb_frontend.h" | ||
37 | #include "at76c651.h" | ||
38 | |||
39 | |||
40 | struct at76c651_state { | ||
41 | |||
42 | struct i2c_adapter* i2c; | ||
43 | |||
44 | struct dvb_frontend_ops ops; | ||
45 | |||
46 | const struct at76c651_config* config; | ||
47 | |||
48 | struct dvb_frontend frontend; | ||
49 | |||
50 | /* revision of the chip */ | ||
51 | u8 revision; | ||
52 | |||
53 | /* last QAM value set */ | ||
54 | u8 qam; | ||
55 | }; | ||
56 | |||
57 | static int debug; | ||
58 | #define dprintk(args...) \ | ||
59 | do { \ | ||
60 | if (debug) printk(KERN_DEBUG "at76c651: " args); \ | ||
61 | } while (0) | ||
62 | |||
63 | |||
64 | #if ! defined(__powerpc__) | ||
65 | static __inline__ int __ilog2(unsigned long x) | ||
66 | { | ||
67 | int i; | ||
68 | |||
69 | if (x == 0) | ||
70 | return -1; | ||
71 | |||
72 | for (i = 0; x != 0; i++) | ||
73 | x >>= 1; | ||
74 | |||
75 | return i - 1; | ||
76 | } | ||
77 | #endif | ||
78 | |||
79 | static int at76c651_writereg(struct at76c651_state* state, u8 reg, u8 data) | ||
80 | { | ||
81 | int ret; | ||
82 | u8 buf[] = { reg, data }; | ||
83 | struct i2c_msg msg = | ||
84 | { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; | ||
85 | |||
86 | ret = i2c_transfer(state->i2c, &msg, 1); | ||
87 | |||
88 | if (ret != 1) | ||
89 | dprintk("%s: writereg error " | ||
90 | "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", | ||
91 | __FUNCTION__, reg, data, ret); | ||
92 | |||
93 | msleep(10); | ||
94 | |||
95 | return (ret != 1) ? -EREMOTEIO : 0; | ||
96 | } | ||
97 | |||
98 | static u8 at76c651_readreg(struct at76c651_state* state, u8 reg) | ||
99 | { | ||
100 | int ret; | ||
101 | u8 val; | ||
102 | struct i2c_msg msg[] = { | ||
103 | { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 }, | ||
104 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = &val, .len = 1 } | ||
105 | }; | ||
106 | |||
107 | ret = i2c_transfer(state->i2c, msg, 2); | ||
108 | |||
109 | if (ret != 2) | ||
110 | dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); | ||
111 | |||
112 | return val; | ||
113 | } | ||
114 | |||
115 | static int at76c651_reset(struct at76c651_state* state) | ||
116 | { | ||
117 | return at76c651_writereg(state, 0x07, 0x01); | ||
118 | } | ||
119 | |||
120 | static void at76c651_disable_interrupts(struct at76c651_state* state) | ||
121 | { | ||
122 | at76c651_writereg(state, 0x0b, 0x00); | ||
123 | } | ||
124 | |||
125 | static int at76c651_set_auto_config(struct at76c651_state *state) | ||
126 | { | ||
127 | /* | ||
128 | * Autoconfig | ||
129 | */ | ||
130 | |||
131 | at76c651_writereg(state, 0x06, 0x01); | ||
132 | |||
133 | /* | ||
134 | * Performance optimizations, should be done after autoconfig | ||
135 | */ | ||
136 | |||
137 | at76c651_writereg(state, 0x10, 0x06); | ||
138 | at76c651_writereg(state, 0x11, ((state->qam == 5) || (state->qam == 7)) ? 0x12 : 0x10); | ||
139 | at76c651_writereg(state, 0x15, 0x28); | ||
140 | at76c651_writereg(state, 0x20, 0x09); | ||
141 | at76c651_writereg(state, 0x24, ((state->qam == 5) || (state->qam == 7)) ? 0xC0 : 0x90); | ||
142 | at76c651_writereg(state, 0x30, 0x90); | ||
143 | if (state->qam == 5) | ||
144 | at76c651_writereg(state, 0x35, 0x2A); | ||
145 | |||
146 | /* | ||
147 | * Initialize A/D-converter | ||
148 | */ | ||
149 | |||
150 | if (state->revision == 0x11) { | ||
151 | at76c651_writereg(state, 0x2E, 0x38); | ||
152 | at76c651_writereg(state, 0x2F, 0x13); | ||
153 | } | ||
154 | |||
155 | at76c651_disable_interrupts(state); | ||
156 | |||
157 | /* | ||
158 | * Restart operation | ||
159 | */ | ||
160 | |||
161 | at76c651_reset(state); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static void at76c651_set_bbfreq(struct at76c651_state* state) | ||
167 | { | ||
168 | at76c651_writereg(state, 0x04, 0x3f); | ||
169 | at76c651_writereg(state, 0x05, 0xee); | ||
170 | } | ||
171 | |||
172 | static int at76c651_set_symbol_rate(struct at76c651_state* state, u32 symbol_rate) | ||
173 | { | ||
174 | u8 exponent; | ||
175 | u32 mantissa; | ||
176 | |||
177 | if (symbol_rate > 9360000) | ||
178 | return -EINVAL; | ||
179 | |||
180 | /* | ||
181 | * FREF = 57800 kHz | ||
182 | * exponent = 10 + floor (log2(symbol_rate / FREF)) | ||
183 | * mantissa = (symbol_rate / FREF) * (1 << (30 - exponent)) | ||
184 | */ | ||
185 | |||
186 | exponent = __ilog2((symbol_rate << 4) / 903125); | ||
187 | mantissa = ((symbol_rate / 3125) * (1 << (24 - exponent))) / 289; | ||
188 | |||
189 | at76c651_writereg(state, 0x00, mantissa >> 13); | ||
190 | at76c651_writereg(state, 0x01, mantissa >> 5); | ||
191 | at76c651_writereg(state, 0x02, (mantissa << 3) | exponent); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static int at76c651_set_qam(struct at76c651_state *state, fe_modulation_t qam) | ||
197 | { | ||
198 | switch (qam) { | ||
199 | case QPSK: | ||
200 | state->qam = 0x02; | ||
201 | break; | ||
202 | case QAM_16: | ||
203 | state->qam = 0x04; | ||
204 | break; | ||
205 | case QAM_32: | ||
206 | state->qam = 0x05; | ||
207 | break; | ||
208 | case QAM_64: | ||
209 | state->qam = 0x06; | ||
210 | break; | ||
211 | case QAM_128: | ||
212 | state->qam = 0x07; | ||
213 | break; | ||
214 | case QAM_256: | ||
215 | state->qam = 0x08; | ||
216 | break; | ||
217 | #if 0 | ||
218 | case QAM_512: | ||
219 | state->qam = 0x09; | ||
220 | break; | ||
221 | case QAM_1024: | ||
222 | state->qam = 0x0A; | ||
223 | break; | ||
224 | #endif | ||
225 | default: | ||
226 | return -EINVAL; | ||
227 | |||
228 | } | ||
229 | |||
230 | return at76c651_writereg(state, 0x03, state->qam); | ||
231 | } | ||
232 | |||
233 | static int at76c651_set_inversion(struct at76c651_state* state, fe_spectral_inversion_t inversion) | ||
234 | { | ||
235 | u8 feciqinv = at76c651_readreg(state, 0x60); | ||
236 | |||
237 | switch (inversion) { | ||
238 | case INVERSION_OFF: | ||
239 | feciqinv |= 0x02; | ||
240 | feciqinv &= 0xFE; | ||
241 | break; | ||
242 | |||
243 | case INVERSION_ON: | ||
244 | feciqinv |= 0x03; | ||
245 | break; | ||
246 | |||
247 | case INVERSION_AUTO: | ||
248 | feciqinv &= 0xFC; | ||
249 | break; | ||
250 | |||
251 | default: | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | |||
255 | return at76c651_writereg(state, 0x60, feciqinv); | ||
256 | } | ||
257 | |||
258 | static int at76c651_set_parameters(struct dvb_frontend* fe, | ||
259 | struct dvb_frontend_parameters *p) | ||
260 | { | ||
261 | int ret; | ||
262 | struct at76c651_state* state = fe->demodulator_priv; | ||
263 | |||
264 | at76c651_writereg(state, 0x0c, 0xc3); | ||
265 | state->config->pll_set(fe, p); | ||
266 | at76c651_writereg(state, 0x0c, 0xc2); | ||
267 | |||
268 | if ((ret = at76c651_set_symbol_rate(state, p->u.qam.symbol_rate))) | ||
269 | return ret; | ||
270 | |||
271 | if ((ret = at76c651_set_inversion(state, p->inversion))) | ||
272 | return ret; | ||
273 | |||
274 | return at76c651_set_auto_config(state); | ||
275 | } | ||
276 | |||
277 | static int at76c651_set_defaults(struct dvb_frontend* fe) | ||
278 | { | ||
279 | struct at76c651_state* state = fe->demodulator_priv; | ||
280 | |||
281 | at76c651_set_symbol_rate(state, 6900000); | ||
282 | at76c651_set_qam(state, QAM_64); | ||
283 | at76c651_set_bbfreq(state); | ||
284 | at76c651_set_auto_config(state); | ||
285 | |||
286 | if (state->config->pll_init) { | ||
287 | at76c651_writereg(state, 0x0c, 0xc3); | ||
288 | state->config->pll_init(fe); | ||
289 | at76c651_writereg(state, 0x0c, 0xc2); | ||
290 | } | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
296 | { | ||
297 | struct at76c651_state* state = fe->demodulator_priv; | ||
298 | u8 sync; | ||
299 | |||
300 | /* | ||
301 | * Bits: FEC, CAR, EQU, TIM, AGC2, AGC1, ADC, PLL (PLL=0) | ||
302 | */ | ||
303 | sync = at76c651_readreg(state, 0x80); | ||
304 | *status = 0; | ||
305 | |||
306 | if (sync & (0x04 | 0x10)) /* AGC1 || TIM */ | ||
307 | *status |= FE_HAS_SIGNAL; | ||
308 | if (sync & 0x10) /* TIM */ | ||
309 | *status |= FE_HAS_CARRIER; | ||
310 | if (sync & 0x80) /* FEC */ | ||
311 | *status |= FE_HAS_VITERBI; | ||
312 | if (sync & 0x40) /* CAR */ | ||
313 | *status |= FE_HAS_SYNC; | ||
314 | if ((sync & 0xF0) == 0xF0) /* TIM && EQU && CAR && FEC */ | ||
315 | *status |= FE_HAS_LOCK; | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber) | ||
321 | { | ||
322 | struct at76c651_state* state = fe->demodulator_priv; | ||
323 | |||
324 | *ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16; | ||
325 | *ber |= at76c651_readreg(state, 0x82) << 8; | ||
326 | *ber |= at76c651_readreg(state, 0x83); | ||
327 | *ber *= 10; | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
333 | { | ||
334 | struct at76c651_state* state = fe->demodulator_priv; | ||
335 | |||
336 | u8 gain = ~at76c651_readreg(state, 0x91); | ||
337 | *strength = (gain << 8) | gain; | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr) | ||
343 | { | ||
344 | struct at76c651_state* state = fe->demodulator_priv; | ||
345 | |||
346 | *snr = 0xFFFF - | ||
347 | ((at76c651_readreg(state, 0x8F) << 8) | | ||
348 | at76c651_readreg(state, 0x90)); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
354 | { | ||
355 | struct at76c651_state* state = fe->demodulator_priv; | ||
356 | |||
357 | *ucblocks = at76c651_readreg(state, 0x82); | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *fesettings) | ||
363 | { | ||
364 | fesettings->min_delay_ms = 50; | ||
365 | fesettings->step_size = 0; | ||
366 | fesettings->max_drift = 0; | ||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static void at76c651_release(struct dvb_frontend* fe) | ||
371 | { | ||
372 | struct at76c651_state* state = fe->demodulator_priv; | ||
373 | kfree(state); | ||
374 | } | ||
375 | |||
376 | static struct dvb_frontend_ops at76c651_ops; | ||
377 | |||
378 | struct dvb_frontend* at76c651_attach(const struct at76c651_config* config, | ||
379 | struct i2c_adapter* i2c) | ||
380 | { | ||
381 | struct at76c651_state* state = NULL; | ||
382 | |||
383 | /* allocate memory for the internal state */ | ||
384 | state = kmalloc(sizeof(struct at76c651_state), GFP_KERNEL); | ||
385 | if (state == NULL) goto error; | ||
386 | |||
387 | /* setup the state */ | ||
388 | state->config = config; | ||
389 | state->qam = 0; | ||
390 | |||
391 | /* check if the demod is there */ | ||
392 | if (at76c651_readreg(state, 0x0e) != 0x65) goto error; | ||
393 | |||
394 | /* finalise state setup */ | ||
395 | state->i2c = i2c; | ||
396 | state->revision = at76c651_readreg(state, 0x0f) & 0xfe; | ||
397 | memcpy(&state->ops, &at76c651_ops, sizeof(struct dvb_frontend_ops)); | ||
398 | |||
399 | /* create dvb_frontend */ | ||
400 | state->frontend.ops = &state->ops; | ||
401 | state->frontend.demodulator_priv = state; | ||
402 | return &state->frontend; | ||
403 | |||
404 | error: | ||
405 | kfree(state); | ||
406 | return NULL; | ||
407 | } | ||
408 | |||
409 | static struct dvb_frontend_ops at76c651_ops = { | ||
410 | |||
411 | .info = { | ||
412 | .name = "Atmel AT76C651B DVB-C", | ||
413 | .type = FE_QAM, | ||
414 | .frequency_min = 48250000, | ||
415 | .frequency_max = 863250000, | ||
416 | .frequency_stepsize = 62500, | ||
417 | /*.frequency_tolerance = */ /* FIXME: 12% of SR */ | ||
418 | .symbol_rate_min = 0, /* FIXME */ | ||
419 | .symbol_rate_max = 9360000, /* FIXME */ | ||
420 | .symbol_rate_tolerance = 4000, | ||
421 | .caps = FE_CAN_INVERSION_AUTO | | ||
422 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
423 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | | ||
424 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | | ||
425 | FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | | ||
426 | FE_CAN_MUTE_TS | FE_CAN_QAM_256 | FE_CAN_RECOVER | ||
427 | }, | ||
428 | |||
429 | .release = at76c651_release, | ||
430 | |||
431 | .init = at76c651_set_defaults, | ||
432 | |||
433 | .set_frontend = at76c651_set_parameters, | ||
434 | .get_tune_settings = at76c651_get_tune_settings, | ||
435 | |||
436 | .read_status = at76c651_read_status, | ||
437 | .read_ber = at76c651_read_ber, | ||
438 | .read_signal_strength = at76c651_read_signal_strength, | ||
439 | .read_snr = at76c651_read_snr, | ||
440 | .read_ucblocks = at76c651_read_ucblocks, | ||
441 | }; | ||
442 | |||
443 | module_param(debug, int, 0644); | ||
444 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
445 | |||
446 | MODULE_DESCRIPTION("Atmel AT76C651 DVB-C Demodulator Driver"); | ||
447 | MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); | ||
448 | MODULE_LICENSE("GPL"); | ||
449 | |||
450 | EXPORT_SYMBOL(at76c651_attach); | ||
diff --git a/drivers/media/dvb/frontends/at76c651.h b/drivers/media/dvb/frontends/at76c651.h deleted file mode 100644 index 34054df93608..000000000000 --- a/drivers/media/dvb/frontends/at76c651.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* | ||
2 | * at76c651.c | ||
3 | * | ||
4 | * Atmel DVB-C Frontend Driver (at76c651) | ||
5 | * | ||
6 | * Copyright (C) 2001 fnbrd <fnbrd@gmx.de> | ||
7 | * & 2002-2004 Andreas Oberritter <obi@linuxtv.org> | ||
8 | * & 2003 Wolfram Joost <dbox2@frokaschwei.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * AT76C651 | ||
25 | * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf | ||
26 | * http://www.atmel.com/atmel/acrobat/doc1320.pdf | ||
27 | */ | ||
28 | |||
29 | #ifndef AT76C651_H | ||
30 | #define AT76C651_H | ||
31 | |||
32 | #include <linux/dvb/frontend.h> | ||
33 | |||
34 | struct at76c651_config | ||
35 | { | ||
36 | /* the demodulator's i2c address */ | ||
37 | u8 demod_address; | ||
38 | |||
39 | /* PLL maintenance */ | ||
40 | int (*pll_init)(struct dvb_frontend* fe); | ||
41 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
42 | }; | ||
43 | |||
44 | extern struct dvb_frontend* at76c651_attach(const struct at76c651_config* config, | ||
45 | struct i2c_adapter* i2c); | ||
46 | |||
47 | #endif // AT76C651_H | ||
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 1b9934ea5b06..4dcb6050d4fa 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -326,11 +326,11 @@ struct dvb_pll_desc dvb_pll_tuv1236d = { | |||
326 | }; | 326 | }; |
327 | EXPORT_SYMBOL(dvb_pll_tuv1236d); | 327 | EXPORT_SYMBOL(dvb_pll_tuv1236d); |
328 | 328 | ||
329 | /* Samsung TBMV30111IN | 329 | /* Samsung TBMV30111IN / TBMV30712IN1 |
330 | * used in Air2PC ATSC - 2nd generation (nxt2002) | 330 | * used in Air2PC ATSC - 2nd generation (nxt2002) |
331 | */ | 331 | */ |
332 | struct dvb_pll_desc dvb_pll_tbmv30111in = { | 332 | struct dvb_pll_desc dvb_pll_samsung_tbmv = { |
333 | .name = "Samsung TBMV30111IN", | 333 | .name = "Samsung TBMV30111IN / TBMV30712IN1", |
334 | .min = 54000000, | 334 | .min = 54000000, |
335 | .max = 860000000, | 335 | .max = 860000000, |
336 | .count = 6, | 336 | .count = 6, |
@@ -343,7 +343,7 @@ struct dvb_pll_desc dvb_pll_tbmv30111in = { | |||
343 | { 999999999, 44000000, 166666, 0xfc, 0x02 }, | 343 | { 999999999, 44000000, 166666, 0xfc, 0x02 }, |
344 | } | 344 | } |
345 | }; | 345 | }; |
346 | EXPORT_SYMBOL(dvb_pll_tbmv30111in); | 346 | EXPORT_SYMBOL(dvb_pll_samsung_tbmv); |
347 | 347 | ||
348 | /* | 348 | /* |
349 | * Philips SD1878 Tuner. | 349 | * Philips SD1878 Tuner. |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index f682c09189b3..bb8d4b4eb183 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
@@ -38,7 +38,7 @@ extern struct dvb_pll_desc dvb_pll_tded4; | |||
38 | 38 | ||
39 | extern struct dvb_pll_desc dvb_pll_tuv1236d; | 39 | extern struct dvb_pll_desc dvb_pll_tuv1236d; |
40 | extern struct dvb_pll_desc dvb_pll_tdhu2; | 40 | extern struct dvb_pll_desc dvb_pll_tdhu2; |
41 | extern struct dvb_pll_desc dvb_pll_tbmv30111in; | 41 | extern struct dvb_pll_desc dvb_pll_samsung_tbmv; |
42 | extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; | 42 | extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; |
43 | 43 | ||
44 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 44 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, |
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c index ec4e641acc64..d3aea83cf218 100644 --- a/drivers/media/dvb/frontends/mt312.c +++ b/drivers/media/dvb/frontends/mt312.c | |||
@@ -612,76 +612,6 @@ static void mt312_release(struct dvb_frontend* fe) | |||
612 | kfree(state); | 612 | kfree(state); |
613 | } | 613 | } |
614 | 614 | ||
615 | static struct dvb_frontend_ops vp310_mt312_ops; | ||
616 | |||
617 | struct dvb_frontend* vp310_attach(const struct mt312_config* config, | ||
618 | struct i2c_adapter* i2c) | ||
619 | { | ||
620 | struct mt312_state* state = NULL; | ||
621 | |||
622 | /* allocate memory for the internal state */ | ||
623 | state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL); | ||
624 | if (state == NULL) | ||
625 | goto error; | ||
626 | |||
627 | /* setup the state */ | ||
628 | state->config = config; | ||
629 | state->i2c = i2c; | ||
630 | memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); | ||
631 | strcpy(state->ops.info.name, "Zarlink VP310 DVB-S"); | ||
632 | |||
633 | /* check if the demod is there */ | ||
634 | if (mt312_readreg(state, ID, &state->id) < 0) | ||
635 | goto error; | ||
636 | if (state->id != ID_VP310) { | ||
637 | goto error; | ||
638 | } | ||
639 | |||
640 | /* create dvb_frontend */ | ||
641 | state->frequency = 90; | ||
642 | state->frontend.ops = &state->ops; | ||
643 | state->frontend.demodulator_priv = state; | ||
644 | return &state->frontend; | ||
645 | |||
646 | error: | ||
647 | kfree(state); | ||
648 | return NULL; | ||
649 | } | ||
650 | |||
651 | struct dvb_frontend* mt312_attach(const struct mt312_config* config, | ||
652 | struct i2c_adapter* i2c) | ||
653 | { | ||
654 | struct mt312_state* state = NULL; | ||
655 | |||
656 | /* allocate memory for the internal state */ | ||
657 | state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL); | ||
658 | if (state == NULL) | ||
659 | goto error; | ||
660 | |||
661 | /* setup the state */ | ||
662 | state->config = config; | ||
663 | state->i2c = i2c; | ||
664 | memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); | ||
665 | strcpy(state->ops.info.name, "Zarlink MT312 DVB-S"); | ||
666 | |||
667 | /* check if the demod is there */ | ||
668 | if (mt312_readreg(state, ID, &state->id) < 0) | ||
669 | goto error; | ||
670 | if (state->id != ID_MT312) { | ||
671 | goto error; | ||
672 | } | ||
673 | |||
674 | /* create dvb_frontend */ | ||
675 | state->frequency = 60; | ||
676 | state->frontend.ops = &state->ops; | ||
677 | state->frontend.demodulator_priv = state; | ||
678 | return &state->frontend; | ||
679 | |||
680 | error: | ||
681 | kfree(state); | ||
682 | return NULL; | ||
683 | } | ||
684 | |||
685 | static struct dvb_frontend_ops vp310_mt312_ops = { | 615 | static struct dvb_frontend_ops vp310_mt312_ops = { |
686 | 616 | ||
687 | .info = { | 617 | .info = { |
@@ -720,6 +650,49 @@ static struct dvb_frontend_ops vp310_mt312_ops = { | |||
720 | .set_voltage = mt312_set_voltage, | 650 | .set_voltage = mt312_set_voltage, |
721 | }; | 651 | }; |
722 | 652 | ||
653 | struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, | ||
654 | struct i2c_adapter* i2c) | ||
655 | { | ||
656 | struct mt312_state* state = NULL; | ||
657 | |||
658 | /* allocate memory for the internal state */ | ||
659 | state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL); | ||
660 | if (state == NULL) | ||
661 | goto error; | ||
662 | |||
663 | /* setup the state */ | ||
664 | state->config = config; | ||
665 | state->i2c = i2c; | ||
666 | memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); | ||
667 | |||
668 | /* check if the demod is there */ | ||
669 | if (mt312_readreg(state, ID, &state->id) < 0) | ||
670 | goto error; | ||
671 | |||
672 | switch (state->id) { | ||
673 | case ID_VP310: | ||
674 | strcpy(state->ops.info.name, "Zarlink VP310 DVB-S"); | ||
675 | state->frequency = 90; | ||
676 | break; | ||
677 | case ID_MT312: | ||
678 | strcpy(state->ops.info.name, "Zarlink MT312 DVB-S"); | ||
679 | state->frequency = 60; | ||
680 | break; | ||
681 | default: | ||
682 | printk (KERN_WARNING "Only Zarlink VP310/MT312 are supported chips.\n"); | ||
683 | goto error; | ||
684 | } | ||
685 | |||
686 | /* create dvb_frontend */ | ||
687 | state->frontend.ops = &state->ops; | ||
688 | state->frontend.demodulator_priv = state; | ||
689 | return &state->frontend; | ||
690 | |||
691 | error: | ||
692 | kfree(state); | ||
693 | return NULL; | ||
694 | } | ||
695 | |||
723 | module_param(debug, int, 0644); | 696 | module_param(debug, int, 0644); |
724 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | 697 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); |
725 | 698 | ||
@@ -727,5 +700,4 @@ MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver"); | |||
727 | MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); | 700 | MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); |
728 | MODULE_LICENSE("GPL"); | 701 | MODULE_LICENSE("GPL"); |
729 | 702 | ||
730 | EXPORT_SYMBOL(mt312_attach); | 703 | EXPORT_SYMBOL(vp310_mt312_attach); |
731 | EXPORT_SYMBOL(vp310_attach); | ||
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h index b3a53a73a117..074d844f0139 100644 --- a/drivers/media/dvb/frontends/mt312.h +++ b/drivers/media/dvb/frontends/mt312.h | |||
@@ -38,10 +38,8 @@ struct mt312_config | |||
38 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | 38 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
39 | }; | 39 | }; |
40 | 40 | ||
41 | extern struct dvb_frontend* mt312_attach(const struct mt312_config* config, | 41 | struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, |
42 | struct i2c_adapter* i2c); | 42 | struct i2c_adapter* i2c); |
43 | 43 | ||
44 | extern struct dvb_frontend* vp310_attach(const struct mt312_config* config, | ||
45 | struct i2c_adapter* i2c); | ||
46 | 44 | ||
47 | #endif // MT312_H | 45 | #endif // MT312_H |
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c deleted file mode 100644 index 4f263e65ba14..000000000000 --- a/drivers/media/dvb/frontends/nxt2002.c +++ /dev/null | |||
@@ -1,706 +0,0 @@ | |||
1 | /* | ||
2 | Support for B2C2/BBTI Technisat Air2PC - ATSC | ||
3 | |||
4 | Copyright (C) 2004 Taylor Jacob <rtjacob@earthlink.net> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | |||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * This driver needs external firmware. Please use the command | ||
24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to | ||
25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware | ||
26 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
27 | */ | ||
28 | #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" | ||
29 | #define CRC_CCIT_MASK 0x1021 | ||
30 | |||
31 | #include <linux/init.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/moduleparam.h> | ||
34 | #include <linux/device.h> | ||
35 | #include <linux/firmware.h> | ||
36 | #include <linux/string.h> | ||
37 | #include <linux/slab.h> | ||
38 | |||
39 | #include "dvb_frontend.h" | ||
40 | #include "nxt2002.h" | ||
41 | |||
42 | struct nxt2002_state { | ||
43 | |||
44 | struct i2c_adapter* i2c; | ||
45 | struct dvb_frontend_ops ops; | ||
46 | const struct nxt2002_config* config; | ||
47 | struct dvb_frontend frontend; | ||
48 | |||
49 | /* demodulator private data */ | ||
50 | u8 initialised:1; | ||
51 | }; | ||
52 | |||
53 | static int debug; | ||
54 | #define dprintk(args...) \ | ||
55 | do { \ | ||
56 | if (debug) printk(KERN_DEBUG "nxt2002: " args); \ | ||
57 | } while (0) | ||
58 | |||
59 | static int i2c_writebytes (struct nxt2002_state* state, u8 reg, u8 *buf, u8 len) | ||
60 | { | ||
61 | /* probbably a much better way or doing this */ | ||
62 | u8 buf2 [256],x; | ||
63 | int err; | ||
64 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 }; | ||
65 | |||
66 | buf2[0] = reg; | ||
67 | for (x = 0 ; x < len ; x++) | ||
68 | buf2[x+1] = buf[x]; | ||
69 | |||
70 | if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { | ||
71 | printk ("%s: i2c write error (addr %02x, err == %i)\n", | ||
72 | __FUNCTION__, state->config->demod_address, err); | ||
73 | return -EREMOTEIO; | ||
74 | } | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static u8 i2c_readbytes (struct nxt2002_state* state, u8 reg, u8* buf, u8 len) | ||
80 | { | ||
81 | u8 reg2 [] = { reg }; | ||
82 | |||
83 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 }, | ||
84 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } }; | ||
85 | |||
86 | int err; | ||
87 | |||
88 | if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) { | ||
89 | printk ("%s: i2c read error (addr %02x, err == %i)\n", | ||
90 | __FUNCTION__, state->config->demod_address, err); | ||
91 | return -EREMOTEIO; | ||
92 | } | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static u16 nxt2002_crc(u16 crc, u8 c) | ||
98 | { | ||
99 | |||
100 | u8 i; | ||
101 | u16 input = (u16) c & 0xFF; | ||
102 | |||
103 | input<<=8; | ||
104 | for(i=0 ;i<8 ;i++) { | ||
105 | if((crc ^ input) & 0x8000) | ||
106 | crc=(crc<<1)^CRC_CCIT_MASK; | ||
107 | else | ||
108 | crc<<=1; | ||
109 | input<<=1; | ||
110 | } | ||
111 | return crc; | ||
112 | } | ||
113 | |||
114 | static int nxt2002_writereg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len) | ||
115 | { | ||
116 | u8 buf; | ||
117 | dprintk("%s\n", __FUNCTION__); | ||
118 | |||
119 | /* set multi register length */ | ||
120 | i2c_writebytes(state,0x34,&len,1); | ||
121 | |||
122 | /* set mutli register register */ | ||
123 | i2c_writebytes(state,0x35,®,1); | ||
124 | |||
125 | /* send the actual data */ | ||
126 | i2c_writebytes(state,0x36,data,len); | ||
127 | |||
128 | /* toggle the multireg write bit*/ | ||
129 | buf = 0x02; | ||
130 | i2c_writebytes(state,0x21,&buf,1); | ||
131 | |||
132 | i2c_readbytes(state,0x21,&buf,1); | ||
133 | |||
134 | if ((buf & 0x02) == 0) | ||
135 | return 0; | ||
136 | |||
137 | dprintk("Error writing multireg register %02X\n",reg); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int nxt2002_readreg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len) | ||
143 | { | ||
144 | u8 len2; | ||
145 | dprintk("%s\n", __FUNCTION__); | ||
146 | |||
147 | /* set multi register length */ | ||
148 | len2 = len & 0x80; | ||
149 | i2c_writebytes(state,0x34,&len2,1); | ||
150 | |||
151 | /* set mutli register register */ | ||
152 | i2c_writebytes(state,0x35,®,1); | ||
153 | |||
154 | /* send the actual data */ | ||
155 | i2c_readbytes(state,reg,data,len); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static void nxt2002_microcontroller_stop (struct nxt2002_state* state) | ||
161 | { | ||
162 | u8 buf[2],counter = 0; | ||
163 | dprintk("%s\n", __FUNCTION__); | ||
164 | |||
165 | buf[0] = 0x80; | ||
166 | i2c_writebytes(state,0x22,buf,1); | ||
167 | |||
168 | while (counter < 20) { | ||
169 | i2c_readbytes(state,0x31,buf,1); | ||
170 | if (buf[0] & 0x40) | ||
171 | return; | ||
172 | msleep(10); | ||
173 | counter++; | ||
174 | } | ||
175 | |||
176 | dprintk("Timeout waiting for micro to stop.. This is ok after firmware upload\n"); | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | static void nxt2002_microcontroller_start (struct nxt2002_state* state) | ||
181 | { | ||
182 | u8 buf; | ||
183 | dprintk("%s\n", __FUNCTION__); | ||
184 | |||
185 | buf = 0x00; | ||
186 | i2c_writebytes(state,0x22,&buf,1); | ||
187 | } | ||
188 | |||
189 | static int nxt2002_writetuner (struct nxt2002_state* state, u8* data) | ||
190 | { | ||
191 | u8 buf,count = 0; | ||
192 | |||
193 | dprintk("Tuner Bytes: %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3]); | ||
194 | |||
195 | dprintk("%s\n", __FUNCTION__); | ||
196 | /* stop the micro first */ | ||
197 | nxt2002_microcontroller_stop(state); | ||
198 | |||
199 | /* set the i2c transfer speed to the tuner */ | ||
200 | buf = 0x03; | ||
201 | i2c_writebytes(state,0x20,&buf,1); | ||
202 | |||
203 | /* setup to transfer 4 bytes via i2c */ | ||
204 | buf = 0x04; | ||
205 | i2c_writebytes(state,0x34,&buf,1); | ||
206 | |||
207 | /* write actual tuner bytes */ | ||
208 | i2c_writebytes(state,0x36,data,4); | ||
209 | |||
210 | /* set tuner i2c address */ | ||
211 | buf = 0xC2; | ||
212 | i2c_writebytes(state,0x35,&buf,1); | ||
213 | |||
214 | /* write UC Opmode to begin transfer */ | ||
215 | buf = 0x80; | ||
216 | i2c_writebytes(state,0x21,&buf,1); | ||
217 | |||
218 | while (count < 20) { | ||
219 | i2c_readbytes(state,0x21,&buf,1); | ||
220 | if ((buf & 0x80)== 0x00) | ||
221 | return 0; | ||
222 | msleep(100); | ||
223 | count++; | ||
224 | } | ||
225 | |||
226 | printk("nxt2002: timeout error writing tuner\n"); | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static void nxt2002_agc_reset(struct nxt2002_state* state) | ||
231 | { | ||
232 | u8 buf; | ||
233 | dprintk("%s\n", __FUNCTION__); | ||
234 | |||
235 | buf = 0x08; | ||
236 | i2c_writebytes(state,0x08,&buf,1); | ||
237 | |||
238 | buf = 0x00; | ||
239 | i2c_writebytes(state,0x08,&buf,1); | ||
240 | |||
241 | return; | ||
242 | } | ||
243 | |||
244 | static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) | ||
245 | { | ||
246 | |||
247 | struct nxt2002_state* state = fe->demodulator_priv; | ||
248 | u8 buf[256],written = 0,chunkpos = 0; | ||
249 | u16 rambase,position,crc = 0; | ||
250 | |||
251 | dprintk("%s\n", __FUNCTION__); | ||
252 | dprintk("Firmware is %zu bytes\n",fw->size); | ||
253 | |||
254 | /* Get the RAM base for this nxt2002 */ | ||
255 | i2c_readbytes(state,0x10,buf,1); | ||
256 | |||
257 | if (buf[0] & 0x10) | ||
258 | rambase = 0x1000; | ||
259 | else | ||
260 | rambase = 0x0000; | ||
261 | |||
262 | dprintk("rambase on this nxt2002 is %04X\n",rambase); | ||
263 | |||
264 | /* Hold the micro in reset while loading firmware */ | ||
265 | buf[0] = 0x80; | ||
266 | i2c_writebytes(state,0x2B,buf,1); | ||
267 | |||
268 | for (position = 0; position < fw->size ; position++) { | ||
269 | if (written == 0) { | ||
270 | crc = 0; | ||
271 | chunkpos = 0x28; | ||
272 | buf[0] = ((rambase + position) >> 8); | ||
273 | buf[1] = (rambase + position) & 0xFF; | ||
274 | buf[2] = 0x81; | ||
275 | /* write starting address */ | ||
276 | i2c_writebytes(state,0x29,buf,3); | ||
277 | } | ||
278 | written++; | ||
279 | chunkpos++; | ||
280 | |||
281 | if ((written % 4) == 0) | ||
282 | i2c_writebytes(state,chunkpos,&fw->data[position-3],4); | ||
283 | |||
284 | crc = nxt2002_crc(crc,fw->data[position]); | ||
285 | |||
286 | if ((written == 255) || (position+1 == fw->size)) { | ||
287 | /* write remaining bytes of firmware */ | ||
288 | i2c_writebytes(state, chunkpos+4-(written %4), | ||
289 | &fw->data[position-(written %4) + 1], | ||
290 | written %4); | ||
291 | buf[0] = crc << 8; | ||
292 | buf[1] = crc & 0xFF; | ||
293 | |||
294 | /* write crc */ | ||
295 | i2c_writebytes(state,0x2C,buf,2); | ||
296 | |||
297 | /* do a read to stop things */ | ||
298 | i2c_readbytes(state,0x2A,buf,1); | ||
299 | |||
300 | /* set transfer mode to complete */ | ||
301 | buf[0] = 0x80; | ||
302 | i2c_writebytes(state,0x2B,buf,1); | ||
303 | |||
304 | written = 0; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | printk ("done.\n"); | ||
309 | return 0; | ||
310 | }; | ||
311 | |||
312 | static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe, | ||
313 | struct dvb_frontend_parameters *p) | ||
314 | { | ||
315 | struct nxt2002_state* state = fe->demodulator_priv; | ||
316 | u32 freq = 0; | ||
317 | u16 tunerfreq = 0; | ||
318 | u8 buf[4]; | ||
319 | |||
320 | freq = 44000 + ( p->frequency / 1000 ); | ||
321 | |||
322 | dprintk("freq = %d p->frequency = %d\n",freq,p->frequency); | ||
323 | |||
324 | tunerfreq = freq * 24/4000; | ||
325 | |||
326 | buf[0] = (tunerfreq >> 8) & 0x7F; | ||
327 | buf[1] = (tunerfreq & 0xFF); | ||
328 | |||
329 | if (p->frequency <= 214000000) { | ||
330 | buf[2] = 0x84 + (0x06 << 3); | ||
331 | buf[3] = (p->frequency <= 172000000) ? 0x01 : 0x02; | ||
332 | } else if (p->frequency <= 721000000) { | ||
333 | buf[2] = 0x84 + (0x07 << 3); | ||
334 | buf[3] = (p->frequency <= 467000000) ? 0x02 : 0x08; | ||
335 | } else if (p->frequency <= 841000000) { | ||
336 | buf[2] = 0x84 + (0x0E << 3); | ||
337 | buf[3] = 0x08; | ||
338 | } else { | ||
339 | buf[2] = 0x84 + (0x0F << 3); | ||
340 | buf[3] = 0x02; | ||
341 | } | ||
342 | |||
343 | /* write frequency information */ | ||
344 | nxt2002_writetuner(state,buf); | ||
345 | |||
346 | /* reset the agc now that tuning has been completed */ | ||
347 | nxt2002_agc_reset(state); | ||
348 | |||
349 | /* set target power level */ | ||
350 | switch (p->u.vsb.modulation) { | ||
351 | case QAM_64: | ||
352 | case QAM_256: | ||
353 | buf[0] = 0x74; | ||
354 | break; | ||
355 | case VSB_8: | ||
356 | buf[0] = 0x70; | ||
357 | break; | ||
358 | default: | ||
359 | return -EINVAL; | ||
360 | break; | ||
361 | } | ||
362 | i2c_writebytes(state,0x42,buf,1); | ||
363 | |||
364 | /* configure sdm */ | ||
365 | buf[0] = 0x87; | ||
366 | i2c_writebytes(state,0x57,buf,1); | ||
367 | |||
368 | /* write sdm1 input */ | ||
369 | buf[0] = 0x10; | ||
370 | buf[1] = 0x00; | ||
371 | nxt2002_writereg_multibyte(state,0x58,buf,2); | ||
372 | |||
373 | /* write sdmx input */ | ||
374 | switch (p->u.vsb.modulation) { | ||
375 | case QAM_64: | ||
376 | buf[0] = 0x68; | ||
377 | break; | ||
378 | case QAM_256: | ||
379 | buf[0] = 0x64; | ||
380 | break; | ||
381 | case VSB_8: | ||
382 | buf[0] = 0x60; | ||
383 | break; | ||
384 | default: | ||
385 | return -EINVAL; | ||
386 | break; | ||
387 | } | ||
388 | buf[1] = 0x00; | ||
389 | nxt2002_writereg_multibyte(state,0x5C,buf,2); | ||
390 | |||
391 | /* write adc power lpf fc */ | ||
392 | buf[0] = 0x05; | ||
393 | i2c_writebytes(state,0x43,buf,1); | ||
394 | |||
395 | /* write adc power lpf fc */ | ||
396 | buf[0] = 0x05; | ||
397 | i2c_writebytes(state,0x43,buf,1); | ||
398 | |||
399 | /* write accumulator2 input */ | ||
400 | buf[0] = 0x80; | ||
401 | buf[1] = 0x00; | ||
402 | nxt2002_writereg_multibyte(state,0x4B,buf,2); | ||
403 | |||
404 | /* write kg1 */ | ||
405 | buf[0] = 0x00; | ||
406 | i2c_writebytes(state,0x4D,buf,1); | ||
407 | |||
408 | /* write sdm12 lpf fc */ | ||
409 | buf[0] = 0x44; | ||
410 | i2c_writebytes(state,0x55,buf,1); | ||
411 | |||
412 | /* write agc control reg */ | ||
413 | buf[0] = 0x04; | ||
414 | i2c_writebytes(state,0x41,buf,1); | ||
415 | |||
416 | /* write agc ucgp0 */ | ||
417 | switch (p->u.vsb.modulation) { | ||
418 | case QAM_64: | ||
419 | buf[0] = 0x02; | ||
420 | break; | ||
421 | case QAM_256: | ||
422 | buf[0] = 0x03; | ||
423 | break; | ||
424 | case VSB_8: | ||
425 | buf[0] = 0x00; | ||
426 | break; | ||
427 | default: | ||
428 | return -EINVAL; | ||
429 | break; | ||
430 | } | ||
431 | i2c_writebytes(state,0x30,buf,1); | ||
432 | |||
433 | /* write agc control reg */ | ||
434 | buf[0] = 0x00; | ||
435 | i2c_writebytes(state,0x41,buf,1); | ||
436 | |||
437 | /* write accumulator2 input */ | ||
438 | buf[0] = 0x80; | ||
439 | buf[1] = 0x00; | ||
440 | nxt2002_writereg_multibyte(state,0x49,buf,2); | ||
441 | nxt2002_writereg_multibyte(state,0x4B,buf,2); | ||
442 | |||
443 | /* write agc control reg */ | ||
444 | buf[0] = 0x04; | ||
445 | i2c_writebytes(state,0x41,buf,1); | ||
446 | |||
447 | nxt2002_microcontroller_start(state); | ||
448 | |||
449 | /* adjacent channel detection should be done here, but I don't | ||
450 | have any stations with this need so I cannot test it */ | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
456 | { | ||
457 | struct nxt2002_state* state = fe->demodulator_priv; | ||
458 | u8 lock; | ||
459 | i2c_readbytes(state,0x31,&lock,1); | ||
460 | |||
461 | *status = 0; | ||
462 | if (lock & 0x20) { | ||
463 | *status |= FE_HAS_SIGNAL; | ||
464 | *status |= FE_HAS_CARRIER; | ||
465 | *status |= FE_HAS_VITERBI; | ||
466 | *status |= FE_HAS_SYNC; | ||
467 | *status |= FE_HAS_LOCK; | ||
468 | } | ||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber) | ||
473 | { | ||
474 | struct nxt2002_state* state = fe->demodulator_priv; | ||
475 | u8 b[3]; | ||
476 | |||
477 | nxt2002_readreg_multibyte(state,0xE6,b,3); | ||
478 | |||
479 | *ber = ((b[0] << 8) + b[1]) * 8; | ||
480 | |||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
485 | { | ||
486 | struct nxt2002_state* state = fe->demodulator_priv; | ||
487 | u8 b[2]; | ||
488 | u16 temp = 0; | ||
489 | |||
490 | /* setup to read cluster variance */ | ||
491 | b[0] = 0x00; | ||
492 | i2c_writebytes(state,0xA1,b,1); | ||
493 | |||
494 | /* get multreg val */ | ||
495 | nxt2002_readreg_multibyte(state,0xA6,b,2); | ||
496 | |||
497 | temp = (b[0] << 8) | b[1]; | ||
498 | *strength = ((0x7FFF - temp) & 0x0FFF) * 16; | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr) | ||
504 | { | ||
505 | |||
506 | struct nxt2002_state* state = fe->demodulator_priv; | ||
507 | u8 b[2]; | ||
508 | u16 temp = 0, temp2; | ||
509 | u32 snrdb = 0; | ||
510 | |||
511 | /* setup to read cluster variance */ | ||
512 | b[0] = 0x00; | ||
513 | i2c_writebytes(state,0xA1,b,1); | ||
514 | |||
515 | /* get multreg val from 0xA6 */ | ||
516 | nxt2002_readreg_multibyte(state,0xA6,b,2); | ||
517 | |||
518 | temp = (b[0] << 8) | b[1]; | ||
519 | temp2 = 0x7FFF - temp; | ||
520 | |||
521 | /* snr will be in db */ | ||
522 | if (temp2 > 0x7F00) | ||
523 | snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) ); | ||
524 | else if (temp2 > 0x7EC0) | ||
525 | snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) ); | ||
526 | else if (temp2 > 0x7C00) | ||
527 | snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) ); | ||
528 | else | ||
529 | snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) ); | ||
530 | |||
531 | /* the value reported back from the frontend will be FFFF=32db 0000=0db */ | ||
532 | |||
533 | *snr = snrdb * (0xFFFF/32000); | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
539 | { | ||
540 | struct nxt2002_state* state = fe->demodulator_priv; | ||
541 | u8 b[3]; | ||
542 | |||
543 | nxt2002_readreg_multibyte(state,0xE6,b,3); | ||
544 | *ucblocks = b[2]; | ||
545 | |||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | static int nxt2002_sleep(struct dvb_frontend* fe) | ||
550 | { | ||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | static int nxt2002_init(struct dvb_frontend* fe) | ||
555 | { | ||
556 | struct nxt2002_state* state = fe->demodulator_priv; | ||
557 | const struct firmware *fw; | ||
558 | int ret; | ||
559 | u8 buf[2]; | ||
560 | |||
561 | if (!state->initialised) { | ||
562 | /* request the firmware, this will block until someone uploads it */ | ||
563 | printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE); | ||
564 | ret = state->config->request_firmware(fe, &fw, NXT2002_DEFAULT_FIRMWARE); | ||
565 | printk("nxt2002: Waiting for firmware upload(2)...\n"); | ||
566 | if (ret) { | ||
567 | printk("nxt2002: no firmware upload (timeout or file not found?)\n"); | ||
568 | return ret; | ||
569 | } | ||
570 | |||
571 | ret = nxt2002_load_firmware(fe, fw); | ||
572 | if (ret) { | ||
573 | printk("nxt2002: writing firmware to device failed\n"); | ||
574 | release_firmware(fw); | ||
575 | return ret; | ||
576 | } | ||
577 | printk("nxt2002: firmware upload complete\n"); | ||
578 | |||
579 | /* Put the micro into reset */ | ||
580 | nxt2002_microcontroller_stop(state); | ||
581 | |||
582 | /* ensure transfer is complete */ | ||
583 | buf[0]=0; | ||
584 | i2c_writebytes(state,0x2B,buf,1); | ||
585 | |||
586 | /* Put the micro into reset for real this time */ | ||
587 | nxt2002_microcontroller_stop(state); | ||
588 | |||
589 | /* soft reset everything (agc,frontend,eq,fec)*/ | ||
590 | buf[0] = 0x0F; | ||
591 | i2c_writebytes(state,0x08,buf,1); | ||
592 | buf[0] = 0x00; | ||
593 | i2c_writebytes(state,0x08,buf,1); | ||
594 | |||
595 | /* write agc sdm configure */ | ||
596 | buf[0] = 0xF1; | ||
597 | i2c_writebytes(state,0x57,buf,1); | ||
598 | |||
599 | /* write mod output format */ | ||
600 | buf[0] = 0x20; | ||
601 | i2c_writebytes(state,0x09,buf,1); | ||
602 | |||
603 | /* write fec mpeg mode */ | ||
604 | buf[0] = 0x7E; | ||
605 | buf[1] = 0x00; | ||
606 | i2c_writebytes(state,0xE9,buf,2); | ||
607 | |||
608 | /* write mux selection */ | ||
609 | buf[0] = 0x00; | ||
610 | i2c_writebytes(state,0xCC,buf,1); | ||
611 | |||
612 | state->initialised = 1; | ||
613 | } | ||
614 | |||
615 | return 0; | ||
616 | } | ||
617 | |||
618 | static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | ||
619 | { | ||
620 | fesettings->min_delay_ms = 500; | ||
621 | fesettings->step_size = 0; | ||
622 | fesettings->max_drift = 0; | ||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static void nxt2002_release(struct dvb_frontend* fe) | ||
627 | { | ||
628 | struct nxt2002_state* state = fe->demodulator_priv; | ||
629 | kfree(state); | ||
630 | } | ||
631 | |||
632 | static struct dvb_frontend_ops nxt2002_ops; | ||
633 | |||
634 | struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config, | ||
635 | struct i2c_adapter* i2c) | ||
636 | { | ||
637 | struct nxt2002_state* state = NULL; | ||
638 | u8 buf [] = {0,0,0,0,0}; | ||
639 | |||
640 | /* allocate memory for the internal state */ | ||
641 | state = kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL); | ||
642 | if (state == NULL) goto error; | ||
643 | |||
644 | /* setup the state */ | ||
645 | state->config = config; | ||
646 | state->i2c = i2c; | ||
647 | memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops)); | ||
648 | state->initialised = 0; | ||
649 | |||
650 | /* Check the first 5 registers to ensure this a revision we can handle */ | ||
651 | |||
652 | i2c_readbytes(state, 0x00, buf, 5); | ||
653 | if (buf[0] != 0x04) goto error; /* device id */ | ||
654 | if (buf[1] != 0x02) goto error; /* fab id */ | ||
655 | if (buf[2] != 0x11) goto error; /* month */ | ||
656 | if (buf[3] != 0x20) goto error; /* year msb */ | ||
657 | if (buf[4] != 0x00) goto error; /* year lsb */ | ||
658 | |||
659 | /* create dvb_frontend */ | ||
660 | state->frontend.ops = &state->ops; | ||
661 | state->frontend.demodulator_priv = state; | ||
662 | return &state->frontend; | ||
663 | |||
664 | error: | ||
665 | kfree(state); | ||
666 | return NULL; | ||
667 | } | ||
668 | |||
669 | static struct dvb_frontend_ops nxt2002_ops = { | ||
670 | |||
671 | .info = { | ||
672 | .name = "Nextwave nxt2002 VSB/QAM frontend", | ||
673 | .type = FE_ATSC, | ||
674 | .frequency_min = 54000000, | ||
675 | .frequency_max = 860000000, | ||
676 | /* stepsize is just a guess */ | ||
677 | .frequency_stepsize = 166666, | ||
678 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
679 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
680 | FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256 | ||
681 | }, | ||
682 | |||
683 | .release = nxt2002_release, | ||
684 | |||
685 | .init = nxt2002_init, | ||
686 | .sleep = nxt2002_sleep, | ||
687 | |||
688 | .set_frontend = nxt2002_setup_frontend_parameters, | ||
689 | .get_tune_settings = nxt2002_get_tune_settings, | ||
690 | |||
691 | .read_status = nxt2002_read_status, | ||
692 | .read_ber = nxt2002_read_ber, | ||
693 | .read_signal_strength = nxt2002_read_signal_strength, | ||
694 | .read_snr = nxt2002_read_snr, | ||
695 | .read_ucblocks = nxt2002_read_ucblocks, | ||
696 | |||
697 | }; | ||
698 | |||
699 | module_param(debug, int, 0644); | ||
700 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
701 | |||
702 | MODULE_DESCRIPTION("NXT2002 ATSC (8VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver"); | ||
703 | MODULE_AUTHOR("Taylor Jacob"); | ||
704 | MODULE_LICENSE("GPL"); | ||
705 | |||
706 | EXPORT_SYMBOL(nxt2002_attach); | ||
diff --git a/drivers/media/dvb/frontends/nxt2002.h b/drivers/media/dvb/frontends/nxt2002.h deleted file mode 100644 index 462301f577ee..000000000000 --- a/drivers/media/dvb/frontends/nxt2002.h +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | /* | ||
2 | Driver for the Nxt2002 demodulator | ||
3 | */ | ||
4 | |||
5 | #ifndef NXT2002_H | ||
6 | #define NXT2002_H | ||
7 | |||
8 | #include <linux/dvb/frontend.h> | ||
9 | #include <linux/firmware.h> | ||
10 | |||
11 | struct nxt2002_config | ||
12 | { | ||
13 | /* the demodulator's i2c address */ | ||
14 | u8 demod_address; | ||
15 | |||
16 | /* request firmware for device */ | ||
17 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | ||
18 | }; | ||
19 | |||
20 | extern struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config, | ||
21 | struct i2c_adapter* i2c); | ||
22 | |||
23 | #endif // NXT2002_H | ||
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c index 78d2b93d35b9..9e3535394509 100644 --- a/drivers/media/dvb/frontends/nxt200x.c +++ b/drivers/media/dvb/frontends/nxt200x.c | |||
@@ -1,9 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * Support for NXT2002 and NXT2004 - VSB/QAM | 2 | * Support for NXT2002 and NXT2004 - VSB/QAM |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com) | 4 | * Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com> |
5 | * Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net> | ||
5 | * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> | 6 | * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> |
6 | * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com) | 7 | * and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com> |
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
@@ -614,7 +615,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
614 | /* write sdm1 input */ | 615 | /* write sdm1 input */ |
615 | buf[0] = 0x10; | 616 | buf[0] = 0x10; |
616 | buf[1] = 0x00; | 617 | buf[1] = 0x00; |
617 | nxt200x_writebytes(state, 0x58, buf, 2); | 618 | switch (state->demod_chip) { |
619 | case NXT2002: | ||
620 | nxt200x_writereg_multibyte(state, 0x58, buf, 2); | ||
621 | break; | ||
622 | case NXT2004: | ||
623 | nxt200x_writebytes(state, 0x58, buf, 2); | ||
624 | break; | ||
625 | default: | ||
626 | return -EINVAL; | ||
627 | break; | ||
628 | } | ||
618 | 629 | ||
619 | /* write sdmx input */ | 630 | /* write sdmx input */ |
620 | switch (p->u.vsb.modulation) { | 631 | switch (p->u.vsb.modulation) { |
@@ -632,7 +643,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
632 | break; | 643 | break; |
633 | } | 644 | } |
634 | buf[1] = 0x00; | 645 | buf[1] = 0x00; |
635 | nxt200x_writebytes(state, 0x5C, buf, 2); | 646 | switch (state->demod_chip) { |
647 | case NXT2002: | ||
648 | nxt200x_writereg_multibyte(state, 0x5C, buf, 2); | ||
649 | break; | ||
650 | case NXT2004: | ||
651 | nxt200x_writebytes(state, 0x5C, buf, 2); | ||
652 | break; | ||
653 | default: | ||
654 | return -EINVAL; | ||
655 | break; | ||
656 | } | ||
636 | 657 | ||
637 | /* write adc power lpf fc */ | 658 | /* write adc power lpf fc */ |
638 | buf[0] = 0x05; | 659 | buf[0] = 0x05; |
@@ -648,7 +669,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
648 | /* write accumulator2 input */ | 669 | /* write accumulator2 input */ |
649 | buf[0] = 0x80; | 670 | buf[0] = 0x80; |
650 | buf[1] = 0x00; | 671 | buf[1] = 0x00; |
651 | nxt200x_writebytes(state, 0x4B, buf, 2); | 672 | switch (state->demod_chip) { |
673 | case NXT2002: | ||
674 | nxt200x_writereg_multibyte(state, 0x4B, buf, 2); | ||
675 | break; | ||
676 | case NXT2004: | ||
677 | nxt200x_writebytes(state, 0x4B, buf, 2); | ||
678 | break; | ||
679 | default: | ||
680 | return -EINVAL; | ||
681 | break; | ||
682 | } | ||
652 | 683 | ||
653 | /* write kg1 */ | 684 | /* write kg1 */ |
654 | buf[0] = 0x00; | 685 | buf[0] = 0x00; |
@@ -714,8 +745,19 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
714 | /* write accumulator2 input */ | 745 | /* write accumulator2 input */ |
715 | buf[0] = 0x80; | 746 | buf[0] = 0x80; |
716 | buf[1] = 0x00; | 747 | buf[1] = 0x00; |
717 | nxt200x_writebytes(state, 0x49, buf,2); | 748 | switch (state->demod_chip) { |
718 | nxt200x_writebytes(state, 0x4B, buf,2); | 749 | case NXT2002: |
750 | nxt200x_writereg_multibyte(state, 0x49, buf, 2); | ||
751 | nxt200x_writereg_multibyte(state, 0x4B, buf, 2); | ||
752 | break; | ||
753 | case NXT2004: | ||
754 | nxt200x_writebytes(state, 0x49, buf, 2); | ||
755 | nxt200x_writebytes(state, 0x4B, buf, 2); | ||
756 | break; | ||
757 | default: | ||
758 | return -EINVAL; | ||
759 | break; | ||
760 | } | ||
719 | 761 | ||
720 | /* write agc control reg */ | 762 | /* write agc control reg */ |
721 | buf[0] = 0x04; | 763 | buf[0] = 0x04; |
@@ -1199,7 +1241,7 @@ module_param(debug, int, 0644); | |||
1199 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | 1241 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); |
1200 | 1242 | ||
1201 | MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); | 1243 | MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); |
1202 | MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob"); | 1244 | MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob"); |
1203 | MODULE_LICENSE("GPL"); | 1245 | MODULE_LICENSE("GPL"); |
1204 | 1246 | ||
1205 | EXPORT_SYMBOL(nxt200x_attach); | 1247 | EXPORT_SYMBOL(nxt200x_attach); |
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c index 6122ba754bc5..eb15676d374f 100644 --- a/drivers/media/dvb/frontends/stv0297.c +++ b/drivers/media/dvb/frontends/stv0297.c | |||
@@ -393,10 +393,6 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
393 | break; | 393 | break; |
394 | 394 | ||
395 | case QAM_128: | 395 | case QAM_128: |
396 | delay = 150; | ||
397 | sweeprate = 1000; | ||
398 | break; | ||
399 | |||
400 | case QAM_256: | 396 | case QAM_256: |
401 | delay = 200; | 397 | delay = 200; |
402 | sweeprate = 500; | 398 | sweeprate = 500; |
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c deleted file mode 100644 index d1cabb6a0a13..000000000000 --- a/drivers/media/dvb/frontends/tda80xx.c +++ /dev/null | |||
@@ -1,734 +0,0 @@ | |||
1 | /* | ||
2 | * tda80xx.c | ||
3 | * | ||
4 | * Philips TDA8044 / TDA8083 QPSK demodulator driver | ||
5 | * | ||
6 | * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net> | ||
7 | * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/config.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/threads.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <asm/irq.h> | ||
34 | #include <asm/div64.h> | ||
35 | |||
36 | #include "dvb_frontend.h" | ||
37 | #include "tda80xx.h" | ||
38 | |||
39 | enum { | ||
40 | ID_TDA8044 = 0x04, | ||
41 | ID_TDA8083 = 0x05, | ||
42 | }; | ||
43 | |||
44 | |||
45 | struct tda80xx_state { | ||
46 | |||
47 | struct i2c_adapter* i2c; | ||
48 | |||
49 | struct dvb_frontend_ops ops; | ||
50 | |||
51 | /* configuration settings */ | ||
52 | const struct tda80xx_config* config; | ||
53 | |||
54 | struct dvb_frontend frontend; | ||
55 | |||
56 | u32 clk; | ||
57 | int afc_loop; | ||
58 | struct work_struct worklet; | ||
59 | fe_code_rate_t code_rate; | ||
60 | fe_spectral_inversion_t spectral_inversion; | ||
61 | fe_status_t status; | ||
62 | u8 id; | ||
63 | }; | ||
64 | |||
65 | static int debug = 1; | ||
66 | #define dprintk if (debug) printk | ||
67 | |||
68 | static u8 tda8044_inittab_pre[] = { | ||
69 | 0x02, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea, | ||
70 | 0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x58, | ||
71 | 0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68, | ||
72 | 0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x00, | ||
73 | 0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
74 | 0x00, 0x00 | ||
75 | }; | ||
76 | |||
77 | static u8 tda8044_inittab_post[] = { | ||
78 | 0x04, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea, | ||
79 | 0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x50, | ||
80 | 0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68, | ||
81 | 0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x6c, | ||
82 | 0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
83 | 0x00, 0x00 | ||
84 | }; | ||
85 | |||
86 | static u8 tda8083_inittab[] = { | ||
87 | 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea, | ||
88 | 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10, | ||
89 | 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8, | ||
90 | 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00, | ||
91 | 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, | ||
92 | 0x00, 0x00, 0x00, 0x00 | ||
93 | }; | ||
94 | |||
95 | static __inline__ u32 tda80xx_div(u32 a, u32 b) | ||
96 | { | ||
97 | return (a + (b / 2)) / b; | ||
98 | } | ||
99 | |||
100 | static __inline__ u32 tda80xx_gcd(u32 a, u32 b) | ||
101 | { | ||
102 | u32 r; | ||
103 | |||
104 | while ((r = a % b)) { | ||
105 | a = b; | ||
106 | b = r; | ||
107 | } | ||
108 | |||
109 | return b; | ||
110 | } | ||
111 | |||
112 | static int tda80xx_read(struct tda80xx_state* state, u8 reg, u8 *buf, u8 len) | ||
113 | { | ||
114 | int ret; | ||
115 | struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 }, | ||
116 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } }; | ||
117 | |||
118 | ret = i2c_transfer(state->i2c, msg, 2); | ||
119 | |||
120 | if (ret != 2) | ||
121 | dprintk("%s: readreg error (reg %02x, ret == %i)\n", | ||
122 | __FUNCTION__, reg, ret); | ||
123 | |||
124 | mdelay(10); | ||
125 | |||
126 | return (ret == 2) ? 0 : -EREMOTEIO; | ||
127 | } | ||
128 | |||
129 | static int tda80xx_write(struct tda80xx_state* state, u8 reg, const u8 *buf, u8 len) | ||
130 | { | ||
131 | int ret; | ||
132 | u8 wbuf[len + 1]; | ||
133 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = wbuf, .len = len + 1 }; | ||
134 | |||
135 | wbuf[0] = reg; | ||
136 | memcpy(&wbuf[1], buf, len); | ||
137 | |||
138 | ret = i2c_transfer(state->i2c, &msg, 1); | ||
139 | |||
140 | if (ret != 1) | ||
141 | dprintk("%s: i2c xfer error (ret == %i)\n", __FUNCTION__, ret); | ||
142 | |||
143 | mdelay(10); | ||
144 | |||
145 | return (ret == 1) ? 0 : -EREMOTEIO; | ||
146 | } | ||
147 | |||
148 | static __inline__ u8 tda80xx_readreg(struct tda80xx_state* state, u8 reg) | ||
149 | { | ||
150 | u8 val; | ||
151 | |||
152 | tda80xx_read(state, reg, &val, 1); | ||
153 | |||
154 | return val; | ||
155 | } | ||
156 | |||
157 | static __inline__ int tda80xx_writereg(struct tda80xx_state* state, u8 reg, u8 data) | ||
158 | { | ||
159 | return tda80xx_write(state, reg, &data, 1); | ||
160 | } | ||
161 | |||
162 | static int tda80xx_set_parameters(struct tda80xx_state* state, | ||
163 | fe_spectral_inversion_t inversion, | ||
164 | u32 symbol_rate, | ||
165 | fe_code_rate_t fec_inner) | ||
166 | { | ||
167 | u8 buf[15]; | ||
168 | u64 ratio; | ||
169 | u32 clk; | ||
170 | u32 k; | ||
171 | u32 sr = symbol_rate; | ||
172 | u32 gcd; | ||
173 | u8 scd; | ||
174 | |||
175 | if (symbol_rate > (state->clk * 3) / 16) | ||
176 | scd = 0; | ||
177 | else if (symbol_rate > (state->clk * 3) / 32) | ||
178 | scd = 1; | ||
179 | else if (symbol_rate > (state->clk * 3) / 64) | ||
180 | scd = 2; | ||
181 | else | ||
182 | scd = 3; | ||
183 | |||
184 | clk = scd ? (state->clk / (scd * 2)) : state->clk; | ||
185 | |||
186 | /* | ||
187 | * Viterbi decoder: | ||
188 | * Differential decoding off | ||
189 | * Spectral inversion unknown | ||
190 | * QPSK modulation | ||
191 | */ | ||
192 | if (inversion == INVERSION_ON) | ||
193 | buf[0] = 0x60; | ||
194 | else if (inversion == INVERSION_OFF) | ||
195 | buf[0] = 0x20; | ||
196 | else | ||
197 | buf[0] = 0x00; | ||
198 | |||
199 | /* | ||
200 | * CLK ratio: | ||
201 | * system clock frequency is up to 64 or 96 MHz | ||
202 | * | ||
203 | * formula: | ||
204 | * r = k * clk / symbol_rate | ||
205 | * | ||
206 | * k: 2^21 for caa 0..3, | ||
207 | * 2^20 for caa 4..5, | ||
208 | * 2^19 for caa 6..7 | ||
209 | */ | ||
210 | if (symbol_rate <= (clk * 3) / 32) | ||
211 | k = (1 << 19); | ||
212 | else if (symbol_rate <= (clk * 3) / 16) | ||
213 | k = (1 << 20); | ||
214 | else | ||
215 | k = (1 << 21); | ||
216 | |||
217 | gcd = tda80xx_gcd(clk, sr); | ||
218 | clk /= gcd; | ||
219 | sr /= gcd; | ||
220 | |||
221 | gcd = tda80xx_gcd(k, sr); | ||
222 | k /= gcd; | ||
223 | sr /= gcd; | ||
224 | |||
225 | ratio = (u64)k * (u64)clk; | ||
226 | do_div(ratio, sr); | ||
227 | |||
228 | buf[1] = ratio >> 16; | ||
229 | buf[2] = ratio >> 8; | ||
230 | buf[3] = ratio; | ||
231 | |||
232 | /* nyquist filter roll-off factor 35% */ | ||
233 | buf[4] = 0x20; | ||
234 | |||
235 | clk = scd ? (state->clk / (scd * 2)) : state->clk; | ||
236 | |||
237 | /* Anti Alias Filter */ | ||
238 | if (symbol_rate < (clk * 3) / 64) | ||
239 | printk("tda80xx: unsupported symbol rate: %u\n", symbol_rate); | ||
240 | else if (symbol_rate <= clk / 16) | ||
241 | buf[4] |= 0x07; | ||
242 | else if (symbol_rate <= (clk * 3) / 32) | ||
243 | buf[4] |= 0x06; | ||
244 | else if (symbol_rate <= clk / 8) | ||
245 | buf[4] |= 0x05; | ||
246 | else if (symbol_rate <= (clk * 3) / 16) | ||
247 | buf[4] |= 0x04; | ||
248 | else if (symbol_rate <= clk / 4) | ||
249 | buf[4] |= 0x03; | ||
250 | else if (symbol_rate <= (clk * 3) / 8) | ||
251 | buf[4] |= 0x02; | ||
252 | else if (symbol_rate <= clk / 2) | ||
253 | buf[4] |= 0x01; | ||
254 | else | ||
255 | buf[4] |= 0x00; | ||
256 | |||
257 | /* Sigma Delta converter */ | ||
258 | buf[5] = 0x00; | ||
259 | |||
260 | /* FEC: Possible puncturing rates */ | ||
261 | if (fec_inner == FEC_NONE) | ||
262 | buf[6] = 0x00; | ||
263 | else if ((fec_inner >= FEC_1_2) && (fec_inner <= FEC_8_9)) | ||
264 | buf[6] = (1 << (8 - fec_inner)); | ||
265 | else if (fec_inner == FEC_AUTO) | ||
266 | buf[6] = 0xff; | ||
267 | else | ||
268 | return -EINVAL; | ||
269 | |||
270 | /* carrier lock detector threshold value */ | ||
271 | buf[7] = 0x30; | ||
272 | /* AFC1: proportional part settings */ | ||
273 | buf[8] = 0x42; | ||
274 | /* AFC1: integral part settings */ | ||
275 | buf[9] = 0x98; | ||
276 | /* PD: Leaky integrator SCPC mode */ | ||
277 | buf[10] = 0x28; | ||
278 | /* AFC2, AFC1 controls */ | ||
279 | buf[11] = 0x30; | ||
280 | /* PD: proportional part settings */ | ||
281 | buf[12] = 0x42; | ||
282 | /* PD: integral part settings */ | ||
283 | buf[13] = 0x99; | ||
284 | /* AGC */ | ||
285 | buf[14] = 0x50 | scd; | ||
286 | |||
287 | printk("symbol_rate=%u clk=%u\n", symbol_rate, clk); | ||
288 | |||
289 | return tda80xx_write(state, 0x01, buf, sizeof(buf)); | ||
290 | } | ||
291 | |||
292 | static int tda80xx_set_clk(struct tda80xx_state* state) | ||
293 | { | ||
294 | u8 buf[2]; | ||
295 | |||
296 | /* CLK proportional part */ | ||
297 | buf[0] = (0x06 << 5) | 0x08; /* CMP[2:0], CSP[4:0] */ | ||
298 | /* CLK integral part */ | ||
299 | buf[1] = (0x04 << 5) | 0x1a; /* CMI[2:0], CSI[4:0] */ | ||
300 | |||
301 | return tda80xx_write(state, 0x17, buf, sizeof(buf)); | ||
302 | } | ||
303 | |||
304 | #if 0 | ||
305 | static int tda80xx_set_scpc_freq_offset(struct tda80xx_state* state) | ||
306 | { | ||
307 | /* a constant value is nonsense here imho */ | ||
308 | return tda80xx_writereg(state, 0x22, 0xf9); | ||
309 | } | ||
310 | #endif | ||
311 | |||
312 | static int tda80xx_close_loop(struct tda80xx_state* state) | ||
313 | { | ||
314 | u8 buf[2]; | ||
315 | |||
316 | /* PD: Loop closed, LD: lock detect enable, SCPC: Sweep mode - AFC1 loop closed */ | ||
317 | buf[0] = 0x68; | ||
318 | /* AFC1: Loop closed, CAR Feedback: 8192 */ | ||
319 | buf[1] = 0x70; | ||
320 | |||
321 | return tda80xx_write(state, 0x0b, buf, sizeof(buf)); | ||
322 | } | ||
323 | |||
324 | static irqreturn_t tda80xx_irq(int irq, void *priv, struct pt_regs *pt) | ||
325 | { | ||
326 | schedule_work(priv); | ||
327 | |||
328 | return IRQ_HANDLED; | ||
329 | } | ||
330 | |||
331 | static void tda80xx_read_status_int(struct tda80xx_state* state) | ||
332 | { | ||
333 | u8 val; | ||
334 | |||
335 | static const fe_spectral_inversion_t inv_tab[] = { | ||
336 | INVERSION_OFF, INVERSION_ON | ||
337 | }; | ||
338 | |||
339 | static const fe_code_rate_t fec_tab[] = { | ||
340 | FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4, | ||
341 | FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8, | ||
342 | }; | ||
343 | |||
344 | val = tda80xx_readreg(state, 0x02); | ||
345 | |||
346 | state->status = 0; | ||
347 | |||
348 | if (val & 0x01) /* demodulator lock */ | ||
349 | state->status |= FE_HAS_SIGNAL; | ||
350 | if (val & 0x02) /* clock recovery lock */ | ||
351 | state->status |= FE_HAS_CARRIER; | ||
352 | if (val & 0x04) /* viterbi lock */ | ||
353 | state->status |= FE_HAS_VITERBI; | ||
354 | if (val & 0x08) /* deinterleaver lock (packet sync) */ | ||
355 | state->status |= FE_HAS_SYNC; | ||
356 | if (val & 0x10) /* derandomizer lock (frame sync) */ | ||
357 | state->status |= FE_HAS_LOCK; | ||
358 | if (val & 0x20) /* frontend can not lock */ | ||
359 | state->status |= FE_TIMEDOUT; | ||
360 | |||
361 | if ((state->status & (FE_HAS_CARRIER)) && (state->afc_loop)) { | ||
362 | printk("tda80xx: closing loop\n"); | ||
363 | tda80xx_close_loop(state); | ||
364 | state->afc_loop = 0; | ||
365 | } | ||
366 | |||
367 | if (state->status & (FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK)) { | ||
368 | val = tda80xx_readreg(state, 0x0e); | ||
369 | state->code_rate = fec_tab[val & 0x07]; | ||
370 | if (state->status & (FE_HAS_SYNC | FE_HAS_LOCK)) | ||
371 | state->spectral_inversion = inv_tab[(val >> 7) & 0x01]; | ||
372 | else | ||
373 | state->spectral_inversion = INVERSION_AUTO; | ||
374 | } | ||
375 | else { | ||
376 | state->code_rate = FEC_AUTO; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | static void tda80xx_worklet(void *priv) | ||
381 | { | ||
382 | struct tda80xx_state *state = priv; | ||
383 | |||
384 | tda80xx_writereg(state, 0x00, 0x04); | ||
385 | enable_irq(state->config->irq); | ||
386 | |||
387 | tda80xx_read_status_int(state); | ||
388 | } | ||
389 | |||
390 | static void tda80xx_wait_diseqc_fifo(struct tda80xx_state* state) | ||
391 | { | ||
392 | size_t i; | ||
393 | |||
394 | for (i = 0; i < 100; i++) { | ||
395 | if (tda80xx_readreg(state, 0x02) & 0x80) | ||
396 | break; | ||
397 | msleep(10); | ||
398 | } | ||
399 | } | ||
400 | |||
401 | static int tda8044_init(struct dvb_frontend* fe) | ||
402 | { | ||
403 | struct tda80xx_state* state = fe->demodulator_priv; | ||
404 | int ret; | ||
405 | |||
406 | /* | ||
407 | * this function is a mess... | ||
408 | */ | ||
409 | |||
410 | if ((ret = tda80xx_write(state, 0x00, tda8044_inittab_pre, sizeof(tda8044_inittab_pre)))) | ||
411 | return ret; | ||
412 | |||
413 | tda80xx_writereg(state, 0x0f, 0x50); | ||
414 | #if 1 | ||
415 | tda80xx_writereg(state, 0x20, 0x8F); /* FIXME */ | ||
416 | tda80xx_writereg(state, 0x20, state->config->volt18setting); /* FIXME */ | ||
417 | //tda80xx_writereg(state, 0x00, 0x04); | ||
418 | tda80xx_writereg(state, 0x00, 0x0C); | ||
419 | #endif | ||
420 | //tda80xx_writereg(state, 0x00, 0x08); /* Reset AFC1 loop filter */ | ||
421 | |||
422 | tda80xx_write(state, 0x00, tda8044_inittab_post, sizeof(tda8044_inittab_post)); | ||
423 | |||
424 | if (state->config->pll_init) { | ||
425 | tda80xx_writereg(state, 0x1c, 0x80); | ||
426 | state->config->pll_init(fe); | ||
427 | tda80xx_writereg(state, 0x1c, 0x00); | ||
428 | } | ||
429 | |||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static int tda8083_init(struct dvb_frontend* fe) | ||
434 | { | ||
435 | struct tda80xx_state* state = fe->demodulator_priv; | ||
436 | |||
437 | tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab)); | ||
438 | |||
439 | if (state->config->pll_init) { | ||
440 | tda80xx_writereg(state, 0x1c, 0x80); | ||
441 | state->config->pll_init(fe); | ||
442 | tda80xx_writereg(state, 0x1c, 0x00); | ||
443 | } | ||
444 | |||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
449 | { | ||
450 | struct tda80xx_state* state = fe->demodulator_priv; | ||
451 | |||
452 | switch (voltage) { | ||
453 | case SEC_VOLTAGE_13: | ||
454 | return tda80xx_writereg(state, 0x20, state->config->volt13setting); | ||
455 | case SEC_VOLTAGE_18: | ||
456 | return tda80xx_writereg(state, 0x20, state->config->volt18setting); | ||
457 | case SEC_VOLTAGE_OFF: | ||
458 | return tda80xx_writereg(state, 0x20, 0); | ||
459 | default: | ||
460 | return -EINVAL; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
465 | { | ||
466 | struct tda80xx_state* state = fe->demodulator_priv; | ||
467 | |||
468 | switch (tone) { | ||
469 | case SEC_TONE_OFF: | ||
470 | return tda80xx_writereg(state, 0x29, 0x00); | ||
471 | case SEC_TONE_ON: | ||
472 | return tda80xx_writereg(state, 0x29, 0x80); | ||
473 | default: | ||
474 | return -EINVAL; | ||
475 | } | ||
476 | } | ||
477 | |||
478 | static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) | ||
479 | { | ||
480 | struct tda80xx_state* state = fe->demodulator_priv; | ||
481 | |||
482 | if (cmd->msg_len > 6) | ||
483 | return -EINVAL; | ||
484 | |||
485 | tda80xx_writereg(state, 0x29, 0x08 | (cmd->msg_len - 3)); | ||
486 | tda80xx_write(state, 0x23, cmd->msg, cmd->msg_len); | ||
487 | tda80xx_writereg(state, 0x29, 0x0c | (cmd->msg_len - 3)); | ||
488 | tda80xx_wait_diseqc_fifo(state); | ||
489 | |||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd) | ||
494 | { | ||
495 | struct tda80xx_state* state = fe->demodulator_priv; | ||
496 | |||
497 | switch (cmd) { | ||
498 | case SEC_MINI_A: | ||
499 | tda80xx_writereg(state, 0x29, 0x14); | ||
500 | break; | ||
501 | case SEC_MINI_B: | ||
502 | tda80xx_writereg(state, 0x29, 0x1c); | ||
503 | break; | ||
504 | default: | ||
505 | return -EINVAL; | ||
506 | } | ||
507 | |||
508 | tda80xx_wait_diseqc_fifo(state); | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static int tda80xx_sleep(struct dvb_frontend* fe) | ||
514 | { | ||
515 | struct tda80xx_state* state = fe->demodulator_priv; | ||
516 | |||
517 | tda80xx_writereg(state, 0x00, 0x02); /* enter standby */ | ||
518 | |||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
523 | { | ||
524 | struct tda80xx_state* state = fe->demodulator_priv; | ||
525 | |||
526 | tda80xx_writereg(state, 0x1c, 0x80); | ||
527 | state->config->pll_set(fe, p); | ||
528 | tda80xx_writereg(state, 0x1c, 0x00); | ||
529 | |||
530 | tda80xx_set_parameters(state, p->inversion, p->u.qpsk.symbol_rate, p->u.qpsk.fec_inner); | ||
531 | tda80xx_set_clk(state); | ||
532 | //tda80xx_set_scpc_freq_offset(state); | ||
533 | state->afc_loop = 1; | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
539 | { | ||
540 | struct tda80xx_state* state = fe->demodulator_priv; | ||
541 | |||
542 | if (!state->config->irq) | ||
543 | tda80xx_read_status_int(state); | ||
544 | |||
545 | p->inversion = state->spectral_inversion; | ||
546 | p->u.qpsk.fec_inner = state->code_rate; | ||
547 | |||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
552 | { | ||
553 | struct tda80xx_state* state = fe->demodulator_priv; | ||
554 | |||
555 | if (!state->config->irq) | ||
556 | tda80xx_read_status_int(state); | ||
557 | *status = state->status; | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber) | ||
563 | { | ||
564 | struct tda80xx_state* state = fe->demodulator_priv; | ||
565 | int ret; | ||
566 | u8 buf[3]; | ||
567 | |||
568 | if ((ret = tda80xx_read(state, 0x0b, buf, sizeof(buf)))) | ||
569 | return ret; | ||
570 | |||
571 | *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2]; | ||
572 | |||
573 | return 0; | ||
574 | } | ||
575 | |||
576 | static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
577 | { | ||
578 | struct tda80xx_state* state = fe->demodulator_priv; | ||
579 | |||
580 | u8 gain = ~tda80xx_readreg(state, 0x01); | ||
581 | *strength = (gain << 8) | gain; | ||
582 | |||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr) | ||
587 | { | ||
588 | struct tda80xx_state* state = fe->demodulator_priv; | ||
589 | |||
590 | u8 quality = tda80xx_readreg(state, 0x08); | ||
591 | *snr = (quality << 8) | quality; | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
597 | { | ||
598 | struct tda80xx_state* state = fe->demodulator_priv; | ||
599 | |||
600 | *ucblocks = tda80xx_readreg(state, 0x0f); | ||
601 | if (*ucblocks == 0xff) | ||
602 | *ucblocks = 0xffffffff; | ||
603 | |||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | static int tda80xx_init(struct dvb_frontend* fe) | ||
608 | { | ||
609 | struct tda80xx_state* state = fe->demodulator_priv; | ||
610 | |||
611 | switch(state->id) { | ||
612 | case ID_TDA8044: | ||
613 | return tda8044_init(fe); | ||
614 | |||
615 | case ID_TDA8083: | ||
616 | return tda8083_init(fe); | ||
617 | } | ||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | static void tda80xx_release(struct dvb_frontend* fe) | ||
622 | { | ||
623 | struct tda80xx_state* state = fe->demodulator_priv; | ||
624 | |||
625 | if (state->config->irq) | ||
626 | free_irq(state->config->irq, &state->worklet); | ||
627 | |||
628 | kfree(state); | ||
629 | } | ||
630 | |||
631 | static struct dvb_frontend_ops tda80xx_ops; | ||
632 | |||
633 | struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config, | ||
634 | struct i2c_adapter* i2c) | ||
635 | { | ||
636 | struct tda80xx_state* state = NULL; | ||
637 | int ret; | ||
638 | |||
639 | /* allocate memory for the internal state */ | ||
640 | state = kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL); | ||
641 | if (state == NULL) goto error; | ||
642 | |||
643 | /* setup the state */ | ||
644 | state->config = config; | ||
645 | state->i2c = i2c; | ||
646 | memcpy(&state->ops, &tda80xx_ops, sizeof(struct dvb_frontend_ops)); | ||
647 | state->spectral_inversion = INVERSION_AUTO; | ||
648 | state->code_rate = FEC_AUTO; | ||
649 | state->status = 0; | ||
650 | state->afc_loop = 0; | ||
651 | |||
652 | /* check if the demod is there */ | ||
653 | if (tda80xx_writereg(state, 0x89, 0x00) < 0) goto error; | ||
654 | state->id = tda80xx_readreg(state, 0x00); | ||
655 | |||
656 | switch (state->id) { | ||
657 | case ID_TDA8044: | ||
658 | state->clk = 96000000; | ||
659 | printk("tda80xx: Detected tda8044\n"); | ||
660 | break; | ||
661 | |||
662 | case ID_TDA8083: | ||
663 | state->clk = 64000000; | ||
664 | printk("tda80xx: Detected tda8083\n"); | ||
665 | break; | ||
666 | |||
667 | default: | ||
668 | goto error; | ||
669 | } | ||
670 | |||
671 | /* setup IRQ */ | ||
672 | if (state->config->irq) { | ||
673 | INIT_WORK(&state->worklet, tda80xx_worklet, state); | ||
674 | if ((ret = request_irq(state->config->irq, tda80xx_irq, SA_ONESHOT, "tda80xx", &state->worklet)) < 0) { | ||
675 | printk(KERN_ERR "tda80xx: request_irq failed (%d)\n", ret); | ||
676 | goto error; | ||
677 | } | ||
678 | } | ||
679 | |||
680 | /* create dvb_frontend */ | ||
681 | state->frontend.ops = &state->ops; | ||
682 | state->frontend.demodulator_priv = state; | ||
683 | return &state->frontend; | ||
684 | |||
685 | error: | ||
686 | kfree(state); | ||
687 | return NULL; | ||
688 | } | ||
689 | |||
690 | static struct dvb_frontend_ops tda80xx_ops = { | ||
691 | |||
692 | .info = { | ||
693 | .name = "Philips TDA80xx DVB-S", | ||
694 | .type = FE_QPSK, | ||
695 | .frequency_min = 500000, | ||
696 | .frequency_max = 2700000, | ||
697 | .frequency_stepsize = 125, | ||
698 | .symbol_rate_min = 4500000, | ||
699 | .symbol_rate_max = 45000000, | ||
700 | .caps = FE_CAN_INVERSION_AUTO | | ||
701 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
702 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | | ||
703 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | | ||
704 | FE_CAN_QPSK | | ||
705 | FE_CAN_MUTE_TS | ||
706 | }, | ||
707 | |||
708 | .release = tda80xx_release, | ||
709 | |||
710 | .init = tda80xx_init, | ||
711 | .sleep = tda80xx_sleep, | ||
712 | |||
713 | .set_frontend = tda80xx_set_frontend, | ||
714 | .get_frontend = tda80xx_get_frontend, | ||
715 | |||
716 | .read_status = tda80xx_read_status, | ||
717 | .read_ber = tda80xx_read_ber, | ||
718 | .read_signal_strength = tda80xx_read_signal_strength, | ||
719 | .read_snr = tda80xx_read_snr, | ||
720 | .read_ucblocks = tda80xx_read_ucblocks, | ||
721 | |||
722 | .diseqc_send_master_cmd = tda80xx_send_diseqc_msg, | ||
723 | .diseqc_send_burst = tda80xx_send_diseqc_burst, | ||
724 | .set_tone = tda80xx_set_tone, | ||
725 | .set_voltage = tda80xx_set_voltage, | ||
726 | }; | ||
727 | |||
728 | module_param(debug, int, 0644); | ||
729 | |||
730 | MODULE_DESCRIPTION("Philips TDA8044 / TDA8083 DVB-S Demodulator driver"); | ||
731 | MODULE_AUTHOR("Felix Domke, Andreas Oberritter"); | ||
732 | MODULE_LICENSE("GPL"); | ||
733 | |||
734 | EXPORT_SYMBOL(tda80xx_attach); | ||
diff --git a/drivers/media/dvb/frontends/tda80xx.h b/drivers/media/dvb/frontends/tda80xx.h deleted file mode 100644 index cd639a0aad55..000000000000 --- a/drivers/media/dvb/frontends/tda80xx.h +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /* | ||
2 | * tda80xx.c | ||
3 | * | ||
4 | * Philips TDA8044 / TDA8083 QPSK demodulator driver | ||
5 | * | ||
6 | * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net> | ||
7 | * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef TDA80XX_H | ||
25 | #define TDA80XX_H | ||
26 | |||
27 | #include <linux/dvb/frontend.h> | ||
28 | |||
29 | struct tda80xx_config | ||
30 | { | ||
31 | /* the demodulator's i2c address */ | ||
32 | u8 demod_address; | ||
33 | |||
34 | /* IRQ to use (0=>no IRQ used) */ | ||
35 | u32 irq; | ||
36 | |||
37 | /* Register setting to use for 13v */ | ||
38 | u8 volt13setting; | ||
39 | |||
40 | /* Register setting to use for 18v */ | ||
41 | u8 volt18setting; | ||
42 | |||
43 | /* PLL maintenance */ | ||
44 | int (*pll_init)(struct dvb_frontend* fe); | ||
45 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
46 | }; | ||
47 | |||
48 | extern struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config, | ||
49 | struct i2c_adapter* i2c); | ||
50 | |||
51 | #endif // TDA80XX_H | ||
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 27494901975f..7c6ccb96b157 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -1439,7 +1439,7 @@ static int check_firmware(struct av7110* av7110) | |||
1439 | len = ntohl(*(u32*) ptr); | 1439 | len = ntohl(*(u32*) ptr); |
1440 | ptr += 4; | 1440 | ptr += 4; |
1441 | if (len >= 512) { | 1441 | if (len >= 512) { |
1442 | printk("dvb-ttpci: dpram file is way to big.\n"); | 1442 | printk("dvb-ttpci: dpram file is way too big.\n"); |
1443 | return -EINVAL; | 1443 | return -EINVAL; |
1444 | } | 1444 | } |
1445 | if (crc != crc32_le(0, ptr, len)) { | 1445 | if (crc != crc32_le(0, ptr, len)) { |
@@ -2329,6 +2329,17 @@ static int frontend_init(struct av7110 *av7110) | |||
2329 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); | 2329 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); |
2330 | break; | 2330 | break; |
2331 | 2331 | ||
2332 | case 0x0004: // Galaxis DVB-S rev1.3 | ||
2333 | /* ALPS BSRV2 */ | ||
2334 | av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); | ||
2335 | if (av7110->fe) { | ||
2336 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | ||
2337 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | ||
2338 | av7110->fe->ops->set_tone = av7110_set_tone; | ||
2339 | av7110->recover = dvb_s_recover; | ||
2340 | } | ||
2341 | break; | ||
2342 | |||
2332 | case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ | 2343 | case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ |
2333 | /* Grundig 29504-451 */ | 2344 | /* Grundig 29504-451 */ |
2334 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); | 2345 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); |
@@ -2466,7 +2477,8 @@ static int frontend_init(struct av7110 *av7110) | |||
2466 | * The same behaviour of missing VSYNC can be duplicated on budget | 2477 | * The same behaviour of missing VSYNC can be duplicated on budget |
2467 | * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble. | 2478 | * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble. |
2468 | */ | 2479 | */ |
2469 | static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) | 2480 | static int __devinit av7110_attach(struct saa7146_dev* dev, |
2481 | struct saa7146_pci_extension_data *pci_ext) | ||
2470 | { | 2482 | { |
2471 | const int length = TS_WIDTH * TS_HEIGHT; | 2483 | const int length = TS_WIDTH * TS_HEIGHT; |
2472 | struct pci_dev *pdev = dev->pci; | 2484 | struct pci_dev *pdev = dev->pci; |
@@ -2816,7 +2828,7 @@ err_kfree_0: | |||
2816 | goto out; | 2828 | goto out; |
2817 | } | 2829 | } |
2818 | 2830 | ||
2819 | static int av7110_detach(struct saa7146_dev* saa) | 2831 | static int __devexit av7110_detach(struct saa7146_dev* saa) |
2820 | { | 2832 | { |
2821 | struct av7110 *av7110 = saa->ext_priv; | 2833 | struct av7110 *av7110 = saa->ext_priv; |
2822 | dprintk(4, "%p\n", av7110); | 2834 | dprintk(4, "%p\n", av7110); |
@@ -2930,6 +2942,7 @@ MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE"); | |||
2930 | MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T"); | 2942 | MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T"); |
2931 | MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C"); | 2943 | MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C"); |
2932 | MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6"); | 2944 | MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6"); |
2945 | MAKE_AV7110_INFO(gxs_1_3, "Galaxis DVB-S rev1.3"); | ||
2933 | 2946 | ||
2934 | static struct pci_device_id pci_tbl[] = { | 2947 | static struct pci_device_id pci_tbl[] = { |
2935 | MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), | 2948 | MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), |
@@ -2937,13 +2950,13 @@ static struct pci_device_id pci_tbl[] = { | |||
2937 | MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), | 2950 | MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), |
2938 | MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002), | 2951 | MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002), |
2939 | MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003), | 2952 | MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003), |
2953 | MAKE_EXTENSION_PCI(gxs_1_3, 0x13c2, 0x0004), | ||
2940 | MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006), | 2954 | MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006), |
2941 | MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008), | 2955 | MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008), |
2942 | MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a), | 2956 | MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a), |
2943 | MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e), | 2957 | MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e), |
2944 | MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002), | 2958 | MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002), |
2945 | 2959 | ||
2946 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte | ||
2947 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 | 2960 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 |
2948 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v???? | 2961 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v???? |
2949 | 2962 | ||
@@ -2962,7 +2975,7 @@ static struct saa7146_extension av7110_extension = { | |||
2962 | .module = THIS_MODULE, | 2975 | .module = THIS_MODULE, |
2963 | .pci_tbl = &pci_tbl[0], | 2976 | .pci_tbl = &pci_tbl[0], |
2964 | .attach = av7110_attach, | 2977 | .attach = av7110_attach, |
2965 | .detach = av7110_detach, | 2978 | .detach = __devexit_p(av7110_detach), |
2966 | 2979 | ||
2967 | .irq_mask = MASK_19 | MASK_03 | MASK_10, | 2980 | .irq_mask = MASK_19 | MASK_03 | MASK_10, |
2968 | .irq_func = av7110_irq, | 2981 | .irq_func = av7110_irq, |
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index 6ea30df2e823..fafd25fab835 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h | |||
@@ -273,8 +273,6 @@ struct av7110 { | |||
273 | extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | 273 | extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, |
274 | u16 subpid, u16 pcrpid); | 274 | u16 subpid, u16 pcrpid); |
275 | 275 | ||
276 | extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config); | ||
277 | |||
278 | extern int av7110_ir_init(struct av7110 *av7110); | 276 | extern int av7110_ir_init(struct av7110 *av7110); |
279 | extern void av7110_ir_exit(struct av7110 *av7110); | 277 | extern void av7110_ir_exit(struct av7110 *av7110); |
280 | 278 | ||
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index b2e63e9fc053..0bb6e74ae7f0 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c | |||
@@ -245,6 +245,9 @@ int av7110_bootarm(struct av7110 *av7110) | |||
245 | 245 | ||
246 | /* test DEBI */ | 246 | /* test DEBI */ |
247 | iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); | 247 | iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); |
248 | /* FIXME: Why does Nexus CA require 2x iwdebi for first init? */ | ||
249 | iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); | ||
250 | |||
248 | if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) { | 251 | if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) { |
249 | printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: " | 252 | printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: " |
250 | "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n", | 253 | "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n", |
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c index 9138132ad25f..d54bbcdde2cc 100644 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ b/drivers/media/dvb/ttpci/av7110_ir.c | |||
@@ -155,6 +155,19 @@ static void input_repeat_key(unsigned long data) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | 157 | ||
158 | static int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) | ||
159 | { | ||
160 | int ret = 0; | ||
161 | |||
162 | dprintk(4, "%p\n", av7110); | ||
163 | if (av7110) { | ||
164 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); | ||
165 | av7110->ir_config = ir_config; | ||
166 | } | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | |||
158 | static int av7110_ir_write_proc(struct file *file, const char __user *buffer, | 171 | static int av7110_ir_write_proc(struct file *file, const char __user *buffer, |
159 | unsigned long count, void *data) | 172 | unsigned long count, void *data) |
160 | { | 173 | { |
@@ -187,19 +200,6 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer, | |||
187 | } | 200 | } |
188 | 201 | ||
189 | 202 | ||
190 | int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) | ||
191 | { | ||
192 | int ret = 0; | ||
193 | |||
194 | dprintk(4, "%p\n", av7110); | ||
195 | if (av7110) { | ||
196 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); | ||
197 | av7110->ir_config = ir_config; | ||
198 | } | ||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | |||
203 | static void ir_handler(struct av7110 *av7110, u32 ircom) | 203 | static void ir_handler(struct av7110 *av7110, u32 ircom) |
204 | { | 204 | { |
205 | dprintk(4, "ircommand = %08x\n", ircom); | 205 | dprintk(4, "ircommand = %08x\n", ircom); |
@@ -208,7 +208,7 @@ static void ir_handler(struct av7110 *av7110, u32 ircom) | |||
208 | } | 208 | } |
209 | 209 | ||
210 | 210 | ||
211 | int __init av7110_ir_init(struct av7110 *av7110) | 211 | int __devinit av7110_ir_init(struct av7110 *av7110) |
212 | { | 212 | { |
213 | static struct proc_dir_entry *e; | 213 | static struct proc_dir_entry *e; |
214 | 214 | ||
@@ -248,7 +248,7 @@ int __init av7110_ir_init(struct av7110 *av7110) | |||
248 | } | 248 | } |
249 | 249 | ||
250 | 250 | ||
251 | void __exit av7110_ir_exit(struct av7110 *av7110) | 251 | void __devexit av7110_ir_exit(struct av7110 *av7110) |
252 | { | 252 | { |
253 | int i; | 253 | int i; |
254 | 254 | ||
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index aa4c4c521880..578b20085082 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
@@ -214,7 +214,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
214 | we can capture, of the first and second field. */ | 214 | we can capture, of the first and second field. */ |
215 | .vbistart = { 7,320 }, | 215 | .vbistart = { 7,320 }, |
216 | },{ | 216 | },{ |
217 | .v4l2_id = V4L2_STD_NTSC_M, | 217 | .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, |
218 | .name = "NTSC", | 218 | .name = "NTSC", |
219 | .Fsc = 28636363, | 219 | .Fsc = 28636363, |
220 | .swidth = 768, | 220 | .swidth = 768, |
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index 297c32ab51e3..840fe0177121 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c | |||
@@ -167,29 +167,32 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user | |||
167 | if (kp->clipcount > 2048) | 167 | if (kp->clipcount > 2048) |
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | if (kp->clipcount) { | 169 | if (kp->clipcount) { |
170 | struct v4l2_clip32 *uclips = compat_ptr(up->clips); | 170 | struct v4l2_clip32 __user *uclips; |
171 | struct v4l2_clip *kclips; | 171 | struct v4l2_clip __user *kclips; |
172 | int n = kp->clipcount; | 172 | int n = kp->clipcount; |
173 | compat_caddr_t p; | ||
173 | 174 | ||
175 | if (get_user(p, &up->clips)) | ||
176 | return -EFAULT; | ||
177 | uclips = compat_ptr(p); | ||
174 | kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); | 178 | kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); |
175 | kp->clips = kclips; | 179 | kp->clips = kclips; |
176 | while (--n >= 0) { | 180 | while (--n >= 0) { |
177 | if (!access_ok(VERIFY_READ, &uclips->c, sizeof(uclips->c)) || | 181 | if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c))) |
178 | copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c))) | 182 | return -EFAULT; |
183 | if (put_user(n ? kclips + 1 : NULL, &kclips->next)) | ||
179 | return -EFAULT; | 184 | return -EFAULT; |
180 | kclips->next = n ? kclips + 1 : 0; | ||
181 | uclips += 1; | 185 | uclips += 1; |
182 | kclips += 1; | 186 | kclips += 1; |
183 | } | 187 | } |
184 | } else | 188 | } else |
185 | kp->clips = 0; | 189 | kp->clips = NULL; |
186 | return 0; | 190 | return 0; |
187 | } | 191 | } |
188 | 192 | ||
189 | static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) | 193 | static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) |
190 | { | 194 | { |
191 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_window32)) || | 195 | if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) || |
192 | copy_to_user(&up->w, &kp->w, sizeof(up->w)) || | ||
193 | put_user(kp->field, &up->field) || | 196 | put_user(kp->field, &up->field) || |
194 | put_user(kp->chromakey, &up->chromakey) || | 197 | put_user(kp->chromakey, &up->chromakey) || |
195 | put_user(kp->clipcount, &up->clipcount)) | 198 | put_user(kp->clipcount, &up->clipcount)) |
@@ -199,33 +202,29 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user | |||
199 | 202 | ||
200 | static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) | 203 | static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) |
201 | { | 204 | { |
202 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_pix_format)) || | 205 | if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) |
203 | copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) | 206 | return -EFAULT; |
204 | return -EFAULT; | ||
205 | return 0; | 207 | return 0; |
206 | } | 208 | } |
207 | 209 | ||
208 | static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) | 210 | static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) |
209 | { | 211 | { |
210 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_pix_format)) || | 212 | if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) |
211 | copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) | 213 | return -EFAULT; |
212 | return -EFAULT; | ||
213 | return 0; | 214 | return 0; |
214 | } | 215 | } |
215 | 216 | ||
216 | static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) | 217 | static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) |
217 | { | 218 | { |
218 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_vbi_format)) || | 219 | if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) |
219 | copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) | 220 | return -EFAULT; |
220 | return -EFAULT; | ||
221 | return 0; | 221 | return 0; |
222 | } | 222 | } |
223 | 223 | ||
224 | static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) | 224 | static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) |
225 | { | 225 | { |
226 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_vbi_format)) || | 226 | if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) |
227 | copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) | 227 | return -EFAULT; |
228 | return -EFAULT; | ||
229 | return 0; | 228 | return 0; |
230 | } | 229 | } |
231 | 230 | ||
@@ -279,18 +278,16 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user | |||
279 | 278 | ||
280 | static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) | 279 | static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) |
281 | { | 280 | { |
282 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard)) || | 281 | if (copy_from_user(kp, up, sizeof(struct v4l2_standard))) |
283 | copy_from_user(kp, up, sizeof(struct v4l2_standard))) | 282 | return -EFAULT; |
284 | return -EFAULT; | ||
285 | return 0; | 283 | return 0; |
286 | 284 | ||
287 | } | 285 | } |
288 | 286 | ||
289 | static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) | 287 | static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) |
290 | { | 288 | { |
291 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard)) || | 289 | if (copy_to_user(up, kp, sizeof(struct v4l2_standard))) |
292 | copy_to_user(up, kp, sizeof(struct v4l2_standard))) | 290 | return -EFAULT; |
293 | return -EFAULT; | ||
294 | return 0; | 291 | return 0; |
295 | } | 292 | } |
296 | 293 | ||
@@ -328,18 +325,16 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 | |||
328 | 325 | ||
329 | static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) | 326 | static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) |
330 | { | 327 | { |
331 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_tuner)) || | 328 | if (copy_from_user(kp, up, sizeof(struct v4l2_tuner))) |
332 | copy_from_user(kp, up, sizeof(struct v4l2_tuner))) | 329 | return -EFAULT; |
333 | return -EFAULT; | ||
334 | return 0; | 330 | return 0; |
335 | 331 | ||
336 | } | 332 | } |
337 | 333 | ||
338 | static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) | 334 | static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) |
339 | { | 335 | { |
340 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_tuner)) || | 336 | if (copy_to_user(up, kp, sizeof(struct v4l2_tuner))) |
341 | copy_to_user(up, kp, sizeof(struct v4l2_tuner))) | 337 | return -EFAULT; |
342 | return -EFAULT; | ||
343 | return 0; | 338 | return 0; |
344 | } | 339 | } |
345 | 340 | ||
@@ -380,11 +375,13 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user | |||
380 | break; | 375 | break; |
381 | case V4L2_MEMORY_USERPTR: | 376 | case V4L2_MEMORY_USERPTR: |
382 | { | 377 | { |
383 | unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr); | 378 | compat_long_t tmp; |
384 | 379 | ||
385 | if(get_user(kp->length, &up->length) || | 380 | if (get_user(kp->length, &up->length) || |
386 | get_user(kp->m.userptr, &tmp)) | 381 | get_user(tmp, &up->m.userptr)) |
387 | return -EFAULT; | 382 | return -EFAULT; |
383 | |||
384 | kp->m.userptr = (unsigned long)compat_ptr(tmp); | ||
388 | } | 385 | } |
389 | break; | 386 | break; |
390 | case V4L2_MEMORY_OVERLAY: | 387 | case V4L2_MEMORY_OVERLAY: |
@@ -468,33 +465,29 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame | |||
468 | 465 | ||
469 | static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) | 466 | static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) |
470 | { | 467 | { |
471 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input) - 4) || | 468 | if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) |
472 | copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) | 469 | return -EFAULT; |
473 | return -EFAULT; | ||
474 | return 0; | 470 | return 0; |
475 | } | 471 | } |
476 | 472 | ||
477 | static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) | 473 | static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) |
478 | { | 474 | { |
479 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input) - 4) || | 475 | if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) |
480 | copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) | 476 | return -EFAULT; |
481 | return -EFAULT; | ||
482 | return 0; | 477 | return 0; |
483 | } | 478 | } |
484 | 479 | ||
485 | static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) | 480 | static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) |
486 | { | 481 | { |
487 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input)) || | 482 | if (copy_from_user(kp, up, sizeof(struct v4l2_input))) |
488 | copy_from_user(kp, up, sizeof(struct v4l2_input))) | 483 | return -EFAULT; |
489 | return -EFAULT; | ||
490 | return 0; | 484 | return 0; |
491 | } | 485 | } |
492 | 486 | ||
493 | static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) | 487 | static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) |
494 | { | 488 | { |
495 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input)) || | 489 | if (copy_to_user(up, kp, sizeof(struct v4l2_input))) |
496 | copy_to_user(up, kp, sizeof(struct v4l2_input))) | 490 | return -EFAULT; |
497 | return -EFAULT; | ||
498 | return 0; | 491 | return 0; |
499 | } | 492 | } |
500 | 493 | ||
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 9f59541155d9..85d964b5b33c 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c | |||
@@ -3369,7 +3369,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, | |||
3369 | //DBG("cpia_ioctl: %u\n", ioctlnr); | 3369 | //DBG("cpia_ioctl: %u\n", ioctlnr); |
3370 | 3370 | ||
3371 | switch (ioctlnr) { | 3371 | switch (ioctlnr) { |
3372 | /* query capabilites */ | 3372 | /* query capabilities */ |
3373 | case VIDIOCGCAP: | 3373 | case VIDIOCGCAP: |
3374 | { | 3374 | { |
3375 | struct video_capability *b = arg; | 3375 | struct video_capability *b = arg; |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index c66c2c1f4809..5588b9a5c430 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -220,33 +220,23 @@ static void input_change(struct i2c_client *client) | |||
220 | cx25840_write(client, 0x808, 0xff); | 220 | cx25840_write(client, 0x808, 0xff); |
221 | cx25840_write(client, 0x80b, 0x10); | 221 | cx25840_write(client, 0x80b, 0x10); |
222 | } else if (std & V4L2_STD_NTSC) { | 222 | } else if (std & V4L2_STD_NTSC) { |
223 | /* NTSC */ | 223 | /* Certain Hauppauge PVR150 models have a hardware bug |
224 | if (state->pvr150_workaround) { | 224 | that causes audio to drop out. For these models the |
225 | /* Certain Hauppauge PVR150 models have a hardware bug | 225 | audio standard must be set explicitly. |
226 | that causes audio to drop out. For these models the | 226 | To be precise: it affects cards with tuner models |
227 | audio standard must be set explicitly. | 227 | 85, 99 and 112 (model numbers from tveeprom). */ |
228 | To be precise: it affects cards with tuner models | 228 | int hw_fix = state->pvr150_workaround; |
229 | 85, 99 and 112 (model numbers from tveeprom). */ | 229 | |
230 | if (std == V4L2_STD_NTSC_M_JP) { | 230 | if (std == V4L2_STD_NTSC_M_JP) { |
231 | /* Japan uses EIAJ audio standard */ | ||
232 | cx25840_write(client, 0x808, 0x2f); | ||
233 | } else { | ||
234 | /* Others use the BTSC audio standard */ | ||
235 | cx25840_write(client, 0x808, 0x1f); | ||
236 | } | ||
237 | /* South Korea uses the A2-M (aka Zweiton M) audio | ||
238 | standard, and should set 0x808 to 0x3f, but I don't | ||
239 | know how to detect this. */ | ||
240 | } else if (std == V4L2_STD_NTSC_M_JP) { | ||
241 | /* Japan uses EIAJ audio standard */ | 231 | /* Japan uses EIAJ audio standard */ |
242 | cx25840_write(client, 0x808, 0xf7); | 232 | cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7); |
233 | } else if (std == V4L2_STD_NTSC_M_KR) { | ||
234 | /* South Korea uses A2 audio standard */ | ||
235 | cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8); | ||
243 | } else { | 236 | } else { |
244 | /* Others use the BTSC audio standard */ | 237 | /* Others use the BTSC audio standard */ |
245 | cx25840_write(client, 0x808, 0xf6); | 238 | cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6); |
246 | } | 239 | } |
247 | /* South Korea uses the A2-M (aka Zweiton M) audio standard, | ||
248 | and should set 0x808 to 0xf8, but I don't know how to | ||
249 | detect this. */ | ||
250 | cx25840_write(client, 0x80b, 0x00); | 240 | cx25840_write(client, 0x80b, 0x00); |
251 | } | 241 | } |
252 | 242 | ||
@@ -330,17 +320,17 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
330 | u8 fmt=0; /* zero is autodetect */ | 320 | u8 fmt=0; /* zero is autodetect */ |
331 | 321 | ||
332 | /* First tests should be against specific std */ | 322 | /* First tests should be against specific std */ |
333 | if (std & V4L2_STD_NTSC_M_JP) { | 323 | if (std == V4L2_STD_NTSC_M_JP) { |
334 | fmt=0x2; | 324 | fmt=0x2; |
335 | } else if (std & V4L2_STD_NTSC_443) { | 325 | } else if (std == V4L2_STD_NTSC_443) { |
336 | fmt=0x3; | 326 | fmt=0x3; |
337 | } else if (std & V4L2_STD_PAL_M) { | 327 | } else if (std == V4L2_STD_PAL_M) { |
338 | fmt=0x5; | 328 | fmt=0x5; |
339 | } else if (std & V4L2_STD_PAL_N) { | 329 | } else if (std == V4L2_STD_PAL_N) { |
340 | fmt=0x6; | 330 | fmt=0x6; |
341 | } else if (std & V4L2_STD_PAL_Nc) { | 331 | } else if (std == V4L2_STD_PAL_Nc) { |
342 | fmt=0x7; | 332 | fmt=0x7; |
343 | } else if (std & V4L2_STD_PAL_60) { | 333 | } else if (std == V4L2_STD_PAL_60) { |
344 | fmt=0x8; | 334 | fmt=0x8; |
345 | } else { | 335 | } else { |
346 | /* Then, test against generic ones */ | 336 | /* Then, test against generic ones */ |
@@ -369,7 +359,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) | |||
369 | } | 359 | } |
370 | 360 | ||
371 | switch (fmt) { | 361 | switch (fmt) { |
372 | case 0x1: return V4L2_STD_NTSC_M; | 362 | case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR; |
373 | case 0x2: return V4L2_STD_NTSC_M_JP; | 363 | case 0x2: return V4L2_STD_NTSC_M_JP; |
374 | case 0x3: return V4L2_STD_NTSC_443; | 364 | case 0x3: return V4L2_STD_NTSC_443; |
375 | case 0x4: return V4L2_STD_PAL; | 365 | case 0x4: return V4L2_STD_PAL; |
@@ -577,7 +567,7 @@ static struct v4l2_queryctrl cx25840_qctrl[] = { | |||
577 | .type = V4L2_CTRL_TYPE_INTEGER, | 567 | .type = V4L2_CTRL_TYPE_INTEGER, |
578 | .name = "Contrast", | 568 | .name = "Contrast", |
579 | .minimum = 0, | 569 | .minimum = 0, |
580 | .maximum = 255, | 570 | .maximum = 127, |
581 | .step = 1, | 571 | .step = 1, |
582 | .default_value = 64, | 572 | .default_value = 64, |
583 | .flags = 0, | 573 | .flags = 0, |
@@ -586,7 +576,7 @@ static struct v4l2_queryctrl cx25840_qctrl[] = { | |||
586 | .type = V4L2_CTRL_TYPE_INTEGER, | 576 | .type = V4L2_CTRL_TYPE_INTEGER, |
587 | .name = "Saturation", | 577 | .name = "Saturation", |
588 | .minimum = 0, | 578 | .minimum = 0, |
589 | .maximum = 255, | 579 | .maximum = 127, |
590 | .step = 1, | 580 | .step = 1, |
591 | .default_value = 64, | 581 | .default_value = 64, |
592 | .flags = 0, | 582 | .flags = 0, |
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 53308911ae6e..87d79df05336 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -15,23 +15,10 @@ config VIDEO_CX88 | |||
15 | To compile this driver as a module, choose M here: the | 15 | To compile this driver as a module, choose M here: the |
16 | module will be called cx8800 | 16 | module will be called cx8800 |
17 | 17 | ||
18 | config VIDEO_CX88_DVB | ||
19 | tristate "DVB/ATSC Support for cx2388x based TV cards" | ||
20 | depends on VIDEO_CX88 && DVB_CORE | ||
21 | select VIDEO_BUF_DVB | ||
22 | ---help--- | ||
23 | This adds support for DVB/ATSC cards based on the | ||
24 | Connexant 2388x chip. | ||
25 | |||
26 | To compile this driver as a module, choose M here: the | ||
27 | module will be called cx88-dvb. | ||
28 | |||
29 | You must also select one or more DVB/ATSC demodulators. | ||
30 | If you are unsure which you need, choose all of them. | ||
31 | |||
32 | config VIDEO_CX88_ALSA | 18 | config VIDEO_CX88_ALSA |
33 | tristate "ALSA DMA audio support" | 19 | tristate "ALSA DMA audio support" |
34 | depends on VIDEO_CX88 && SND && EXPERIMENTAL | 20 | depends on VIDEO_CX88 && SND && EXPERIMENTAL |
21 | select SND_PCM | ||
35 | ---help--- | 22 | ---help--- |
36 | This is a video4linux driver for direct (DMA) audio on | 23 | This is a video4linux driver for direct (DMA) audio on |
37 | Conexant 2388x based TV cards. | 24 | Conexant 2388x based TV cards. |
@@ -43,11 +30,26 @@ config VIDEO_CX88_ALSA | |||
43 | To compile this driver as a module, choose M here: the | 30 | To compile this driver as a module, choose M here: the |
44 | module will be called cx88-alsa. | 31 | module will be called cx88-alsa. |
45 | 32 | ||
33 | config VIDEO_CX88_DVB | ||
34 | tristate "DVB/ATSC Support for cx2388x based TV cards" | ||
35 | depends on VIDEO_CX88 && DVB_CORE | ||
36 | select VIDEO_BUF_DVB | ||
37 | ---help--- | ||
38 | This adds support for DVB/ATSC cards based on the | ||
39 | Connexant 2388x chip. | ||
40 | |||
41 | To compile this driver as a module, choose M here: the | ||
42 | module will be called cx88-dvb. | ||
43 | |||
44 | You must also select one or more DVB/ATSC demodulators. | ||
45 | If you are unsure which you need, choose all of them. | ||
46 | |||
46 | config VIDEO_CX88_DVB_ALL_FRONTENDS | 47 | config VIDEO_CX88_DVB_ALL_FRONTENDS |
47 | bool "Build all supported frontends for cx2388x based TV cards" | 48 | bool "Build all supported frontends for cx2388x based TV cards" |
48 | default y | 49 | default y |
49 | depends on VIDEO_CX88_DVB | 50 | depends on VIDEO_CX88_DVB |
50 | select DVB_MT352 | 51 | select DVB_MT352 |
52 | select VIDEO_CX88_VP3054 | ||
51 | select DVB_OR51132 | 53 | select DVB_OR51132 |
52 | select DVB_CX22702 | 54 | select DVB_CX22702 |
53 | select DVB_LGDT330X | 55 | select DVB_LGDT330X |
@@ -69,6 +71,16 @@ config VIDEO_CX88_DVB_MT352 | |||
69 | This adds DVB-T support for cards based on the | 71 | This adds DVB-T support for cards based on the |
70 | Connexant 2388x chip and the MT352 demodulator. | 72 | Connexant 2388x chip and the MT352 demodulator. |
71 | 73 | ||
74 | config VIDEO_CX88_VP3054 | ||
75 | tristate "VP-3054 Secondary I2C Bus Support" | ||
76 | default m | ||
77 | depends on DVB_MT352 | ||
78 | ---help--- | ||
79 | This adds DVB-T support for cards based on the | ||
80 | Connexant 2388x chip and the MT352 demodulator, | ||
81 | which also require support for the VP-3054 | ||
82 | Secondary I2C bus, such at DNTV Live! DVB-T Pro. | ||
83 | |||
72 | config VIDEO_CX88_DVB_OR51132 | 84 | config VIDEO_CX88_DVB_OR51132 |
73 | bool "OR51132 ATSC Support" | 85 | bool "OR51132 ATSC Support" |
74 | default y | 86 | default y |
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 6e5eaa22619e..2b902784facc 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
@@ -4,8 +4,9 @@ cx8800-objs := cx88-video.o cx88-vbi.o | |||
4 | cx8802-objs := cx88-mpeg.o | 4 | cx8802-objs := cx88-mpeg.o |
5 | 5 | ||
6 | obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o | 6 | obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o |
7 | obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o | 7 | obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o |
8 | obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o | 8 | obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o |
9 | obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o | ||
9 | 10 | ||
10 | EXTRA_CFLAGS += -I$(src)/.. | 11 | EXTRA_CFLAGS += -I$(src)/.. |
11 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 12 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core |
@@ -18,6 +19,6 @@ extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 | |||
18 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 | 19 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 |
19 | extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 | 20 | extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 |
20 | extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 | 21 | extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 |
21 | extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1 | 22 | extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1 |
22 | 23 | ||
23 | EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) | 24 | EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index a2e36a1e5f59..2acccd6d49bc 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -128,7 +128,7 @@ MODULE_PARM_DESC(debug,"enable debug messages"); | |||
128 | * BOARD Specific: Sets audio DMA | 128 | * BOARD Specific: Sets audio DMA |
129 | */ | 129 | */ |
130 | 130 | ||
131 | int _cx88_start_audio_dma(snd_cx88_card_t *chip) | 131 | static int _cx88_start_audio_dma(snd_cx88_card_t *chip) |
132 | { | 132 | { |
133 | struct cx88_buffer *buf = chip->buf; | 133 | struct cx88_buffer *buf = chip->buf; |
134 | struct cx88_core *core=chip->core; | 134 | struct cx88_core *core=chip->core; |
@@ -173,7 +173,7 @@ int _cx88_start_audio_dma(snd_cx88_card_t *chip) | |||
173 | /* | 173 | /* |
174 | * BOARD Specific: Resets audio DMA | 174 | * BOARD Specific: Resets audio DMA |
175 | */ | 175 | */ |
176 | int _cx88_stop_audio_dma(snd_cx88_card_t *chip) | 176 | static int _cx88_stop_audio_dma(snd_cx88_card_t *chip) |
177 | { | 177 | { |
178 | struct cx88_core *core=chip->core; | 178 | struct cx88_core *core=chip->core; |
179 | dprintk(1, "Stopping audio DMA\n"); | 179 | dprintk(1, "Stopping audio DMA\n"); |
@@ -613,7 +613,7 @@ static snd_kcontrol_new_t snd_cx88_capture_volume = { | |||
613 | * Only boards with eeprom and byte 1 at eeprom=1 have it | 613 | * Only boards with eeprom and byte 1 at eeprom=1 have it |
614 | */ | 614 | */ |
615 | 615 | ||
616 | struct pci_device_id cx88_audio_pci_tbl[] = { | 616 | static struct pci_device_id cx88_audio_pci_tbl[] = { |
617 | {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, | 617 | {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, |
618 | {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, | 618 | {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, |
619 | {0, } | 619 | {0, } |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index ad2f565f522c..1bc999247fdc 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1246,6 +1246,11 @@ struct cx88_subid cx88_subids[] = { | |||
1246 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL, | 1246 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL, |
1247 | },{ | 1247 | },{ |
1248 | .subvendor = 0x18ac, | 1248 | .subvendor = 0x18ac, |
1249 | .subdevice = 0xdb54, | ||
1250 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL, | ||
1251 | /* Re-branded DViCO: DigitalNow DVB-T Dual */ | ||
1252 | },{ | ||
1253 | .subvendor = 0x18ac, | ||
1249 | .subdevice = 0xdb11, | 1254 | .subdevice = 0xdb11, |
1250 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, | 1255 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, |
1251 | /* Re-branded DViCO: UltraView DVB-T Plus */ | 1256 | /* Re-branded DViCO: UltraView DVB-T Plus */ |
@@ -1293,6 +1298,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
1293 | switch (tv.model) | 1298 | switch (tv.model) |
1294 | { | 1299 | { |
1295 | case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ | 1300 | case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ |
1301 | case 34519: /* WinTV-PCI-FM */ | ||
1296 | case 90002: /* Nova-T-PCI (9002) */ | 1302 | case 90002: /* Nova-T-PCI (9002) */ |
1297 | case 92001: /* Nova-S-Plus (Video and IR) */ | 1303 | case 92001: /* Nova-S-Plus (Video and IR) */ |
1298 | case 92002: /* Nova-S-Plus (Video and IR) */ | 1304 | case 92002: /* Nova-S-Plus (Video and IR) */ |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 8d6d6a6cf785..3720f24a25cf 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -787,12 +787,14 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) | |||
787 | 787 | ||
788 | int cx88_start_audio_dma(struct cx88_core *core) | 788 | int cx88_start_audio_dma(struct cx88_core *core) |
789 | { | 789 | { |
790 | /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */ | ||
791 | int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4; | ||
790 | /* setup fifo + format */ | 792 | /* setup fifo + format */ |
791 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0); | 793 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0); |
792 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0); | 794 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0); |
793 | 795 | ||
794 | cx_write(MO_AUDD_LNGTH, 128); /* fifo bpl size */ | 796 | cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */ |
795 | cx_write(MO_AUDR_LNGTH, 128); /* fifo bpl size */ | 797 | cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */ |
796 | 798 | ||
797 | /* start dma */ | 799 | /* start dma */ |
798 | cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ | 800 | cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index da2ad5c4b553..165d948624a3 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -482,6 +482,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
482 | switch (core->board) { | 482 | switch (core->board) { |
483 | case CX88_BOARD_DNTV_LIVE_DVB_T: | 483 | case CX88_BOARD_DNTV_LIVE_DVB_T: |
484 | case CX88_BOARD_KWORLD_DVB_T: | 484 | case CX88_BOARD_KWORLD_DVB_T: |
485 | case CX88_BOARD_KWORLD_DVB_T_CX22702: | ||
485 | ir_codes = ir_codes_dntv_live_dvb_t; | 486 | ir_codes = ir_codes_dntv_live_dvb_t; |
486 | ir->gpio_addr = MO_GP1_IO; | 487 | ir->gpio_addr = MO_GP1_IO; |
487 | ir->mask_keycode = 0x1f; | 488 | ir->mask_keycode = 0x1f; |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index dff3893f32fd..e5ee8bceb210 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -139,6 +139,9 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | |||
139 | { | 139 | { |
140 | int ret, byte; | 140 | int ret, byte; |
141 | 141 | ||
142 | if (dev->state & DEV_DISCONNECTED) | ||
143 | return(-ENODEV); | ||
144 | |||
142 | em28xx_regdbg("req=%02x, reg=%02x ", req, reg); | 145 | em28xx_regdbg("req=%02x, reg=%02x ", req, reg); |
143 | 146 | ||
144 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 147 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, |
@@ -165,6 +168,9 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) | |||
165 | u8 val; | 168 | u8 val; |
166 | int ret; | 169 | int ret; |
167 | 170 | ||
171 | if (dev->state & DEV_DISCONNECTED) | ||
172 | return(-ENODEV); | ||
173 | |||
168 | em28xx_regdbg("req=%02x, reg=%02x:", req, reg); | 174 | em28xx_regdbg("req=%02x, reg=%02x:", req, reg); |
169 | 175 | ||
170 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 176 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, |
@@ -195,7 +201,12 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
195 | int ret; | 201 | int ret; |
196 | 202 | ||
197 | /*usb_control_msg seems to expect a kmalloced buffer */ | 203 | /*usb_control_msg seems to expect a kmalloced buffer */ |
198 | unsigned char *bufs = kmalloc(len, GFP_KERNEL); | 204 | unsigned char *bufs; |
205 | |||
206 | if (dev->state & DEV_DISCONNECTED) | ||
207 | return(-ENODEV); | ||
208 | |||
209 | bufs = kmalloc(len, GFP_KERNEL); | ||
199 | 210 | ||
200 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); | 211 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); |
201 | 212 | ||
@@ -212,7 +223,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
212 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, | 223 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, |
213 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 224 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
214 | 0x0000, reg, bufs, len, HZ); | 225 | 0x0000, reg, bufs, len, HZ); |
215 | mdelay(5); /* FIXME: magic number */ | 226 | msleep(5); /* FIXME: magic number */ |
216 | kfree(bufs); | 227 | kfree(bufs); |
217 | return ret; | 228 | return ret; |
218 | } | 229 | } |
@@ -253,7 +264,7 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val) | |||
253 | if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) | 264 | if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) |
254 | return ret; | 265 | return ret; |
255 | else if (((u8) ret) & 0x01) { | 266 | else if (((u8) ret) & 0x01) { |
256 | em28xx_warn ("AC97 command still being exectuted: not handled properly!\n"); | 267 | em28xx_warn ("AC97 command still being executed: not handled properly!\n"); |
257 | } | 268 | } |
258 | return 0; | 269 | return 0; |
259 | } | 270 | } |
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 0591a705b7a1..6ca8631bc36d 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -78,7 +78,7 @@ static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr, | |||
78 | ret = dev->em28xx_read_reg(dev, 0x05); | 78 | ret = dev->em28xx_read_reg(dev, 0x05); |
79 | if (ret == 0x80 + len - 1) | 79 | if (ret == 0x80 + len - 1) |
80 | return len; | 80 | return len; |
81 | mdelay(5); | 81 | msleep(5); |
82 | } | 82 | } |
83 | em28xx_warn("i2c write timed out\n"); | 83 | em28xx_warn("i2c write timed out\n"); |
84 | return -EIO; | 84 | return -EIO; |
@@ -138,7 +138,7 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr) | |||
138 | return -ENODEV; | 138 | return -ENODEV; |
139 | else if (msg == 0x84) | 139 | else if (msg == 0x84) |
140 | return 0; | 140 | return 0; |
141 | mdelay(5); | 141 | msleep(5); |
142 | } | 142 | } |
143 | return -ENODEV; | 143 | return -ENODEV; |
144 | } | 144 | } |
@@ -278,9 +278,9 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
278 | msgs[i].buf, | 278 | msgs[i].buf, |
279 | msgs[i].len, | 279 | msgs[i].len, |
280 | i == num - 1); | 280 | i == num - 1); |
281 | if (rc < 0) | ||
282 | goto err; | ||
283 | } | 281 | } |
282 | if (rc < 0) | ||
283 | goto err; | ||
284 | if (i2c_debug>=2) | 284 | if (i2c_debug>=2) |
285 | printk("\n"); | 285 | printk("\n"); |
286 | } | 286 | } |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index eea304f75176..5b267808a9d4 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -6,6 +6,9 @@ | |||
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> |
7 | Sascha Sommer <saschasommer@freenet.de> | 7 | Sascha Sommer <saschasommer@freenet.de> |
8 | 8 | ||
9 | Some parts based on SN9C10x PC Camera Controllers GPL driver made | ||
10 | by Luca Risolia <luca.risolia@studio.unibo.it> | ||
11 | |||
9 | This program is free software; you can redistribute it and/or modify | 12 | This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 13 | it under the terms of the GNU General Public License as published by |
11 | the Free Software Foundation; either version 2 of the License, or | 14 | the Free Software Foundation; either version 2 of the License, or |
@@ -364,6 +367,9 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
364 | em28xx_capture_start(dev, 1); | 367 | em28xx_capture_start(dev, 1); |
365 | em28xx_resolution_set(dev); | 368 | em28xx_resolution_set(dev); |
366 | 369 | ||
370 | /* device needs to be initialized before isoc transfer */ | ||
371 | video_mux(dev, 0); | ||
372 | |||
367 | /* start the transfer */ | 373 | /* start the transfer */ |
368 | errCode = em28xx_init_isoc(dev); | 374 | errCode = em28xx_init_isoc(dev); |
369 | if (errCode) | 375 | if (errCode) |
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 8416ceff524b..41715cacf926 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | mxb - v4l2 driver for the Multimedia eXtension Board | 2 | mxb - v4l2 driver for the Multimedia eXtension Board |
3 | 3 | ||
4 | Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> | 4 | Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de> |
5 | 5 | ||
6 | Visit http://www.mihu.de/linux/saa7146/mxb/ | 6 | Visit http://www.mihu.de/linux/saa7146/mxb/ |
7 | for further details about this card. | 7 | for further details about this card. |
@@ -327,6 +327,7 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
327 | struct video_decoder_init init; | 327 | struct video_decoder_init init; |
328 | struct i2c_msg msg; | 328 | struct i2c_msg msg; |
329 | struct tuner_setup tun_setup; | 329 | struct tuner_setup tun_setup; |
330 | v4l2_std_id std = V4L2_STD_PAL_BG; | ||
330 | 331 | ||
331 | int i = 0, err = 0; | 332 | int i = 0, err = 0; |
332 | struct tea6415c_multiplex vm; | 333 | struct tea6415c_multiplex vm; |
@@ -361,6 +362,9 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
361 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, | 362 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, |
362 | &mxb->cur_freq); | 363 | &mxb->cur_freq); |
363 | 364 | ||
365 | /* set a default video standard */ | ||
366 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); | ||
367 | |||
364 | /* mute audio on tea6420s */ | 368 | /* mute audio on tea6420s */ |
365 | mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]); | 369 | mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]); |
366 | mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]); | 370 | mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]); |
@@ -921,17 +925,21 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) | |||
921 | int one = 1; | 925 | int one = 1; |
922 | 926 | ||
923 | if(V4L2_STD_PAL_I == std->id ) { | 927 | if(V4L2_STD_PAL_I == std->id ) { |
928 | v4l2_std_id std = V4L2_STD_PAL_I; | ||
924 | DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n")); | 929 | DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n")); |
925 | /* set the 7146 gpio register -- I don't know what this does exactly */ | 930 | /* set the 7146 gpio register -- I don't know what this does exactly */ |
926 | saa7146_write(dev, GPIO_CTRL, 0x00404050); | 931 | saa7146_write(dev, GPIO_CTRL, 0x00404050); |
927 | /* unset the 7111 gpio register -- I don't know what this does exactly */ | 932 | /* unset the 7111 gpio register -- I don't know what this does exactly */ |
928 | mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero); | 933 | mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero); |
934 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); | ||
929 | } else { | 935 | } else { |
936 | v4l2_std_id std = V4L2_STD_PAL_BG; | ||
930 | DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n")); | 937 | DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n")); |
931 | /* set the 7146 gpio register -- I don't know what this does exactly */ | 938 | /* set the 7146 gpio register -- I don't know what this does exactly */ |
932 | saa7146_write(dev, GPIO_CTRL, 0x00404050); | 939 | saa7146_write(dev, GPIO_CTRL, 0x00404050); |
933 | /* set the 7111 gpio register -- I don't know what this does exactly */ | 940 | /* set the 7111 gpio register -- I don't know what this does exactly */ |
934 | mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one); | 941 | mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one); |
942 | mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); | ||
935 | } | 943 | } |
936 | return 0; | 944 | return 0; |
937 | } | 945 | } |
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 048d000941c7..ffd87ce55556 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
@@ -1027,7 +1027,7 @@ static struct v4l2_queryctrl saa7115_qctrl[] = { | |||
1027 | .type = V4L2_CTRL_TYPE_INTEGER, | 1027 | .type = V4L2_CTRL_TYPE_INTEGER, |
1028 | .name = "Contrast", | 1028 | .name = "Contrast", |
1029 | .minimum = 0, | 1029 | .minimum = 0, |
1030 | .maximum = 255, | 1030 | .maximum = 127, |
1031 | .step = 1, | 1031 | .step = 1, |
1032 | .default_value = 64, | 1032 | .default_value = 64, |
1033 | .flags = 0, | 1033 | .flags = 0, |
@@ -1036,7 +1036,7 @@ static struct v4l2_queryctrl saa7115_qctrl[] = { | |||
1036 | .type = V4L2_CTRL_TYPE_INTEGER, | 1036 | .type = V4L2_CTRL_TYPE_INTEGER, |
1037 | .name = "Saturation", | 1037 | .name = "Saturation", |
1038 | .minimum = 0, | 1038 | .minimum = 0, |
1039 | .maximum = 255, | 1039 | .maximum = 127, |
1040 | .step = 1, | 1040 | .step = 1, |
1041 | .default_value = 64, | 1041 | .default_value = 64, |
1042 | .flags = 0, | 1042 | .flags = 0, |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index a7a6ab9298a9..7df5e0826e12 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -54,10 +54,12 @@ MODULE_PARM_DESC(debug,"enable debug messages [alsa]"); | |||
54 | 54 | ||
55 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 55 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
56 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 56 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
57 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; | 57 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; |
58 | 58 | ||
59 | module_param_array(index, int, NULL, 0444); | 59 | module_param_array(index, int, NULL, 0444); |
60 | module_param_array(enable, int, NULL, 0444); | ||
60 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); | 61 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); |
62 | MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s)."); | ||
61 | 63 | ||
62 | #define dprintk(fmt, arg...) if (debug) \ | 64 | #define dprintk(fmt, arg...) if (debug) \ |
63 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg) | 65 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg) |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index c64718aec9cb..6bc63a4086c1 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -136,7 +136,7 @@ struct saa7134_board saa7134_boards[] = { | |||
136 | }, | 136 | }, |
137 | [SAA7134_BOARD_FLYVIDEO2000] = { | 137 | [SAA7134_BOARD_FLYVIDEO2000] = { |
138 | /* "TC Wan" <tcwan@cs.usm.my> */ | 138 | /* "TC Wan" <tcwan@cs.usm.my> */ |
139 | .name = "LifeView FlyVIDEO2000", | 139 | .name = "LifeView/Typhoon FlyVIDEO2000", |
140 | .audio_clock = 0x00200000, | 140 | .audio_clock = 0x00200000, |
141 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 141 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
142 | .radio_type = UNSET, | 142 | .radio_type = UNSET, |
@@ -977,7 +977,7 @@ struct saa7134_board saa7134_boards[] = { | |||
977 | .radio_type = UNSET, | 977 | .radio_type = UNSET, |
978 | .tuner_addr = ADDR_UNSET, | 978 | .tuner_addr = ADDR_UNSET, |
979 | .radio_addr = ADDR_UNSET, | 979 | .radio_addr = ADDR_UNSET, |
980 | .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_ACTIVE, | 980 | .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_INACTIVE, |
981 | .inputs = {{ | 981 | .inputs = {{ |
982 | .name = name_tv, | 982 | .name = name_tv, |
983 | .vmux = 3, | 983 | .vmux = 3, |
@@ -1666,7 +1666,7 @@ struct saa7134_board saa7134_boards[] = { | |||
1666 | .radio_type = UNSET, | 1666 | .radio_type = UNSET, |
1667 | .tuner_addr = ADDR_UNSET, | 1667 | .tuner_addr = ADDR_UNSET, |
1668 | .radio_addr = ADDR_UNSET, | 1668 | .radio_addr = ADDR_UNSET, |
1669 | .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_ACTIVE, | 1669 | .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_INACTIVE, |
1670 | .mpeg = SAA7134_MPEG_DVB, | 1670 | .mpeg = SAA7134_MPEG_DVB, |
1671 | .inputs = {{ | 1671 | .inputs = {{ |
1672 | .name = name_tv, | 1672 | .name = name_tv, |
@@ -1884,44 +1884,38 @@ struct saa7134_board saa7134_boards[] = { | |||
1884 | .gpio = 0x000, | 1884 | .gpio = 0x000, |
1885 | }, | 1885 | }, |
1886 | }, | 1886 | }, |
1887 | [SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS] = { | 1887 | [SAA7134_BOARD_FLYDVBT_DUO_CARDBUS] = { |
1888 | .name = "Typhoon DVB-T Duo Digital/Analog Cardbus", | 1888 | .name = "LifeView/Typhoon FlyDVB-T Duo Cardbus", |
1889 | .audio_clock = 0x00200000, | 1889 | .audio_clock = 0x00200000, |
1890 | .tuner_type = TUNER_PHILIPS_TDA8290, | 1890 | .tuner_type = TUNER_PHILIPS_TDA8290, |
1891 | .radio_type = UNSET, | 1891 | .radio_type = UNSET, |
1892 | .tuner_addr = ADDR_UNSET, | 1892 | .tuner_addr = ADDR_UNSET, |
1893 | .radio_addr = ADDR_UNSET, | 1893 | .radio_addr = ADDR_UNSET, |
1894 | .mpeg = SAA7134_MPEG_DVB, | 1894 | .mpeg = SAA7134_MPEG_DVB, |
1895 | /* .gpiomask = 0xe000, */ | 1895 | .gpiomask = 0x00200000, |
1896 | .inputs = {{ | 1896 | .inputs = {{ |
1897 | .name = name_tv, | 1897 | .name = name_tv, |
1898 | .vmux = 1, | 1898 | .vmux = 1, |
1899 | .amux = TV, | 1899 | .amux = TV, |
1900 | /* .gpio = 0x0000, */ | 1900 | .gpio = 0x200000, /* GPIO21=High for TV input */ |
1901 | .tv = 1, | 1901 | .tv = 1, |
1902 | },{ | 1902 | },{ |
1903 | .name = name_svideo, /* S-Video signal on S-Video input */ | ||
1904 | .vmux = 8, | ||
1905 | .amux = LINE2, | ||
1906 | },{ | ||
1903 | .name = name_comp1, /* Composite signal on S-Video input */ | 1907 | .name = name_comp1, /* Composite signal on S-Video input */ |
1904 | .vmux = 0, | 1908 | .vmux = 0, |
1905 | .amux = LINE2, | 1909 | .amux = LINE2, |
1906 | /* .gpio = 0x4000, */ | ||
1907 | },{ | 1910 | },{ |
1908 | .name = name_comp2, /* Composite input */ | 1911 | .name = name_comp2, /* Composite input */ |
1909 | .vmux = 3, | 1912 | .vmux = 3, |
1910 | .amux = LINE2, | 1913 | .amux = LINE2, |
1911 | /* .gpio = 0x4000, */ | ||
1912 | },{ | ||
1913 | .name = name_svideo, /* S-Video signal on S-Video input */ | ||
1914 | .vmux = 8, | ||
1915 | .amux = LINE2, | ||
1916 | /* .gpio = 0x4000, */ | ||
1917 | }}, | 1914 | }}, |
1918 | .radio = { | 1915 | .radio = { |
1919 | .name = name_radio, | 1916 | .name = name_radio, |
1920 | .amux = LINE2, | 1917 | .amux = TV, |
1921 | }, | 1918 | .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */ |
1922 | .mute = { | ||
1923 | .name = name_mute, | ||
1924 | .amux = LINE1, | ||
1925 | }, | 1919 | }, |
1926 | }, | 1920 | }, |
1927 | [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII] = { | 1921 | [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII] = { |
@@ -2193,7 +2187,7 @@ struct saa7134_board saa7134_boards[] = { | |||
2193 | .radio_type = UNSET, | 2187 | .radio_type = UNSET, |
2194 | .tuner_addr = 0x61, | 2188 | .tuner_addr = 0x61, |
2195 | .radio_addr = ADDR_UNSET, | 2189 | .radio_addr = ADDR_UNSET, |
2196 | .tda9887_conf = TDA9887_PRESENT, | 2190 | .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE, |
2197 | .mpeg = SAA7134_MPEG_DVB, | 2191 | .mpeg = SAA7134_MPEG_DVB, |
2198 | .inputs = {{ | 2192 | .inputs = {{ |
2199 | .name = name_tv, | 2193 | .name = name_tv, |
@@ -2217,7 +2211,7 @@ struct saa7134_board saa7134_boards[] = { | |||
2217 | .radio_type = UNSET, | 2211 | .radio_type = UNSET, |
2218 | .tuner_addr = 0x61, | 2212 | .tuner_addr = 0x61, |
2219 | .radio_addr = ADDR_UNSET, | 2213 | .radio_addr = ADDR_UNSET, |
2220 | .tda9887_conf = TDA9887_PRESENT, | 2214 | .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE, |
2221 | .mpeg = SAA7134_MPEG_DVB, | 2215 | .mpeg = SAA7134_MPEG_DVB, |
2222 | .inputs = {{ | 2216 | .inputs = {{ |
2223 | .name = name_tv, | 2217 | .name = name_tv, |
@@ -2398,7 +2392,7 @@ struct saa7134_board saa7134_boards[] = { | |||
2398 | }}, | 2392 | }}, |
2399 | }, | 2393 | }, |
2400 | [SAA7134_BOARD_PINNACLE_PCTV_110i] = { | 2394 | [SAA7134_BOARD_PINNACLE_PCTV_110i] = { |
2401 | .name = "Pinnacle PCTV 110i (saa7133)", | 2395 | .name = "Pinnacle PCTV 40i/50i/110i (saa7133)", |
2402 | .audio_clock = 0x00187de7, | 2396 | .audio_clock = 0x00187de7, |
2403 | .tuner_type = TUNER_PHILIPS_TDA8290, | 2397 | .tuner_type = TUNER_PHILIPS_TDA8290, |
2404 | .radio_type = UNSET, | 2398 | .radio_type = UNSET, |
@@ -2413,6 +2407,10 @@ struct saa7134_board saa7134_boards[] = { | |||
2413 | },{ | 2407 | },{ |
2414 | .name = name_comp1, | 2408 | .name = name_comp1, |
2415 | .vmux = 1, | 2409 | .vmux = 1, |
2410 | .amux = LINE2, | ||
2411 | },{ | ||
2412 | .name = name_comp2, | ||
2413 | .vmux = 0, | ||
2416 | .amux = LINE2, | 2414 | .amux = LINE2, |
2417 | },{ | 2415 | },{ |
2418 | .name = name_svideo, | 2416 | .name = name_svideo, |
@@ -2701,6 +2699,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2701 | .driver_data = SAA7134_BOARD_FLYVIDEO2000, | 2699 | .driver_data = SAA7134_BOARD_FLYVIDEO2000, |
2702 | },{ | 2700 | },{ |
2703 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2701 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2702 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | ||
2703 | .subvendor = 0x4e42, /* Typhoon */ | ||
2704 | .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */ | ||
2705 | .driver_data = SAA7134_BOARD_FLYVIDEO2000, | ||
2706 | },{ | ||
2707 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2704 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2708 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
2705 | .subvendor = 0x5168, | 2709 | .subvendor = 0x5168, |
2706 | .subdevice = 0x0212, /* minipci, LR212 */ | 2710 | .subdevice = 0x0212, /* minipci, LR212 */ |
@@ -2745,7 +2749,7 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2745 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2749 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2746 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | 2750 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, |
2747 | .subvendor = 0x1048, | 2751 | .subvendor = 0x1048, |
2748 | .subdevice = 0x226b, | 2752 | .subdevice = 0x226a, |
2749 | .driver_data = SAA7134_BOARD_ELSA_500TV, | 2753 | .driver_data = SAA7134_BOARD_ELSA_500TV, |
2750 | },{ | 2754 | },{ |
2751 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2755 | .vendor = PCI_VENDOR_ID_PHILIPS, |
@@ -2935,7 +2939,7 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2935 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2939 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
2936 | .subvendor = 0x5168, | 2940 | .subvendor = 0x5168, |
2937 | .subdevice = 0x0502, /* Cardbus version */ | 2941 | .subdevice = 0x0502, /* Cardbus version */ |
2938 | .driver_data = SAA7134_BOARD_FLYDVBTDUO, | 2942 | .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS, |
2939 | },{ | 2943 | },{ |
2940 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2944 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2941 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2945 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
@@ -2980,12 +2984,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2980 | .subdevice = 0x1370, /* cardbus version */ | 2984 | .subdevice = 0x1370, /* cardbus version */ |
2981 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, | 2985 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, |
2982 | 2986 | ||
2983 | },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */ | 2987 | },{ |
2984 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2988 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2985 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2989 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
2986 | .subvendor = 0x4e42, | 2990 | .subvendor = 0x4e42, /* Typhoon */ |
2987 | .subdevice = 0x0502, | 2991 | .subdevice = 0x0502, /* LifeView LR502 OEM */ |
2988 | .driver_data = SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS, | 2992 | .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS, |
2989 | },{ | 2993 | },{ |
2990 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2994 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2991 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2995 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
@@ -3201,13 +3205,17 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
3201 | /* power-up tuner chip */ | 3205 | /* power-up tuner chip */ |
3202 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); | 3206 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); |
3203 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); | 3207 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); |
3208 | case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: | ||
3209 | /* this turns the remote control chip off to work around a bug in it */ | ||
3210 | saa_writeb(SAA7134_GPIO_GPMODE1, 0x80); | ||
3211 | saa_writeb(SAA7134_GPIO_GPSTATUS1, 0x80); | ||
3212 | break; | ||
3204 | case SAA7134_BOARD_MONSTERTV_MOBILE: | 3213 | case SAA7134_BOARD_MONSTERTV_MOBILE: |
3205 | /* power-up tuner chip */ | 3214 | /* power-up tuner chip */ |
3206 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); | 3215 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); |
3207 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004); | 3216 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004); |
3208 | break; | 3217 | break; |
3209 | case SAA7134_BOARD_FLYDVBTDUO: | 3218 | case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: |
3210 | case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS: | ||
3211 | /* turn the fan on */ | 3219 | /* turn the fan on */ |
3212 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); | 3220 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); |
3213 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); | 3221 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 399f9952596c..9db8e13f21c3 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -110,6 +110,7 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe) | |||
110 | mt352_write(fe, fsm_ctl_cfg, sizeof(fsm_ctl_cfg)); | 110 | mt352_write(fe, fsm_ctl_cfg, sizeof(fsm_ctl_cfg)); |
111 | mt352_write(fe, scan_ctl_cfg, sizeof(scan_ctl_cfg)); | 111 | mt352_write(fe, scan_ctl_cfg, sizeof(scan_ctl_cfg)); |
112 | mt352_write(fe, irq_cfg, sizeof(irq_cfg)); | 112 | mt352_write(fe, irq_cfg, sizeof(irq_cfg)); |
113 | |||
113 | return 0; | 114 | return 0; |
114 | } | 115 | } |
115 | 116 | ||
@@ -117,8 +118,10 @@ static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, | |||
117 | struct dvb_frontend_parameters* params, | 118 | struct dvb_frontend_parameters* params, |
118 | u8* pllbuf) | 119 | u8* pllbuf) |
119 | { | 120 | { |
120 | static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE; | 121 | u8 off[] = { 0x00, 0xf1}; |
121 | static int off = TDA9887_PRESENT | TDA9887_PORT2_ACTIVE; | 122 | u8 on[] = { 0x00, 0x71}; |
123 | struct i2c_msg msg = {.addr=0x43, .flags=0, .buf=off, .len = sizeof(off)}; | ||
124 | |||
122 | struct saa7134_dev *dev = fe->dvb->priv; | 125 | struct saa7134_dev *dev = fe->dvb->priv; |
123 | struct v4l2_frequency f; | 126 | struct v4l2_frequency f; |
124 | 127 | ||
@@ -126,9 +129,10 @@ static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, | |||
126 | f.tuner = 0; | 129 | f.tuner = 0; |
127 | f.type = V4L2_TUNER_DIGITAL_TV; | 130 | f.type = V4L2_TUNER_DIGITAL_TV; |
128 | f.frequency = params->frequency / 1000 * 16 / 1000; | 131 | f.frequency = params->frequency / 1000 * 16 / 1000; |
129 | saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on); | 132 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
130 | saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f); | 133 | saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f); |
131 | saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&off); | 134 | msg.buf = on; |
135 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
132 | 136 | ||
133 | pinnacle_antenna_pwr(dev, antenna_pwr); | 137 | pinnacle_antenna_pwr(dev, antenna_pwr); |
134 | 138 | ||
@@ -861,7 +865,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
861 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, | 865 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, |
862 | &dev->i2c_adap); | 866 | &dev->i2c_adap); |
863 | break; | 867 | break; |
864 | case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS: | 868 | case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: |
865 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, | 869 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, |
866 | &dev->i2c_adap); | 870 | &dev->i2c_adap); |
867 | break; | 871 | break; |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index e70eae8d29bb..3261d8bebdd1 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -185,7 +185,7 @@ struct saa7134_format { | |||
185 | #define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57 | 185 | #define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57 |
186 | #define SAA7134_BOARD_ADS_INSTANT_TV 58 | 186 | #define SAA7134_BOARD_ADS_INSTANT_TV 58 |
187 | #define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59 | 187 | #define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59 |
188 | #define SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS 60 | 188 | #define SAA7134_BOARD_FLYDVBT_DUO_CARDBUS 60 |
189 | #define SAA7134_BOARD_PHILIPS_TOUGH 61 | 189 | #define SAA7134_BOARD_PHILIPS_TOUGH 61 |
190 | #define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62 | 190 | #define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62 |
191 | #define SAA7134_BOARD_KWORLD_XPERT 63 | 191 | #define SAA7134_BOARD_KWORLD_XPERT 63 |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 54fc33011ffb..9d769264a329 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -2012,7 +2012,6 @@ static int __devinit init_saa7146(struct pci_dev *pdev) | |||
2012 | { | 2012 | { |
2013 | struct saa7146 *saa = pci_get_drvdata(pdev); | 2013 | struct saa7146 *saa = pci_get_drvdata(pdev); |
2014 | 2014 | ||
2015 | memset(saa, 0, sizeof(*saa)); | ||
2016 | saa->user = 0; | 2015 | saa->user = 0; |
2017 | /* reset the saa7146 */ | 2016 | /* reset the saa7146 */ |
2018 | saawrite(0xffff0000, SAA7146_MC1); | 2017 | saawrite(0xffff0000, SAA7146_MC1); |
@@ -2062,16 +2061,16 @@ static int __devinit init_saa7146(struct pci_dev *pdev) | |||
2062 | } | 2061 | } |
2063 | if (saa->audbuf == NULL && (saa->audbuf = vmalloc(65536)) == NULL) { | 2062 | if (saa->audbuf == NULL && (saa->audbuf = vmalloc(65536)) == NULL) { |
2064 | dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr); | 2063 | dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr); |
2065 | goto errvid; | 2064 | goto errfree; |
2066 | } | 2065 | } |
2067 | if (saa->osdbuf == NULL && (saa->osdbuf = vmalloc(131072)) == NULL) { | 2066 | if (saa->osdbuf == NULL && (saa->osdbuf = vmalloc(131072)) == NULL) { |
2068 | dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr); | 2067 | dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr); |
2069 | goto erraud; | 2068 | goto errfree; |
2070 | } | 2069 | } |
2071 | /* allocate 81920 byte buffer for clipping */ | 2070 | /* allocate 81920 byte buffer for clipping */ |
2072 | if ((saa->dmavid2 = kzalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) { | 2071 | if ((saa->dmavid2 = kzalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) { |
2073 | dev_err(&pdev->dev, "%d: clip kmalloc failed\n", saa->nr); | 2072 | dev_err(&pdev->dev, "%d: clip kmalloc failed\n", saa->nr); |
2074 | goto errosd; | 2073 | goto errfree; |
2075 | } | 2074 | } |
2076 | /* setup clipping registers */ | 2075 | /* setup clipping registers */ |
2077 | saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2); | 2076 | saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2); |
@@ -2085,15 +2084,11 @@ static int __devinit init_saa7146(struct pci_dev *pdev) | |||
2085 | I2CBusScan(saa); | 2084 | I2CBusScan(saa); |
2086 | 2085 | ||
2087 | return 0; | 2086 | return 0; |
2088 | errosd: | 2087 | errfree: |
2089 | vfree(saa->osdbuf); | 2088 | vfree(saa->osdbuf); |
2090 | saa->osdbuf = NULL; | ||
2091 | erraud: | ||
2092 | vfree(saa->audbuf); | 2089 | vfree(saa->audbuf); |
2093 | saa->audbuf = NULL; | ||
2094 | errvid: | ||
2095 | vfree(saa->vidbuf); | 2090 | vfree(saa->vidbuf); |
2096 | saa->vidbuf = NULL; | 2091 | saa->audbuf = saa->osdbuf = saa->vidbuf = NULL; |
2097 | err: | 2092 | err: |
2098 | return -ENOMEM; | 2093 | return -ENOMEM; |
2099 | } | 2094 | } |
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index 7b4fb282ac82..a796a4e1917c 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c | |||
@@ -580,9 +580,10 @@ int tda8290_init(struct i2c_client *c) | |||
580 | 580 | ||
581 | int tda8290_probe(struct i2c_client *c) | 581 | int tda8290_probe(struct i2c_client *c) |
582 | { | 582 | { |
583 | unsigned char soft_reset[] = { 0x00, 0x00 }; | 583 | unsigned char soft_reset[] = { 0x00, 0x00 }; |
584 | unsigned char easy_mode_b[] = { 0x01, 0x02 }; | 584 | unsigned char easy_mode_b[] = { 0x01, 0x02 }; |
585 | unsigned char easy_mode_g[] = { 0x01, 0x04 }; | 585 | unsigned char easy_mode_g[] = { 0x01, 0x04 }; |
586 | unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 }; | ||
586 | unsigned char addr_dto_lsb = 0x07; | 587 | unsigned char addr_dto_lsb = 0x07; |
587 | unsigned char data; | 588 | unsigned char data; |
588 | 589 | ||
@@ -599,6 +600,7 @@ int tda8290_probe(struct i2c_client *c) | |||
599 | return 0; | 600 | return 0; |
600 | } | 601 | } |
601 | } | 602 | } |
603 | i2c_master_send(c, restore_9886, 3); | ||
602 | return -1; | 604 | return -1; |
603 | } | 605 | } |
604 | 606 | ||
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 5815649bdc78..0d54f6c1982b 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
@@ -231,7 +231,7 @@ static struct tvnorm tvnorms[] = { | |||
231 | cAudioIF_6_5 | | 231 | cAudioIF_6_5 | |
232 | cVideoIF_38_90 ), | 232 | cVideoIF_38_90 ), |
233 | },{ | 233 | },{ |
234 | .std = V4L2_STD_NTSC_M, | 234 | .std = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, |
235 | .name = "NTSC-M", | 235 | .name = "NTSC-M", |
236 | .b = ( cNegativeFmTV | | 236 | .b = ( cNegativeFmTV | |
237 | cQSS ), | 237 | cQSS ), |
@@ -619,6 +619,11 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
619 | tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); | 619 | tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); |
620 | t->std = V4L2_STD_NTSC_M_JP; | 620 | t->std = V4L2_STD_NTSC_M_JP; |
621 | break; | 621 | break; |
622 | case 'k': | ||
623 | case 'K': | ||
624 | tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n"); | ||
625 | t->std = V4L2_STD_NTSC_M_KR; | ||
626 | break; | ||
622 | case '-': | 627 | case '-': |
623 | /* default parameter, do nothing */ | 628 | /* default parameter, do nothing */ |
624 | break; | 629 | break; |
@@ -876,7 +881,7 @@ static int tda9887_resume(struct device * dev) | |||
876 | /* ----------------------------------------------------------------------- */ | 881 | /* ----------------------------------------------------------------------- */ |
877 | 882 | ||
878 | static struct i2c_driver driver = { | 883 | static struct i2c_driver driver = { |
879 | .id = -1, /* FIXME */ | 884 | .id = I2C_DRIVERID_TDA9887, |
880 | .attach_adapter = tda9887_probe, | 885 | .attach_adapter = tda9887_probe, |
881 | .detach_client = tda9887_detach, | 886 | .detach_client = tda9887_detach, |
882 | .command = tda9887_command, | 887 | .command = tda9887_command, |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 2995b22acb43..b6101bf446d4 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -216,6 +216,7 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
216 | buffer[3] = 0xa4; | 216 | buffer[3] = 0xa4; |
217 | i2c_master_send(c,buffer,4); | 217 | i2c_master_send(c,buffer,4); |
218 | default_tuner_init(c); | 218 | default_tuner_init(c); |
219 | break; | ||
219 | default: | 220 | default: |
220 | default_tuner_init(c); | 221 | default_tuner_init(c); |
221 | break; | 222 | break; |
@@ -365,6 +366,11 @@ static int tuner_fixup_std(struct tuner *t) | |||
365 | tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); | 366 | tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); |
366 | t->std = V4L2_STD_NTSC_M_JP; | 367 | t->std = V4L2_STD_NTSC_M_JP; |
367 | break; | 368 | break; |
369 | case 'k': | ||
370 | case 'K': | ||
371 | tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n"); | ||
372 | t->std = V4L2_STD_NTSC_M_KR; | ||
373 | break; | ||
368 | case '-': | 374 | case '-': |
369 | /* default parameter, do nothing */ | 375 | /* default parameter, do nothing */ |
370 | break; | 376 | break; |
@@ -448,7 +454,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
448 | printk("%02x ",buffer[i]); | 454 | printk("%02x ",buffer[i]); |
449 | printk("\n"); | 455 | printk("\n"); |
450 | } | 456 | } |
451 | /* TEA5767 autodetection code - only for addr = 0xc0 */ | 457 | /* autodetection code based on the i2c addr */ |
452 | if (!no_autodetect) { | 458 | if (!no_autodetect) { |
453 | switch (addr) { | 459 | switch (addr) { |
454 | case 0x42: | 460 | case 0x42: |
@@ -707,8 +713,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
707 | struct v4l2_frequency *f = arg; | 713 | struct v4l2_frequency *f = arg; |
708 | 714 | ||
709 | switch_v4l2(); | 715 | switch_v4l2(); |
710 | if (V4L2_TUNER_RADIO == f->type && | 716 | if ((V4L2_TUNER_RADIO == f->type && V4L2_TUNER_RADIO != t->mode) |
711 | V4L2_TUNER_RADIO != t->mode) { | 717 | || (V4L2_TUNER_DIGITAL_TV == f->type |
718 | && V4L2_TUNER_DIGITAL_TV != t->mode)) { | ||
712 | if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") | 719 | if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") |
713 | == EINVAL) | 720 | == EINVAL) |
714 | return 0; | 721 | return 0; |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 6d03b9b05c6e..c8e5ad0e8185 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
@@ -390,6 +390,14 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode) | |||
390 | chip_write(chip, TDA9840_SW, t); | 390 | chip_write(chip, TDA9840_SW, t); |
391 | } | 391 | } |
392 | 392 | ||
393 | static int tda9840_checkit(struct CHIPSTATE *chip) | ||
394 | { | ||
395 | int rc; | ||
396 | rc = chip_read(chip); | ||
397 | /* lower 5 bits should be 0 */ | ||
398 | return ((rc & 0x1f) == 0) ? 1 : 0; | ||
399 | } | ||
400 | |||
393 | /* ---------------------------------------------------------------------- */ | 401 | /* ---------------------------------------------------------------------- */ |
394 | /* audio chip descriptions - defines+functions for tda985x */ | 402 | /* audio chip descriptions - defines+functions for tda985x */ |
395 | 403 | ||
@@ -1264,6 +1272,7 @@ static struct CHIPDESC chiplist[] = { | |||
1264 | .addr_hi = I2C_TDA9840 >> 1, | 1272 | .addr_hi = I2C_TDA9840 >> 1, |
1265 | .registers = 5, | 1273 | .registers = 5, |
1266 | 1274 | ||
1275 | .checkit = tda9840_checkit, | ||
1267 | .getmode = tda9840_getmode, | 1276 | .getmode = tda9840_getmode, |
1268 | .setmode = tda9840_setmode, | 1277 | .setmode = tda9840_setmode, |
1269 | .checkmode = generic_checkmode, | 1278 | .checkmode = generic_checkmode, |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index fad9ea0ae4f2..1864423b3046 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -746,24 +746,27 @@ static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std) | |||
746 | 746 | ||
747 | static inline void tvp5150_reset(struct i2c_client *c) | 747 | static inline void tvp5150_reset(struct i2c_client *c) |
748 | { | 748 | { |
749 | u8 type, ver_656, msb_id, lsb_id, msb_rom, lsb_rom; | 749 | u8 msb_id, lsb_id, msb_rom, lsb_rom; |
750 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 750 | struct tvp5150 *decoder = i2c_get_clientdata(c); |
751 | 751 | ||
752 | type=tvp5150_read(c,TVP5150_AUTOSW_MSK); | ||
753 | msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID); | 752 | msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID); |
754 | lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID); | 753 | lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID); |
755 | msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER); | 754 | msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER); |
756 | lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER); | 755 | lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER); |
757 | 756 | ||
758 | if (type==0xdc) { | 757 | if ((msb_rom==4)&&(lsb_rom==0)) { /* Is TVP5150AM1 */ |
759 | ver_656=tvp5150_read(c,TVP5150_REV_SELECT); | 758 | tvp5150_info("tvp%02x%02xam1 detected.\n",msb_id, lsb_id); |
760 | tvp5150_info("tvp%02x%02xam1 detected 656 version is %d.\n",msb_id, lsb_id,ver_656); | 759 | |
761 | } else if (type==0xfc) { | 760 | /* ITU-T BT.656.4 timing */ |
762 | tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id); | 761 | tvp5150_write(c,TVP5150_REV_SELECT,0); |
763 | } else { | 762 | } else { |
764 | tvp5150_info("unknown tvp%02x%02x chip detected(%d).\n",msb_id,lsb_id,type); | 763 | if ((msb_rom==3)||(lsb_rom==0x21)) { /* Is TVP5150A */ |
764 | tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id); | ||
765 | } else { | ||
766 | tvp5150_info("*** unknown tvp%02x%02x chip detected.\n",msb_id,lsb_id); | ||
767 | tvp5150_info("*** Rom ver is %d.%d\n",msb_rom,lsb_rom); | ||
768 | } | ||
765 | } | 769 | } |
766 | tvp5150_info("Rom ver is %d.%d\n",msb_rom,lsb_rom); | ||
767 | 770 | ||
768 | /* Initializes TVP5150 to its default values */ | 771 | /* Initializes TVP5150 to its default values */ |
769 | tvp5150_write_inittab(c, tvp5150_init_default); | 772 | tvp5150_write_inittab(c, tvp5150_init_default); |
@@ -893,6 +896,17 @@ static int tvp5150_command(struct i2c_client *c, | |||
893 | } | 896 | } |
894 | case DECODER_GET_STATUS: | 897 | case DECODER_GET_STATUS: |
895 | { | 898 | { |
899 | int *iarg = arg; | ||
900 | int status; | ||
901 | int res=0; | ||
902 | status = tvp5150_read(c, 0x88); | ||
903 | if(status&0x08){ | ||
904 | res |= DECODER_STATUS_COLOR; | ||
905 | } | ||
906 | if(status&0x04 && status&0x02){ | ||
907 | res |= DECODER_STATUS_GOOD; | ||
908 | } | ||
909 | *iarg=res; | ||
896 | break; | 910 | break; |
897 | } | 911 | } |
898 | 912 | ||
diff --git a/drivers/media/video/videocodec.h b/drivers/media/video/videocodec.h index 156ae57096fe..b1239ac7f371 100644 --- a/drivers/media/video/videocodec.h +++ b/drivers/media/video/videocodec.h | |||
@@ -56,7 +56,7 @@ | |||
56 | the slave is bound to it). Otherwise it doesn't need this functions and | 56 | the slave is bound to it). Otherwise it doesn't need this functions and |
57 | therfor they may not be initialized. | 57 | therfor they may not be initialized. |
58 | 58 | ||
59 | The other fuctions are just for convenience, as they are for shure used by | 59 | The other fuctions are just for convenience, as they are for sure used by |
60 | most/all of the codecs. The last ones may be ommited, too. | 60 | most/all of the codecs. The last ones may be ommited, too. |
61 | 61 | ||
62 | See the structure declaration below for more information and which data has | 62 | See the structure declaration below for more information and which data has |
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c index bd0cd28543ca..6699725be605 100644 --- a/drivers/media/video/zr36050.c +++ b/drivers/media/video/zr36050.c | |||
@@ -159,7 +159,7 @@ zr36050_wait_end (struct zr36050 *ptr) | |||
159 | 159 | ||
160 | while (!(zr36050_read_status1(ptr) & 0x4)) { | 160 | while (!(zr36050_read_status1(ptr) & 0x4)) { |
161 | udelay(1); | 161 | udelay(1); |
162 | if (i++ > 200000) { // 200ms, there is for shure something wrong!!! | 162 | if (i++ > 200000) { // 200ms, there is for sure something wrong!!! |
163 | dprintk(1, | 163 | dprintk(1, |
164 | "%s: timout at wait_end (last status: 0x%02x)\n", | 164 | "%s: timout at wait_end (last status: 0x%02x)\n", |
165 | ptr->name, ptr->status1); | 165 | ptr->name, ptr->status1); |
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c index 28fa31a5f150..d8dd003a7aad 100644 --- a/drivers/media/video/zr36060.c +++ b/drivers/media/video/zr36060.c | |||
@@ -161,7 +161,7 @@ zr36060_wait_end (struct zr36060 *ptr) | |||
161 | 161 | ||
162 | while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) { | 162 | while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) { |
163 | udelay(1); | 163 | udelay(1); |
164 | if (i++ > 200000) { // 200ms, there is for shure something wrong!!! | 164 | if (i++ > 200000) { // 200ms, there is for sure something wrong!!! |
165 | dprintk(1, | 165 | dprintk(1, |
166 | "%s: timout at wait_end (last status: 0x%02x)\n", | 166 | "%s: timout at wait_end (last status: 0x%02x)\n", |
167 | ptr->name, ptr->status); | 167 | ptr->name, ptr->status); |
diff --git a/drivers/media/video/zr36120_i2c.c b/drivers/media/video/zr36120_i2c.c index 6bfe84d657f1..21fde43a6aed 100644 --- a/drivers/media/video/zr36120_i2c.c +++ b/drivers/media/video/zr36120_i2c.c | |||
@@ -65,7 +65,7 @@ void attach_inform(struct i2c_bus *bus, int id) | |||
65 | case I2C_DRIVERID_VIDEODECODER: | 65 | case I2C_DRIVERID_VIDEODECODER: |
66 | DEBUG(printk(CARD_INFO "decoder attached\n",CARD)); | 66 | DEBUG(printk(CARD_INFO "decoder attached\n",CARD)); |
67 | 67 | ||
68 | /* fetch the capabilites of the decoder */ | 68 | /* fetch the capabilities of the decoder */ |
69 | rv = i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_CAPABILITIES, &dc); | 69 | rv = i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_CAPABILITIES, &dc); |
70 | if (rv) { | 70 | if (rv) { |
71 | DEBUG(printk(CARD_DEBUG "decoder is not V4L aware!\n",CARD)); | 71 | DEBUG(printk(CARD_DEBUG "decoder is not V4L aware!\n",CARD)); |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 9a2c7605d49c..642a61b6d0a4 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -452,8 +452,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) | |||
452 | } else if (func == MPI_FUNCTION_EVENT_ACK) { | 452 | } else if (func == MPI_FUNCTION_EVENT_ACK) { |
453 | dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n", | 453 | dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n", |
454 | ioc->name)); | 454 | ioc->name)); |
455 | } else if (func == MPI_FUNCTION_CONFIG || | 455 | } else if (func == MPI_FUNCTION_CONFIG) { |
456 | func == MPI_FUNCTION_TOOLBOX) { | ||
457 | CONFIGPARMS *pCfg; | 456 | CONFIGPARMS *pCfg; |
458 | unsigned long flags; | 457 | unsigned long flags; |
459 | 458 | ||
@@ -5327,115 +5326,6 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) | |||
5327 | } | 5326 | } |
5328 | 5327 | ||
5329 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 5328 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
5330 | /** | ||
5331 | * mpt_toolbox - Generic function to issue toolbox message | ||
5332 | * @ioc - Pointer to an adapter structure | ||
5333 | * @cfg - Pointer to a toolbox structure. Struct contains | ||
5334 | * action, page address, direction, physical address | ||
5335 | * and pointer to a configuration page header | ||
5336 | * Page header is updated. | ||
5337 | * | ||
5338 | * Returns 0 for success | ||
5339 | * -EPERM if not allowed due to ISR context | ||
5340 | * -EAGAIN if no msg frames currently available | ||
5341 | * -EFAULT for non-successful reply or no reply (timeout) | ||
5342 | */ | ||
5343 | int | ||
5344 | mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) | ||
5345 | { | ||
5346 | ToolboxIstwiReadWriteRequest_t *pReq; | ||
5347 | MPT_FRAME_HDR *mf; | ||
5348 | struct pci_dev *pdev; | ||
5349 | unsigned long flags; | ||
5350 | int rc; | ||
5351 | u32 flagsLength; | ||
5352 | int in_isr; | ||
5353 | |||
5354 | /* Prevent calling wait_event() (below), if caller happens | ||
5355 | * to be in ISR context, because that is fatal! | ||
5356 | */ | ||
5357 | in_isr = in_interrupt(); | ||
5358 | if (in_isr) { | ||
5359 | dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n", | ||
5360 | ioc->name)); | ||
5361 | return -EPERM; | ||
5362 | } | ||
5363 | |||
5364 | /* Get and Populate a free Frame | ||
5365 | */ | ||
5366 | if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { | ||
5367 | dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n", | ||
5368 | ioc->name)); | ||
5369 | return -EAGAIN; | ||
5370 | } | ||
5371 | pReq = (ToolboxIstwiReadWriteRequest_t *)mf; | ||
5372 | pReq->Tool = pCfg->action; | ||
5373 | pReq->Reserved = 0; | ||
5374 | pReq->ChainOffset = 0; | ||
5375 | pReq->Function = MPI_FUNCTION_TOOLBOX; | ||
5376 | pReq->Reserved1 = 0; | ||
5377 | pReq->Reserved2 = 0; | ||
5378 | pReq->MsgFlags = 0; | ||
5379 | pReq->Flags = pCfg->dir; | ||
5380 | pReq->BusNum = 0; | ||
5381 | pReq->Reserved3 = 0; | ||
5382 | pReq->NumAddressBytes = 0x01; | ||
5383 | pReq->Reserved4 = 0; | ||
5384 | pReq->DataLength = cpu_to_le16(0x04); | ||
5385 | pdev = ioc->pcidev; | ||
5386 | if (pdev->devfn & 1) | ||
5387 | pReq->DeviceAddr = 0xB2; | ||
5388 | else | ||
5389 | pReq->DeviceAddr = 0xB0; | ||
5390 | pReq->Addr1 = 0; | ||
5391 | pReq->Addr2 = 0; | ||
5392 | pReq->Addr3 = 0; | ||
5393 | pReq->Reserved5 = 0; | ||
5394 | |||
5395 | /* Add a SGE to the config request. | ||
5396 | */ | ||
5397 | |||
5398 | flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4; | ||
5399 | |||
5400 | mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr); | ||
5401 | |||
5402 | dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n", | ||
5403 | ioc->name, pReq->Tool)); | ||
5404 | |||
5405 | /* Append pCfg pointer to end of mf | ||
5406 | */ | ||
5407 | *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg; | ||
5408 | |||
5409 | /* Initalize the timer | ||
5410 | */ | ||
5411 | init_timer(&pCfg->timer); | ||
5412 | pCfg->timer.data = (unsigned long) ioc; | ||
5413 | pCfg->timer.function = mpt_timer_expired; | ||
5414 | pCfg->wait_done = 0; | ||
5415 | |||
5416 | /* Set the timer; ensure 10 second minimum */ | ||
5417 | if (pCfg->timeout < 10) | ||
5418 | pCfg->timer.expires = jiffies + HZ*10; | ||
5419 | else | ||
5420 | pCfg->timer.expires = jiffies + HZ*pCfg->timeout; | ||
5421 | |||
5422 | /* Add to end of Q, set timer and then issue this command */ | ||
5423 | spin_lock_irqsave(&ioc->FreeQlock, flags); | ||
5424 | list_add_tail(&pCfg->linkage, &ioc->configQ); | ||
5425 | spin_unlock_irqrestore(&ioc->FreeQlock, flags); | ||
5426 | |||
5427 | add_timer(&pCfg->timer); | ||
5428 | mpt_put_msg_frame(mpt_base_index, ioc, mf); | ||
5429 | wait_event(mpt_waitq, pCfg->wait_done); | ||
5430 | |||
5431 | /* mf has been freed - do not access */ | ||
5432 | |||
5433 | rc = pCfg->status; | ||
5434 | |||
5435 | return rc; | ||
5436 | } | ||
5437 | |||
5438 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
5439 | /* | 5329 | /* |
5440 | * mpt_timer_expired - Call back for timer process. | 5330 | * mpt_timer_expired - Call back for timer process. |
5441 | * Used only internal config functionality. | 5331 | * Used only internal config functionality. |
@@ -6142,7 +6032,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply | |||
6142 | if (ioc->events && (ioc->eventTypes & ( 1 << event))) { | 6032 | if (ioc->events && (ioc->eventTypes & ( 1 << event))) { |
6143 | int idx; | 6033 | int idx; |
6144 | 6034 | ||
6145 | idx = ioc->eventContext % ioc->eventLogSize; | 6035 | idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; |
6146 | 6036 | ||
6147 | ioc->events[idx].event = event; | 6037 | ioc->events[idx].event = event; |
6148 | ioc->events[idx].eventContext = ioc->eventContext; | 6038 | ioc->events[idx].eventContext = ioc->eventContext; |
@@ -6540,7 +6430,6 @@ EXPORT_SYMBOL(mpt_lan_index); | |||
6540 | EXPORT_SYMBOL(mpt_stm_index); | 6430 | EXPORT_SYMBOL(mpt_stm_index); |
6541 | EXPORT_SYMBOL(mpt_HardResetHandler); | 6431 | EXPORT_SYMBOL(mpt_HardResetHandler); |
6542 | EXPORT_SYMBOL(mpt_config); | 6432 | EXPORT_SYMBOL(mpt_config); |
6543 | EXPORT_SYMBOL(mpt_toolbox); | ||
6544 | EXPORT_SYMBOL(mpt_findImVolumes); | 6433 | EXPORT_SYMBOL(mpt_findImVolumes); |
6545 | EXPORT_SYMBOL(mpt_read_ioc_pg_3); | 6434 | EXPORT_SYMBOL(mpt_read_ioc_pg_3); |
6546 | EXPORT_SYMBOL(mpt_alloc_fw_memory); | 6435 | EXPORT_SYMBOL(mpt_alloc_fw_memory); |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index ea2649ecad1f..723d54300953 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -616,6 +616,7 @@ typedef struct _MPT_ADAPTER | |||
616 | * increments by 32 bytes | 616 | * increments by 32 bytes |
617 | */ | 617 | */ |
618 | int errata_flag_1064; | 618 | int errata_flag_1064; |
619 | int aen_event_read_flag; /* flag to indicate event log was read*/ | ||
619 | u8 FirstWhoInit; | 620 | u8 FirstWhoInit; |
620 | u8 upload_fw; /* If set, do a fw upload */ | 621 | u8 upload_fw; /* If set, do a fw upload */ |
621 | u8 reload_fw; /* Force a FW Reload on next reset */ | 622 | u8 reload_fw; /* Force a FW Reload on next reset */ |
@@ -1026,7 +1027,6 @@ extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); | |||
1026 | extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); | 1027 | extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); |
1027 | extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); | 1028 | extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); |
1028 | extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); | 1029 | extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); |
1029 | extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); | ||
1030 | extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); | 1030 | extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); |
1031 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); | 1031 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); |
1032 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); | 1032 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index bdf709987982..9b64e07400da 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -136,6 +136,12 @@ static void mptctl_free_tm_flags(MPT_ADAPTER *ioc); | |||
136 | */ | 136 | */ |
137 | static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase); | 137 | static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase); |
138 | 138 | ||
139 | /* | ||
140 | * Event Handler function | ||
141 | */ | ||
142 | static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); | ||
143 | struct fasync_struct *async_queue=NULL; | ||
144 | |||
139 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 145 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
140 | /* | 146 | /* |
141 | * Scatter gather list (SGL) sizes and limits... | 147 | * Scatter gather list (SGL) sizes and limits... |
@@ -385,18 +391,18 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) | |||
385 | } | 391 | } |
386 | 392 | ||
387 | /* Now wait for the command to complete */ | 393 | /* Now wait for the command to complete */ |
388 | ii = wait_event_interruptible_timeout(mptctl_wait, | 394 | ii = wait_event_timeout(mptctl_wait, |
389 | ioctl->wait_done == 1, | 395 | ioctl->wait_done == 1, |
390 | HZ*5 /* 5 second timeout */); | 396 | HZ*5 /* 5 second timeout */); |
391 | 397 | ||
392 | if(ii <=0 && (ioctl->wait_done != 1 )) { | 398 | if(ii <=0 && (ioctl->wait_done != 1 )) { |
399 | mpt_free_msg_frame(hd->ioc, mf); | ||
393 | ioctl->wait_done = 0; | 400 | ioctl->wait_done = 0; |
394 | retval = -1; /* return failure */ | 401 | retval = -1; /* return failure */ |
395 | } | 402 | } |
396 | 403 | ||
397 | mptctl_bus_reset_done: | 404 | mptctl_bus_reset_done: |
398 | 405 | ||
399 | mpt_free_msg_frame(hd->ioc, mf); | ||
400 | mptctl_free_tm_flags(ioctl->ioc); | 406 | mptctl_free_tm_flags(ioctl->ioc); |
401 | return retval; | 407 | return retval; |
402 | } | 408 | } |
@@ -472,6 +478,69 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
472 | } | 478 | } |
473 | 479 | ||
474 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 480 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
481 | /* ASYNC Event Notification Support */ | ||
482 | static int | ||
483 | mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | ||
484 | { | ||
485 | u8 event; | ||
486 | |||
487 | event = le32_to_cpu(pEvReply->Event) & 0xFF; | ||
488 | |||
489 | dctlprintk(("%s() called\n", __FUNCTION__)); | ||
490 | if(async_queue == NULL) | ||
491 | return 1; | ||
492 | |||
493 | /* Raise SIGIO for persistent events. | ||
494 | * TODO - this define is not in MPI spec yet, | ||
495 | * but they plan to set it to 0x21 | ||
496 | */ | ||
497 | if (event == 0x21 ) { | ||
498 | ioc->aen_event_read_flag=1; | ||
499 | dctlprintk(("Raised SIGIO to application\n")); | ||
500 | devtprintk(("Raised SIGIO to application\n")); | ||
501 | kill_fasync(&async_queue, SIGIO, POLL_IN); | ||
502 | return 1; | ||
503 | } | ||
504 | |||
505 | /* This flag is set after SIGIO was raised, and | ||
506 | * remains set until the application has read | ||
507 | * the event log via ioctl=MPTEVENTREPORT | ||
508 | */ | ||
509 | if(ioc->aen_event_read_flag) | ||
510 | return 1; | ||
511 | |||
512 | /* Signal only for the events that are | ||
513 | * requested for by the application | ||
514 | */ | ||
515 | if (ioc->events && (ioc->eventTypes & ( 1 << event))) { | ||
516 | ioc->aen_event_read_flag=1; | ||
517 | dctlprintk(("Raised SIGIO to application\n")); | ||
518 | devtprintk(("Raised SIGIO to application\n")); | ||
519 | kill_fasync(&async_queue, SIGIO, POLL_IN); | ||
520 | } | ||
521 | return 1; | ||
522 | } | ||
523 | |||
524 | static int | ||
525 | mptctl_fasync(int fd, struct file *filep, int mode) | ||
526 | { | ||
527 | MPT_ADAPTER *ioc; | ||
528 | |||
529 | list_for_each_entry(ioc, &ioc_list, list) | ||
530 | ioc->aen_event_read_flag=0; | ||
531 | |||
532 | dctlprintk(("%s() called\n", __FUNCTION__)); | ||
533 | return fasync_helper(fd, filep, mode, &async_queue); | ||
534 | } | ||
535 | |||
536 | static int | ||
537 | mptctl_release(struct inode *inode, struct file *filep) | ||
538 | { | ||
539 | dctlprintk(("%s() called\n", __FUNCTION__)); | ||
540 | return fasync_helper(-1, filep, 0, &async_queue); | ||
541 | } | ||
542 | |||
543 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
475 | /* | 544 | /* |
476 | * MPT ioctl handler | 545 | * MPT ioctl handler |
477 | * cmd - specify the particular IOCTL command to be issued | 546 | * cmd - specify the particular IOCTL command to be issued |
@@ -674,22 +743,23 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) | |||
674 | u16 iocstat; | 743 | u16 iocstat; |
675 | pFWDownloadReply_t ReplyMsg = NULL; | 744 | pFWDownloadReply_t ReplyMsg = NULL; |
676 | 745 | ||
677 | dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id)); | 746 | dctlprintk(("mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id)); |
678 | 747 | ||
679 | dctlprintk((KERN_INFO "DbG: kfwdl.bufp = %p\n", ufwbuf)); | 748 | dctlprintk(("DbG: kfwdl.bufp = %p\n", ufwbuf)); |
680 | dctlprintk((KERN_INFO "DbG: kfwdl.fwlen = %d\n", (int)fwlen)); | 749 | dctlprintk(("DbG: kfwdl.fwlen = %d\n", (int)fwlen)); |
681 | dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc)); | 750 | dctlprintk(("DbG: kfwdl.ioc = %04xh\n", ioc)); |
682 | 751 | ||
683 | if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) { | 752 | if (mpt_verify_adapter(ioc, &iocp) < 0) { |
684 | dctlprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n", | 753 | dctlprintk(("ioctl_fwdl - ioc%d not found!\n", |
685 | __FILE__, __LINE__, ioc)); | 754 | ioc)); |
686 | return -ENODEV; /* (-6) No such device or address */ | 755 | return -ENODEV; /* (-6) No such device or address */ |
687 | } | 756 | } else { |
688 | 757 | ||
689 | /* Valid device. Get a message frame and construct the FW download message. | 758 | /* Valid device. Get a message frame and construct the FW download message. |
690 | */ | 759 | */ |
691 | if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) | 760 | if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) |
692 | return -EAGAIN; | 761 | return -EAGAIN; |
762 | } | ||
693 | dlmsg = (FWDownload_t*) mf; | 763 | dlmsg = (FWDownload_t*) mf; |
694 | ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; | 764 | ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; |
695 | sgOut = (char *) (ptsge + 1); | 765 | sgOut = (char *) (ptsge + 1); |
@@ -702,7 +772,11 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) | |||
702 | dlmsg->ChainOffset = 0; | 772 | dlmsg->ChainOffset = 0; |
703 | dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD; | 773 | dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD; |
704 | dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0; | 774 | dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0; |
705 | dlmsg->MsgFlags = 0; | 775 | if (iocp->facts.MsgVersion >= MPI_VERSION_01_05) |
776 | dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT; | ||
777 | else | ||
778 | dlmsg->MsgFlags = 0; | ||
779 | |||
706 | 780 | ||
707 | /* Set up the Transaction SGE. | 781 | /* Set up the Transaction SGE. |
708 | */ | 782 | */ |
@@ -754,7 +828,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) | |||
754 | goto fwdl_out; | 828 | goto fwdl_out; |
755 | } | 829 | } |
756 | 830 | ||
757 | dctlprintk((KERN_INFO "DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags)); | 831 | dctlprintk(("DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags)); |
758 | 832 | ||
759 | /* | 833 | /* |
760 | * Parse SG list, copying sgl itself, | 834 | * Parse SG list, copying sgl itself, |
@@ -803,11 +877,11 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) | |||
803 | /* | 877 | /* |
804 | * Finally, perform firmware download. | 878 | * Finally, perform firmware download. |
805 | */ | 879 | */ |
806 | iocp->ioctl->wait_done = 0; | 880 | ReplyMsg = NULL; |
807 | mpt_put_msg_frame(mptctl_id, iocp, mf); | 881 | mpt_put_msg_frame(mptctl_id, iocp, mf); |
808 | 882 | ||
809 | /* Now wait for the command to complete */ | 883 | /* Now wait for the command to complete */ |
810 | ret = wait_event_interruptible_timeout(mptctl_wait, | 884 | ret = wait_event_timeout(mptctl_wait, |
811 | iocp->ioctl->wait_done == 1, | 885 | iocp->ioctl->wait_done == 1, |
812 | HZ*60); | 886 | HZ*60); |
813 | 887 | ||
@@ -1145,7 +1219,9 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) | |||
1145 | /* Fill in the data and return the structure to the calling | 1219 | /* Fill in the data and return the structure to the calling |
1146 | * program | 1220 | * program |
1147 | */ | 1221 | */ |
1148 | if (ioc->bus_type == FC) | 1222 | if (ioc->bus_type == SAS) |
1223 | karg->adapterType = MPT_IOCTL_INTERFACE_SAS; | ||
1224 | else if (ioc->bus_type == FC) | ||
1149 | karg->adapterType = MPT_IOCTL_INTERFACE_FC; | 1225 | karg->adapterType = MPT_IOCTL_INTERFACE_FC; |
1150 | else | 1226 | else |
1151 | karg->adapterType = MPT_IOCTL_INTERFACE_SCSI; | 1227 | karg->adapterType = MPT_IOCTL_INTERFACE_SCSI; |
@@ -1170,12 +1246,11 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) | |||
1170 | karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); | 1246 | karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); |
1171 | karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); | 1247 | karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); |
1172 | } else if (cim_rev == 2) { | 1248 | } else if (cim_rev == 2) { |
1173 | /* Get the PCI bus, device, function and segment ID numbers | 1249 | /* Get the PCI bus, device, function and segment ID numbers |
1174 | for the IOC */ | 1250 | for the IOC */ |
1175 | karg->pciInfo.u.bits.busNumber = pdev->bus->number; | 1251 | karg->pciInfo.u.bits.busNumber = pdev->bus->number; |
1176 | karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); | 1252 | karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); |
1177 | karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); | 1253 | karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); |
1178 | karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); | ||
1179 | karg->pciInfo.segmentID = pci_domain_nr(pdev->bus); | 1254 | karg->pciInfo.segmentID = pci_domain_nr(pdev->bus); |
1180 | } | 1255 | } |
1181 | 1256 | ||
@@ -1500,7 +1575,7 @@ mptctl_eventquery (unsigned long arg) | |||
1500 | return -ENODEV; | 1575 | return -ENODEV; |
1501 | } | 1576 | } |
1502 | 1577 | ||
1503 | karg.eventEntries = ioc->eventLogSize; | 1578 | karg.eventEntries = MPTCTL_EVENT_LOG_SIZE; |
1504 | karg.eventTypes = ioc->eventTypes; | 1579 | karg.eventTypes = ioc->eventTypes; |
1505 | 1580 | ||
1506 | /* Copy the data from kernel memory to user memory | 1581 | /* Copy the data from kernel memory to user memory |
@@ -1550,7 +1625,6 @@ mptctl_eventenable (unsigned long arg) | |||
1550 | memset(ioc->events, 0, sz); | 1625 | memset(ioc->events, 0, sz); |
1551 | ioc->alloc_total += sz; | 1626 | ioc->alloc_total += sz; |
1552 | 1627 | ||
1553 | ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE; | ||
1554 | ioc->eventContext = 0; | 1628 | ioc->eventContext = 0; |
1555 | } | 1629 | } |
1556 | 1630 | ||
@@ -1590,7 +1664,7 @@ mptctl_eventreport (unsigned long arg) | |||
1590 | maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS); | 1664 | maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS); |
1591 | 1665 | ||
1592 | 1666 | ||
1593 | max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents; | 1667 | max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents; |
1594 | 1668 | ||
1595 | /* If fewer than 1 event is requested, there must have | 1669 | /* If fewer than 1 event is requested, there must have |
1596 | * been some type of error. | 1670 | * been some type of error. |
@@ -1598,6 +1672,9 @@ mptctl_eventreport (unsigned long arg) | |||
1598 | if ((max < 1) || !ioc->events) | 1672 | if ((max < 1) || !ioc->events) |
1599 | return -ENODATA; | 1673 | return -ENODATA; |
1600 | 1674 | ||
1675 | /* reset this flag so SIGIO can restart */ | ||
1676 | ioc->aen_event_read_flag=0; | ||
1677 | |||
1601 | /* Copy the data from kernel memory to user memory | 1678 | /* Copy the data from kernel memory to user memory |
1602 | */ | 1679 | */ |
1603 | numBytes = max * sizeof(MPT_IOCTL_EVENTS); | 1680 | numBytes = max * sizeof(MPT_IOCTL_EVENTS); |
@@ -1817,6 +1894,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1817 | case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: | 1894 | case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: |
1818 | case MPI_FUNCTION_FW_DOWNLOAD: | 1895 | case MPI_FUNCTION_FW_DOWNLOAD: |
1819 | case MPI_FUNCTION_FC_PRIMITIVE_SEND: | 1896 | case MPI_FUNCTION_FC_PRIMITIVE_SEND: |
1897 | case MPI_FUNCTION_TOOLBOX: | ||
1898 | case MPI_FUNCTION_SAS_IO_UNIT_CONTROL: | ||
1820 | break; | 1899 | break; |
1821 | 1900 | ||
1822 | case MPI_FUNCTION_SCSI_IO_REQUEST: | 1901 | case MPI_FUNCTION_SCSI_IO_REQUEST: |
@@ -1837,7 +1916,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1837 | goto done_free_mem; | 1916 | goto done_free_mem; |
1838 | } | 1917 | } |
1839 | 1918 | ||
1840 | pScsiReq->MsgFlags = mpt_msg_flags(); | 1919 | pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; |
1920 | pScsiReq->MsgFlags |= mpt_msg_flags(); | ||
1921 | |||
1841 | 1922 | ||
1842 | /* verify that app has not requested | 1923 | /* verify that app has not requested |
1843 | * more sense data than driver | 1924 | * more sense data than driver |
@@ -1888,6 +1969,25 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1888 | } | 1969 | } |
1889 | break; | 1970 | break; |
1890 | 1971 | ||
1972 | case MPI_FUNCTION_SMP_PASSTHROUGH: | ||
1973 | /* Check mf->PassthruFlags to determine if | ||
1974 | * transfer is ImmediateMode or not. | ||
1975 | * Immediate mode returns data in the ReplyFrame. | ||
1976 | * Else, we are sending request and response data | ||
1977 | * in two SGLs at the end of the mf. | ||
1978 | */ | ||
1979 | break; | ||
1980 | |||
1981 | case MPI_FUNCTION_SATA_PASSTHROUGH: | ||
1982 | if (!ioc->sh) { | ||
1983 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " | ||
1984 | "SCSI driver is not loaded. \n", | ||
1985 | __FILE__, __LINE__); | ||
1986 | rc = -EFAULT; | ||
1987 | goto done_free_mem; | ||
1988 | } | ||
1989 | break; | ||
1990 | |||
1891 | case MPI_FUNCTION_RAID_ACTION: | 1991 | case MPI_FUNCTION_RAID_ACTION: |
1892 | /* Just add a SGE | 1992 | /* Just add a SGE |
1893 | */ | 1993 | */ |
@@ -1900,7 +2000,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1900 | int scsidir = MPI_SCSIIO_CONTROL_READ; | 2000 | int scsidir = MPI_SCSIIO_CONTROL_READ; |
1901 | int dataSize; | 2001 | int dataSize; |
1902 | 2002 | ||
1903 | pScsiReq->MsgFlags = mpt_msg_flags(); | 2003 | pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; |
2004 | pScsiReq->MsgFlags |= mpt_msg_flags(); | ||
2005 | |||
1904 | 2006 | ||
1905 | /* verify that app has not requested | 2007 | /* verify that app has not requested |
1906 | * more sense data than driver | 2008 | * more sense data than driver |
@@ -2130,7 +2232,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
2130 | 2232 | ||
2131 | /* Now wait for the command to complete */ | 2233 | /* Now wait for the command to complete */ |
2132 | timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT; | 2234 | timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT; |
2133 | timeout = wait_event_interruptible_timeout(mptctl_wait, | 2235 | timeout = wait_event_timeout(mptctl_wait, |
2134 | ioc->ioctl->wait_done == 1, | 2236 | ioc->ioctl->wait_done == 1, |
2135 | HZ*timeout); | 2237 | HZ*timeout); |
2136 | 2238 | ||
@@ -2246,13 +2348,16 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) | |||
2246 | hp_host_info_t __user *uarg = (void __user *) arg; | 2348 | hp_host_info_t __user *uarg = (void __user *) arg; |
2247 | MPT_ADAPTER *ioc; | 2349 | MPT_ADAPTER *ioc; |
2248 | struct pci_dev *pdev; | 2350 | struct pci_dev *pdev; |
2249 | char *pbuf; | 2351 | char *pbuf=NULL; |
2250 | dma_addr_t buf_dma; | 2352 | dma_addr_t buf_dma; |
2251 | hp_host_info_t karg; | 2353 | hp_host_info_t karg; |
2252 | CONFIGPARMS cfg; | 2354 | CONFIGPARMS cfg; |
2253 | ConfigPageHeader_t hdr; | 2355 | ConfigPageHeader_t hdr; |
2254 | int iocnum; | 2356 | int iocnum; |
2255 | int rc, cim_rev; | 2357 | int rc, cim_rev; |
2358 | ToolboxIstwiReadWriteRequest_t *IstwiRWRequest; | ||
2359 | MPT_FRAME_HDR *mf = NULL; | ||
2360 | MPIHeader_t *mpi_hdr; | ||
2256 | 2361 | ||
2257 | dctlprintk((": mptctl_hp_hostinfo called.\n")); | 2362 | dctlprintk((": mptctl_hp_hostinfo called.\n")); |
2258 | /* Reset long to int. Should affect IA64 and SPARC only | 2363 | /* Reset long to int. Should affect IA64 and SPARC only |
@@ -2370,7 +2475,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) | |||
2370 | 2475 | ||
2371 | karg.base_io_addr = pci_resource_start(pdev, 0); | 2476 | karg.base_io_addr = pci_resource_start(pdev, 0); |
2372 | 2477 | ||
2373 | if (ioc->bus_type == FC) | 2478 | if ((ioc->bus_type == SAS) || (ioc->bus_type == FC)) |
2374 | karg.bus_phys_width = HP_BUS_WIDTH_UNK; | 2479 | karg.bus_phys_width = HP_BUS_WIDTH_UNK; |
2375 | else | 2480 | else |
2376 | karg.bus_phys_width = HP_BUS_WIDTH_16; | 2481 | karg.bus_phys_width = HP_BUS_WIDTH_16; |
@@ -2388,20 +2493,67 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) | |||
2388 | } | 2493 | } |
2389 | } | 2494 | } |
2390 | 2495 | ||
2391 | cfg.pageAddr = 0; | 2496 | /* |
2392 | cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL; | 2497 | * Gather ISTWI(Industry Standard Two Wire Interface) Data |
2393 | cfg.dir = MPI_TB_ISTWI_FLAGS_READ; | 2498 | */ |
2394 | cfg.timeout = 10; | 2499 | if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) { |
2500 | dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n", | ||
2501 | ioc->name,__FUNCTION__)); | ||
2502 | goto out; | ||
2503 | } | ||
2504 | |||
2505 | IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf; | ||
2506 | mpi_hdr = (MPIHeader_t *) mf; | ||
2507 | memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t)); | ||
2508 | IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX; | ||
2509 | IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL; | ||
2510 | IstwiRWRequest->MsgContext = mpi_hdr->MsgContext; | ||
2511 | IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ; | ||
2512 | IstwiRWRequest->NumAddressBytes = 0x01; | ||
2513 | IstwiRWRequest->DataLength = cpu_to_le16(0x04); | ||
2514 | if (pdev->devfn & 1) | ||
2515 | IstwiRWRequest->DeviceAddr = 0xB2; | ||
2516 | else | ||
2517 | IstwiRWRequest->DeviceAddr = 0xB0; | ||
2518 | |||
2395 | pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma); | 2519 | pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma); |
2396 | if (pbuf) { | 2520 | if (!pbuf) |
2397 | cfg.physAddr = buf_dma; | 2521 | goto out; |
2398 | if ((mpt_toolbox(ioc, &cfg)) == 0) { | 2522 | mpt_add_sge((char *)&IstwiRWRequest->SGL, |
2399 | karg.rsvd = *(u32 *)pbuf; | 2523 | (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma); |
2400 | } | 2524 | |
2401 | pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); | 2525 | ioc->ioctl->wait_done = 0; |
2402 | pbuf = NULL; | 2526 | mpt_put_msg_frame(mptctl_id, ioc, mf); |
2527 | |||
2528 | rc = wait_event_timeout(mptctl_wait, | ||
2529 | ioc->ioctl->wait_done == 1, | ||
2530 | HZ*MPT_IOCTL_DEFAULT_TIMEOUT /* 10 sec */); | ||
2531 | |||
2532 | if(rc <=0 && (ioc->ioctl->wait_done != 1 )) { | ||
2533 | /* | ||
2534 | * Now we need to reset the board | ||
2535 | */ | ||
2536 | mpt_free_msg_frame(ioc, mf); | ||
2537 | mptctl_timeout_expired(ioc->ioctl); | ||
2538 | goto out; | ||
2403 | } | 2539 | } |
2404 | 2540 | ||
2541 | /* | ||
2542 | *ISTWI Data Definition | ||
2543 | * pbuf[0] = FW_VERSION = 0x4 | ||
2544 | * pbuf[1] = Bay Count = 6 or 4 or 2, depending on | ||
2545 | * the config, you should be seeing one out of these three values | ||
2546 | * pbuf[2] = Drive Installed Map = bit pattern depend on which | ||
2547 | * bays have drives in them | ||
2548 | * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3) | ||
2549 | */ | ||
2550 | if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID) | ||
2551 | karg.rsvd = *(u32 *)pbuf; | ||
2552 | |||
2553 | out: | ||
2554 | if (pbuf) | ||
2555 | pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); | ||
2556 | |||
2405 | /* Copy the data from kernel memory to user memory | 2557 | /* Copy the data from kernel memory to user memory |
2406 | */ | 2558 | */ |
2407 | if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { | 2559 | if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { |
@@ -2459,7 +2611,7 @@ mptctl_hp_targetinfo(unsigned long arg) | |||
2459 | 2611 | ||
2460 | /* There is nothing to do for FCP parts. | 2612 | /* There is nothing to do for FCP parts. |
2461 | */ | 2613 | */ |
2462 | if (ioc->bus_type == FC) | 2614 | if ((ioc->bus_type == SAS) || (ioc->bus_type == FC)) |
2463 | return 0; | 2615 | return 0; |
2464 | 2616 | ||
2465 | if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL)) | 2617 | if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL)) |
@@ -2569,6 +2721,8 @@ mptctl_hp_targetinfo(unsigned long arg) | |||
2569 | static struct file_operations mptctl_fops = { | 2721 | static struct file_operations mptctl_fops = { |
2570 | .owner = THIS_MODULE, | 2722 | .owner = THIS_MODULE, |
2571 | .llseek = no_llseek, | 2723 | .llseek = no_llseek, |
2724 | .release = mptctl_release, | ||
2725 | .fasync = mptctl_fasync, | ||
2572 | .unlocked_ioctl = mptctl_ioctl, | 2726 | .unlocked_ioctl = mptctl_ioctl, |
2573 | #ifdef CONFIG_COMPAT | 2727 | #ifdef CONFIG_COMPAT |
2574 | .compat_ioctl = compat_mpctl_ioctl, | 2728 | .compat_ioctl = compat_mpctl_ioctl, |
@@ -2813,6 +2967,11 @@ static int __init mptctl_init(void) | |||
2813 | /* FIXME! */ | 2967 | /* FIXME! */ |
2814 | } | 2968 | } |
2815 | 2969 | ||
2970 | if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) { | ||
2971 | devtprintk((KERN_INFO MYNAM | ||
2972 | ": Registered for IOC event notifications\n")); | ||
2973 | } | ||
2974 | |||
2816 | return 0; | 2975 | return 0; |
2817 | 2976 | ||
2818 | out_fail: | 2977 | out_fail: |
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h index 518996e03481..a2f8a97992e6 100644 --- a/drivers/message/fusion/mptctl.h +++ b/drivers/message/fusion/mptctl.h | |||
@@ -169,8 +169,10 @@ struct mpt_ioctl_pci_info2 { | |||
169 | * Read only. | 169 | * Read only. |
170 | * Data starts at offset 0xC | 170 | * Data starts at offset 0xC |
171 | */ | 171 | */ |
172 | #define MPT_IOCTL_INTERFACE_FC (0x01) | ||
173 | #define MPT_IOCTL_INTERFACE_SCSI (0x00) | 172 | #define MPT_IOCTL_INTERFACE_SCSI (0x00) |
173 | #define MPT_IOCTL_INTERFACE_FC (0x01) | ||
174 | #define MPT_IOCTL_INTERFACE_FC_IP (0x02) | ||
175 | #define MPT_IOCTL_INTERFACE_SAS (0x03) | ||
174 | #define MPT_IOCTL_VERSION_LENGTH (32) | 176 | #define MPT_IOCTL_VERSION_LENGTH (32) |
175 | 177 | ||
176 | struct mpt_ioctl_iocinfo { | 178 | struct mpt_ioctl_iocinfo { |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 05789e505464..4fee6befc93d 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -2489,7 +2489,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR | |||
2489 | int idx; | 2489 | int idx; |
2490 | MPT_ADAPTER *ioc = hd->ioc; | 2490 | MPT_ADAPTER *ioc = hd->ioc; |
2491 | 2491 | ||
2492 | idx = ioc->eventContext % ioc->eventLogSize; | 2492 | idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; |
2493 | ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; | 2493 | ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; |
2494 | ioc->events[idx].eventContext = ioc->eventContext; | 2494 | ioc->events[idx].eventContext = ioc->eventContext; |
2495 | 2495 | ||
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c index f9e5a23697a1..c08ddac3717d 100644 --- a/drivers/message/i2o/i2o_scsi.c +++ b/drivers/message/i2o/i2o_scsi.c | |||
@@ -732,7 +732,7 @@ static int i2o_scsi_abort(struct scsi_cmnd *SCpnt) | |||
732 | cpu_to_le32(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid); | 732 | cpu_to_le32(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid); |
733 | msg->body[0] = cpu_to_le32(i2o_cntxt_list_get_ptr(c, SCpnt)); | 733 | msg->body[0] = cpu_to_le32(i2o_cntxt_list_get_ptr(c, SCpnt)); |
734 | 734 | ||
735 | if (i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT)) | 735 | if (!i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT)) |
736 | status = SUCCESS; | 736 | status = SUCCESS; |
737 | 737 | ||
738 | return status; | 738 | return status; |
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h index 1cef2387fa65..6aba41954448 100644 --- a/drivers/misc/ibmasm/ibmasm.h +++ b/drivers/misc/ibmasm/ibmasm.h | |||
@@ -101,15 +101,16 @@ struct command { | |||
101 | static inline void command_put(struct command *cmd) | 101 | static inline void command_put(struct command *cmd) |
102 | { | 102 | { |
103 | unsigned long flags; | 103 | unsigned long flags; |
104 | spinlock_t *lock = cmd->lock; | ||
104 | 105 | ||
105 | spin_lock_irqsave(cmd->lock, flags); | 106 | spin_lock_irqsave(lock, flags); |
106 | kobject_put(&cmd->kobj); | 107 | kobject_put(&cmd->kobj); |
107 | spin_unlock_irqrestore(cmd->lock, flags); | 108 | spin_unlock_irqrestore(lock, flags); |
108 | } | 109 | } |
109 | 110 | ||
110 | static inline void command_get(struct command *cmd) | 111 | static inline void command_get(struct command *cmd) |
111 | { | 112 | { |
112 | kobject_get(&cmd->kobj); | 113 | kobject_get(&cmd->kobj); |
113 | } | 114 | } |
114 | 115 | ||
115 | 116 | ||
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index c483a863b116..5d397b7a5497 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig | |||
@@ -65,7 +65,7 @@ config MMC_AU1X | |||
65 | depends on SOC_AU1X00 && MMC | 65 | depends on SOC_AU1X00 && MMC |
66 | help | 66 | help |
67 | This selects the AMD Alchemy(R) Multimedia card interface. | 67 | This selects the AMD Alchemy(R) Multimedia card interface. |
68 | iIf you have a Alchemy platform with a MMC slot, say Y or M here. | 68 | If you have a Alchemy platform with a MMC slot, say Y or M here. |
69 | 69 | ||
70 | If unsure, say N. | 70 | If unsure, say N. |
71 | 71 | ||
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index aaf04638054e..8d84b045bc83 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/config.h> | 37 | #include <linux/config.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/device.h> | 40 | #include <linux/platform_device.h> |
41 | #include <linux/mm.h> | 41 | #include <linux/mm.h> |
42 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
43 | #include <linux/dma-mapping.h> | 43 | #include <linux/dma-mapping.h> |
@@ -194,7 +194,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | |||
194 | 194 | ||
195 | u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); | 195 | u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); |
196 | 196 | ||
197 | switch(cmd->flags) { | 197 | switch (mmc_resp_type(cmd)) { |
198 | case MMC_RSP_R1: | 198 | case MMC_RSP_R1: |
199 | mmccmd |= SD_CMD_RT_1; | 199 | mmccmd |= SD_CMD_RT_1; |
200 | break; | 200 | break; |
@@ -483,34 +483,35 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) | |||
483 | cmd = mrq->cmd; | 483 | cmd = mrq->cmd; |
484 | cmd->error = MMC_ERR_NONE; | 484 | cmd->error = MMC_ERR_NONE; |
485 | 485 | ||
486 | if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) { | 486 | if (cmd->flags & MMC_RSP_PRESENT) { |
487 | 487 | if (cmd->flags & MMC_RSP_136) { | |
488 | /* Techincally, we should be getting all 48 bits of the response | 488 | u32 r[4]; |
489 | * (SD_RESP1 + SD_RESP2), but because our response omits the CRC, | 489 | int i; |
490 | * our data ends up being shifted 8 bits to the right. In this case, | 490 | |
491 | * that means that the OSR data starts at bit 31, so we can just | 491 | r[0] = au_readl(host->iobase + SD_RESP3); |
492 | * read RESP0 and return that | 492 | r[1] = au_readl(host->iobase + SD_RESP2); |
493 | */ | 493 | r[2] = au_readl(host->iobase + SD_RESP1); |
494 | 494 | r[3] = au_readl(host->iobase + SD_RESP0); | |
495 | cmd->resp[0] = au_readl(host->iobase + SD_RESP0); | 495 | |
496 | } | 496 | /* The CRC is omitted from the response, so really |
497 | else if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_LONG) { | 497 | * we only got 120 bytes, but the engine expects |
498 | u32 r[4]; | 498 | * 128 bits, so we have to shift things up |
499 | int i; | 499 | */ |
500 | 500 | ||
501 | r[0] = au_readl(host->iobase + SD_RESP3); | 501 | for(i = 0; i < 4; i++) { |
502 | r[1] = au_readl(host->iobase + SD_RESP2); | 502 | cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8; |
503 | r[2] = au_readl(host->iobase + SD_RESP1); | 503 | if (i != 3) |
504 | r[3] = au_readl(host->iobase + SD_RESP0); | 504 | cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24; |
505 | 505 | } | |
506 | /* The CRC is omitted from the response, so really we only got | 506 | } else { |
507 | * 120 bytes, but the engine expects 128 bits, so we have to shift | 507 | /* Techincally, we should be getting all 48 bits of |
508 | * things up | 508 | * the response (SD_RESP1 + SD_RESP2), but because |
509 | */ | 509 | * our response omits the CRC, our data ends up |
510 | 510 | * being shifted 8 bits to the right. In this case, | |
511 | for(i = 0; i < 4; i++) { | 511 | * that means that the OSR data starts at bit 31, |
512 | cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8; | 512 | * so we can just read RESP0 and return that |
513 | if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24; | 513 | */ |
514 | cmd->resp[0] = au_readl(host->iobase + SD_RESP0); | ||
514 | } | 515 | } |
515 | } | 516 | } |
516 | 517 | ||
@@ -739,7 +740,6 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
739 | static void au1xmmc_dma_callback(int irq, void *dev_id, struct pt_regs *regs) | 740 | static void au1xmmc_dma_callback(int irq, void *dev_id, struct pt_regs *regs) |
740 | { | 741 | { |
741 | struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id; | 742 | struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id; |
742 | u32 status; | ||
743 | 743 | ||
744 | /* Avoid spurious interrupts */ | 744 | /* Avoid spurious interrupts */ |
745 | 745 | ||
@@ -886,7 +886,7 @@ struct mmc_host_ops au1xmmc_ops = { | |||
886 | .set_ios = au1xmmc_set_ios, | 886 | .set_ios = au1xmmc_set_ios, |
887 | }; | 887 | }; |
888 | 888 | ||
889 | static int au1xmmc_probe(struct device *dev) | 889 | static int __devinit au1xmmc_probe(struct platform_device *pdev) |
890 | { | 890 | { |
891 | 891 | ||
892 | int i, ret = 0; | 892 | int i, ret = 0; |
@@ -903,7 +903,7 @@ static int au1xmmc_probe(struct device *dev) | |||
903 | disable_irq(AU1100_SD_IRQ); | 903 | disable_irq(AU1100_SD_IRQ); |
904 | 904 | ||
905 | for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { | 905 | for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { |
906 | struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), dev); | 906 | struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); |
907 | struct au1xmmc_host *host = 0; | 907 | struct au1xmmc_host *host = 0; |
908 | 908 | ||
909 | if (!mmc) { | 909 | if (!mmc) { |
@@ -966,7 +966,7 @@ static int au1xmmc_probe(struct device *dev) | |||
966 | return 0; | 966 | return 0; |
967 | } | 967 | } |
968 | 968 | ||
969 | static int au1xmmc_remove(struct device *dev) | 969 | static int __devexit au1xmmc_remove(struct platform_device *pdev) |
970 | { | 970 | { |
971 | 971 | ||
972 | int i; | 972 | int i; |
@@ -996,23 +996,24 @@ static int au1xmmc_remove(struct device *dev) | |||
996 | return 0; | 996 | return 0; |
997 | } | 997 | } |
998 | 998 | ||
999 | static struct device_driver au1xmmc_driver = { | 999 | static struct platform_driver au1xmmc_driver = { |
1000 | .name = DRIVER_NAME, | ||
1001 | .bus = &platform_bus_type, | ||
1002 | .probe = au1xmmc_probe, | 1000 | .probe = au1xmmc_probe, |
1003 | .remove = au1xmmc_remove, | 1001 | .remove = au1xmmc_remove, |
1004 | .suspend = NULL, | 1002 | .suspend = NULL, |
1005 | .resume = NULL | 1003 | .resume = NULL, |
1004 | .driver = { | ||
1005 | .name = DRIVER_NAME, | ||
1006 | }, | ||
1006 | }; | 1007 | }; |
1007 | 1008 | ||
1008 | static int __init au1xmmc_init(void) | 1009 | static int __init au1xmmc_init(void) |
1009 | { | 1010 | { |
1010 | return driver_register(&au1xmmc_driver); | 1011 | return platform_driver_register(&au1xmmc_driver); |
1011 | } | 1012 | } |
1012 | 1013 | ||
1013 | static void __exit au1xmmc_exit(void) | 1014 | static void __exit au1xmmc_exit(void) |
1014 | { | 1015 | { |
1015 | driver_unregister(&au1xmmc_driver); | 1016 | platform_driver_unregister(&au1xmmc_driver); |
1016 | } | 1017 | } |
1017 | 1018 | ||
1018 | module_init(au1xmmc_init); | 1019 | module_init(au1xmmc_init); |
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index bfca5c176e88..1888060c5e0c 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
@@ -211,7 +211,7 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca, | |||
211 | 211 | ||
212 | appcmd.opcode = MMC_APP_CMD; | 212 | appcmd.opcode = MMC_APP_CMD; |
213 | appcmd.arg = rca << 16; | 213 | appcmd.arg = rca << 16; |
214 | appcmd.flags = MMC_RSP_R1; | 214 | appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
215 | appcmd.retries = 0; | 215 | appcmd.retries = 0; |
216 | memset(appcmd.resp, 0, sizeof(appcmd.resp)); | 216 | memset(appcmd.resp, 0, sizeof(appcmd.resp)); |
217 | appcmd.data = NULL; | 217 | appcmd.data = NULL; |
@@ -331,7 +331,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) | |||
331 | 331 | ||
332 | cmd.opcode = MMC_SELECT_CARD; | 332 | cmd.opcode = MMC_SELECT_CARD; |
333 | cmd.arg = card->rca << 16; | 333 | cmd.arg = card->rca << 16; |
334 | cmd.flags = MMC_RSP_R1; | 334 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
335 | 335 | ||
336 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 336 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
337 | if (err != MMC_ERR_NONE) | 337 | if (err != MMC_ERR_NONE) |
@@ -358,7 +358,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) | |||
358 | struct mmc_command cmd; | 358 | struct mmc_command cmd; |
359 | cmd.opcode = SD_APP_SET_BUS_WIDTH; | 359 | cmd.opcode = SD_APP_SET_BUS_WIDTH; |
360 | cmd.arg = SD_BUS_WIDTH_4; | 360 | cmd.arg = SD_BUS_WIDTH_4; |
361 | cmd.flags = MMC_RSP_R1; | 361 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
362 | 362 | ||
363 | err = mmc_wait_for_app_cmd(host, card->rca, &cmd, | 363 | err = mmc_wait_for_app_cmd(host, card->rca, &cmd, |
364 | CMD_RETRIES); | 364 | CMD_RETRIES); |
@@ -386,7 +386,7 @@ static void mmc_deselect_cards(struct mmc_host *host) | |||
386 | 386 | ||
387 | cmd.opcode = MMC_SELECT_CARD; | 387 | cmd.opcode = MMC_SELECT_CARD; |
388 | cmd.arg = 0; | 388 | cmd.arg = 0; |
389 | cmd.flags = MMC_RSP_NONE; | 389 | cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; |
390 | 390 | ||
391 | mmc_wait_for_cmd(host, &cmd, 0); | 391 | mmc_wait_for_cmd(host, &cmd, 0); |
392 | } | 392 | } |
@@ -677,7 +677,7 @@ static void mmc_idle_cards(struct mmc_host *host) | |||
677 | 677 | ||
678 | cmd.opcode = MMC_GO_IDLE_STATE; | 678 | cmd.opcode = MMC_GO_IDLE_STATE; |
679 | cmd.arg = 0; | 679 | cmd.arg = 0; |
680 | cmd.flags = MMC_RSP_NONE; | 680 | cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; |
681 | 681 | ||
682 | mmc_wait_for_cmd(host, &cmd, 0); | 682 | mmc_wait_for_cmd(host, &cmd, 0); |
683 | 683 | ||
@@ -738,7 +738,7 @@ static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
738 | 738 | ||
739 | cmd.opcode = MMC_SEND_OP_COND; | 739 | cmd.opcode = MMC_SEND_OP_COND; |
740 | cmd.arg = ocr; | 740 | cmd.arg = ocr; |
741 | cmd.flags = MMC_RSP_R3; | 741 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; |
742 | 742 | ||
743 | for (i = 100; i; i--) { | 743 | for (i = 100; i; i--) { |
744 | err = mmc_wait_for_cmd(host, &cmd, 0); | 744 | err = mmc_wait_for_cmd(host, &cmd, 0); |
@@ -766,7 +766,7 @@ static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
766 | 766 | ||
767 | cmd.opcode = SD_APP_OP_COND; | 767 | cmd.opcode = SD_APP_OP_COND; |
768 | cmd.arg = ocr; | 768 | cmd.arg = ocr; |
769 | cmd.flags = MMC_RSP_R3; | 769 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; |
770 | 770 | ||
771 | for (i = 100; i; i--) { | 771 | for (i = 100; i; i--) { |
772 | err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES); | 772 | err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES); |
@@ -805,7 +805,7 @@ static void mmc_discover_cards(struct mmc_host *host) | |||
805 | 805 | ||
806 | cmd.opcode = MMC_ALL_SEND_CID; | 806 | cmd.opcode = MMC_ALL_SEND_CID; |
807 | cmd.arg = 0; | 807 | cmd.arg = 0; |
808 | cmd.flags = MMC_RSP_R2; | 808 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; |
809 | 809 | ||
810 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 810 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
811 | if (err == MMC_ERR_TIMEOUT) { | 811 | if (err == MMC_ERR_TIMEOUT) { |
@@ -835,7 +835,7 @@ static void mmc_discover_cards(struct mmc_host *host) | |||
835 | 835 | ||
836 | cmd.opcode = SD_SEND_RELATIVE_ADDR; | 836 | cmd.opcode = SD_SEND_RELATIVE_ADDR; |
837 | cmd.arg = 0; | 837 | cmd.arg = 0; |
838 | cmd.flags = MMC_RSP_R6; | 838 | cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; |
839 | 839 | ||
840 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 840 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
841 | if (err != MMC_ERR_NONE) | 841 | if (err != MMC_ERR_NONE) |
@@ -856,7 +856,7 @@ static void mmc_discover_cards(struct mmc_host *host) | |||
856 | } else { | 856 | } else { |
857 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | 857 | cmd.opcode = MMC_SET_RELATIVE_ADDR; |
858 | cmd.arg = card->rca << 16; | 858 | cmd.arg = card->rca << 16; |
859 | cmd.flags = MMC_RSP_R1; | 859 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
860 | 860 | ||
861 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 861 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
862 | if (err != MMC_ERR_NONE) | 862 | if (err != MMC_ERR_NONE) |
@@ -878,7 +878,7 @@ static void mmc_read_csds(struct mmc_host *host) | |||
878 | 878 | ||
879 | cmd.opcode = MMC_SEND_CSD; | 879 | cmd.opcode = MMC_SEND_CSD; |
880 | cmd.arg = card->rca << 16; | 880 | cmd.arg = card->rca << 16; |
881 | cmd.flags = MMC_RSP_R2; | 881 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; |
882 | 882 | ||
883 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 883 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
884 | if (err != MMC_ERR_NONE) { | 884 | if (err != MMC_ERR_NONE) { |
@@ -920,7 +920,7 @@ static void mmc_read_scrs(struct mmc_host *host) | |||
920 | 920 | ||
921 | cmd.opcode = MMC_APP_CMD; | 921 | cmd.opcode = MMC_APP_CMD; |
922 | cmd.arg = card->rca << 16; | 922 | cmd.arg = card->rca << 16; |
923 | cmd.flags = MMC_RSP_R1; | 923 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
924 | 924 | ||
925 | err = mmc_wait_for_cmd(host, &cmd, 0); | 925 | err = mmc_wait_for_cmd(host, &cmd, 0); |
926 | if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) { | 926 | if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) { |
@@ -932,7 +932,7 @@ static void mmc_read_scrs(struct mmc_host *host) | |||
932 | 932 | ||
933 | cmd.opcode = SD_APP_SEND_SCR; | 933 | cmd.opcode = SD_APP_SEND_SCR; |
934 | cmd.arg = 0; | 934 | cmd.arg = 0; |
935 | cmd.flags = MMC_RSP_R1; | 935 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; |
936 | 936 | ||
937 | memset(&data, 0, sizeof(struct mmc_data)); | 937 | memset(&data, 0, sizeof(struct mmc_data)); |
938 | 938 | ||
@@ -1003,7 +1003,7 @@ static void mmc_check_cards(struct mmc_host *host) | |||
1003 | 1003 | ||
1004 | cmd.opcode = MMC_SEND_STATUS; | 1004 | cmd.opcode = MMC_SEND_STATUS; |
1005 | cmd.arg = card->rca << 16; | 1005 | cmd.arg = card->rca << 16; |
1006 | cmd.flags = MMC_RSP_R1; | 1006 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
1007 | 1007 | ||
1008 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 1008 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
1009 | if (err == MMC_ERR_NONE) | 1009 | if (err == MMC_ERR_NONE) |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 5b014c370e80..8eb2a2ede64b 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
@@ -171,14 +171,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
171 | brq.mrq.data = &brq.data; | 171 | brq.mrq.data = &brq.data; |
172 | 172 | ||
173 | brq.cmd.arg = req->sector << 9; | 173 | brq.cmd.arg = req->sector << 9; |
174 | brq.cmd.flags = MMC_RSP_R1; | 174 | brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; |
175 | brq.data.timeout_ns = card->csd.tacc_ns * 10; | 175 | brq.data.timeout_ns = card->csd.tacc_ns * 10; |
176 | brq.data.timeout_clks = card->csd.tacc_clks * 10; | 176 | brq.data.timeout_clks = card->csd.tacc_clks * 10; |
177 | brq.data.blksz_bits = md->block_bits; | 177 | brq.data.blksz_bits = md->block_bits; |
178 | brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); | 178 | brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); |
179 | brq.stop.opcode = MMC_STOP_TRANSMISSION; | 179 | brq.stop.opcode = MMC_STOP_TRANSMISSION; |
180 | brq.stop.arg = 0; | 180 | brq.stop.arg = 0; |
181 | brq.stop.flags = MMC_RSP_R1B; | 181 | brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC; |
182 | 182 | ||
183 | if (rq_data_dir(req) == READ) { | 183 | if (rq_data_dir(req) == READ) { |
184 | brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; | 184 | brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; |
@@ -223,7 +223,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
223 | 223 | ||
224 | cmd.opcode = MMC_SEND_STATUS; | 224 | cmd.opcode = MMC_SEND_STATUS; |
225 | cmd.arg = card->rca << 16; | 225 | cmd.arg = card->rca << 16; |
226 | cmd.flags = MMC_RSP_R1; | 226 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
227 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | 227 | err = mmc_wait_for_cmd(card->host, &cmd, 5); |
228 | if (err) { | 228 | if (err) { |
229 | printk(KERN_ERR "%s: error %d requesting status\n", | 229 | printk(KERN_ERR "%s: error %d requesting status\n", |
@@ -430,7 +430,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | |||
430 | mmc_card_claim_host(card); | 430 | mmc_card_claim_host(card); |
431 | cmd.opcode = MMC_SET_BLOCKLEN; | 431 | cmd.opcode = MMC_SET_BLOCKLEN; |
432 | cmd.arg = 1 << md->block_bits; | 432 | cmd.arg = 1 << md->block_bits; |
433 | cmd.flags = MMC_RSP_R1; | 433 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
434 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | 434 | err = mmc_wait_for_cmd(card->host, &cmd, 5); |
435 | mmc_card_release_host(card); | 435 | mmc_card_release_host(card); |
436 | 436 | ||
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 634ef53e85a5..9fef29d978b5 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c | |||
@@ -97,6 +97,13 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
97 | if (data->flags & MMC_DATA_READ) { | 97 | if (data->flags & MMC_DATA_READ) { |
98 | datactrl |= MCI_DPSM_DIRECTION; | 98 | datactrl |= MCI_DPSM_DIRECTION; |
99 | irqmask = MCI_RXFIFOHALFFULLMASK; | 99 | irqmask = MCI_RXFIFOHALFFULLMASK; |
100 | |||
101 | /* | ||
102 | * If we have less than a FIFOSIZE of bytes to transfer, | ||
103 | * trigger a PIO interrupt as soon as any data is available. | ||
104 | */ | ||
105 | if (host->size < MCI_FIFOSIZE) | ||
106 | irqmask |= MCI_RXDATAAVLBLMASK; | ||
100 | } else { | 107 | } else { |
101 | /* | 108 | /* |
102 | * We don't actually need to include "FIFO empty" here | 109 | * We don't actually need to include "FIFO empty" here |
@@ -124,15 +131,10 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) | |||
124 | } | 131 | } |
125 | 132 | ||
126 | c |= cmd->opcode | MCI_CPSM_ENABLE; | 133 | c |= cmd->opcode | MCI_CPSM_ENABLE; |
127 | switch (cmd->flags & MMC_RSP_MASK) { | 134 | if (cmd->flags & MMC_RSP_PRESENT) { |
128 | case MMC_RSP_NONE: | 135 | if (cmd->flags & MMC_RSP_136) |
129 | default: | 136 | c |= MCI_CPSM_LONGRSP; |
130 | break; | ||
131 | case MMC_RSP_LONG: | ||
132 | c |= MCI_CPSM_LONGRSP; | ||
133 | case MMC_RSP_SHORT: | ||
134 | c |= MCI_CPSM_RESPONSE; | 137 | c |= MCI_CPSM_RESPONSE; |
135 | break; | ||
136 | } | 138 | } |
137 | if (/*interrupt*/0) | 139 | if (/*interrupt*/0) |
138 | c |= MCI_CPSM_INTERRUPT; | 140 | c |= MCI_CPSM_INTERRUPT; |
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index ee8f8a0420d1..285d7d068097 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c | |||
@@ -178,14 +178,15 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, | |||
178 | if (cmd->flags & MMC_RSP_BUSY) | 178 | if (cmd->flags & MMC_RSP_BUSY) |
179 | cmdat |= CMDAT_BUSY; | 179 | cmdat |= CMDAT_BUSY; |
180 | 180 | ||
181 | switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) { | 181 | #define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) |
182 | case MMC_RSP_SHORT | MMC_RSP_CRC: | 182 | switch (RSP_TYPE(mmc_resp_type(cmd))) { |
183 | case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6 */ | ||
183 | cmdat |= CMDAT_RESP_SHORT; | 184 | cmdat |= CMDAT_RESP_SHORT; |
184 | break; | 185 | break; |
185 | case MMC_RSP_SHORT: | 186 | case RSP_TYPE(MMC_RSP_R3): |
186 | cmdat |= CMDAT_RESP_R3; | 187 | cmdat |= CMDAT_RESP_R3; |
187 | break; | 188 | break; |
188 | case MMC_RSP_LONG | MMC_RSP_CRC: | 189 | case RSP_TYPE(MMC_RSP_R2): |
189 | cmdat |= CMDAT_RESP_R2; | 190 | cmdat |= CMDAT_RESP_R2; |
190 | break; | 191 | break; |
191 | default: | 192 | default: |
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index f25757625361..3be397d436fa 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
@@ -459,7 +459,7 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) | |||
459 | /* | 459 | /* |
460 | * Do we expect a reply? | 460 | * Do we expect a reply? |
461 | */ | 461 | */ |
462 | if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) { | 462 | if (cmd->flags & MMC_RSP_PRESENT) { |
463 | /* | 463 | /* |
464 | * Read back status. | 464 | * Read back status. |
465 | */ | 465 | */ |
@@ -476,10 +476,10 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) | |||
476 | cmd->error = MMC_ERR_BADCRC; | 476 | cmd->error = MMC_ERR_BADCRC; |
477 | /* All ok */ | 477 | /* All ok */ |
478 | else { | 478 | else { |
479 | if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) | 479 | if (cmd->flags & MMC_RSP_136) |
480 | wbsd_get_short_reply(host, cmd); | ||
481 | else | ||
482 | wbsd_get_long_reply(host, cmd); | 480 | wbsd_get_long_reply(host, cmd); |
481 | else | ||
482 | wbsd_get_short_reply(host, cmd); | ||
483 | } | 483 | } |
484 | } | 484 | } |
485 | 485 | ||
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index effa0d7a73ac..205bb7083335 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig | |||
@@ -301,7 +301,7 @@ config MTD_JEDEC | |||
301 | 301 | ||
302 | config MTD_XIP | 302 | config MTD_XIP |
303 | bool "XIP aware MTD support" | 303 | bool "XIP aware MTD support" |
304 | depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM | 304 | depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARCH_MTD_XIP |
305 | default y if XIP_KERNEL | 305 | default y if XIP_KERNEL |
306 | help | 306 | help |
307 | This allows MTD support to work with flash memory which is also | 307 | This allows MTD support to work with flash memory which is also |
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 69c04945591f..1c074d63ff3a 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c | |||
@@ -408,6 +408,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) | |||
408 | cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; | 408 | cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; |
409 | cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; | 409 | cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; |
410 | cfi->chips[i].ref_point_counter = 0; | 410 | cfi->chips[i].ref_point_counter = 0; |
411 | init_waitqueue_head(&(cfi->chips[i].wq)); | ||
411 | } | 412 | } |
412 | 413 | ||
413 | map->fldrv = &cfi_intelext_chipdrv; | 414 | map->fldrv = &cfi_intelext_chipdrv; |
@@ -1019,8 +1020,8 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip, | |||
1019 | #define XIP_INVAL_CACHED_RANGE(map, from, size) \ | 1020 | #define XIP_INVAL_CACHED_RANGE(map, from, size) \ |
1020 | INVALIDATE_CACHED_RANGE(map, from, size) | 1021 | INVALIDATE_CACHED_RANGE(map, from, size) |
1021 | 1022 | ||
1022 | #define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \ | 1023 | #define INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr, adr, len, usec) \ |
1023 | UDELAY(map, chip, adr, usec) | 1024 | UDELAY(map, chip, cmd_adr, usec) |
1024 | 1025 | ||
1025 | /* | 1026 | /* |
1026 | * Extra notes: | 1027 | * Extra notes: |
@@ -1052,7 +1053,7 @@ do { \ | |||
1052 | spin_lock(chip->mutex); \ | 1053 | spin_lock(chip->mutex); \ |
1053 | } while (0) | 1054 | } while (0) |
1054 | 1055 | ||
1055 | #define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \ | 1056 | #define INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr, adr, len, usec) \ |
1056 | do { \ | 1057 | do { \ |
1057 | spin_unlock(chip->mutex); \ | 1058 | spin_unlock(chip->mutex); \ |
1058 | INVALIDATE_CACHED_RANGE(map, adr, len); \ | 1059 | INVALIDATE_CACHED_RANGE(map, adr, len); \ |
@@ -1284,7 +1285,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | |||
1284 | map_write(map, datum, adr); | 1285 | map_write(map, datum, adr); |
1285 | chip->state = mode; | 1286 | chip->state = mode; |
1286 | 1287 | ||
1287 | INVALIDATE_CACHE_UDELAY(map, chip, | 1288 | INVALIDATE_CACHE_UDELAY(map, chip, adr, |
1288 | adr, map_bankwidth(map), | 1289 | adr, map_bankwidth(map), |
1289 | chip->word_write_time); | 1290 | chip->word_write_time); |
1290 | 1291 | ||
@@ -1572,8 +1573,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1572 | map_write(map, CMD(0xd0), cmd_adr); | 1573 | map_write(map, CMD(0xd0), cmd_adr); |
1573 | chip->state = FL_WRITING; | 1574 | chip->state = FL_WRITING; |
1574 | 1575 | ||
1575 | INVALIDATE_CACHE_UDELAY(map, chip, | 1576 | INVALIDATE_CACHE_UDELAY(map, chip, cmd_adr, |
1576 | cmd_adr, len, | 1577 | adr, len, |
1577 | chip->buffer_write_time); | 1578 | chip->buffer_write_time); |
1578 | 1579 | ||
1579 | timeo = jiffies + (HZ/2); | 1580 | timeo = jiffies + (HZ/2); |
@@ -1744,7 +1745,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
1744 | chip->state = FL_ERASING; | 1745 | chip->state = FL_ERASING; |
1745 | chip->erase_suspended = 0; | 1746 | chip->erase_suspended = 0; |
1746 | 1747 | ||
1747 | INVALIDATE_CACHE_UDELAY(map, chip, | 1748 | INVALIDATE_CACHE_UDELAY(map, chip, adr, |
1748 | adr, len, | 1749 | adr, len, |
1749 | chip->erase_time*1000/2); | 1750 | chip->erase_time*1000/2); |
1750 | 1751 | ||
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 155737e7483f..a19480d07888 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
@@ -178,7 +178,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
178 | * we're at a block boundary and need to erase the whole block. | 178 | * we're at a block boundary and need to erase the whole block. |
179 | */ | 179 | */ |
180 | pageaddr = instr->addr / priv->page_size; | 180 | pageaddr = instr->addr / priv->page_size; |
181 | do_block = (pageaddr & 0x7) == 0 && instr->len <= blocksize; | 181 | do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize; |
182 | pageaddr = pageaddr << priv->page_offset; | 182 | pageaddr = pageaddr << priv->page_offset; |
183 | 183 | ||
184 | command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE; | 184 | command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE; |
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 7b7ca5ab5ae4..8815c8dbef2d 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: redboot.c,v 1.18 2005/11/07 11:14:21 gleixner Exp $ | 2 | * $Id: redboot.c,v 1.19 2005/12/01 10:03:51 dwmw2 Exp $ |
3 | * | 3 | * |
4 | * Parse RedBoot-style Flash Image System (FIS) tables and | 4 | * Parse RedBoot-style Flash Image System (FIS) tables and |
5 | * produce a Linux partition array to match. | 5 | * produce a Linux partition array to match. |
@@ -89,8 +89,32 @@ static int parse_redboot_partitions(struct mtd_info *master, | |||
89 | i = numslots; | 89 | i = numslots; |
90 | break; | 90 | break; |
91 | } | 91 | } |
92 | if (!memcmp(buf[i].name, "FIS directory", 14)) | 92 | if (!memcmp(buf[i].name, "FIS directory", 14)) { |
93 | /* This is apparently the FIS directory entry for the | ||
94 | * FIS directory itself. The FIS directory size is | ||
95 | * one erase block; if the buf[i].size field is | ||
96 | * swab32(erasesize) then we know we are looking at | ||
97 | * a byte swapped FIS directory - swap all the entries! | ||
98 | * (NOTE: this is 'size' not 'data_length'; size is | ||
99 | * the full size of the entry.) | ||
100 | */ | ||
101 | if (swab32(buf[i].size) == master->erasesize) { | ||
102 | int j; | ||
103 | for (j = 0; j < numslots && buf[j].name[0] != 0xff; ++j) { | ||
104 | /* The unsigned long fields were written with the | ||
105 | * wrong byte sex, name and pad have no byte sex. | ||
106 | */ | ||
107 | swab32s(&buf[j].flash_base); | ||
108 | swab32s(&buf[j].mem_base); | ||
109 | swab32s(&buf[j].size); | ||
110 | swab32s(&buf[j].entry_point); | ||
111 | swab32s(&buf[j].data_length); | ||
112 | swab32s(&buf[j].desc_cksum); | ||
113 | swab32s(&buf[j].file_cksum); | ||
114 | } | ||
115 | } | ||
93 | break; | 116 | break; |
117 | } | ||
94 | } | 118 | } |
95 | if (i == numslots) { | 119 | if (i == numslots) { |
96 | /* Didn't find it */ | 120 | /* Didn't find it */ |
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 824e430486c2..830528dce0ca 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c | |||
@@ -1574,6 +1574,7 @@ MODULE_LICENSE("GPL"); | |||
1574 | 1574 | ||
1575 | static int __init el3_init_module(void) | 1575 | static int __init el3_init_module(void) |
1576 | { | 1576 | { |
1577 | int ret = 0; | ||
1577 | el3_cards = 0; | 1578 | el3_cards = 0; |
1578 | 1579 | ||
1579 | if (debug >= 0) | 1580 | if (debug >= 0) |
@@ -1589,14 +1590,16 @@ static int __init el3_init_module(void) | |||
1589 | } | 1590 | } |
1590 | 1591 | ||
1591 | #ifdef CONFIG_EISA | 1592 | #ifdef CONFIG_EISA |
1592 | if (eisa_driver_register (&el3_eisa_driver) < 0) { | 1593 | ret = eisa_driver_register(&el3_eisa_driver); |
1593 | eisa_driver_unregister (&el3_eisa_driver); | ||
1594 | } | ||
1595 | #endif | 1594 | #endif |
1596 | #ifdef CONFIG_MCA | 1595 | #ifdef CONFIG_MCA |
1597 | mca_register_driver(&el3_mca_driver); | 1596 | { |
1597 | int err = mca_register_driver(&el3_mca_driver); | ||
1598 | if (ret == 0) | ||
1599 | ret = err; | ||
1600 | } | ||
1598 | #endif | 1601 | #endif |
1599 | return 0; | 1602 | return ret; |
1600 | } | 1603 | } |
1601 | 1604 | ||
1602 | static void __exit el3_cleanup_module(void) | 1605 | static void __exit el3_cleanup_module(void) |
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index f822cd3025ff..dd410496aadb 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c | |||
@@ -1118,13 +1118,18 @@ err_out: | |||
1118 | return -ENOMEM; | 1118 | return -ENOMEM; |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | static void cp_init_rings_index (struct cp_private *cp) | ||
1122 | { | ||
1123 | cp->rx_tail = 0; | ||
1124 | cp->tx_head = cp->tx_tail = 0; | ||
1125 | } | ||
1126 | |||
1121 | static int cp_init_rings (struct cp_private *cp) | 1127 | static int cp_init_rings (struct cp_private *cp) |
1122 | { | 1128 | { |
1123 | memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); | 1129 | memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); |
1124 | cp->tx_ring[CP_TX_RING_SIZE - 1].opts1 = cpu_to_le32(RingEnd); | 1130 | cp->tx_ring[CP_TX_RING_SIZE - 1].opts1 = cpu_to_le32(RingEnd); |
1125 | 1131 | ||
1126 | cp->rx_tail = 0; | 1132 | cp_init_rings_index(cp); |
1127 | cp->tx_head = cp->tx_tail = 0; | ||
1128 | 1133 | ||
1129 | return cp_refill_rx (cp); | 1134 | return cp_refill_rx (cp); |
1130 | } | 1135 | } |
@@ -1886,30 +1891,30 @@ static int cp_suspend (struct pci_dev *pdev, pm_message_t state) | |||
1886 | 1891 | ||
1887 | spin_unlock_irqrestore (&cp->lock, flags); | 1892 | spin_unlock_irqrestore (&cp->lock, flags); |
1888 | 1893 | ||
1889 | if (cp->pdev && cp->wol_enabled) { | 1894 | pci_save_state(pdev); |
1890 | pci_save_state (cp->pdev); | 1895 | pci_enable_wake(pdev, pci_choose_state(pdev, state), cp->wol_enabled); |
1891 | cp_set_d3_state (cp); | 1896 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
1892 | } | ||
1893 | 1897 | ||
1894 | return 0; | 1898 | return 0; |
1895 | } | 1899 | } |
1896 | 1900 | ||
1897 | static int cp_resume (struct pci_dev *pdev) | 1901 | static int cp_resume (struct pci_dev *pdev) |
1898 | { | 1902 | { |
1899 | struct net_device *dev; | 1903 | struct net_device *dev = pci_get_drvdata (pdev); |
1900 | struct cp_private *cp; | 1904 | struct cp_private *cp = netdev_priv(dev); |
1901 | unsigned long flags; | 1905 | unsigned long flags; |
1902 | 1906 | ||
1903 | dev = pci_get_drvdata (pdev); | 1907 | if (!netif_running(dev)) |
1904 | cp = netdev_priv(dev); | 1908 | return 0; |
1905 | 1909 | ||
1906 | netif_device_attach (dev); | 1910 | netif_device_attach (dev); |
1907 | 1911 | ||
1908 | if (cp->pdev && cp->wol_enabled) { | 1912 | pci_set_power_state(pdev, PCI_D0); |
1909 | pci_set_power_state (cp->pdev, PCI_D0); | 1913 | pci_restore_state(pdev); |
1910 | pci_restore_state (cp->pdev); | 1914 | pci_enable_wake(pdev, PCI_D0, 0); |
1911 | } | 1915 | |
1912 | 1916 | /* FIXME: sh*t may happen if the Rx ring buffer is depleted */ | |
1917 | cp_init_rings_index (cp); | ||
1913 | cp_init_hw (cp); | 1918 | cp_init_hw (cp); |
1914 | netif_start_queue (dev); | 1919 | netif_start_queue (dev); |
1915 | 1920 | ||
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index adfba44dac5a..2beac55b57d6 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -586,6 +586,7 @@ struct rtl8139_private { | |||
586 | dma_addr_t tx_bufs_dma; | 586 | dma_addr_t tx_bufs_dma; |
587 | signed char phys[4]; /* MII device addresses. */ | 587 | signed char phys[4]; /* MII device addresses. */ |
588 | char twistie, twist_row, twist_col; /* Twister tune state. */ | 588 | char twistie, twist_row, twist_col; /* Twister tune state. */ |
589 | unsigned int watchdog_fired : 1; | ||
589 | unsigned int default_port : 4; /* Last dev->if_port value. */ | 590 | unsigned int default_port : 4; /* Last dev->if_port value. */ |
590 | unsigned int have_thread : 1; | 591 | unsigned int have_thread : 1; |
591 | spinlock_t lock; | 592 | spinlock_t lock; |
@@ -638,6 +639,7 @@ static void rtl8139_set_rx_mode (struct net_device *dev); | |||
638 | static void __set_rx_mode (struct net_device *dev); | 639 | static void __set_rx_mode (struct net_device *dev); |
639 | static void rtl8139_hw_start (struct net_device *dev); | 640 | static void rtl8139_hw_start (struct net_device *dev); |
640 | static void rtl8139_thread (void *_data); | 641 | static void rtl8139_thread (void *_data); |
642 | static void rtl8139_tx_timeout_task(void *_data); | ||
641 | static struct ethtool_ops rtl8139_ethtool_ops; | 643 | static struct ethtool_ops rtl8139_ethtool_ops; |
642 | 644 | ||
643 | /* write MMIO register, with flush */ | 645 | /* write MMIO register, with flush */ |
@@ -1598,13 +1600,14 @@ static void rtl8139_thread (void *_data) | |||
1598 | { | 1600 | { |
1599 | struct net_device *dev = _data; | 1601 | struct net_device *dev = _data; |
1600 | struct rtl8139_private *tp = netdev_priv(dev); | 1602 | struct rtl8139_private *tp = netdev_priv(dev); |
1601 | unsigned long thr_delay; | 1603 | unsigned long thr_delay = next_tick; |
1602 | 1604 | ||
1603 | if (rtnl_shlock_nowait() == 0) { | 1605 | if (tp->watchdog_fired) { |
1606 | tp->watchdog_fired = 0; | ||
1607 | rtl8139_tx_timeout_task(_data); | ||
1608 | } else if (rtnl_shlock_nowait() == 0) { | ||
1604 | rtl8139_thread_iter (dev, tp, tp->mmio_addr); | 1609 | rtl8139_thread_iter (dev, tp, tp->mmio_addr); |
1605 | rtnl_unlock (); | 1610 | rtnl_unlock (); |
1606 | |||
1607 | thr_delay = next_tick; | ||
1608 | } else { | 1611 | } else { |
1609 | /* unlikely race. mitigate with fast poll. */ | 1612 | /* unlikely race. mitigate with fast poll. */ |
1610 | thr_delay = HZ / 2; | 1613 | thr_delay = HZ / 2; |
@@ -1631,7 +1634,8 @@ static void rtl8139_stop_thread(struct rtl8139_private *tp) | |||
1631 | if (tp->have_thread) { | 1634 | if (tp->have_thread) { |
1632 | cancel_rearming_delayed_work(&tp->thread); | 1635 | cancel_rearming_delayed_work(&tp->thread); |
1633 | tp->have_thread = 0; | 1636 | tp->have_thread = 0; |
1634 | } | 1637 | } else |
1638 | flush_scheduled_work(); | ||
1635 | } | 1639 | } |
1636 | 1640 | ||
1637 | static inline void rtl8139_tx_clear (struct rtl8139_private *tp) | 1641 | static inline void rtl8139_tx_clear (struct rtl8139_private *tp) |
@@ -1642,14 +1646,13 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp) | |||
1642 | /* XXX account for unsent Tx packets in tp->stats.tx_dropped */ | 1646 | /* XXX account for unsent Tx packets in tp->stats.tx_dropped */ |
1643 | } | 1647 | } |
1644 | 1648 | ||
1645 | 1649 | static void rtl8139_tx_timeout_task (void *_data) | |
1646 | static void rtl8139_tx_timeout (struct net_device *dev) | ||
1647 | { | 1650 | { |
1651 | struct net_device *dev = _data; | ||
1648 | struct rtl8139_private *tp = netdev_priv(dev); | 1652 | struct rtl8139_private *tp = netdev_priv(dev); |
1649 | void __iomem *ioaddr = tp->mmio_addr; | 1653 | void __iomem *ioaddr = tp->mmio_addr; |
1650 | int i; | 1654 | int i; |
1651 | u8 tmp8; | 1655 | u8 tmp8; |
1652 | unsigned long flags; | ||
1653 | 1656 | ||
1654 | printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x " | 1657 | printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x " |
1655 | "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd), | 1658 | "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd), |
@@ -1670,23 +1673,34 @@ static void rtl8139_tx_timeout (struct net_device *dev) | |||
1670 | if (tmp8 & CmdTxEnb) | 1673 | if (tmp8 & CmdTxEnb) |
1671 | RTL_W8 (ChipCmd, CmdRxEnb); | 1674 | RTL_W8 (ChipCmd, CmdRxEnb); |
1672 | 1675 | ||
1673 | spin_lock(&tp->rx_lock); | 1676 | spin_lock_bh(&tp->rx_lock); |
1674 | /* Disable interrupts by clearing the interrupt mask. */ | 1677 | /* Disable interrupts by clearing the interrupt mask. */ |
1675 | RTL_W16 (IntrMask, 0x0000); | 1678 | RTL_W16 (IntrMask, 0x0000); |
1676 | 1679 | ||
1677 | /* Stop a shared interrupt from scavenging while we are. */ | 1680 | /* Stop a shared interrupt from scavenging while we are. */ |
1678 | spin_lock_irqsave (&tp->lock, flags); | 1681 | spin_lock_irq(&tp->lock); |
1679 | rtl8139_tx_clear (tp); | 1682 | rtl8139_tx_clear (tp); |
1680 | spin_unlock_irqrestore (&tp->lock, flags); | 1683 | spin_unlock_irq(&tp->lock); |
1681 | 1684 | ||
1682 | /* ...and finally, reset everything */ | 1685 | /* ...and finally, reset everything */ |
1683 | if (netif_running(dev)) { | 1686 | if (netif_running(dev)) { |
1684 | rtl8139_hw_start (dev); | 1687 | rtl8139_hw_start (dev); |
1685 | netif_wake_queue (dev); | 1688 | netif_wake_queue (dev); |
1686 | } | 1689 | } |
1687 | spin_unlock(&tp->rx_lock); | 1690 | spin_unlock_bh(&tp->rx_lock); |
1688 | } | 1691 | } |
1689 | 1692 | ||
1693 | static void rtl8139_tx_timeout (struct net_device *dev) | ||
1694 | { | ||
1695 | struct rtl8139_private *tp = netdev_priv(dev); | ||
1696 | |||
1697 | if (!tp->have_thread) { | ||
1698 | INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev); | ||
1699 | schedule_delayed_work(&tp->thread, next_tick); | ||
1700 | } else | ||
1701 | tp->watchdog_fired = 1; | ||
1702 | |||
1703 | } | ||
1690 | 1704 | ||
1691 | static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) | 1705 | static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) |
1692 | { | 1706 | { |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6a6a08441804..aa633fa95e64 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -4,9 +4,9 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | menu "Network device support" | 6 | menu "Network device support" |
7 | depends on NET | ||
7 | 8 | ||
8 | config NETDEVICES | 9 | config NETDEVICES |
9 | depends on NET | ||
10 | default y if UML | 10 | default y if UML |
11 | bool "Network device support" | 11 | bool "Network device support" |
12 | ---help--- | 12 | ---help--- |
@@ -24,9 +24,6 @@ config NETDEVICES | |||
24 | 24 | ||
25 | If unsure, say Y. | 25 | If unsure, say Y. |
26 | 26 | ||
27 | # All the following symbols are dependent on NETDEVICES - do not repeat | ||
28 | # that for each of the symbols. | ||
29 | if NETDEVICES | ||
30 | 27 | ||
31 | config IFB | 28 | config IFB |
32 | tristate "Intermediate Functional Block support" | 29 | tristate "Intermediate Functional Block support" |
@@ -1090,7 +1087,8 @@ config NE2000 | |||
1090 | without a specific driver are compatible with NE2000. | 1087 | without a specific driver are compatible with NE2000. |
1091 | 1088 | ||
1092 | If you have a PCI NE2000 card however, say N here and Y to "PCI | 1089 | If you have a PCI NE2000 card however, say N here and Y to "PCI |
1093 | NE2000 support", above. If you have a NE2000 card and are running on | 1090 | NE2000 and clone support" under "EISA, VLB, PCI and on board |
1091 | controllers" below. If you have a NE2000 card and are running on | ||
1094 | an MCA system (a bus system used on some IBM PS/2 computers and | 1092 | an MCA system (a bus system used on some IBM PS/2 computers and |
1095 | laptops), say N here and Y to "NE/2 (ne2000 MCA version) support", | 1093 | laptops), say N here and Y to "NE/2 (ne2000 MCA version) support", |
1096 | below. | 1094 | below. |
@@ -2023,8 +2021,8 @@ config SIS190 | |||
2023 | will be called sis190. This is recommended. | 2021 | will be called sis190. This is recommended. |
2024 | 2022 | ||
2025 | config SKGE | 2023 | config SKGE |
2026 | tristate "New SysKonnect GigaEthernet support (EXPERIMENTAL)" | 2024 | tristate "New SysKonnect GigaEthernet support" |
2027 | depends on PCI && EXPERIMENTAL | 2025 | depends on PCI |
2028 | select CRC32 | 2026 | select CRC32 |
2029 | ---help--- | 2027 | ---help--- |
2030 | This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx | 2028 | This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx |
@@ -2085,7 +2083,6 @@ config SK98LIN | |||
2085 | - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter | 2083 | - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter |
2086 | - Allied Telesyn AT-2971T Gigabit Ethernet Adapter | 2084 | - Allied Telesyn AT-2971T Gigabit Ethernet Adapter |
2087 | - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45 | 2085 | - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45 |
2088 | - DGE-530T Gigabit Ethernet Adapter | ||
2089 | - EG1032 v2 Instant Gigabit Network Adapter | 2086 | - EG1032 v2 Instant Gigabit Network Adapter |
2090 | - EG1064 v2 Instant Gigabit Network Adapter | 2087 | - EG1064 v2 Instant Gigabit Network Adapter |
2091 | - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) | 2088 | - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) |
@@ -2718,8 +2715,6 @@ config NETCONSOLE | |||
2718 | If you want to log kernel messages over the network, enable this. | 2715 | If you want to log kernel messages over the network, enable this. |
2719 | See <file:Documentation/networking/netconsole.txt> for details. | 2716 | See <file:Documentation/networking/netconsole.txt> for details. |
2720 | 2717 | ||
2721 | endif #NETDEVICES | ||
2722 | |||
2723 | config NETPOLL | 2718 | config NETPOLL |
2724 | def_bool NETCONSOLE | 2719 | def_bool NETCONSOLE |
2725 | 2720 | ||
diff --git a/drivers/net/appletalk/cops.h b/drivers/net/appletalk/cops.h index c68ba9c2ef46..fd2750b269c8 100644 --- a/drivers/net/appletalk/cops.h +++ b/drivers/net/appletalk/cops.h | |||
@@ -51,7 +51,7 @@ | |||
51 | struct ltfirmware | 51 | struct ltfirmware |
52 | { | 52 | { |
53 | unsigned int length; | 53 | unsigned int length; |
54 | unsigned char * data; | 54 | const unsigned char *data; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | #define DAYNA 1 | 57 | #define DAYNA 1 |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4ff006c37626..bcf9f17daf0d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1145,7 +1145,8 @@ int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1145 | } | 1145 | } |
1146 | 1146 | ||
1147 | #define BOND_INTERSECT_FEATURES \ | 1147 | #define BOND_INTERSECT_FEATURES \ |
1148 | (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) | 1148 | (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\ |
1149 | NETIF_F_TSO|NETIF_F_UFO) | ||
1149 | 1150 | ||
1150 | /* | 1151 | /* |
1151 | * Compute the common dev->feature set available to all slaves. Some | 1152 | * Compute the common dev->feature set available to all slaves. Some |
@@ -1168,6 +1169,16 @@ static int bond_compute_features(struct bonding *bond) | |||
1168 | NETIF_F_HW_CSUM))) | 1169 | NETIF_F_HW_CSUM))) |
1169 | features &= ~NETIF_F_SG; | 1170 | features &= ~NETIF_F_SG; |
1170 | 1171 | ||
1172 | /* | ||
1173 | * features will include NETIF_F_TSO (NETIF_F_UFO) iff all | ||
1174 | * slave devices support NETIF_F_TSO (NETIF_F_UFO), which | ||
1175 | * implies that all slaves also support scatter-gather | ||
1176 | * (NETIF_F_SG), which implies that features also includes | ||
1177 | * NETIF_F_SG. So no need to check whether we have an | ||
1178 | * illegal combination of NETIF_F_{TSO,UFO} and | ||
1179 | * !NETIF_F_SG | ||
1180 | */ | ||
1181 | |||
1171 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); | 1182 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); |
1172 | bond_dev->features = features; | 1183 | bond_dev->features = features; |
1173 | 1184 | ||
@@ -1570,6 +1581,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1570 | printk(KERN_INFO DRV_NAME | 1581 | printk(KERN_INFO DRV_NAME |
1571 | ": %s: %s not enslaved\n", | 1582 | ": %s: %s not enslaved\n", |
1572 | bond_dev->name, slave_dev->name); | 1583 | bond_dev->name, slave_dev->name); |
1584 | write_unlock_bh(&bond->lock); | ||
1573 | return -EINVAL; | 1585 | return -EINVAL; |
1574 | } | 1586 | } |
1575 | 1587 | ||
@@ -4080,6 +4092,8 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev, | |||
4080 | 4092 | ||
4081 | static struct ethtool_ops bond_ethtool_ops = { | 4093 | static struct ethtool_ops bond_ethtool_ops = { |
4082 | .get_tx_csum = ethtool_op_get_tx_csum, | 4094 | .get_tx_csum = ethtool_op_get_tx_csum, |
4095 | .get_tso = ethtool_op_get_tso, | ||
4096 | .get_ufo = ethtool_op_get_ufo, | ||
4083 | .get_sg = ethtool_op_get_sg, | 4097 | .get_sg = ethtool_op_get_sg, |
4084 | .get_drvinfo = bond_ethtool_get_drvinfo, | 4098 | .get_drvinfo = bond_ethtool_get_drvinfo, |
4085 | }; | 4099 | }; |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 32d13da43a0b..041bcc583557 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -260,7 +260,7 @@ static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer, | |||
260 | char *ifname; | 260 | char *ifname; |
261 | int i, res, found, ret = count; | 261 | int i, res, found, ret = count; |
262 | struct slave *slave; | 262 | struct slave *slave; |
263 | struct net_device *dev = 0; | 263 | struct net_device *dev = NULL; |
264 | struct bonding *bond = to_bond(cd); | 264 | struct bonding *bond = to_bond(cd); |
265 | 265 | ||
266 | /* Quick sanity check -- is the bond interface up? */ | 266 | /* Quick sanity check -- is the bond interface up? */ |
@@ -995,7 +995,7 @@ static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, s | |||
995 | printk(KERN_INFO DRV_NAME | 995 | printk(KERN_INFO DRV_NAME |
996 | ": %s: Setting primary slave to None.\n", | 996 | ": %s: Setting primary slave to None.\n", |
997 | bond->dev->name); | 997 | bond->dev->name); |
998 | bond->primary_slave = 0; | 998 | bond->primary_slave = NULL; |
999 | bond_select_active_slave(bond); | 999 | bond_select_active_slave(bond); |
1000 | } else { | 1000 | } else { |
1001 | printk(KERN_INFO DRV_NAME | 1001 | printk(KERN_INFO DRV_NAME |
@@ -1123,7 +1123,7 @@ static ssize_t bonding_store_active_slave(struct class_device *cd, const char *b | |||
1123 | printk(KERN_INFO DRV_NAME | 1123 | printk(KERN_INFO DRV_NAME |
1124 | ": %s: Setting active slave to None.\n", | 1124 | ": %s: Setting active slave to None.\n", |
1125 | bond->dev->name); | 1125 | bond->dev->name); |
1126 | bond->primary_slave = 0; | 1126 | bond->primary_slave = NULL; |
1127 | bond_select_active_slave(bond); | 1127 | bond_select_active_slave(bond); |
1128 | } else { | 1128 | } else { |
1129 | printk(KERN_INFO DRV_NAME | 1129 | printk(KERN_INFO DRV_NAME |
diff --git a/drivers/net/chelsio/espi.c b/drivers/net/chelsio/espi.c index 230642571c92..e824acaf188a 100644 --- a/drivers/net/chelsio/espi.c +++ b/drivers/net/chelsio/espi.c | |||
@@ -296,9 +296,7 @@ void t1_espi_destroy(struct peespi *espi) | |||
296 | 296 | ||
297 | struct peespi *t1_espi_create(adapter_t *adapter) | 297 | struct peespi *t1_espi_create(adapter_t *adapter) |
298 | { | 298 | { |
299 | struct peespi *espi = kmalloc(sizeof(*espi), GFP_KERNEL); | 299 | struct peespi *espi = kzalloc(sizeof(*espi), GFP_KERNEL); |
300 | |||
301 | memset(espi, 0, sizeof(*espi)); | ||
302 | 300 | ||
303 | if (espi) | 301 | if (espi) |
304 | espi->adapter = adapter; | 302 | espi->adapter = adapter; |
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 2c5b849b7ba4..30ff8ea1a402 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c | |||
@@ -1021,7 +1021,7 @@ static void restart_tx_queues(struct sge *sge) | |||
1021 | if (test_and_clear_bit(nd->if_port, | 1021 | if (test_and_clear_bit(nd->if_port, |
1022 | &sge->stopped_tx_queues) && | 1022 | &sge->stopped_tx_queues) && |
1023 | netif_running(nd)) { | 1023 | netif_running(nd)) { |
1024 | sge->stats.cmdQ_restarted[3]++; | 1024 | sge->stats.cmdQ_restarted[2]++; |
1025 | netif_wake_queue(nd); | 1025 | netif_wake_queue(nd); |
1026 | } | 1026 | } |
1027 | } | 1027 | } |
@@ -1350,7 +1350,7 @@ static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter, | |||
1350 | if (unlikely(credits < count)) { | 1350 | if (unlikely(credits < count)) { |
1351 | netif_stop_queue(dev); | 1351 | netif_stop_queue(dev); |
1352 | set_bit(dev->if_port, &sge->stopped_tx_queues); | 1352 | set_bit(dev->if_port, &sge->stopped_tx_queues); |
1353 | sge->stats.cmdQ_full[3]++; | 1353 | sge->stats.cmdQ_full[2]++; |
1354 | spin_unlock(&q->lock); | 1354 | spin_unlock(&q->lock); |
1355 | if (!netif_queue_stopped(dev)) | 1355 | if (!netif_queue_stopped(dev)) |
1356 | CH_ERR("%s: Tx ring full while queue awake!\n", | 1356 | CH_ERR("%s: Tx ring full while queue awake!\n", |
@@ -1358,7 +1358,7 @@ static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter, | |||
1358 | return NETDEV_TX_BUSY; | 1358 | return NETDEV_TX_BUSY; |
1359 | } | 1359 | } |
1360 | if (unlikely(credits - count < q->stop_thres)) { | 1360 | if (unlikely(credits - count < q->stop_thres)) { |
1361 | sge->stats.cmdQ_full[3]++; | 1361 | sge->stats.cmdQ_full[2]++; |
1362 | netif_stop_queue(dev); | 1362 | netif_stop_queue(dev); |
1363 | set_bit(dev->if_port, &sge->stopped_tx_queues); | 1363 | set_bit(dev->if_port, &sge->stopped_tx_queues); |
1364 | } | 1364 | } |
diff --git a/drivers/net/de620.c b/drivers/net/de620.c index 0069f5fa973a..22fc5b869a60 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c | |||
@@ -1012,7 +1012,7 @@ static int __init read_eeprom(struct net_device *dev) | |||
1012 | #ifdef MODULE | 1012 | #ifdef MODULE |
1013 | static struct net_device *de620_dev; | 1013 | static struct net_device *de620_dev; |
1014 | 1014 | ||
1015 | int init_module(void) | 1015 | int __init init_module(void) |
1016 | { | 1016 | { |
1017 | de620_dev = de620_probe(-1); | 1017 | de620_dev = de620_probe(-1); |
1018 | if (IS_ERR(de620_dev)) | 1018 | if (IS_ERR(de620_dev)) |
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 430c628279b3..fb9dae302dcc 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c | |||
@@ -50,8 +50,8 @@ | |||
50 | 50 | ||
51 | */ | 51 | */ |
52 | #define DRV_NAME "D-Link DL2000-based linux driver" | 52 | #define DRV_NAME "D-Link DL2000-based linux driver" |
53 | #define DRV_VERSION "v1.17a" | 53 | #define DRV_VERSION "v1.17b" |
54 | #define DRV_RELDATE "2002/10/04" | 54 | #define DRV_RELDATE "2006/03/10" |
55 | #include "dl2k.h" | 55 | #include "dl2k.h" |
56 | 56 | ||
57 | static char version[] __devinitdata = | 57 | static char version[] __devinitdata = |
@@ -765,7 +765,7 @@ rio_free_tx (struct net_device *dev, int irq) | |||
765 | break; | 765 | break; |
766 | skb = np->tx_skbuff[entry]; | 766 | skb = np->tx_skbuff[entry]; |
767 | pci_unmap_single (np->pdev, | 767 | pci_unmap_single (np->pdev, |
768 | np->tx_ring[entry].fraginfo, | 768 | np->tx_ring[entry].fraginfo & 0xffffffffffff, |
769 | skb->len, PCI_DMA_TODEVICE); | 769 | skb->len, PCI_DMA_TODEVICE); |
770 | if (irq) | 770 | if (irq) |
771 | dev_kfree_skb_irq (skb); | 771 | dev_kfree_skb_irq (skb); |
@@ -892,14 +892,16 @@ receive_packet (struct net_device *dev) | |||
892 | 892 | ||
893 | /* Small skbuffs for short packets */ | 893 | /* Small skbuffs for short packets */ |
894 | if (pkt_len > copy_thresh) { | 894 | if (pkt_len > copy_thresh) { |
895 | pci_unmap_single (np->pdev, desc->fraginfo, | 895 | pci_unmap_single (np->pdev, |
896 | desc->fraginfo & 0xffffffffffff, | ||
896 | np->rx_buf_sz, | 897 | np->rx_buf_sz, |
897 | PCI_DMA_FROMDEVICE); | 898 | PCI_DMA_FROMDEVICE); |
898 | skb_put (skb = np->rx_skbuff[entry], pkt_len); | 899 | skb_put (skb = np->rx_skbuff[entry], pkt_len); |
899 | np->rx_skbuff[entry] = NULL; | 900 | np->rx_skbuff[entry] = NULL; |
900 | } else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) { | 901 | } else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) { |
901 | pci_dma_sync_single_for_cpu(np->pdev, | 902 | pci_dma_sync_single_for_cpu(np->pdev, |
902 | desc->fraginfo, | 903 | desc->fraginfo & |
904 | 0xffffffffffff, | ||
903 | np->rx_buf_sz, | 905 | np->rx_buf_sz, |
904 | PCI_DMA_FROMDEVICE); | 906 | PCI_DMA_FROMDEVICE); |
905 | skb->dev = dev; | 907 | skb->dev = dev; |
@@ -910,7 +912,8 @@ receive_packet (struct net_device *dev) | |||
910 | pkt_len, 0); | 912 | pkt_len, 0); |
911 | skb_put (skb, pkt_len); | 913 | skb_put (skb, pkt_len); |
912 | pci_dma_sync_single_for_device(np->pdev, | 914 | pci_dma_sync_single_for_device(np->pdev, |
913 | desc->fraginfo, | 915 | desc->fraginfo & |
916 | 0xffffffffffff, | ||
914 | np->rx_buf_sz, | 917 | np->rx_buf_sz, |
915 | PCI_DMA_FROMDEVICE); | 918 | PCI_DMA_FROMDEVICE); |
916 | } | 919 | } |
@@ -1796,8 +1799,9 @@ rio_close (struct net_device *dev) | |||
1796 | np->rx_ring[i].fraginfo = 0; | 1799 | np->rx_ring[i].fraginfo = 0; |
1797 | skb = np->rx_skbuff[i]; | 1800 | skb = np->rx_skbuff[i]; |
1798 | if (skb) { | 1801 | if (skb) { |
1799 | pci_unmap_single (np->pdev, np->rx_ring[i].fraginfo, | 1802 | pci_unmap_single(np->pdev, |
1800 | skb->len, PCI_DMA_FROMDEVICE); | 1803 | np->rx_ring[i].fraginfo & 0xffffffffffff, |
1804 | skb->len, PCI_DMA_FROMDEVICE); | ||
1801 | dev_kfree_skb (skb); | 1805 | dev_kfree_skb (skb); |
1802 | np->rx_skbuff[i] = NULL; | 1806 | np->rx_skbuff[i] = NULL; |
1803 | } | 1807 | } |
@@ -1805,8 +1809,9 @@ rio_close (struct net_device *dev) | |||
1805 | for (i = 0; i < TX_RING_SIZE; i++) { | 1809 | for (i = 0; i < TX_RING_SIZE; i++) { |
1806 | skb = np->tx_skbuff[i]; | 1810 | skb = np->tx_skbuff[i]; |
1807 | if (skb) { | 1811 | if (skb) { |
1808 | pci_unmap_single (np->pdev, np->tx_ring[i].fraginfo, | 1812 | pci_unmap_single(np->pdev, |
1809 | skb->len, PCI_DMA_TODEVICE); | 1813 | np->tx_ring[i].fraginfo & 0xffffffffffff, |
1814 | skb->len, PCI_DMA_TODEVICE); | ||
1810 | dev_kfree_skb (skb); | 1815 | dev_kfree_skb (skb); |
1811 | np->tx_skbuff[i] = NULL; | 1816 | np->tx_skbuff[i] = NULL; |
1812 | } | 1817 | } |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index bf1fd2b98bf8..f57a85feda3d 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -2154,6 +2154,9 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) | |||
2154 | 2154 | ||
2155 | msleep(10); | 2155 | msleep(10); |
2156 | 2156 | ||
2157 | pci_dma_sync_single_for_cpu(nic->pdev, nic->rx_to_clean->dma_addr, | ||
2158 | RFD_BUF_LEN, PCI_DMA_FROMDEVICE); | ||
2159 | |||
2157 | if(memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd), | 2160 | if(memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd), |
2158 | skb->data, ETH_DATA_LEN)) | 2161 | skb->data, ETH_DATA_LEN)) |
2159 | err = -EAGAIN; | 2162 | err = -EAGAIN; |
@@ -2161,8 +2164,8 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) | |||
2161 | err_loopback_none: | 2164 | err_loopback_none: |
2162 | mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 0); | 2165 | mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 0); |
2163 | nic->loopback = lb_none; | 2166 | nic->loopback = lb_none; |
2164 | e100_hw_init(nic); | ||
2165 | e100_clean_cbs(nic); | 2167 | e100_clean_cbs(nic); |
2168 | e100_hw_reset(nic); | ||
2166 | err_clean_rx: | 2169 | err_clean_rx: |
2167 | e100_rx_clean_list(nic); | 2170 | e100_rx_clean_list(nic); |
2168 | return err; | 2171 | return err; |
@@ -2752,8 +2755,6 @@ static int e100_resume(struct pci_dev *pdev) | |||
2752 | retval = pci_enable_wake(pdev, 0, 0); | 2755 | retval = pci_enable_wake(pdev, 0, 0); |
2753 | if (retval) | 2756 | if (retval) |
2754 | DPRINTK(PROBE,ERR, "Error clearing wake events\n"); | 2757 | DPRINTK(PROBE,ERR, "Error clearing wake events\n"); |
2755 | if(e100_hw_init(nic)) | ||
2756 | DPRINTK(HW, ERR, "e100_hw_init failed\n"); | ||
2757 | 2758 | ||
2758 | netif_device_attach(netdev); | 2759 | netif_device_attach(netdev); |
2759 | if(netif_running(netdev)) | 2760 | if(netif_running(netdev)) |
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 27c77306193b..99baf0e099fc 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h | |||
@@ -225,9 +225,6 @@ struct e1000_rx_ring { | |||
225 | struct e1000_ps_page *ps_page; | 225 | struct e1000_ps_page *ps_page; |
226 | struct e1000_ps_page_dma *ps_page_dma; | 226 | struct e1000_ps_page_dma *ps_page_dma; |
227 | 227 | ||
228 | struct sk_buff *rx_skb_top; | ||
229 | struct sk_buff *rx_skb_prev; | ||
230 | |||
231 | /* cpu for rx queue */ | 228 | /* cpu for rx queue */ |
232 | int cpu; | 229 | int cpu; |
233 | 230 | ||
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 31e332935e5a..84dcca3776ee 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -103,7 +103,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; | |||
103 | #else | 103 | #else |
104 | #define DRIVERNAPI "-NAPI" | 104 | #define DRIVERNAPI "-NAPI" |
105 | #endif | 105 | #endif |
106 | #define DRV_VERSION "6.3.9-k2"DRIVERNAPI | 106 | #define DRV_VERSION "6.3.9-k4"DRIVERNAPI |
107 | char e1000_driver_version[] = DRV_VERSION; | 107 | char e1000_driver_version[] = DRV_VERSION; |
108 | static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; | 108 | static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; |
109 | 109 | ||
@@ -1635,8 +1635,6 @@ setup_rx_desc_die: | |||
1635 | 1635 | ||
1636 | rxdr->next_to_clean = 0; | 1636 | rxdr->next_to_clean = 0; |
1637 | rxdr->next_to_use = 0; | 1637 | rxdr->next_to_use = 0; |
1638 | rxdr->rx_skb_top = NULL; | ||
1639 | rxdr->rx_skb_prev = NULL; | ||
1640 | 1638 | ||
1641 | return 0; | 1639 | return 0; |
1642 | } | 1640 | } |
@@ -1713,8 +1711,23 @@ e1000_setup_rctl(struct e1000_adapter *adapter) | |||
1713 | rctl |= adapter->rx_buffer_len << 0x11; | 1711 | rctl |= adapter->rx_buffer_len << 0x11; |
1714 | } else { | 1712 | } else { |
1715 | rctl &= ~E1000_RCTL_SZ_4096; | 1713 | rctl &= ~E1000_RCTL_SZ_4096; |
1716 | rctl &= ~E1000_RCTL_BSEX; | 1714 | rctl |= E1000_RCTL_BSEX; |
1717 | rctl |= E1000_RCTL_SZ_2048; | 1715 | switch (adapter->rx_buffer_len) { |
1716 | case E1000_RXBUFFER_2048: | ||
1717 | default: | ||
1718 | rctl |= E1000_RCTL_SZ_2048; | ||
1719 | rctl &= ~E1000_RCTL_BSEX; | ||
1720 | break; | ||
1721 | case E1000_RXBUFFER_4096: | ||
1722 | rctl |= E1000_RCTL_SZ_4096; | ||
1723 | break; | ||
1724 | case E1000_RXBUFFER_8192: | ||
1725 | rctl |= E1000_RCTL_SZ_8192; | ||
1726 | break; | ||
1727 | case E1000_RXBUFFER_16384: | ||
1728 | rctl |= E1000_RCTL_SZ_16384; | ||
1729 | break; | ||
1730 | } | ||
1718 | } | 1731 | } |
1719 | 1732 | ||
1720 | #ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT | 1733 | #ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT |
@@ -2107,16 +2120,6 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter, | |||
2107 | } | 2120 | } |
2108 | } | 2121 | } |
2109 | 2122 | ||
2110 | /* there also may be some cached data in our adapter */ | ||
2111 | if (rx_ring->rx_skb_top) { | ||
2112 | dev_kfree_skb(rx_ring->rx_skb_top); | ||
2113 | |||
2114 | /* rx_skb_prev will be wiped out by rx_skb_top */ | ||
2115 | rx_ring->rx_skb_top = NULL; | ||
2116 | rx_ring->rx_skb_prev = NULL; | ||
2117 | } | ||
2118 | |||
2119 | |||
2120 | size = sizeof(struct e1000_buffer) * rx_ring->count; | 2123 | size = sizeof(struct e1000_buffer) * rx_ring->count; |
2121 | memset(rx_ring->buffer_info, 0, size); | 2124 | memset(rx_ring->buffer_info, 0, size); |
2122 | size = sizeof(struct e1000_ps_page) * rx_ring->count; | 2125 | size = sizeof(struct e1000_ps_page) * rx_ring->count; |
@@ -2914,7 +2917,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2914 | if (!__pskb_pull_tail(skb, pull_size)) { | 2917 | if (!__pskb_pull_tail(skb, pull_size)) { |
2915 | printk(KERN_ERR "__pskb_pull_tail failed.\n"); | 2918 | printk(KERN_ERR "__pskb_pull_tail failed.\n"); |
2916 | dev_kfree_skb_any(skb); | 2919 | dev_kfree_skb_any(skb); |
2917 | return -EFAULT; | 2920 | return NETDEV_TX_OK; |
2918 | } | 2921 | } |
2919 | len = skb->len - skb->data_len; | 2922 | len = skb->len - skb->data_len; |
2920 | } | 2923 | } |
@@ -3106,24 +3109,27 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
3106 | break; | 3109 | break; |
3107 | } | 3110 | } |
3108 | 3111 | ||
3109 | /* since the driver code now supports splitting a packet across | 3112 | |
3110 | * multiple descriptors, most of the fifo related limitations on | ||
3111 | * jumbo frame traffic have gone away. | ||
3112 | * simply use 2k descriptors for everything. | ||
3113 | * | ||
3114 | * NOTE: dev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN | ||
3115 | * means we reserve 2 more, this pushes us to allocate from the next | ||
3116 | * larger slab size | ||
3117 | * i.e. RXBUFFER_2048 --> size-4096 slab */ | ||
3118 | |||
3119 | /* recent hardware supports 1KB granularity */ | ||
3120 | if (adapter->hw.mac_type > e1000_82547_rev_2) { | 3113 | if (adapter->hw.mac_type > e1000_82547_rev_2) { |
3121 | adapter->rx_buffer_len = | 3114 | adapter->rx_buffer_len = max_frame; |
3122 | ((max_frame < E1000_RXBUFFER_2048) ? | ||
3123 | max_frame : E1000_RXBUFFER_2048); | ||
3124 | E1000_ROUNDUP(adapter->rx_buffer_len, 1024); | 3115 | E1000_ROUNDUP(adapter->rx_buffer_len, 1024); |
3125 | } else | 3116 | } else { |
3126 | adapter->rx_buffer_len = E1000_RXBUFFER_2048; | 3117 | if(unlikely((adapter->hw.mac_type < e1000_82543) && |
3118 | (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) { | ||
3119 | DPRINTK(PROBE, ERR, "Jumbo Frames not supported " | ||
3120 | "on 82542\n"); | ||
3121 | return -EINVAL; | ||
3122 | } else { | ||
3123 | if(max_frame <= E1000_RXBUFFER_2048) | ||
3124 | adapter->rx_buffer_len = E1000_RXBUFFER_2048; | ||
3125 | else if(max_frame <= E1000_RXBUFFER_4096) | ||
3126 | adapter->rx_buffer_len = E1000_RXBUFFER_4096; | ||
3127 | else if(max_frame <= E1000_RXBUFFER_8192) | ||
3128 | adapter->rx_buffer_len = E1000_RXBUFFER_8192; | ||
3129 | else if(max_frame <= E1000_RXBUFFER_16384) | ||
3130 | adapter->rx_buffer_len = E1000_RXBUFFER_16384; | ||
3131 | } | ||
3132 | } | ||
3127 | 3133 | ||
3128 | netdev->mtu = new_mtu; | 3134 | netdev->mtu = new_mtu; |
3129 | 3135 | ||
@@ -3620,7 +3626,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
3620 | uint8_t last_byte; | 3626 | uint8_t last_byte; |
3621 | unsigned int i; | 3627 | unsigned int i; |
3622 | int cleaned_count = 0; | 3628 | int cleaned_count = 0; |
3623 | boolean_t cleaned = FALSE, multi_descriptor = FALSE; | 3629 | boolean_t cleaned = FALSE; |
3624 | 3630 | ||
3625 | i = rx_ring->next_to_clean; | 3631 | i = rx_ring->next_to_clean; |
3626 | rx_desc = E1000_RX_DESC(*rx_ring, i); | 3632 | rx_desc = E1000_RX_DESC(*rx_ring, i); |
@@ -3652,43 +3658,12 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
3652 | 3658 | ||
3653 | length = le16_to_cpu(rx_desc->length); | 3659 | length = le16_to_cpu(rx_desc->length); |
3654 | 3660 | ||
3655 | skb_put(skb, length); | 3661 | if (unlikely(!(status & E1000_RXD_STAT_EOP))) { |
3656 | 3662 | /* All receives must fit into a single buffer */ | |
3657 | if (!(status & E1000_RXD_STAT_EOP)) { | 3663 | E1000_DBG("%s: Receive packet consumed multiple" |
3658 | if (!rx_ring->rx_skb_top) { | 3664 | " buffers\n", netdev->name); |
3659 | rx_ring->rx_skb_top = skb; | 3665 | dev_kfree_skb_irq(skb); |
3660 | rx_ring->rx_skb_top->len = length; | ||
3661 | rx_ring->rx_skb_prev = skb; | ||
3662 | } else { | ||
3663 | if (skb_shinfo(rx_ring->rx_skb_top)->frag_list) { | ||
3664 | rx_ring->rx_skb_prev->next = skb; | ||
3665 | skb->prev = rx_ring->rx_skb_prev; | ||
3666 | } else { | ||
3667 | skb_shinfo(rx_ring->rx_skb_top)->frag_list = skb; | ||
3668 | } | ||
3669 | rx_ring->rx_skb_prev = skb; | ||
3670 | rx_ring->rx_skb_top->data_len += length; | ||
3671 | } | ||
3672 | goto next_desc; | 3666 | goto next_desc; |
3673 | } else { | ||
3674 | if (rx_ring->rx_skb_top) { | ||
3675 | if (skb_shinfo(rx_ring->rx_skb_top) | ||
3676 | ->frag_list) { | ||
3677 | rx_ring->rx_skb_prev->next = skb; | ||
3678 | skb->prev = rx_ring->rx_skb_prev; | ||
3679 | } else | ||
3680 | skb_shinfo(rx_ring->rx_skb_top) | ||
3681 | ->frag_list = skb; | ||
3682 | |||
3683 | rx_ring->rx_skb_top->data_len += length; | ||
3684 | rx_ring->rx_skb_top->len += | ||
3685 | rx_ring->rx_skb_top->data_len; | ||
3686 | |||
3687 | skb = rx_ring->rx_skb_top; | ||
3688 | multi_descriptor = TRUE; | ||
3689 | rx_ring->rx_skb_top = NULL; | ||
3690 | rx_ring->rx_skb_prev = NULL; | ||
3691 | } | ||
3692 | } | 3667 | } |
3693 | 3668 | ||
3694 | if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) { | 3669 | if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) { |
@@ -3712,10 +3687,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
3712 | * performance for small packets with large amounts | 3687 | * performance for small packets with large amounts |
3713 | * of reassembly being done in the stack */ | 3688 | * of reassembly being done in the stack */ |
3714 | #define E1000_CB_LENGTH 256 | 3689 | #define E1000_CB_LENGTH 256 |
3715 | if ((length < E1000_CB_LENGTH) && | 3690 | if (length < E1000_CB_LENGTH) { |
3716 | !rx_ring->rx_skb_top && | ||
3717 | /* or maybe (status & E1000_RXD_STAT_EOP) && */ | ||
3718 | !multi_descriptor) { | ||
3719 | struct sk_buff *new_skb = | 3691 | struct sk_buff *new_skb = |
3720 | dev_alloc_skb(length + NET_IP_ALIGN); | 3692 | dev_alloc_skb(length + NET_IP_ALIGN); |
3721 | if (new_skb) { | 3693 | if (new_skb) { |
@@ -3729,7 +3701,8 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
3729 | skb = new_skb; | 3701 | skb = new_skb; |
3730 | skb_put(skb, length); | 3702 | skb_put(skb, length); |
3731 | } | 3703 | } |
3732 | } | 3704 | } else |
3705 | skb_put(skb, length); | ||
3733 | 3706 | ||
3734 | /* end copybreak code */ | 3707 | /* end copybreak code */ |
3735 | 3708 | ||
@@ -3737,7 +3710,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
3737 | e1000_rx_checksum(adapter, | 3710 | e1000_rx_checksum(adapter, |
3738 | (uint32_t)(status) | | 3711 | (uint32_t)(status) | |
3739 | ((uint32_t)(rx_desc->errors) << 24), | 3712 | ((uint32_t)(rx_desc->errors) << 24), |
3740 | rx_desc->csum, skb); | 3713 | le16_to_cpu(rx_desc->csum), skb); |
3741 | 3714 | ||
3742 | skb->protocol = eth_type_trans(skb, netdev); | 3715 | skb->protocol = eth_type_trans(skb, netdev); |
3743 | #ifdef CONFIG_E1000_NAPI | 3716 | #ifdef CONFIG_E1000_NAPI |
@@ -3881,11 +3854,11 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
3881 | } | 3854 | } |
3882 | 3855 | ||
3883 | e1000_rx_checksum(adapter, staterr, | 3856 | e1000_rx_checksum(adapter, staterr, |
3884 | rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); | 3857 | le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); |
3885 | skb->protocol = eth_type_trans(skb, netdev); | 3858 | skb->protocol = eth_type_trans(skb, netdev); |
3886 | 3859 | ||
3887 | if (likely(rx_desc->wb.upper.header_status & | 3860 | if (likely(rx_desc->wb.upper.header_status & |
3888 | E1000_RXDPS_HDRSTAT_HDRSP)) | 3861 | cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))) |
3889 | adapter->rx_hdr_split++; | 3862 | adapter->rx_hdr_split++; |
3890 | #ifdef CONFIG_E1000_NAPI | 3863 | #ifdef CONFIG_E1000_NAPI |
3891 | if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) { | 3864 | if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) { |
@@ -3911,7 +3884,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
3911 | #endif | 3884 | #endif |
3912 | 3885 | ||
3913 | next_desc: | 3886 | next_desc: |
3914 | rx_desc->wb.middle.status_error &= ~0xFF; | 3887 | rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF); |
3915 | buffer_info->skb = NULL; | 3888 | buffer_info->skb = NULL; |
3916 | 3889 | ||
3917 | /* return some buffers to hardware, one at a time is too slow */ | 3890 | /* return some buffers to hardware, one at a time is too slow */ |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 0c18dbd67d3b..0e8e3fcde9ff 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -199,8 +199,7 @@ static int gfar_probe(struct platform_device *pdev) | |||
199 | 199 | ||
200 | /* get a pointer to the register memory */ | 200 | /* get a pointer to the register memory */ |
201 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 201 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
202 | priv->regs = (struct gfar *) | 202 | priv->regs = ioremap(r->start, sizeof (struct gfar)); |
203 | ioremap(r->start, sizeof (struct gfar)); | ||
204 | 203 | ||
205 | if (NULL == priv->regs) { | 204 | if (NULL == priv->regs) { |
206 | err = -ENOMEM; | 205 | err = -ENOMEM; |
@@ -369,7 +368,7 @@ static int gfar_probe(struct platform_device *pdev) | |||
369 | return 0; | 368 | return 0; |
370 | 369 | ||
371 | register_fail: | 370 | register_fail: |
372 | iounmap((void *) priv->regs); | 371 | iounmap(priv->regs); |
373 | regs_fail: | 372 | regs_fail: |
374 | free_netdev(dev); | 373 | free_netdev(dev); |
375 | return err; | 374 | return err; |
@@ -382,7 +381,7 @@ static int gfar_remove(struct platform_device *pdev) | |||
382 | 381 | ||
383 | platform_set_drvdata(pdev, NULL); | 382 | platform_set_drvdata(pdev, NULL); |
384 | 383 | ||
385 | iounmap((void *) priv->regs); | 384 | iounmap(priv->regs); |
386 | free_netdev(dev); | 385 | free_netdev(dev); |
387 | 386 | ||
388 | return 0; | 387 | return 0; |
@@ -454,8 +453,7 @@ static void init_registers(struct net_device *dev) | |||
454 | 453 | ||
455 | /* Zero out the rmon mib registers if it has them */ | 454 | /* Zero out the rmon mib registers if it has them */ |
456 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { | 455 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { |
457 | memset((void *) &(priv->regs->rmon), 0, | 456 | memset_io(&(priv->regs->rmon), 0, sizeof (struct rmon_mib)); |
458 | sizeof (struct rmon_mib)); | ||
459 | 457 | ||
460 | /* Mask off the CAM interrupts */ | 458 | /* Mask off the CAM interrupts */ |
461 | gfar_write(&priv->regs->rmon.cam1, 0xffffffff); | 459 | gfar_write(&priv->regs->rmon.cam1, 0xffffffff); |
@@ -477,7 +475,7 @@ static void init_registers(struct net_device *dev) | |||
477 | void gfar_halt(struct net_device *dev) | 475 | void gfar_halt(struct net_device *dev) |
478 | { | 476 | { |
479 | struct gfar_private *priv = netdev_priv(dev); | 477 | struct gfar_private *priv = netdev_priv(dev); |
480 | struct gfar *regs = priv->regs; | 478 | struct gfar __iomem *regs = priv->regs; |
481 | u32 tempval; | 479 | u32 tempval; |
482 | 480 | ||
483 | /* Mask all interrupts */ | 481 | /* Mask all interrupts */ |
@@ -507,7 +505,7 @@ void gfar_halt(struct net_device *dev) | |||
507 | void stop_gfar(struct net_device *dev) | 505 | void stop_gfar(struct net_device *dev) |
508 | { | 506 | { |
509 | struct gfar_private *priv = netdev_priv(dev); | 507 | struct gfar_private *priv = netdev_priv(dev); |
510 | struct gfar *regs = priv->regs; | 508 | struct gfar __iomem *regs = priv->regs; |
511 | unsigned long flags; | 509 | unsigned long flags; |
512 | 510 | ||
513 | phy_stop(priv->phydev); | 511 | phy_stop(priv->phydev); |
@@ -590,7 +588,7 @@ static void free_skb_resources(struct gfar_private *priv) | |||
590 | void gfar_start(struct net_device *dev) | 588 | void gfar_start(struct net_device *dev) |
591 | { | 589 | { |
592 | struct gfar_private *priv = netdev_priv(dev); | 590 | struct gfar_private *priv = netdev_priv(dev); |
593 | struct gfar *regs = priv->regs; | 591 | struct gfar __iomem *regs = priv->regs; |
594 | u32 tempval; | 592 | u32 tempval; |
595 | 593 | ||
596 | /* Enable Rx and Tx in MACCFG1 */ | 594 | /* Enable Rx and Tx in MACCFG1 */ |
@@ -624,7 +622,7 @@ int startup_gfar(struct net_device *dev) | |||
624 | unsigned long vaddr; | 622 | unsigned long vaddr; |
625 | int i; | 623 | int i; |
626 | struct gfar_private *priv = netdev_priv(dev); | 624 | struct gfar_private *priv = netdev_priv(dev); |
627 | struct gfar *regs = priv->regs; | 625 | struct gfar __iomem *regs = priv->regs; |
628 | int err = 0; | 626 | int err = 0; |
629 | u32 rctrl = 0; | 627 | u32 rctrl = 0; |
630 | u32 attrs = 0; | 628 | u32 attrs = 0; |
@@ -1622,7 +1620,7 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1622 | static void adjust_link(struct net_device *dev) | 1620 | static void adjust_link(struct net_device *dev) |
1623 | { | 1621 | { |
1624 | struct gfar_private *priv = netdev_priv(dev); | 1622 | struct gfar_private *priv = netdev_priv(dev); |
1625 | struct gfar *regs = priv->regs; | 1623 | struct gfar __iomem *regs = priv->regs; |
1626 | unsigned long flags; | 1624 | unsigned long flags; |
1627 | struct phy_device *phydev = priv->phydev; | 1625 | struct phy_device *phydev = priv->phydev; |
1628 | int new_state = 0; | 1626 | int new_state = 0; |
@@ -1703,7 +1701,7 @@ static void gfar_set_multi(struct net_device *dev) | |||
1703 | { | 1701 | { |
1704 | struct dev_mc_list *mc_ptr; | 1702 | struct dev_mc_list *mc_ptr; |
1705 | struct gfar_private *priv = netdev_priv(dev); | 1703 | struct gfar_private *priv = netdev_priv(dev); |
1706 | struct gfar *regs = priv->regs; | 1704 | struct gfar __iomem *regs = priv->regs; |
1707 | u32 tempval; | 1705 | u32 tempval; |
1708 | 1706 | ||
1709 | if(dev->flags & IFF_PROMISC) { | 1707 | if(dev->flags & IFF_PROMISC) { |
@@ -1842,7 +1840,7 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr) | |||
1842 | int idx; | 1840 | int idx; |
1843 | char tmpbuf[MAC_ADDR_LEN]; | 1841 | char tmpbuf[MAC_ADDR_LEN]; |
1844 | u32 tempval; | 1842 | u32 tempval; |
1845 | u32 *macptr = &priv->regs->macstnaddr1; | 1843 | u32 __iomem *macptr = &priv->regs->macstnaddr1; |
1846 | 1844 | ||
1847 | macptr += num*2; | 1845 | macptr += num*2; |
1848 | 1846 | ||
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index cb9d66ac3ab9..d37d5401be6e 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -682,8 +682,8 @@ struct gfar_private { | |||
682 | struct rxbd8 *cur_rx; /* Next free rx ring entry */ | 682 | struct rxbd8 *cur_rx; /* Next free rx ring entry */ |
683 | struct txbd8 *cur_tx; /* Next free ring entry */ | 683 | struct txbd8 *cur_tx; /* Next free ring entry */ |
684 | struct txbd8 *dirty_tx; /* The Ring entry to be freed. */ | 684 | struct txbd8 *dirty_tx; /* The Ring entry to be freed. */ |
685 | struct gfar *regs; /* Pointer to the GFAR memory mapped Registers */ | 685 | struct gfar __iomem *regs; /* Pointer to the GFAR memory mapped Registers */ |
686 | u32 *hash_regs[16]; | 686 | u32 __iomem *hash_regs[16]; |
687 | int hash_width; | 687 | int hash_width; |
688 | struct net_device_stats stats; /* linux network statistics */ | 688 | struct net_device_stats stats; /* linux network statistics */ |
689 | struct gfar_extra_stats extra_stats; | 689 | struct gfar_extra_stats extra_stats; |
@@ -718,14 +718,14 @@ struct gfar_private { | |||
718 | uint32_t msg_enable; | 718 | uint32_t msg_enable; |
719 | }; | 719 | }; |
720 | 720 | ||
721 | static inline u32 gfar_read(volatile unsigned *addr) | 721 | static inline u32 gfar_read(volatile unsigned __iomem *addr) |
722 | { | 722 | { |
723 | u32 val; | 723 | u32 val; |
724 | val = in_be32(addr); | 724 | val = in_be32(addr); |
725 | return val; | 725 | return val; |
726 | } | 726 | } |
727 | 727 | ||
728 | static inline void gfar_write(volatile unsigned *addr, u32 val) | 728 | static inline void gfar_write(volatile unsigned __iomem *addr, u32 val) |
729 | { | 729 | { |
730 | out_be32(addr, val); | 730 | out_be32(addr, val); |
731 | } | 731 | } |
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 765e810620fe..5de7b2e259dc 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c | |||
@@ -144,11 +144,11 @@ static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, | |||
144 | u64 *extra = (u64 *) & priv->extra_stats; | 144 | u64 *extra = (u64 *) & priv->extra_stats; |
145 | 145 | ||
146 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { | 146 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { |
147 | u32 *rmon = (u32 *) & priv->regs->rmon; | 147 | u32 __iomem *rmon = (u32 __iomem *) & priv->regs->rmon; |
148 | struct gfar_stats *stats = (struct gfar_stats *) buf; | 148 | struct gfar_stats *stats = (struct gfar_stats *) buf; |
149 | 149 | ||
150 | for (i = 0; i < GFAR_RMON_LEN; i++) | 150 | for (i = 0; i < GFAR_RMON_LEN; i++) |
151 | stats->rmon[i] = (u64) (rmon[i]); | 151 | stats->rmon[i] = (u64) gfar_read(&rmon[i]); |
152 | 152 | ||
153 | for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) | 153 | for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) |
154 | stats->extra[i] = extra[i]; | 154 | stats->extra[i] = extra[i]; |
@@ -221,11 +221,11 @@ static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, voi | |||
221 | { | 221 | { |
222 | int i; | 222 | int i; |
223 | struct gfar_private *priv = netdev_priv(dev); | 223 | struct gfar_private *priv = netdev_priv(dev); |
224 | u32 *theregs = (u32 *) priv->regs; | 224 | u32 __iomem *theregs = (u32 __iomem *) priv->regs; |
225 | u32 *buf = (u32 *) regbuf; | 225 | u32 *buf = (u32 *) regbuf; |
226 | 226 | ||
227 | for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++) | 227 | for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++) |
228 | buf[i] = theregs[i]; | 228 | buf[i] = gfar_read(&theregs[i]); |
229 | } | 229 | } |
230 | 230 | ||
231 | /* Convert microseconds to ethernet clock ticks, which changes | 231 | /* Convert microseconds to ethernet clock ticks, which changes |
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index 74e52fcbf806..c6b725529af5 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c | |||
@@ -50,7 +50,7 @@ | |||
50 | * All PHY configuration is done through the TSEC1 MIIM regs */ | 50 | * All PHY configuration is done through the TSEC1 MIIM regs */ |
51 | int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) | 51 | int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) |
52 | { | 52 | { |
53 | struct gfar_mii *regs = bus->priv; | 53 | struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; |
54 | 54 | ||
55 | /* Set the PHY address and the register address we want to write */ | 55 | /* Set the PHY address and the register address we want to write */ |
56 | gfar_write(®s->miimadd, (mii_id << 8) | regnum); | 56 | gfar_write(®s->miimadd, (mii_id << 8) | regnum); |
@@ -70,7 +70,7 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) | |||
70 | * configuration has to be done through the TSEC1 MIIM regs */ | 70 | * configuration has to be done through the TSEC1 MIIM regs */ |
71 | int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | 71 | int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) |
72 | { | 72 | { |
73 | struct gfar_mii *regs = bus->priv; | 73 | struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; |
74 | u16 value; | 74 | u16 value; |
75 | 75 | ||
76 | /* Set the PHY address and the register address we want to read */ | 76 | /* Set the PHY address and the register address we want to read */ |
@@ -94,7 +94,7 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | |||
94 | /* Reset the MIIM registers, and wait for the bus to free */ | 94 | /* Reset the MIIM registers, and wait for the bus to free */ |
95 | int gfar_mdio_reset(struct mii_bus *bus) | 95 | int gfar_mdio_reset(struct mii_bus *bus) |
96 | { | 96 | { |
97 | struct gfar_mii *regs = bus->priv; | 97 | struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; |
98 | unsigned int timeout = PHY_INIT_TIMEOUT; | 98 | unsigned int timeout = PHY_INIT_TIMEOUT; |
99 | 99 | ||
100 | spin_lock_bh(&bus->mdio_lock); | 100 | spin_lock_bh(&bus->mdio_lock); |
@@ -126,7 +126,7 @@ int gfar_mdio_probe(struct device *dev) | |||
126 | { | 126 | { |
127 | struct platform_device *pdev = to_platform_device(dev); | 127 | struct platform_device *pdev = to_platform_device(dev); |
128 | struct gianfar_mdio_data *pdata; | 128 | struct gianfar_mdio_data *pdata; |
129 | struct gfar_mii *regs; | 129 | struct gfar_mii __iomem *regs; |
130 | struct mii_bus *new_bus; | 130 | struct mii_bus *new_bus; |
131 | struct resource *r; | 131 | struct resource *r; |
132 | int err = 0; | 132 | int err = 0; |
@@ -155,15 +155,14 @@ int gfar_mdio_probe(struct device *dev) | |||
155 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 155 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
156 | 156 | ||
157 | /* Set the PHY base address */ | 157 | /* Set the PHY base address */ |
158 | regs = (struct gfar_mii *) ioremap(r->start, | 158 | regs = ioremap(r->start, sizeof (struct gfar_mii)); |
159 | sizeof (struct gfar_mii)); | ||
160 | 159 | ||
161 | if (NULL == regs) { | 160 | if (NULL == regs) { |
162 | err = -ENOMEM; | 161 | err = -ENOMEM; |
163 | goto reg_map_fail; | 162 | goto reg_map_fail; |
164 | } | 163 | } |
165 | 164 | ||
166 | new_bus->priv = regs; | 165 | new_bus->priv = (void __force *)regs; |
167 | 166 | ||
168 | new_bus->irq = pdata->irq; | 167 | new_bus->irq = pdata->irq; |
169 | 168 | ||
@@ -181,7 +180,7 @@ int gfar_mdio_probe(struct device *dev) | |||
181 | return 0; | 180 | return 0; |
182 | 181 | ||
183 | bus_register_fail: | 182 | bus_register_fail: |
184 | iounmap((void *) regs); | 183 | iounmap(regs); |
185 | reg_map_fail: | 184 | reg_map_fail: |
186 | kfree(new_bus); | 185 | kfree(new_bus); |
187 | 186 | ||
@@ -197,7 +196,7 @@ int gfar_mdio_remove(struct device *dev) | |||
197 | 196 | ||
198 | dev_set_drvdata(dev, NULL); | 197 | dev_set_drvdata(dev, NULL); |
199 | 198 | ||
200 | iounmap((void *) (&bus->priv)); | 199 | iounmap((void __iomem *)bus->priv); |
201 | bus->priv = NULL; | 200 | bus->priv = NULL; |
202 | kfree(bus); | 201 | kfree(bus); |
203 | 202 | ||
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index 3b1bef1ee215..77411a00d1ee 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c | |||
@@ -86,7 +86,6 @@ | |||
86 | #include <linux/bitops.h> | 86 | #include <linux/bitops.h> |
87 | #include <linux/jiffies.h> | 87 | #include <linux/jiffies.h> |
88 | 88 | ||
89 | #include <asm/bug.h> | ||
90 | #include <asm/system.h> | 89 | #include <asm/system.h> |
91 | #include <asm/uaccess.h> | 90 | #include <asm/uaccess.h> |
92 | 91 | ||
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 1b699259b4ec..31fb2d75dc44 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c | |||
@@ -57,7 +57,7 @@ struct ifb_private { | |||
57 | struct sk_buff_head tq; | 57 | struct sk_buff_head tq; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static int numifbs = 1; | 60 | static int numifbs = 2; |
61 | 61 | ||
62 | static void ri_tasklet(unsigned long dev); | 62 | static void ri_tasklet(unsigned long dev); |
63 | static int ifb_xmit(struct sk_buff *skb, struct net_device *dev); | 63 | static int ifb_xmit(struct sk_buff *skb, struct net_device *dev); |
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index fa176ffb4ad5..8936058a3cce 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
@@ -108,6 +108,7 @@ static void irda_usb_close(struct irda_usb_cb *self); | |||
108 | static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs); | 108 | static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs); |
109 | static void write_bulk_callback(struct urb *urb, struct pt_regs *regs); | 109 | static void write_bulk_callback(struct urb *urb, struct pt_regs *regs); |
110 | static void irda_usb_receive(struct urb *urb, struct pt_regs *regs); | 110 | static void irda_usb_receive(struct urb *urb, struct pt_regs *regs); |
111 | static void irda_usb_rx_defer_expired(unsigned long data); | ||
111 | static int irda_usb_net_open(struct net_device *dev); | 112 | static int irda_usb_net_open(struct net_device *dev); |
112 | static int irda_usb_net_close(struct net_device *dev); | 113 | static int irda_usb_net_close(struct net_device *dev); |
113 | static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 114 | static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
@@ -677,6 +678,12 @@ static void irda_usb_net_timeout(struct net_device *netdev) | |||
677 | * on the interrupt pipe and hang the Rx URB only when an interrupt is | 678 | * on the interrupt pipe and hang the Rx URB only when an interrupt is |
678 | * received. | 679 | * received. |
679 | * Jean II | 680 | * Jean II |
681 | * | ||
682 | * Note : don't read the above as what we are currently doing, but as | ||
683 | * something we could do with KC dongle. Also don't forget that the | ||
684 | * interrupt pipe is not part of the original standard, so this would | ||
685 | * need to be optional... | ||
686 | * Jean II | ||
680 | */ | 687 | */ |
681 | 688 | ||
682 | /*------------------------------------------------------------------*/ | 689 | /*------------------------------------------------------------------*/ |
@@ -704,10 +711,8 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc | |||
704 | /* Reinitialize URB */ | 711 | /* Reinitialize URB */ |
705 | usb_fill_bulk_urb(urb, self->usbdev, | 712 | usb_fill_bulk_urb(urb, self->usbdev, |
706 | usb_rcvbulkpipe(self->usbdev, self->bulk_in_ep), | 713 | usb_rcvbulkpipe(self->usbdev, self->bulk_in_ep), |
707 | skb->data, skb->truesize, | 714 | skb->data, IRDA_SKB_MAX_MTU, |
708 | irda_usb_receive, skb); | 715 | irda_usb_receive, skb); |
709 | /* Note : unlink *must* be synchronous because of the code in | ||
710 | * irda_usb_net_close() -> free the skb - Jean II */ | ||
711 | urb->status = 0; | 716 | urb->status = 0; |
712 | 717 | ||
713 | /* Can be called from irda_usb_receive (irq handler) -> GFP_ATOMIC */ | 718 | /* Can be called from irda_usb_receive (irq handler) -> GFP_ATOMIC */ |
@@ -734,6 +739,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
734 | struct irda_skb_cb *cb; | 739 | struct irda_skb_cb *cb; |
735 | struct sk_buff *newskb; | 740 | struct sk_buff *newskb; |
736 | struct sk_buff *dataskb; | 741 | struct sk_buff *dataskb; |
742 | struct urb *next_urb; | ||
737 | int docopy; | 743 | int docopy; |
738 | 744 | ||
739 | IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length); | 745 | IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length); |
@@ -755,20 +761,37 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) | |||
755 | if (urb->status != 0) { | 761 | if (urb->status != 0) { |
756 | switch (urb->status) { | 762 | switch (urb->status) { |
757 | case -EILSEQ: | 763 | case -EILSEQ: |
758 | self->stats.rx_errors++; | ||
759 | self->stats.rx_crc_errors++; | 764 | self->stats.rx_crc_errors++; |
760 | break; | 765 | /* Also precursor to a hot-unplug on UHCI. */ |
766 | /* Fallthrough... */ | ||
761 | case -ECONNRESET: /* -104 */ | 767 | case -ECONNRESET: /* -104 */ |
762 | IRDA_DEBUG(0, "%s(), Connection Reset (-104), transfer_flags 0x%04X \n", __FUNCTION__, urb->transfer_flags); | 768 | /* Random error, if I remember correctly */ |
763 | /* uhci_cleanup_unlink() is going to kill the Rx | 769 | /* uhci_cleanup_unlink() is going to kill the Rx |
764 | * URB just after we return. No problem, at this | 770 | * URB just after we return. No problem, at this |
765 | * point the URB will be idle ;-) - Jean II */ | 771 | * point the URB will be idle ;-) - Jean II */ |
766 | break; | 772 | case -ESHUTDOWN: /* -108 */ |
773 | /* That's usually a hot-unplug. Submit will fail... */ | ||
774 | case -ETIMEDOUT: /* -110 */ | ||
775 | /* Usually precursor to a hot-unplug on OHCI. */ | ||
767 | default: | 776 | default: |
768 | IRDA_DEBUG(0, "%s(), RX status %d,transfer_flags 0x%04X \n", __FUNCTION__, urb->status, urb->transfer_flags); | 777 | self->stats.rx_errors++; |
778 | IRDA_DEBUG(0, "%s(), RX status %d, transfer_flags 0x%04X \n", __FUNCTION__, urb->status, urb->transfer_flags); | ||
769 | break; | 779 | break; |
770 | } | 780 | } |
771 | goto done; | 781 | /* If we received an error, we don't want to resubmit the |
782 | * Rx URB straight away but to give the USB layer a little | ||
783 | * bit of breathing room. | ||
784 | * We are in the USB thread context, therefore there is a | ||
785 | * danger of recursion (new URB we submit fails, we come | ||
786 | * back here). | ||
787 | * With recent USB stack (2.6.15+), I'm seeing that on | ||
788 | * hot unplug of the dongle... | ||
789 | * Lowest effective timer is 10ms... | ||
790 | * Jean II */ | ||
791 | self->rx_defer_timer.function = &irda_usb_rx_defer_expired; | ||
792 | self->rx_defer_timer.data = (unsigned long) urb; | ||
793 | mod_timer(&self->rx_defer_timer, jiffies + (10 * HZ / 1000)); | ||
794 | return; | ||
772 | } | 795 | } |
773 | 796 | ||
774 | /* Check for empty frames */ | 797 | /* Check for empty frames */ |
@@ -845,13 +868,45 @@ done: | |||
845 | * idle slot.... | 868 | * idle slot.... |
846 | * Jean II */ | 869 | * Jean II */ |
847 | /* Note : with this scheme, we could submit the idle URB before | 870 | /* Note : with this scheme, we could submit the idle URB before |
848 | * processing the Rx URB. Another time... Jean II */ | 871 | * processing the Rx URB. I don't think it would buy us anything as |
872 | * we are running in the USB thread context. Jean II */ | ||
873 | next_urb = self->idle_rx_urb; | ||
849 | 874 | ||
850 | /* Submit the idle URB to replace the URB we've just received */ | ||
851 | irda_usb_submit(self, skb, self->idle_rx_urb); | ||
852 | /* Recycle Rx URB : Now, the idle URB is the present one */ | 875 | /* Recycle Rx URB : Now, the idle URB is the present one */ |
853 | urb->context = NULL; | 876 | urb->context = NULL; |
854 | self->idle_rx_urb = urb; | 877 | self->idle_rx_urb = urb; |
878 | |||
879 | /* Submit the idle URB to replace the URB we've just received. | ||
880 | * Do it last to avoid race conditions... Jean II */ | ||
881 | irda_usb_submit(self, skb, next_urb); | ||
882 | } | ||
883 | |||
884 | /*------------------------------------------------------------------*/ | ||
885 | /* | ||
886 | * In case of errors, we want the USB layer to have time to recover. | ||
887 | * Now, it is time to resubmit ouur Rx URB... | ||
888 | */ | ||
889 | static void irda_usb_rx_defer_expired(unsigned long data) | ||
890 | { | ||
891 | struct urb *urb = (struct urb *) data; | ||
892 | struct sk_buff *skb = (struct sk_buff *) urb->context; | ||
893 | struct irda_usb_cb *self; | ||
894 | struct irda_skb_cb *cb; | ||
895 | struct urb *next_urb; | ||
896 | |||
897 | IRDA_DEBUG(2, "%s()\n", __FUNCTION__); | ||
898 | |||
899 | /* Find ourselves */ | ||
900 | cb = (struct irda_skb_cb *) skb->cb; | ||
901 | IRDA_ASSERT(cb != NULL, return;); | ||
902 | self = (struct irda_usb_cb *) cb->context; | ||
903 | IRDA_ASSERT(self != NULL, return;); | ||
904 | |||
905 | /* Same stuff as when Rx is done, see above... */ | ||
906 | next_urb = self->idle_rx_urb; | ||
907 | urb->context = NULL; | ||
908 | self->idle_rx_urb = urb; | ||
909 | irda_usb_submit(self, skb, next_urb); | ||
855 | } | 910 | } |
856 | 911 | ||
857 | /*------------------------------------------------------------------*/ | 912 | /*------------------------------------------------------------------*/ |
@@ -990,6 +1045,9 @@ static int irda_usb_net_close(struct net_device *netdev) | |||
990 | /* Stop network Tx queue */ | 1045 | /* Stop network Tx queue */ |
991 | netif_stop_queue(netdev); | 1046 | netif_stop_queue(netdev); |
992 | 1047 | ||
1048 | /* Kill defered Rx URB */ | ||
1049 | del_timer(&self->rx_defer_timer); | ||
1050 | |||
993 | /* Deallocate all the Rx path buffers (URBs and skb) */ | 1051 | /* Deallocate all the Rx path buffers (URBs and skb) */ |
994 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1052 | for (i = 0; i < IU_MAX_RX_URBS; i++) { |
995 | struct urb *urb = self->rx_urb[i]; | 1053 | struct urb *urb = self->rx_urb[i]; |
@@ -1365,6 +1423,7 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
1365 | self = net->priv; | 1423 | self = net->priv; |
1366 | self->netdev = net; | 1424 | self->netdev = net; |
1367 | spin_lock_init(&self->lock); | 1425 | spin_lock_init(&self->lock); |
1426 | init_timer(&self->rx_defer_timer); | ||
1368 | 1427 | ||
1369 | /* Create all of the needed urbs */ | 1428 | /* Create all of the needed urbs */ |
1370 | for (i = 0; i < IU_MAX_RX_URBS; i++) { | 1429 | for (i = 0; i < IU_MAX_RX_URBS; i++) { |
@@ -1498,6 +1557,9 @@ static void irda_usb_disconnect(struct usb_interface *intf) | |||
1498 | * This will stop/desactivate the Tx path. - Jean II */ | 1557 | * This will stop/desactivate the Tx path. - Jean II */ |
1499 | self->present = 0; | 1558 | self->present = 0; |
1500 | 1559 | ||
1560 | /* Kill defered Rx URB */ | ||
1561 | del_timer(&self->rx_defer_timer); | ||
1562 | |||
1501 | /* We need to have irq enabled to unlink the URBs. That's OK, | 1563 | /* We need to have irq enabled to unlink the URBs. That's OK, |
1502 | * at this point the Tx path is gone - Jean II */ | 1564 | * at this point the Tx path is gone - Jean II */ |
1503 | spin_unlock_irqrestore(&self->lock, flags); | 1565 | spin_unlock_irqrestore(&self->lock, flags); |
@@ -1507,11 +1569,11 @@ static void irda_usb_disconnect(struct usb_interface *intf) | |||
1507 | /* Accept no more transmissions */ | 1569 | /* Accept no more transmissions */ |
1508 | /*netif_device_detach(self->netdev);*/ | 1570 | /*netif_device_detach(self->netdev);*/ |
1509 | netif_stop_queue(self->netdev); | 1571 | netif_stop_queue(self->netdev); |
1510 | /* Stop all the receive URBs */ | 1572 | /* Stop all the receive URBs. Must be synchronous. */ |
1511 | for (i = 0; i < IU_MAX_RX_URBS; i++) | 1573 | for (i = 0; i < IU_MAX_RX_URBS; i++) |
1512 | usb_kill_urb(self->rx_urb[i]); | 1574 | usb_kill_urb(self->rx_urb[i]); |
1513 | /* Cancel Tx and speed URB. | 1575 | /* Cancel Tx and speed URB. |
1514 | * Toggle flags to make sure it's synchronous. */ | 1576 | * Make sure it's synchronous to avoid races. */ |
1515 | usb_kill_urb(self->tx_urb); | 1577 | usb_kill_urb(self->tx_urb); |
1516 | usb_kill_urb(self->speed_urb); | 1578 | usb_kill_urb(self->speed_urb); |
1517 | } | 1579 | } |
diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index bd8f66542322..4026af42dd47 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h | |||
@@ -136,8 +136,6 @@ struct irda_usb_cb { | |||
136 | __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ | 136 | __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ |
137 | __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ | 137 | __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ |
138 | 138 | ||
139 | wait_queue_head_t wait_q; /* for timeouts */ | ||
140 | |||
141 | struct urb *rx_urb[IU_MAX_RX_URBS]; /* URBs used to receive data frames */ | 139 | struct urb *rx_urb[IU_MAX_RX_URBS]; /* URBs used to receive data frames */ |
142 | struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ | 140 | struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ |
143 | struct urb *tx_urb; /* URB used to send data frames */ | 141 | struct urb *tx_urb; /* URB used to send data frames */ |
@@ -147,17 +145,18 @@ struct irda_usb_cb { | |||
147 | struct net_device_stats stats; | 145 | struct net_device_stats stats; |
148 | struct irlap_cb *irlap; /* The link layer we are binded to */ | 146 | struct irlap_cb *irlap; /* The link layer we are binded to */ |
149 | struct qos_info qos; | 147 | struct qos_info qos; |
150 | hashbin_t *tx_list; /* Queued transmit skb's */ | ||
151 | char *speed_buff; /* Buffer for speed changes */ | 148 | char *speed_buff; /* Buffer for speed changes */ |
152 | 149 | ||
153 | struct timeval stamp; | 150 | struct timeval stamp; |
154 | struct timeval now; | 151 | struct timeval now; |
155 | 152 | ||
156 | spinlock_t lock; /* For serializing operations */ | 153 | spinlock_t lock; /* For serializing Tx operations */ |
157 | 154 | ||
158 | __u16 xbofs; /* Current xbofs setting */ | 155 | __u16 xbofs; /* Current xbofs setting */ |
159 | __s16 new_xbofs; /* xbofs we need to set */ | 156 | __s16 new_xbofs; /* xbofs we need to set */ |
160 | __u32 speed; /* Current speed */ | 157 | __u32 speed; /* Current speed */ |
161 | __s32 new_speed; /* speed we need to set */ | 158 | __s32 new_speed; /* speed we need to set */ |
159 | |||
160 | struct timer_list rx_defer_timer; /* Wait for Rx error to clear */ | ||
162 | }; | 161 | }; |
163 | 162 | ||
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 7ef4b0434a3f..c0998ef938e0 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -32,6 +32,8 @@ | |||
32 | */ | 32 | */ |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | #include <linux/in.h> | ||
36 | #include <linux/ip.h> | ||
35 | #include <linux/tcp.h> | 37 | #include <linux/tcp.h> |
36 | #include <linux/udp.h> | 38 | #include <linux/udp.h> |
37 | #include <linux/etherdevice.h> | 39 | #include <linux/etherdevice.h> |
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 01ddfc8cce3f..aa5581369399 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
@@ -806,6 +806,7 @@ static struct pcmcia_device_id axnet_ids[] = { | |||
806 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309), | 806 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309), |
807 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1106), | 807 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1106), |
808 | PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab), | 808 | PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab), |
809 | PCMCIA_DEVICE_PROD_ID12("AmbiCom,Inc.", "Fast Ethernet PC Card(AMB8110)", 0x49b020a7, 0x119cc9fc), | ||
809 | PCMCIA_DEVICE_PROD_ID124("Fast Ethernet", "16-bit PC Card", "AX88190", 0xb4be14e3, 0x9a12eb6a, 0xab9be5ef), | 810 | PCMCIA_DEVICE_PROD_ID124("Fast Ethernet", "16-bit PC Card", "AX88190", 0xb4be14e3, 0x9a12eb6a, 0xab9be5ef), |
810 | PCMCIA_DEVICE_PROD_ID12("ASIX", "AX88190", 0x0959823b, 0xab9be5ef), | 811 | PCMCIA_DEVICE_PROD_ID12("ASIX", "AX88190", 0x0959823b, 0xab9be5ef), |
811 | PCMCIA_DEVICE_PROD_ID12("Billionton", "LNA-100B", 0x552ab682, 0xbc3b87e1), | 812 | PCMCIA_DEVICE_PROD_ID12("Billionton", "LNA-100B", 0x552ab682, 0xbc3b87e1), |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 1c6d328165bb..0245e40b51a1 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -1610,6 +1610,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1610 | } | 1610 | } |
1611 | else if (!pskb_may_pull(skb, skb->len)) | 1611 | else if (!pskb_may_pull(skb, skb->len)) |
1612 | goto err; | 1612 | goto err; |
1613 | else | ||
1614 | skb->ip_summed = CHECKSUM_NONE; | ||
1613 | 1615 | ||
1614 | len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2); | 1616 | len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2); |
1615 | if (len <= 0) { | 1617 | if (len <= 0) { |
@@ -1690,6 +1692,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1690 | kfree_skb(skb); | 1692 | kfree_skb(skb); |
1691 | } else { | 1693 | } else { |
1692 | skb_pull(skb, 2); /* chop off protocol */ | 1694 | skb_pull(skb, 2); /* chop off protocol */ |
1695 | skb_postpull_rcsum(skb, skb->data - 2, 2); | ||
1693 | skb->dev = ppp->dev; | 1696 | skb->dev = ppp->dev; |
1694 | skb->protocol = htons(npindex_to_ethertype[npi]); | 1697 | skb->protocol = htons(npindex_to_ethertype[npi]); |
1695 | skb->mac.raw = skb->data; | 1698 | skb->mac.raw = skb->data; |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 2e1bed153c39..8cc0d0bbdf50 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -287,6 +287,20 @@ enum RTL8169_register_content { | |||
287 | TxInterFrameGapShift = 24, | 287 | TxInterFrameGapShift = 24, |
288 | TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ | 288 | TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ |
289 | 289 | ||
290 | /* Config1 register p.24 */ | ||
291 | PMEnable = (1 << 0), /* Power Management Enable */ | ||
292 | |||
293 | /* Config3 register p.25 */ | ||
294 | MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ | ||
295 | LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ | ||
296 | |||
297 | /* Config5 register p.27 */ | ||
298 | BWF = (1 << 6), /* Accept Broadcast wakeup frame */ | ||
299 | MWF = (1 << 5), /* Accept Multicast wakeup frame */ | ||
300 | UWF = (1 << 4), /* Accept Unicast wakeup frame */ | ||
301 | LanWake = (1 << 1), /* LanWake enable/disable */ | ||
302 | PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ | ||
303 | |||
290 | /* TBICSR p.28 */ | 304 | /* TBICSR p.28 */ |
291 | TBIReset = 0x80000000, | 305 | TBIReset = 0x80000000, |
292 | TBILoopback = 0x40000000, | 306 | TBILoopback = 0x40000000, |
@@ -433,6 +447,7 @@ struct rtl8169_private { | |||
433 | unsigned int (*phy_reset_pending)(void __iomem *); | 447 | unsigned int (*phy_reset_pending)(void __iomem *); |
434 | unsigned int (*link_ok)(void __iomem *); | 448 | unsigned int (*link_ok)(void __iomem *); |
435 | struct work_struct task; | 449 | struct work_struct task; |
450 | unsigned wol_enabled : 1; | ||
436 | }; | 451 | }; |
437 | 452 | ||
438 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); | 453 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); |
@@ -484,13 +499,12 @@ static void mdio_write(void __iomem *ioaddr, int RegAddr, int value) | |||
484 | int i; | 499 | int i; |
485 | 500 | ||
486 | RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); | 501 | RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); |
487 | udelay(1000); | ||
488 | 502 | ||
489 | for (i = 2000; i > 0; i--) { | 503 | for (i = 20; i > 0; i--) { |
490 | /* Check if the RTL8169 has completed writing to the specified MII register */ | 504 | /* Check if the RTL8169 has completed writing to the specified MII register */ |
491 | if (!(RTL_R32(PHYAR) & 0x80000000)) | 505 | if (!(RTL_R32(PHYAR) & 0x80000000)) |
492 | break; | 506 | break; |
493 | udelay(100); | 507 | udelay(25); |
494 | } | 508 | } |
495 | } | 509 | } |
496 | 510 | ||
@@ -499,15 +513,14 @@ static int mdio_read(void __iomem *ioaddr, int RegAddr) | |||
499 | int i, value = -1; | 513 | int i, value = -1; |
500 | 514 | ||
501 | RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); | 515 | RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); |
502 | udelay(1000); | ||
503 | 516 | ||
504 | for (i = 2000; i > 0; i--) { | 517 | for (i = 20; i > 0; i--) { |
505 | /* Check if the RTL8169 has completed retrieving data from the specified MII register */ | 518 | /* Check if the RTL8169 has completed retrieving data from the specified MII register */ |
506 | if (RTL_R32(PHYAR) & 0x80000000) { | 519 | if (RTL_R32(PHYAR) & 0x80000000) { |
507 | value = (int) (RTL_R32(PHYAR) & 0xFFFF); | 520 | value = (int) (RTL_R32(PHYAR) & 0xFFFF); |
508 | break; | 521 | break; |
509 | } | 522 | } |
510 | udelay(100); | 523 | udelay(25); |
511 | } | 524 | } |
512 | return value; | 525 | return value; |
513 | } | 526 | } |
@@ -609,6 +622,80 @@ static void rtl8169_link_option(int idx, u8 *autoneg, u16 *speed, u8 *duplex) | |||
609 | *duplex = p->duplex; | 622 | *duplex = p->duplex; |
610 | } | 623 | } |
611 | 624 | ||
625 | static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
626 | { | ||
627 | struct rtl8169_private *tp = netdev_priv(dev); | ||
628 | void __iomem *ioaddr = tp->mmio_addr; | ||
629 | u8 options; | ||
630 | |||
631 | wol->wolopts = 0; | ||
632 | |||
633 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) | ||
634 | wol->supported = WAKE_ANY; | ||
635 | |||
636 | spin_lock_irq(&tp->lock); | ||
637 | |||
638 | options = RTL_R8(Config1); | ||
639 | if (!(options & PMEnable)) | ||
640 | goto out_unlock; | ||
641 | |||
642 | options = RTL_R8(Config3); | ||
643 | if (options & LinkUp) | ||
644 | wol->wolopts |= WAKE_PHY; | ||
645 | if (options & MagicPacket) | ||
646 | wol->wolopts |= WAKE_MAGIC; | ||
647 | |||
648 | options = RTL_R8(Config5); | ||
649 | if (options & UWF) | ||
650 | wol->wolopts |= WAKE_UCAST; | ||
651 | if (options & BWF) | ||
652 | wol->wolopts |= WAKE_BCAST; | ||
653 | if (options & MWF) | ||
654 | wol->wolopts |= WAKE_MCAST; | ||
655 | |||
656 | out_unlock: | ||
657 | spin_unlock_irq(&tp->lock); | ||
658 | } | ||
659 | |||
660 | static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
661 | { | ||
662 | struct rtl8169_private *tp = netdev_priv(dev); | ||
663 | void __iomem *ioaddr = tp->mmio_addr; | ||
664 | int i; | ||
665 | static struct { | ||
666 | u32 opt; | ||
667 | u16 reg; | ||
668 | u8 mask; | ||
669 | } cfg[] = { | ||
670 | { WAKE_ANY, Config1, PMEnable }, | ||
671 | { WAKE_PHY, Config3, LinkUp }, | ||
672 | { WAKE_MAGIC, Config3, MagicPacket }, | ||
673 | { WAKE_UCAST, Config5, UWF }, | ||
674 | { WAKE_BCAST, Config5, BWF }, | ||
675 | { WAKE_MCAST, Config5, MWF }, | ||
676 | { WAKE_ANY, Config5, LanWake } | ||
677 | }; | ||
678 | |||
679 | spin_lock_irq(&tp->lock); | ||
680 | |||
681 | RTL_W8(Cfg9346, Cfg9346_Unlock); | ||
682 | |||
683 | for (i = 0; i < ARRAY_SIZE(cfg); i++) { | ||
684 | u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; | ||
685 | if (wol->wolopts & cfg[i].opt) | ||
686 | options |= cfg[i].mask; | ||
687 | RTL_W8(cfg[i].reg, options); | ||
688 | } | ||
689 | |||
690 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
691 | |||
692 | tp->wol_enabled = (wol->wolopts) ? 1 : 0; | ||
693 | |||
694 | spin_unlock_irq(&tp->lock); | ||
695 | |||
696 | return 0; | ||
697 | } | ||
698 | |||
612 | static void rtl8169_get_drvinfo(struct net_device *dev, | 699 | static void rtl8169_get_drvinfo(struct net_device *dev, |
613 | struct ethtool_drvinfo *info) | 700 | struct ethtool_drvinfo *info) |
614 | { | 701 | { |
@@ -677,6 +764,9 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, | |||
677 | 764 | ||
678 | if (duplex == DUPLEX_HALF) | 765 | if (duplex == DUPLEX_HALF) |
679 | auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); | 766 | auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); |
767 | |||
768 | if (duplex == DUPLEX_FULL) | ||
769 | auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half); | ||
680 | } | 770 | } |
681 | 771 | ||
682 | tp->phy_auto_nego_reg = auto_nego; | 772 | tp->phy_auto_nego_reg = auto_nego; |
@@ -1024,6 +1114,8 @@ static struct ethtool_ops rtl8169_ethtool_ops = { | |||
1024 | .get_tso = ethtool_op_get_tso, | 1114 | .get_tso = ethtool_op_get_tso, |
1025 | .set_tso = ethtool_op_set_tso, | 1115 | .set_tso = ethtool_op_set_tso, |
1026 | .get_regs = rtl8169_get_regs, | 1116 | .get_regs = rtl8169_get_regs, |
1117 | .get_wol = rtl8169_get_wol, | ||
1118 | .set_wol = rtl8169_set_wol, | ||
1027 | .get_strings = rtl8169_get_strings, | 1119 | .get_strings = rtl8169_get_strings, |
1028 | .get_stats_count = rtl8169_get_stats_count, | 1120 | .get_stats_count = rtl8169_get_stats_count, |
1029 | .get_ethtool_stats = rtl8169_get_ethtool_stats, | 1121 | .get_ethtool_stats = rtl8169_get_ethtool_stats, |
@@ -1441,6 +1533,11 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out, | |||
1441 | } | 1533 | } |
1442 | tp->chipset = i; | 1534 | tp->chipset = i; |
1443 | 1535 | ||
1536 | RTL_W8(Cfg9346, Cfg9346_Unlock); | ||
1537 | RTL_W8(Config1, RTL_R8(Config1) | PMEnable); | ||
1538 | RTL_W8(Config5, RTL_R8(Config5) & PMEStatus); | ||
1539 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
1540 | |||
1444 | *ioaddr_out = ioaddr; | 1541 | *ioaddr_out = ioaddr; |
1445 | *dev_out = dev; | 1542 | *dev_out = dev; |
1446 | out: | 1543 | out: |
@@ -1611,49 +1708,6 @@ rtl8169_remove_one(struct pci_dev *pdev) | |||
1611 | pci_set_drvdata(pdev, NULL); | 1708 | pci_set_drvdata(pdev, NULL); |
1612 | } | 1709 | } |
1613 | 1710 | ||
1614 | #ifdef CONFIG_PM | ||
1615 | |||
1616 | static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1617 | { | ||
1618 | struct net_device *dev = pci_get_drvdata(pdev); | ||
1619 | struct rtl8169_private *tp = netdev_priv(dev); | ||
1620 | void __iomem *ioaddr = tp->mmio_addr; | ||
1621 | unsigned long flags; | ||
1622 | |||
1623 | if (!netif_running(dev)) | ||
1624 | return 0; | ||
1625 | |||
1626 | netif_device_detach(dev); | ||
1627 | netif_stop_queue(dev); | ||
1628 | spin_lock_irqsave(&tp->lock, flags); | ||
1629 | |||
1630 | /* Disable interrupts, stop Rx and Tx */ | ||
1631 | RTL_W16(IntrMask, 0); | ||
1632 | RTL_W8(ChipCmd, 0); | ||
1633 | |||
1634 | /* Update the error counts. */ | ||
1635 | tp->stats.rx_missed_errors += RTL_R32(RxMissed); | ||
1636 | RTL_W32(RxMissed, 0); | ||
1637 | spin_unlock_irqrestore(&tp->lock, flags); | ||
1638 | |||
1639 | return 0; | ||
1640 | } | ||
1641 | |||
1642 | static int rtl8169_resume(struct pci_dev *pdev) | ||
1643 | { | ||
1644 | struct net_device *dev = pci_get_drvdata(pdev); | ||
1645 | |||
1646 | if (!netif_running(dev)) | ||
1647 | return 0; | ||
1648 | |||
1649 | netif_device_attach(dev); | ||
1650 | rtl8169_hw_start(dev); | ||
1651 | |||
1652 | return 0; | ||
1653 | } | ||
1654 | |||
1655 | #endif /* CONFIG_PM */ | ||
1656 | |||
1657 | static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, | 1711 | static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, |
1658 | struct net_device *dev) | 1712 | struct net_device *dev) |
1659 | { | 1713 | { |
@@ -2699,6 +2753,56 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) | |||
2699 | return &tp->stats; | 2753 | return &tp->stats; |
2700 | } | 2754 | } |
2701 | 2755 | ||
2756 | #ifdef CONFIG_PM | ||
2757 | |||
2758 | static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state) | ||
2759 | { | ||
2760 | struct net_device *dev = pci_get_drvdata(pdev); | ||
2761 | struct rtl8169_private *tp = netdev_priv(dev); | ||
2762 | void __iomem *ioaddr = tp->mmio_addr; | ||
2763 | |||
2764 | if (!netif_running(dev)) | ||
2765 | goto out; | ||
2766 | |||
2767 | netif_device_detach(dev); | ||
2768 | netif_stop_queue(dev); | ||
2769 | |||
2770 | spin_lock_irq(&tp->lock); | ||
2771 | |||
2772 | rtl8169_asic_down(ioaddr); | ||
2773 | |||
2774 | tp->stats.rx_missed_errors += RTL_R32(RxMissed); | ||
2775 | RTL_W32(RxMissed, 0); | ||
2776 | |||
2777 | spin_unlock_irq(&tp->lock); | ||
2778 | |||
2779 | pci_save_state(pdev); | ||
2780 | pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled); | ||
2781 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
2782 | out: | ||
2783 | return 0; | ||
2784 | } | ||
2785 | |||
2786 | static int rtl8169_resume(struct pci_dev *pdev) | ||
2787 | { | ||
2788 | struct net_device *dev = pci_get_drvdata(pdev); | ||
2789 | |||
2790 | if (!netif_running(dev)) | ||
2791 | goto out; | ||
2792 | |||
2793 | netif_device_attach(dev); | ||
2794 | |||
2795 | pci_set_power_state(pdev, PCI_D0); | ||
2796 | pci_restore_state(pdev); | ||
2797 | pci_enable_wake(pdev, PCI_D0, 0); | ||
2798 | |||
2799 | rtl8169_schedule_work(dev, rtl8169_reset_task); | ||
2800 | out: | ||
2801 | return 0; | ||
2802 | } | ||
2803 | |||
2804 | #endif /* CONFIG_PM */ | ||
2805 | |||
2702 | static struct pci_driver rtl8169_pci_driver = { | 2806 | static struct pci_driver rtl8169_pci_driver = { |
2703 | .name = MODULENAME, | 2807 | .name = MODULENAME, |
2704 | .id_table = rtl8169_pci_tbl, | 2808 | .id_table = rtl8169_pci_tbl, |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 49b597cbc19a..b7f00d6eb6a6 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -4092,6 +4092,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
4092 | i++, mclist = mclist->next) { | 4092 | i++, mclist = mclist->next) { |
4093 | memcpy(sp->usr_addrs[i].addr, mclist->dmi_addr, | 4093 | memcpy(sp->usr_addrs[i].addr, mclist->dmi_addr, |
4094 | ETH_ALEN); | 4094 | ETH_ALEN); |
4095 | mac_addr = 0; | ||
4095 | for (j = 0; j < ETH_ALEN; j++) { | 4096 | for (j = 0; j < ETH_ALEN; j++) { |
4096 | mac_addr |= mclist->dmi_addr[j]; | 4097 | mac_addr |= mclist->dmi_addr[j]; |
4097 | mac_addr <<= 8; | 4098 | mac_addr <<= 8; |
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index b420182eec4b..ed4bc91638d2 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c | |||
@@ -1791,6 +1791,8 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, | |||
1791 | goto out; | 1791 | goto out; |
1792 | } | 1792 | } |
1793 | 1793 | ||
1794 | pci_set_drvdata(pdev, dev); | ||
1795 | |||
1794 | tp = netdev_priv(dev); | 1796 | tp = netdev_priv(dev); |
1795 | ioaddr = tp->mmio_addr; | 1797 | ioaddr = tp->mmio_addr; |
1796 | 1798 | ||
@@ -1827,8 +1829,6 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, | |||
1827 | if (rc < 0) | 1829 | if (rc < 0) |
1828 | goto err_remove_mii; | 1830 | goto err_remove_mii; |
1829 | 1831 | ||
1830 | pci_set_drvdata(pdev, dev); | ||
1831 | |||
1832 | net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), " | 1832 | net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), " |
1833 | "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", | 1833 | "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", |
1834 | pci_name(pdev), sis_chip_info[ent->driver_data].name, | 1834 | pci_name(pdev), sis_chip_info[ent->driver_data].name, |
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 3d95fa20cd88..7a952fe60be2 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c | |||
@@ -540,7 +540,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, | |||
540 | printk("%2.2x.\n", net_dev->dev_addr[i]); | 540 | printk("%2.2x.\n", net_dev->dev_addr[i]); |
541 | 541 | ||
542 | /* Detect Wake on Lan support */ | 542 | /* Detect Wake on Lan support */ |
543 | ret = inl(CFGPMC & PMESP); | 543 | ret = (inl(net_dev->base_addr + CFGPMC) & PMESP) >> 27; |
544 | if (netif_msg_probe(sis_priv) && (ret & PME_D3C) == 0) | 544 | if (netif_msg_probe(sis_priv) && (ret & PME_D3C) == 0) |
545 | printk(KERN_INFO "%s: Wake on LAN only available from suspend to RAM.", net_dev->name); | 545 | printk(KERN_INFO "%s: Wake on LAN only available from suspend to RAM.", net_dev->name); |
546 | 546 | ||
@@ -2040,7 +2040,7 @@ static int sis900_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wo | |||
2040 | 2040 | ||
2041 | if (wol->wolopts == 0) { | 2041 | if (wol->wolopts == 0) { |
2042 | pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr); | 2042 | pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr); |
2043 | cfgpmcsr |= ~PME_EN; | 2043 | cfgpmcsr &= ~PME_EN; |
2044 | pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr); | 2044 | pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr); |
2045 | outl(pmctrl_bits, pmctrl_addr); | 2045 | outl(pmctrl_bits, pmctrl_addr); |
2046 | if (netif_msg_wol(sis_priv)) | 2046 | if (netif_msg_wol(sis_priv)) |
diff --git a/drivers/net/sis900.h b/drivers/net/sis900.h index 4233ea55670f..50323941e3c0 100644 --- a/drivers/net/sis900.h +++ b/drivers/net/sis900.h | |||
@@ -33,7 +33,6 @@ enum sis900_registers { | |||
33 | rxcfg=0x34, //Receive Configuration Register | 33 | rxcfg=0x34, //Receive Configuration Register |
34 | flctrl=0x38, //Flow Control Register | 34 | flctrl=0x38, //Flow Control Register |
35 | rxlen=0x3c, //Receive Packet Length Register | 35 | rxlen=0x3c, //Receive Packet Length Register |
36 | cfgpmcsr=0x44, //Configuration Power Management Control/Status Register | ||
37 | rfcr=0x48, //Receive Filter Control Register | 36 | rfcr=0x48, //Receive Filter Control Register |
38 | rfdr=0x4C, //Receive Filter Data Register | 37 | rfdr=0x4C, //Receive Filter Data Register |
39 | pmctrl=0xB0, //Power Management Control Register | 38 | pmctrl=0xB0, //Power Management Control Register |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index bf55a4cfb3d2..25e028b7ce48 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -879,13 +879,12 @@ static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val) | |||
879 | int i; | 879 | int i; |
880 | 880 | ||
881 | xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); | 881 | xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); |
882 | xm_read16(hw, port, XM_PHY_DATA); | 882 | *val = xm_read16(hw, port, XM_PHY_DATA); |
883 | 883 | ||
884 | /* Need to wait for external PHY */ | ||
885 | for (i = 0; i < PHY_RETRIES; i++) { | 884 | for (i = 0; i < PHY_RETRIES; i++) { |
886 | udelay(1); | ||
887 | if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY) | 885 | if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY) |
888 | goto ready; | 886 | goto ready; |
887 | udelay(1); | ||
889 | } | 888 | } |
890 | 889 | ||
891 | return -ETIMEDOUT; | 890 | return -ETIMEDOUT; |
@@ -918,7 +917,12 @@ static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) | |||
918 | 917 | ||
919 | ready: | 918 | ready: |
920 | xm_write16(hw, port, XM_PHY_DATA, val); | 919 | xm_write16(hw, port, XM_PHY_DATA, val); |
921 | return 0; | 920 | for (i = 0; i < PHY_RETRIES; i++) { |
921 | if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) | ||
922 | return 0; | ||
923 | udelay(1); | ||
924 | } | ||
925 | return -ETIMEDOUT; | ||
922 | } | 926 | } |
923 | 927 | ||
924 | static void genesis_init(struct skge_hw *hw) | 928 | static void genesis_init(struct skge_hw *hw) |
@@ -1168,13 +1172,17 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1168 | u32 r; | 1172 | u32 r; |
1169 | const u8 zero[6] = { 0 }; | 1173 | const u8 zero[6] = { 0 }; |
1170 | 1174 | ||
1171 | /* Clear MIB counters */ | 1175 | for (i = 0; i < 10; i++) { |
1172 | xm_write16(hw, port, XM_STAT_CMD, | 1176 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), |
1173 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | 1177 | MFF_SET_MAC_RST); |
1174 | /* Clear two times according to Errata #3 */ | 1178 | if (skge_read16(hw, SK_REG(port, TX_MFF_CTRL1)) & MFF_SET_MAC_RST) |
1175 | xm_write16(hw, port, XM_STAT_CMD, | 1179 | goto reset_ok; |
1176 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | 1180 | udelay(1); |
1181 | } | ||
1177 | 1182 | ||
1183 | printk(KERN_WARNING PFX "%s: genesis reset failed\n", dev->name); | ||
1184 | |||
1185 | reset_ok: | ||
1178 | /* Unreset the XMAC. */ | 1186 | /* Unreset the XMAC. */ |
1179 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); | 1187 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); |
1180 | 1188 | ||
@@ -1191,7 +1199,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1191 | r |= GP_DIR_2|GP_IO_2; | 1199 | r |= GP_DIR_2|GP_IO_2; |
1192 | 1200 | ||
1193 | skge_write32(hw, B2_GP_IO, r); | 1201 | skge_write32(hw, B2_GP_IO, r); |
1194 | skge_read32(hw, B2_GP_IO); | 1202 | |
1195 | 1203 | ||
1196 | /* Enable GMII interface */ | 1204 | /* Enable GMII interface */ |
1197 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); | 1205 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); |
@@ -1205,6 +1213,13 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1205 | for (i = 1; i < 16; i++) | 1213 | for (i = 1; i < 16; i++) |
1206 | xm_outaddr(hw, port, XM_EXM(i), zero); | 1214 | xm_outaddr(hw, port, XM_EXM(i), zero); |
1207 | 1215 | ||
1216 | /* Clear MIB counters */ | ||
1217 | xm_write16(hw, port, XM_STAT_CMD, | ||
1218 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | ||
1219 | /* Clear two times according to Errata #3 */ | ||
1220 | xm_write16(hw, port, XM_STAT_CMD, | ||
1221 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | ||
1222 | |||
1208 | /* configure Rx High Water Mark (XM_RX_HI_WM) */ | 1223 | /* configure Rx High Water Mark (XM_RX_HI_WM) */ |
1209 | xm_write16(hw, port, XM_RX_HI_WM, 1450); | 1224 | xm_write16(hw, port, XM_RX_HI_WM, 1450); |
1210 | 1225 | ||
@@ -1697,6 +1712,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1697 | skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET); | 1712 | skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET); |
1698 | skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR); | 1713 | skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR); |
1699 | skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); | 1714 | skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); |
1715 | |||
1700 | if (skge->autoneg == AUTONEG_DISABLE) { | 1716 | if (skge->autoneg == AUTONEG_DISABLE) { |
1701 | reg = GM_GPCR_AU_ALL_DIS; | 1717 | reg = GM_GPCR_AU_ALL_DIS; |
1702 | gma_write16(hw, port, GM_GP_CTRL, | 1718 | gma_write16(hw, port, GM_GP_CTRL, |
@@ -1704,16 +1720,23 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1704 | 1720 | ||
1705 | switch (skge->speed) { | 1721 | switch (skge->speed) { |
1706 | case SPEED_1000: | 1722 | case SPEED_1000: |
1723 | reg &= ~GM_GPCR_SPEED_100; | ||
1707 | reg |= GM_GPCR_SPEED_1000; | 1724 | reg |= GM_GPCR_SPEED_1000; |
1708 | /* fallthru */ | 1725 | break; |
1709 | case SPEED_100: | 1726 | case SPEED_100: |
1727 | reg &= ~GM_GPCR_SPEED_1000; | ||
1710 | reg |= GM_GPCR_SPEED_100; | 1728 | reg |= GM_GPCR_SPEED_100; |
1729 | break; | ||
1730 | case SPEED_10: | ||
1731 | reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); | ||
1732 | break; | ||
1711 | } | 1733 | } |
1712 | 1734 | ||
1713 | if (skge->duplex == DUPLEX_FULL) | 1735 | if (skge->duplex == DUPLEX_FULL) |
1714 | reg |= GM_GPCR_DUP_FULL; | 1736 | reg |= GM_GPCR_DUP_FULL; |
1715 | } else | 1737 | } else |
1716 | reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; | 1738 | reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; |
1739 | |||
1717 | switch (skge->flow_control) { | 1740 | switch (skge->flow_control) { |
1718 | case FLOW_MODE_NONE: | 1741 | case FLOW_MODE_NONE: |
1719 | skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | 1742 | skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
@@ -2162,8 +2185,10 @@ static int skge_up(struct net_device *dev) | |||
2162 | skge->tx_avail = skge->tx_ring.count - 1; | 2185 | skge->tx_avail = skge->tx_ring.count - 1; |
2163 | 2186 | ||
2164 | /* Enable IRQ from port */ | 2187 | /* Enable IRQ from port */ |
2188 | spin_lock_irq(&hw->hw_lock); | ||
2165 | hw->intr_mask |= portirqmask[port]; | 2189 | hw->intr_mask |= portirqmask[port]; |
2166 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2190 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2191 | spin_unlock_irq(&hw->hw_lock); | ||
2167 | 2192 | ||
2168 | /* Initialize MAC */ | 2193 | /* Initialize MAC */ |
2169 | spin_lock_bh(&hw->phy_lock); | 2194 | spin_lock_bh(&hw->phy_lock); |
@@ -2221,8 +2246,10 @@ static int skge_down(struct net_device *dev) | |||
2221 | else | 2246 | else |
2222 | yukon_stop(skge); | 2247 | yukon_stop(skge); |
2223 | 2248 | ||
2249 | spin_lock_irq(&hw->hw_lock); | ||
2224 | hw->intr_mask &= ~portirqmask[skge->port]; | 2250 | hw->intr_mask &= ~portirqmask[skge->port]; |
2225 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2251 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2252 | spin_unlock_irq(&hw->hw_lock); | ||
2226 | 2253 | ||
2227 | /* Stop transmitter */ | 2254 | /* Stop transmitter */ |
2228 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); | 2255 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); |
@@ -2670,8 +2697,7 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2670 | 2697 | ||
2671 | /* restart receiver */ | 2698 | /* restart receiver */ |
2672 | wmb(); | 2699 | wmb(); |
2673 | skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), | 2700 | skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START); |
2674 | CSR_START | CSR_IRQ_CL_F); | ||
2675 | 2701 | ||
2676 | *budget -= work_done; | 2702 | *budget -= work_done; |
2677 | dev->quota -= work_done; | 2703 | dev->quota -= work_done; |
@@ -2679,10 +2705,11 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2679 | if (work_done >= to_do) | 2705 | if (work_done >= to_do) |
2680 | return 1; /* not done */ | 2706 | return 1; /* not done */ |
2681 | 2707 | ||
2682 | netif_rx_complete(dev); | 2708 | spin_lock_irq(&hw->hw_lock); |
2683 | hw->intr_mask |= portirqmask[skge->port]; | 2709 | __netif_rx_complete(dev); |
2684 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2710 | hw->intr_mask |= portirqmask[skge->port]; |
2685 | skge_read32(hw, B0_IMSK); | 2711 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2712 | spin_unlock_irq(&hw->hw_lock); | ||
2686 | 2713 | ||
2687 | return 0; | 2714 | return 0; |
2688 | } | 2715 | } |
@@ -2842,18 +2869,10 @@ static void skge_extirq(unsigned long data) | |||
2842 | } | 2869 | } |
2843 | spin_unlock(&hw->phy_lock); | 2870 | spin_unlock(&hw->phy_lock); |
2844 | 2871 | ||
2845 | local_irq_disable(); | 2872 | spin_lock_irq(&hw->hw_lock); |
2846 | hw->intr_mask |= IS_EXT_REG; | 2873 | hw->intr_mask |= IS_EXT_REG; |
2847 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2874 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2848 | local_irq_enable(); | 2875 | spin_unlock_irq(&hw->hw_lock); |
2849 | } | ||
2850 | |||
2851 | static inline void skge_wakeup(struct net_device *dev) | ||
2852 | { | ||
2853 | struct skge_port *skge = netdev_priv(dev); | ||
2854 | |||
2855 | prefetch(skge->rx_ring.to_clean); | ||
2856 | netif_rx_schedule(dev); | ||
2857 | } | 2876 | } |
2858 | 2877 | ||
2859 | static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | 2878 | static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) |
@@ -2864,15 +2883,17 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2864 | if (status == 0 || status == ~0) /* hotplug or shared irq */ | 2883 | if (status == 0 || status == ~0) /* hotplug or shared irq */ |
2865 | return IRQ_NONE; | 2884 | return IRQ_NONE; |
2866 | 2885 | ||
2867 | status &= hw->intr_mask; | 2886 | spin_lock(&hw->hw_lock); |
2868 | if (status & IS_R1_F) { | 2887 | if (status & IS_R1_F) { |
2888 | skge_write8(hw, Q_ADDR(Q_R1, Q_CSR), CSR_IRQ_CL_F); | ||
2869 | hw->intr_mask &= ~IS_R1_F; | 2889 | hw->intr_mask &= ~IS_R1_F; |
2870 | skge_wakeup(hw->dev[0]); | 2890 | netif_rx_schedule(hw->dev[0]); |
2871 | } | 2891 | } |
2872 | 2892 | ||
2873 | if (status & IS_R2_F) { | 2893 | if (status & IS_R2_F) { |
2894 | skge_write8(hw, Q_ADDR(Q_R2, Q_CSR), CSR_IRQ_CL_F); | ||
2874 | hw->intr_mask &= ~IS_R2_F; | 2895 | hw->intr_mask &= ~IS_R2_F; |
2875 | skge_wakeup(hw->dev[1]); | 2896 | netif_rx_schedule(hw->dev[1]); |
2876 | } | 2897 | } |
2877 | 2898 | ||
2878 | if (status & IS_XA1_F) | 2899 | if (status & IS_XA1_F) |
@@ -2914,6 +2935,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2914 | } | 2935 | } |
2915 | 2936 | ||
2916 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2937 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2938 | spin_unlock(&hw->hw_lock); | ||
2917 | 2939 | ||
2918 | return IRQ_HANDLED; | 2940 | return IRQ_HANDLED; |
2919 | } | 2941 | } |
@@ -3282,6 +3304,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3282 | 3304 | ||
3283 | hw->pdev = pdev; | 3305 | hw->pdev = pdev; |
3284 | spin_lock_init(&hw->phy_lock); | 3306 | spin_lock_init(&hw->phy_lock); |
3307 | spin_lock_init(&hw->hw_lock); | ||
3285 | tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); | 3308 | tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); |
3286 | 3309 | ||
3287 | hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); | 3310 | hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 2efdacc290e5..941f12a333b6 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
@@ -2402,6 +2402,7 @@ struct skge_hw { | |||
2402 | 2402 | ||
2403 | struct tasklet_struct ext_tasklet; | 2403 | struct tasklet_struct ext_tasklet; |
2404 | spinlock_t phy_lock; | 2404 | spinlock_t phy_lock; |
2405 | spinlock_t hw_lock; | ||
2405 | }; | 2406 | }; |
2406 | 2407 | ||
2407 | enum { | 2408 | enum { |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index f8b973a04b65..73260364cba3 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -23,12 +23,6 @@ | |||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | /* | ||
27 | * TOTEST | ||
28 | * - speed setting | ||
29 | * - suspend/resume | ||
30 | */ | ||
31 | |||
32 | #include <linux/config.h> | 26 | #include <linux/config.h> |
33 | #include <linux/crc32.h> | 27 | #include <linux/crc32.h> |
34 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
@@ -57,7 +51,7 @@ | |||
57 | #include "sky2.h" | 51 | #include "sky2.h" |
58 | 52 | ||
59 | #define DRV_NAME "sky2" | 53 | #define DRV_NAME "sky2" |
60 | #define DRV_VERSION "0.13" | 54 | #define DRV_VERSION "0.15" |
61 | #define PFX DRV_NAME " " | 55 | #define PFX DRV_NAME " " |
62 | 56 | ||
63 | /* | 57 | /* |
@@ -80,7 +74,7 @@ | |||
80 | #define TX_RING_SIZE 512 | 74 | #define TX_RING_SIZE 512 |
81 | #define TX_DEF_PENDING (TX_RING_SIZE - 1) | 75 | #define TX_DEF_PENDING (TX_RING_SIZE - 1) |
82 | #define TX_MIN_PENDING 64 | 76 | #define TX_MIN_PENDING 64 |
83 | #define MAX_SKB_TX_LE (4 + 2*MAX_SKB_FRAGS) | 77 | #define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) |
84 | 78 | ||
85 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ | 79 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ |
86 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) | 80 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) |
@@ -197,11 +191,11 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
197 | pr_debug("sky2_set_power_state %d\n", state); | 191 | pr_debug("sky2_set_power_state %d\n", state); |
198 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 192 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
199 | 193 | ||
200 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control); | 194 | power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_PMC); |
201 | vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) && | 195 | vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) && |
202 | (power_control & PCI_PM_CAP_PME_D3cold); | 196 | (power_control & PCI_PM_CAP_PME_D3cold); |
203 | 197 | ||
204 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control); | 198 | power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL); |
205 | 199 | ||
206 | power_control |= PCI_PM_CTRL_PME_STATUS; | 200 | power_control |= PCI_PM_CTRL_PME_STATUS; |
207 | power_control &= ~(PCI_PM_CTRL_STATE_MASK); | 201 | power_control &= ~(PCI_PM_CTRL_STATE_MASK); |
@@ -225,7 +219,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
225 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 219 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
226 | 220 | ||
227 | /* Turn off phy power saving */ | 221 | /* Turn off phy power saving */ |
228 | pci_read_config_dword(hw->pdev, PCI_DEV_REG1, ®1); | 222 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); |
229 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | 223 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
230 | 224 | ||
231 | /* looks like this XL is back asswards .. */ | 225 | /* looks like this XL is back asswards .. */ |
@@ -234,18 +228,28 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
234 | if (hw->ports > 1) | 228 | if (hw->ports > 1) |
235 | reg1 |= PCI_Y2_PHY2_COMA; | 229 | reg1 |= PCI_Y2_PHY2_COMA; |
236 | } | 230 | } |
237 | pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1); | 231 | |
232 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | ||
233 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | ||
234 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); | ||
235 | reg1 &= P_ASPM_CONTROL_MSK; | ||
236 | sky2_pci_write32(hw, PCI_DEV_REG4, reg1); | ||
237 | sky2_pci_write32(hw, PCI_DEV_REG5, 0); | ||
238 | } | ||
239 | |||
240 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
241 | |||
238 | break; | 242 | break; |
239 | 243 | ||
240 | case PCI_D3hot: | 244 | case PCI_D3hot: |
241 | case PCI_D3cold: | 245 | case PCI_D3cold: |
242 | /* Turn on phy power saving */ | 246 | /* Turn on phy power saving */ |
243 | pci_read_config_dword(hw->pdev, PCI_DEV_REG1, ®1); | 247 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); |
244 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 248 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
245 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | 249 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
246 | else | 250 | else |
247 | reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | 251 | reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
248 | pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1); | 252 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); |
249 | 253 | ||
250 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 254 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
251 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 255 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
@@ -267,7 +271,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
267 | ret = -1; | 271 | ret = -1; |
268 | } | 272 | } |
269 | 273 | ||
270 | pci_write_config_byte(hw->pdev, hw->pm_cap + PCI_PM_CTRL, power_control); | 274 | sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control); |
271 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 275 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
272 | return ret; | 276 | return ret; |
273 | } | 277 | } |
@@ -465,16 +469,31 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
465 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); | 469 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); |
466 | } | 470 | } |
467 | 471 | ||
468 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | 472 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) { |
473 | /* apply fixes in PHY AFE */ | ||
474 | gm_phy_write(hw, port, 22, 255); | ||
475 | /* increase differential signal amplitude in 10BASE-T */ | ||
476 | gm_phy_write(hw, port, 24, 0xaa99); | ||
477 | gm_phy_write(hw, port, 23, 0x2011); | ||
469 | 478 | ||
470 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { | 479 | /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ |
471 | /* turn on 100 Mbps LED (LED_LINK100) */ | 480 | gm_phy_write(hw, port, 24, 0xa204); |
472 | ledover |= PHY_M_LED_MO_100(MO_LED_ON); | 481 | gm_phy_write(hw, port, 23, 0x2002); |
473 | } | ||
474 | 482 | ||
475 | if (ledover) | 483 | /* set page register to 0 */ |
476 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); | 484 | gm_phy_write(hw, port, 22, 0); |
485 | } else { | ||
486 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | ||
487 | |||
488 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { | ||
489 | /* turn on 100 Mbps LED (LED_LINK100) */ | ||
490 | ledover |= PHY_M_LED_MO_100(MO_LED_ON); | ||
491 | } | ||
492 | |||
493 | if (ledover) | ||
494 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); | ||
477 | 495 | ||
496 | } | ||
478 | /* Enable phy interrupt on auto-negotiation complete (or link up) */ | 497 | /* Enable phy interrupt on auto-negotiation complete (or link up) */ |
479 | if (sky2->autoneg == AUTONEG_ENABLE) | 498 | if (sky2->autoneg == AUTONEG_ENABLE) |
480 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); | 499 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); |
@@ -522,10 +541,16 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
522 | 541 | ||
523 | switch (sky2->speed) { | 542 | switch (sky2->speed) { |
524 | case SPEED_1000: | 543 | case SPEED_1000: |
544 | reg &= ~GM_GPCR_SPEED_100; | ||
525 | reg |= GM_GPCR_SPEED_1000; | 545 | reg |= GM_GPCR_SPEED_1000; |
526 | /* fallthru */ | 546 | break; |
527 | case SPEED_100: | 547 | case SPEED_100: |
548 | reg &= ~GM_GPCR_SPEED_1000; | ||
528 | reg |= GM_GPCR_SPEED_100; | 549 | reg |= GM_GPCR_SPEED_100; |
550 | break; | ||
551 | case SPEED_10: | ||
552 | reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); | ||
553 | break; | ||
529 | } | 554 | } |
530 | 555 | ||
531 | if (sky2->duplex == DUPLEX_FULL) | 556 | if (sky2->duplex == DUPLEX_FULL) |
@@ -597,8 +622,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
597 | 622 | ||
598 | /* Configure Rx MAC FIFO */ | 623 | /* Configure Rx MAC FIFO */ |
599 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 624 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
600 | sky2_write16(hw, SK_REG(port, RX_GMF_CTRL_T), | 625 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), |
601 | GMF_RX_CTRL_DEF); | 626 | GMF_OPER_ON | GMF_RX_F_FL_ON); |
602 | 627 | ||
603 | /* Flush Rx MAC FIFO on any flow control or error */ | 628 | /* Flush Rx MAC FIFO on any flow control or error */ |
604 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); | 629 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); |
@@ -949,6 +974,12 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
949 | 974 | ||
950 | sky2->rx_put = sky2->rx_next = 0; | 975 | sky2->rx_put = sky2->rx_next = 0; |
951 | sky2_qset(hw, rxq); | 976 | sky2_qset(hw, rxq); |
977 | |||
978 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) { | ||
979 | /* MAC Rx RAM Read is controlled by hardware */ | ||
980 | sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS); | ||
981 | } | ||
982 | |||
952 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); | 983 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); |
953 | 984 | ||
954 | rx_set_checksum(sky2); | 985 | rx_set_checksum(sky2); |
@@ -964,6 +995,10 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
964 | sky2_rx_add(sky2, re->mapaddr); | 995 | sky2_rx_add(sky2, re->mapaddr); |
965 | } | 996 | } |
966 | 997 | ||
998 | /* Truncate oversize frames */ | ||
999 | sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 8); | ||
1000 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON); | ||
1001 | |||
967 | /* Tell chip about available buffers */ | 1002 | /* Tell chip about available buffers */ |
968 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); | 1003 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); |
969 | sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX)); | 1004 | sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX)); |
@@ -1031,9 +1066,10 @@ static int sky2_up(struct net_device *dev) | |||
1031 | RB_RST_SET); | 1066 | RB_RST_SET); |
1032 | 1067 | ||
1033 | sky2_qset(hw, txqaddr[port]); | 1068 | sky2_qset(hw, txqaddr[port]); |
1034 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) | ||
1035 | sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0); | ||
1036 | 1069 | ||
1070 | /* Set almost empty threshold */ | ||
1071 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == 1) | ||
1072 | sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0); | ||
1037 | 1073 | ||
1038 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | 1074 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
1039 | TX_RING_SIZE - 1); | 1075 | TX_RING_SIZE - 1); |
@@ -1043,8 +1079,10 @@ static int sky2_up(struct net_device *dev) | |||
1043 | goto err_out; | 1079 | goto err_out; |
1044 | 1080 | ||
1045 | /* Enable interrupts from phy/mac for port */ | 1081 | /* Enable interrupts from phy/mac for port */ |
1082 | spin_lock_irq(&hw->hw_lock); | ||
1046 | hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; | 1083 | hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; |
1047 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 1084 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1085 | spin_unlock_irq(&hw->hw_lock); | ||
1048 | return 0; | 1086 | return 0; |
1049 | 1087 | ||
1050 | err_out: | 1088 | err_out: |
@@ -1111,6 +1149,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1111 | struct sky2_tx_le *le = NULL; | 1149 | struct sky2_tx_le *le = NULL; |
1112 | struct tx_ring_info *re; | 1150 | struct tx_ring_info *re; |
1113 | unsigned i, len; | 1151 | unsigned i, len; |
1152 | int avail; | ||
1114 | dma_addr_t mapping; | 1153 | dma_addr_t mapping; |
1115 | u32 addr64; | 1154 | u32 addr64; |
1116 | u16 mss; | 1155 | u16 mss; |
@@ -1253,12 +1292,16 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1253 | re->idx = sky2->tx_prod; | 1292 | re->idx = sky2->tx_prod; |
1254 | le->ctrl |= EOP; | 1293 | le->ctrl |= EOP; |
1255 | 1294 | ||
1295 | avail = tx_avail(sky2); | ||
1296 | if (mss != 0 || avail < TX_MIN_PENDING) { | ||
1297 | le->ctrl |= FRC_STAT; | ||
1298 | if (avail <= MAX_SKB_TX_LE) | ||
1299 | netif_stop_queue(dev); | ||
1300 | } | ||
1301 | |||
1256 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod, | 1302 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod, |
1257 | &sky2->tx_last_put, TX_RING_SIZE); | 1303 | &sky2->tx_last_put, TX_RING_SIZE); |
1258 | 1304 | ||
1259 | if (tx_avail(sky2) <= MAX_SKB_TX_LE) | ||
1260 | netif_stop_queue(dev); | ||
1261 | |||
1262 | out_unlock: | 1305 | out_unlock: |
1263 | spin_unlock(&sky2->tx_lock); | 1306 | spin_unlock(&sky2->tx_lock); |
1264 | 1307 | ||
@@ -1344,10 +1387,10 @@ static int sky2_down(struct net_device *dev) | |||
1344 | netif_stop_queue(dev); | 1387 | netif_stop_queue(dev); |
1345 | 1388 | ||
1346 | /* Disable port IRQ */ | 1389 | /* Disable port IRQ */ |
1347 | local_irq_disable(); | 1390 | spin_lock_irq(&hw->hw_lock); |
1348 | hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); | 1391 | hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); |
1349 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 1392 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1350 | local_irq_enable(); | 1393 | spin_unlock_irq(&hw->hw_lock); |
1351 | 1394 | ||
1352 | flush_scheduled_work(); | 1395 | flush_scheduled_work(); |
1353 | 1396 | ||
@@ -1448,6 +1491,29 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
1448 | sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); | 1491 | sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); |
1449 | 1492 | ||
1450 | reg = gma_read16(hw, port, GM_GP_CTRL); | 1493 | reg = gma_read16(hw, port, GM_GP_CTRL); |
1494 | if (sky2->autoneg == AUTONEG_DISABLE) { | ||
1495 | reg |= GM_GPCR_AU_ALL_DIS; | ||
1496 | |||
1497 | /* Is write/read necessary? Copied from sky2_mac_init */ | ||
1498 | gma_write16(hw, port, GM_GP_CTRL, reg); | ||
1499 | gma_read16(hw, port, GM_GP_CTRL); | ||
1500 | |||
1501 | switch (sky2->speed) { | ||
1502 | case SPEED_1000: | ||
1503 | reg &= ~GM_GPCR_SPEED_100; | ||
1504 | reg |= GM_GPCR_SPEED_1000; | ||
1505 | break; | ||
1506 | case SPEED_100: | ||
1507 | reg &= ~GM_GPCR_SPEED_1000; | ||
1508 | reg |= GM_GPCR_SPEED_100; | ||
1509 | break; | ||
1510 | case SPEED_10: | ||
1511 | reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); | ||
1512 | break; | ||
1513 | } | ||
1514 | } else | ||
1515 | reg &= ~GM_GPCR_AU_ALL_DIS; | ||
1516 | |||
1451 | if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE) | 1517 | if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE) |
1452 | reg |= GM_GPCR_DUP_FULL; | 1518 | reg |= GM_GPCR_DUP_FULL; |
1453 | 1519 | ||
@@ -1606,10 +1672,10 @@ static void sky2_phy_task(void *arg) | |||
1606 | out: | 1672 | out: |
1607 | up(&sky2->phy_sema); | 1673 | up(&sky2->phy_sema); |
1608 | 1674 | ||
1609 | local_irq_disable(); | 1675 | spin_lock_irq(&hw->hw_lock); |
1610 | hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2; | 1676 | hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2; |
1611 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 1677 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1612 | local_irq_enable(); | 1678 | spin_unlock_irq(&hw->hw_lock); |
1613 | } | 1679 | } |
1614 | 1680 | ||
1615 | 1681 | ||
@@ -1650,10 +1716,12 @@ static void sky2_tx_timeout(struct net_device *dev) | |||
1650 | 1716 | ||
1651 | 1717 | ||
1652 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) | 1718 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) |
1653 | /* Want receive buffer size to be multiple of 64 bits, and incl room for vlan */ | 1719 | /* Want receive buffer size to be multiple of 64 bits |
1720 | * and incl room for vlan and truncation | ||
1721 | */ | ||
1654 | static inline unsigned sky2_buf_size(int mtu) | 1722 | static inline unsigned sky2_buf_size(int mtu) |
1655 | { | 1723 | { |
1656 | return roundup(mtu + ETH_HLEN + 4, 8); | 1724 | return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; |
1657 | } | 1725 | } |
1658 | 1726 | ||
1659 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) | 1727 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) |
@@ -1736,7 +1804,7 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2, | |||
1736 | if (!(status & GMR_FS_RX_OK)) | 1804 | if (!(status & GMR_FS_RX_OK)) |
1737 | goto resubmit; | 1805 | goto resubmit; |
1738 | 1806 | ||
1739 | if ((status >> 16) != length || length > sky2->rx_bufsize) | 1807 | if (length > sky2->netdev->mtu + ETH_HLEN) |
1740 | goto oversize; | 1808 | goto oversize; |
1741 | 1809 | ||
1742 | if (length < copybreak) { | 1810 | if (length < copybreak) { |
@@ -1834,6 +1902,19 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
1834 | u16 hwidx; | 1902 | u16 hwidx; |
1835 | u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS }; | 1903 | u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS }; |
1836 | 1904 | ||
1905 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | ||
1906 | |||
1907 | /* | ||
1908 | * Kick the STAT_LEV_TIMER_CTRL timer. | ||
1909 | * This fixes my hangs on Yukon-EC (0xb6) rev 1. | ||
1910 | * The if clause is there to start the timer only if it has been | ||
1911 | * configured correctly and not been disabled via ethtool. | ||
1912 | */ | ||
1913 | if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) { | ||
1914 | sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP); | ||
1915 | sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START); | ||
1916 | } | ||
1917 | |||
1837 | hwidx = sky2_read16(hw, STAT_PUT_IDX); | 1918 | hwidx = sky2_read16(hw, STAT_PUT_IDX); |
1838 | BUG_ON(hwidx >= STATUS_RING_SIZE); | 1919 | BUG_ON(hwidx >= STATUS_RING_SIZE); |
1839 | rmb(); | 1920 | rmb(); |
@@ -1913,21 +1994,22 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
1913 | } | 1994 | } |
1914 | 1995 | ||
1915 | exit_loop: | 1996 | exit_loop: |
1916 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | ||
1917 | |||
1918 | sky2_tx_check(hw, 0, tx_done[0]); | 1997 | sky2_tx_check(hw, 0, tx_done[0]); |
1919 | sky2_tx_check(hw, 1, tx_done[1]); | 1998 | sky2_tx_check(hw, 1, tx_done[1]); |
1920 | 1999 | ||
1921 | if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) { | 2000 | if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { |
1922 | /* need to restart TX timer */ | 2001 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); |
1923 | if (is_ec_a1(hw)) { | 2002 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); |
1924 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); | 2003 | } |
1925 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); | 2004 | |
1926 | } | 2005 | if (likely(work_done < to_do)) { |
2006 | spin_lock_irq(&hw->hw_lock); | ||
2007 | __netif_rx_complete(dev0); | ||
1927 | 2008 | ||
1928 | netif_rx_complete(dev0); | ||
1929 | hw->intr_mask |= Y2_IS_STAT_BMU; | 2009 | hw->intr_mask |= Y2_IS_STAT_BMU; |
1930 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 2010 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
2011 | spin_unlock_irq(&hw->hw_lock); | ||
2012 | |||
1931 | return 0; | 2013 | return 0; |
1932 | } else { | 2014 | } else { |
1933 | *budget -= work_done; | 2015 | *budget -= work_done; |
@@ -1990,13 +2072,13 @@ static void sky2_hw_intr(struct sky2_hw *hw) | |||
1990 | if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { | 2072 | if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { |
1991 | u16 pci_err; | 2073 | u16 pci_err; |
1992 | 2074 | ||
1993 | pci_read_config_word(hw->pdev, PCI_STATUS, &pci_err); | 2075 | pci_err = sky2_pci_read16(hw, PCI_STATUS); |
1994 | if (net_ratelimit()) | 2076 | if (net_ratelimit()) |
1995 | printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n", | 2077 | printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n", |
1996 | pci_name(hw->pdev), pci_err); | 2078 | pci_name(hw->pdev), pci_err); |
1997 | 2079 | ||
1998 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 2080 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
1999 | pci_write_config_word(hw->pdev, PCI_STATUS, | 2081 | sky2_pci_write16(hw, PCI_STATUS, |
2000 | pci_err | PCI_STATUS_ERROR_BITS); | 2082 | pci_err | PCI_STATUS_ERROR_BITS); |
2001 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 2083 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
2002 | } | 2084 | } |
@@ -2005,7 +2087,7 @@ static void sky2_hw_intr(struct sky2_hw *hw) | |||
2005 | /* PCI-Express uncorrectable Error occurred */ | 2087 | /* PCI-Express uncorrectable Error occurred */ |
2006 | u32 pex_err; | 2088 | u32 pex_err; |
2007 | 2089 | ||
2008 | pci_read_config_dword(hw->pdev, PEX_UNC_ERR_STAT, &pex_err); | 2090 | pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT); |
2009 | 2091 | ||
2010 | if (net_ratelimit()) | 2092 | if (net_ratelimit()) |
2011 | printk(KERN_ERR PFX "%s: pci express error (0x%x)\n", | 2093 | printk(KERN_ERR PFX "%s: pci express error (0x%x)\n", |
@@ -2013,7 +2095,7 @@ static void sky2_hw_intr(struct sky2_hw *hw) | |||
2013 | 2095 | ||
2014 | /* clear the interrupt */ | 2096 | /* clear the interrupt */ |
2015 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 2097 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2016 | pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT, | 2098 | sky2_pci_write32(hw, PEX_UNC_ERR_STAT, |
2017 | 0xffffffffUL); | 2099 | 0xffffffffUL); |
2018 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 2100 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
2019 | 2101 | ||
@@ -2059,6 +2141,7 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) | |||
2059 | 2141 | ||
2060 | hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); | 2142 | hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); |
2061 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 2143 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
2144 | |||
2062 | schedule_work(&sky2->phy_task); | 2145 | schedule_work(&sky2->phy_task); |
2063 | } | 2146 | } |
2064 | 2147 | ||
@@ -2072,6 +2155,7 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2072 | if (status == 0 || status == ~0) | 2155 | if (status == 0 || status == ~0) |
2073 | return IRQ_NONE; | 2156 | return IRQ_NONE; |
2074 | 2157 | ||
2158 | spin_lock(&hw->hw_lock); | ||
2075 | if (status & Y2_IS_HW_ERR) | 2159 | if (status & Y2_IS_HW_ERR) |
2076 | sky2_hw_intr(hw); | 2160 | sky2_hw_intr(hw); |
2077 | 2161 | ||
@@ -2100,7 +2184,7 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2100 | 2184 | ||
2101 | sky2_write32(hw, B0_Y2_SP_ICR, 2); | 2185 | sky2_write32(hw, B0_Y2_SP_ICR, 2); |
2102 | 2186 | ||
2103 | sky2_read32(hw, B0_IMSK); | 2187 | spin_unlock(&hw->hw_lock); |
2104 | 2188 | ||
2105 | return IRQ_HANDLED; | 2189 | return IRQ_HANDLED; |
2106 | } | 2190 | } |
@@ -2141,14 +2225,12 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) | |||
2141 | 2225 | ||
2142 | static int sky2_reset(struct sky2_hw *hw) | 2226 | static int sky2_reset(struct sky2_hw *hw) |
2143 | { | 2227 | { |
2144 | u32 ctst; | ||
2145 | u16 status; | 2228 | u16 status; |
2146 | u8 t8, pmd_type; | 2229 | u8 t8, pmd_type; |
2147 | int i; | 2230 | int i; |
2148 | 2231 | ||
2149 | ctst = sky2_read32(hw, B0_CTST); | ||
2150 | |||
2151 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2232 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2233 | |||
2152 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); | 2234 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); |
2153 | if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { | 2235 | if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { |
2154 | printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", | 2236 | printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", |
@@ -2156,12 +2238,6 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2156 | return -EOPNOTSUPP; | 2238 | return -EOPNOTSUPP; |
2157 | } | 2239 | } |
2158 | 2240 | ||
2159 | /* ring for status responses */ | ||
2160 | hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, | ||
2161 | &hw->st_dma); | ||
2162 | if (!hw->st_le) | ||
2163 | return -ENOMEM; | ||
2164 | |||
2165 | /* disable ASF */ | 2241 | /* disable ASF */ |
2166 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { | 2242 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { |
2167 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); | 2243 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); |
@@ -2173,20 +2249,18 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2173 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2249 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2174 | 2250 | ||
2175 | /* clear PCI errors, if any */ | 2251 | /* clear PCI errors, if any */ |
2176 | pci_read_config_word(hw->pdev, PCI_STATUS, &status); | 2252 | status = sky2_pci_read16(hw, PCI_STATUS); |
2253 | |||
2177 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 2254 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2178 | pci_write_config_word(hw->pdev, PCI_STATUS, | 2255 | sky2_pci_write16(hw, PCI_STATUS, status | PCI_STATUS_ERROR_BITS); |
2179 | status | PCI_STATUS_ERROR_BITS); | 2256 | |
2180 | 2257 | ||
2181 | sky2_write8(hw, B0_CTST, CS_MRST_CLR); | 2258 | sky2_write8(hw, B0_CTST, CS_MRST_CLR); |
2182 | 2259 | ||
2183 | /* clear any PEX errors */ | 2260 | /* clear any PEX errors */ |
2184 | if (is_pciex(hw)) { | 2261 | if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) |
2185 | u16 lstat; | 2262 | sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL); |
2186 | pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT, | 2263 | |
2187 | 0xffffffffUL); | ||
2188 | pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat); | ||
2189 | } | ||
2190 | 2264 | ||
2191 | pmd_type = sky2_read8(hw, B2_PMD_TYP); | 2265 | pmd_type = sky2_read8(hw, B2_PMD_TYP); |
2192 | hw->copper = !(pmd_type == 'L' || pmd_type == 'S'); | 2266 | hw->copper = !(pmd_type == 'L' || pmd_type == 'S'); |
@@ -2285,8 +2359,7 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2285 | sky2_write8(hw, STAT_FIFO_ISR_WM, 16); | 2359 | sky2_write8(hw, STAT_FIFO_ISR_WM, 16); |
2286 | 2360 | ||
2287 | sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000)); | 2361 | sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000)); |
2288 | sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100)); | 2362 | sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 7)); |
2289 | sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20)); | ||
2290 | } | 2363 | } |
2291 | 2364 | ||
2292 | /* enable status unit */ | 2365 | /* enable status unit */ |
@@ -2551,19 +2624,24 @@ static struct net_device_stats *sky2_get_stats(struct net_device *dev) | |||
2551 | static int sky2_set_mac_address(struct net_device *dev, void *p) | 2624 | static int sky2_set_mac_address(struct net_device *dev, void *p) |
2552 | { | 2625 | { |
2553 | struct sky2_port *sky2 = netdev_priv(dev); | 2626 | struct sky2_port *sky2 = netdev_priv(dev); |
2554 | struct sockaddr *addr = p; | 2627 | struct sky2_hw *hw = sky2->hw; |
2628 | unsigned port = sky2->port; | ||
2629 | const struct sockaddr *addr = p; | ||
2555 | 2630 | ||
2556 | if (!is_valid_ether_addr(addr->sa_data)) | 2631 | if (!is_valid_ether_addr(addr->sa_data)) |
2557 | return -EADDRNOTAVAIL; | 2632 | return -EADDRNOTAVAIL; |
2558 | 2633 | ||
2559 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | 2634 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
2560 | memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8, | 2635 | memcpy_toio(hw->regs + B2_MAC_1 + port * 8, |
2561 | dev->dev_addr, ETH_ALEN); | 2636 | dev->dev_addr, ETH_ALEN); |
2562 | memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8, | 2637 | memcpy_toio(hw->regs + B2_MAC_2 + port * 8, |
2563 | dev->dev_addr, ETH_ALEN); | 2638 | dev->dev_addr, ETH_ALEN); |
2564 | 2639 | ||
2565 | if (netif_running(dev)) | 2640 | /* virtual address for data */ |
2566 | sky2_phy_reinit(sky2); | 2641 | gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr); |
2642 | |||
2643 | /* physical address: used for pause frames */ | ||
2644 | gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr); | ||
2567 | 2645 | ||
2568 | return 0; | 2646 | return 0; |
2569 | } | 2647 | } |
@@ -2815,11 +2893,11 @@ static int sky2_set_coalesce(struct net_device *dev, | |||
2815 | (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax)) | 2893 | (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax)) |
2816 | return -EINVAL; | 2894 | return -EINVAL; |
2817 | 2895 | ||
2818 | if (ecmd->tx_max_coalesced_frames > 0xffff) | 2896 | if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE-1) |
2819 | return -EINVAL; | 2897 | return -EINVAL; |
2820 | if (ecmd->rx_max_coalesced_frames > 0xff) | 2898 | if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING) |
2821 | return -EINVAL; | 2899 | return -EINVAL; |
2822 | if (ecmd->rx_max_coalesced_frames_irq > 0xff) | 2900 | if (ecmd->rx_max_coalesced_frames_irq >RX_MAX_PENDING) |
2823 | return -EINVAL; | 2901 | return -EINVAL; |
2824 | 2902 | ||
2825 | if (ecmd->tx_coalesce_usecs == 0) | 2903 | if (ecmd->tx_coalesce_usecs == 0) |
@@ -2843,7 +2921,7 @@ static int sky2_set_coalesce(struct net_device *dev, | |||
2843 | if (ecmd->rx_coalesce_usecs_irq == 0) | 2921 | if (ecmd->rx_coalesce_usecs_irq == 0) |
2844 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP); | 2922 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP); |
2845 | else { | 2923 | else { |
2846 | sky2_write32(hw, STAT_TX_TIMER_INI, | 2924 | sky2_write32(hw, STAT_ISR_TIMER_INI, |
2847 | sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq)); | 2925 | sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq)); |
2848 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); | 2926 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); |
2849 | } | 2927 | } |
@@ -3106,17 +3184,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3106 | } | 3184 | } |
3107 | } | 3185 | } |
3108 | 3186 | ||
3109 | #ifdef __BIG_ENDIAN | ||
3110 | /* byte swap descriptors in hardware */ | ||
3111 | { | ||
3112 | u32 reg; | ||
3113 | |||
3114 | pci_read_config_dword(pdev, PCI_DEV_REG2, ®); | ||
3115 | reg |= PCI_REV_DESC; | ||
3116 | pci_write_config_dword(pdev, PCI_DEV_REG2, reg); | ||
3117 | } | ||
3118 | #endif | ||
3119 | |||
3120 | err = -ENOMEM; | 3187 | err = -ENOMEM; |
3121 | hw = kzalloc(sizeof(*hw), GFP_KERNEL); | 3188 | hw = kzalloc(sizeof(*hw), GFP_KERNEL); |
3122 | if (!hw) { | 3189 | if (!hw) { |
@@ -3134,6 +3201,24 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3134 | goto err_out_free_hw; | 3201 | goto err_out_free_hw; |
3135 | } | 3202 | } |
3136 | hw->pm_cap = pm_cap; | 3203 | hw->pm_cap = pm_cap; |
3204 | spin_lock_init(&hw->hw_lock); | ||
3205 | |||
3206 | #ifdef __BIG_ENDIAN | ||
3207 | /* byte swap descriptors in hardware */ | ||
3208 | { | ||
3209 | u32 reg; | ||
3210 | |||
3211 | reg = sky2_pci_read32(hw, PCI_DEV_REG2); | ||
3212 | reg |= PCI_REV_DESC; | ||
3213 | sky2_pci_write32(hw, PCI_DEV_REG2, reg); | ||
3214 | } | ||
3215 | #endif | ||
3216 | |||
3217 | /* ring for status responses */ | ||
3218 | hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, | ||
3219 | &hw->st_dma); | ||
3220 | if (!hw->st_le) | ||
3221 | goto err_out_iounmap; | ||
3137 | 3222 | ||
3138 | err = sky2_reset(hw); | 3223 | err = sky2_reset(hw); |
3139 | if (err) | 3224 | if (err) |
@@ -3263,25 +3348,33 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3263 | static int sky2_resume(struct pci_dev *pdev) | 3348 | static int sky2_resume(struct pci_dev *pdev) |
3264 | { | 3349 | { |
3265 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 3350 | struct sky2_hw *hw = pci_get_drvdata(pdev); |
3266 | int i; | 3351 | int i, err; |
3267 | 3352 | ||
3268 | pci_restore_state(pdev); | 3353 | pci_restore_state(pdev); |
3269 | pci_enable_wake(pdev, PCI_D0, 0); | 3354 | pci_enable_wake(pdev, PCI_D0, 0); |
3270 | sky2_set_power_state(hw, PCI_D0); | 3355 | err = sky2_set_power_state(hw, PCI_D0); |
3356 | if (err) | ||
3357 | goto out; | ||
3271 | 3358 | ||
3272 | sky2_reset(hw); | 3359 | err = sky2_reset(hw); |
3360 | if (err) | ||
3361 | goto out; | ||
3273 | 3362 | ||
3274 | for (i = 0; i < 2; i++) { | 3363 | for (i = 0; i < 2; i++) { |
3275 | struct net_device *dev = hw->dev[i]; | 3364 | struct net_device *dev = hw->dev[i]; |
3276 | if (dev) { | 3365 | if (dev && netif_running(dev)) { |
3277 | if (netif_running(dev)) { | 3366 | netif_device_attach(dev); |
3278 | netif_device_attach(dev); | 3367 | err = sky2_up(dev); |
3279 | if (sky2_up(dev)) | 3368 | if (err) { |
3280 | dev_close(dev); | 3369 | printk(KERN_ERR PFX "%s: could not up: %d\n", |
3370 | dev->name, err); | ||
3371 | dev_close(dev); | ||
3372 | break; | ||
3281 | } | 3373 | } |
3282 | } | 3374 | } |
3283 | } | 3375 | } |
3284 | return 0; | 3376 | out: |
3377 | return err; | ||
3285 | } | 3378 | } |
3286 | #endif | 3379 | #endif |
3287 | 3380 | ||
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 95518921001c..dce955c76f3c 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -5,14 +5,22 @@ | |||
5 | #define _SKY2_H | 5 | #define _SKY2_H |
6 | 6 | ||
7 | /* PCI config registers */ | 7 | /* PCI config registers */ |
8 | #define PCI_DEV_REG1 0x40 | 8 | enum { |
9 | #define PCI_DEV_REG2 0x44 | 9 | PCI_DEV_REG1 = 0x40, |
10 | #define PCI_DEV_STATUS 0x7c | 10 | PCI_DEV_REG2 = 0x44, |
11 | #define PCI_OS_PCI_X (1<<26) | 11 | PCI_DEV_STATUS = 0x7c, |
12 | PCI_DEV_REG3 = 0x80, | ||
13 | PCI_DEV_REG4 = 0x84, | ||
14 | PCI_DEV_REG5 = 0x88, | ||
15 | }; | ||
12 | 16 | ||
13 | #define PEX_LNK_STAT 0xf2 | 17 | enum { |
14 | #define PEX_UNC_ERR_STAT 0x104 | 18 | PEX_DEV_CAP = 0xe4, |
15 | #define PEX_DEV_CTRL 0xe8 | 19 | PEX_DEV_CTRL = 0xe8, |
20 | PEX_DEV_STA = 0xea, | ||
21 | PEX_LNK_STAT = 0xf2, | ||
22 | PEX_UNC_ERR_STAT= 0x104, | ||
23 | }; | ||
16 | 24 | ||
17 | /* Yukon-2 */ | 25 | /* Yukon-2 */ |
18 | enum pci_dev_reg_1 { | 26 | enum pci_dev_reg_1 { |
@@ -37,6 +45,25 @@ enum pci_dev_reg_2 { | |||
37 | PCI_USEDATA64 = 1<<0, /* Use 64Bit Data bus ext */ | 45 | PCI_USEDATA64 = 1<<0, /* Use 64Bit Data bus ext */ |
38 | }; | 46 | }; |
39 | 47 | ||
48 | /* PCI_OUR_REG_4 32 bit Our Register 4 (Yukon-ECU only) */ | ||
49 | enum pci_dev_reg_4 { | ||
50 | /* (Link Training & Status State Machine) */ | ||
51 | P_TIMER_VALUE_MSK = 0xffL<<16, /* Bit 23..16: Timer Value Mask */ | ||
52 | /* (Active State Power Management) */ | ||
53 | P_FORCE_ASPM_REQUEST = 1<<15, /* Force ASPM Request (A1 only) */ | ||
54 | P_ASPM_GPHY_LINK_DOWN = 1<<14, /* GPHY Link Down (A1 only) */ | ||
55 | P_ASPM_INT_FIFO_EMPTY = 1<<13, /* Internal FIFO Empty (A1 only) */ | ||
56 | P_ASPM_CLKRUN_REQUEST = 1<<12, /* CLKRUN Request (A1 only) */ | ||
57 | |||
58 | P_ASPM_FORCE_CLKREQ_ENA = 1<<4, /* Force CLKREQ Enable (A1b only) */ | ||
59 | P_ASPM_CLKREQ_PAD_CTL = 1<<3, /* CLKREQ PAD Control (A1 only) */ | ||
60 | P_ASPM_A1_MODE_SELECT = 1<<2, /* A1 Mode Select (A1 only) */ | ||
61 | P_CLK_GATE_PEX_UNIT_ENA = 1<<1, /* Enable Gate PEX Unit Clock */ | ||
62 | P_CLK_GATE_ROOT_COR_ENA = 1<<0, /* Enable Gate Root Core Clock */ | ||
63 | P_ASPM_CONTROL_MSK = P_FORCE_ASPM_REQUEST | P_ASPM_GPHY_LINK_DOWN | ||
64 | | P_ASPM_CLKRUN_REQUEST | P_ASPM_INT_FIFO_EMPTY, | ||
65 | }; | ||
66 | |||
40 | 67 | ||
41 | #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ | 68 | #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ |
42 | PCI_STATUS_SIG_SYSTEM_ERROR | \ | 69 | PCI_STATUS_SIG_SYSTEM_ERROR | \ |
@@ -507,6 +534,16 @@ enum { | |||
507 | }; | 534 | }; |
508 | #define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs)) | 535 | #define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs)) |
509 | 536 | ||
537 | /* Q_F 32 bit Flag Register */ | ||
538 | enum { | ||
539 | F_ALM_FULL = 1<<27, /* Rx FIFO: almost full */ | ||
540 | F_EMPTY = 1<<27, /* Tx FIFO: empty flag */ | ||
541 | F_FIFO_EOF = 1<<26, /* Tag (EOF Flag) bit in FIFO */ | ||
542 | F_WM_REACHED = 1<<25, /* Watermark reached */ | ||
543 | F_M_RX_RAM_DIS = 1<<24, /* MAC Rx RAM Read Port disable */ | ||
544 | F_FIFO_LEVEL = 0x1fL<<16, /* Bit 23..16: # of Qwords in FIFO */ | ||
545 | F_WATER_MARK = 0x0007ffL, /* Bit 10.. 0: Watermark */ | ||
546 | }; | ||
510 | 547 | ||
511 | /* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/ | 548 | /* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/ |
512 | enum { | 549 | enum { |
@@ -909,10 +946,12 @@ enum { | |||
909 | PHY_BCOM_ID1_C0 = 0x6044, | 946 | PHY_BCOM_ID1_C0 = 0x6044, |
910 | PHY_BCOM_ID1_C5 = 0x6047, | 947 | PHY_BCOM_ID1_C5 = 0x6047, |
911 | 948 | ||
912 | PHY_MARV_ID1_B0 = 0x0C23, /* Yukon (PHY 88E1011) */ | 949 | PHY_MARV_ID1_B0 = 0x0C23, /* Yukon (PHY 88E1011) */ |
913 | PHY_MARV_ID1_B2 = 0x0C25, /* Yukon-Plus (PHY 88E1011) */ | 950 | PHY_MARV_ID1_B2 = 0x0C25, /* Yukon-Plus (PHY 88E1011) */ |
914 | PHY_MARV_ID1_C2 = 0x0CC2, /* Yukon-EC (PHY 88E1111) */ | 951 | PHY_MARV_ID1_C2 = 0x0CC2, /* Yukon-EC (PHY 88E1111) */ |
915 | PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */ | 952 | PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */ |
953 | PHY_MARV_ID1_FE = 0x0C83, /* Yukon-FE (PHY 88E3082 Rev.A1) */ | ||
954 | PHY_MARV_ID1_ECU= 0x0CB0, /* Yukon-ECU (PHY 88E1149 Rev.B2?) */ | ||
916 | }; | 955 | }; |
917 | 956 | ||
918 | /* Advertisement register bits */ | 957 | /* Advertisement register bits */ |
@@ -1837,8 +1876,9 @@ struct sky2_port { | |||
1837 | struct sky2_hw { | 1876 | struct sky2_hw { |
1838 | void __iomem *regs; | 1877 | void __iomem *regs; |
1839 | struct pci_dev *pdev; | 1878 | struct pci_dev *pdev; |
1840 | u32 intr_mask; | ||
1841 | struct net_device *dev[2]; | 1879 | struct net_device *dev[2]; |
1880 | spinlock_t hw_lock; | ||
1881 | u32 intr_mask; | ||
1842 | 1882 | ||
1843 | int pm_cap; | 1883 | int pm_cap; |
1844 | u8 chip_id; | 1884 | u8 chip_id; |
@@ -1867,14 +1907,6 @@ static inline u8 sky2_read8(const struct sky2_hw *hw, unsigned reg) | |||
1867 | return readb(hw->regs + reg); | 1907 | return readb(hw->regs + reg); |
1868 | } | 1908 | } |
1869 | 1909 | ||
1870 | /* This should probably go away, bus based tweeks suck */ | ||
1871 | static inline int is_pciex(const struct sky2_hw *hw) | ||
1872 | { | ||
1873 | u32 status; | ||
1874 | pci_read_config_dword(hw->pdev, PCI_DEV_STATUS, &status); | ||
1875 | return (status & PCI_OS_PCI_X) == 0; | ||
1876 | } | ||
1877 | |||
1878 | static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val) | 1910 | static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val) |
1879 | { | 1911 | { |
1880 | writel(val, hw->regs + reg); | 1912 | writel(val, hw->regs + reg); |
@@ -1919,4 +1951,25 @@ static inline void gma_set_addr(struct sky2_hw *hw, unsigned port, unsigned reg, | |||
1919 | gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8)); | 1951 | gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8)); |
1920 | gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8)); | 1952 | gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8)); |
1921 | } | 1953 | } |
1954 | |||
1955 | /* PCI config space access */ | ||
1956 | static inline u32 sky2_pci_read32(const struct sky2_hw *hw, unsigned reg) | ||
1957 | { | ||
1958 | return sky2_read32(hw, Y2_CFG_SPC + reg); | ||
1959 | } | ||
1960 | |||
1961 | static inline u16 sky2_pci_read16(const struct sky2_hw *hw, unsigned reg) | ||
1962 | { | ||
1963 | return sky2_read16(hw, Y2_CFG_SPC + reg); | ||
1964 | } | ||
1965 | |||
1966 | static inline void sky2_pci_write32(struct sky2_hw *hw, unsigned reg, u32 val) | ||
1967 | { | ||
1968 | sky2_write32(hw, Y2_CFG_SPC + reg, val); | ||
1969 | } | ||
1970 | |||
1971 | static inline void sky2_pci_write16(struct sky2_hw *hw, unsigned reg, u16 val) | ||
1972 | { | ||
1973 | sky2_write16(hw, Y2_CFG_SPC + reg, val); | ||
1974 | } | ||
1922 | #endif | 1975 | #endif |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e7dc653d5bd6..caf4102b54ce 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -3532,9 +3532,23 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) | |||
3532 | (base + len + 8 < base)); | 3532 | (base + len + 8 < base)); |
3533 | } | 3533 | } |
3534 | 3534 | ||
3535 | /* Test for DMA addresses > 40-bit */ | ||
3536 | static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, | ||
3537 | int len) | ||
3538 | { | ||
3539 | #if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64) | ||
3540 | if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) | ||
3541 | return (((u64) mapping + len) > DMA_40BIT_MASK); | ||
3542 | return 0; | ||
3543 | #else | ||
3544 | return 0; | ||
3545 | #endif | ||
3546 | } | ||
3547 | |||
3535 | static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32); | 3548 | static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32); |
3536 | 3549 | ||
3537 | static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, | 3550 | /* Workaround 4GB and 40-bit hardware DMA bugs. */ |
3551 | static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, | ||
3538 | u32 last_plus_one, u32 *start, | 3552 | u32 last_plus_one, u32 *start, |
3539 | u32 base_flags, u32 mss) | 3553 | u32 base_flags, u32 mss) |
3540 | { | 3554 | { |
@@ -3742,6 +3756,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3742 | if (tg3_4g_overflow_test(mapping, len)) | 3756 | if (tg3_4g_overflow_test(mapping, len)) |
3743 | would_hit_hwbug = 1; | 3757 | would_hit_hwbug = 1; |
3744 | 3758 | ||
3759 | if (tg3_40bit_overflow_test(tp, mapping, len)) | ||
3760 | would_hit_hwbug = 1; | ||
3761 | |||
3745 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) | 3762 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) |
3746 | tg3_set_txd(tp, entry, mapping, len, | 3763 | tg3_set_txd(tp, entry, mapping, len, |
3747 | base_flags, (i == last)|(mss << 1)); | 3764 | base_flags, (i == last)|(mss << 1)); |
@@ -3763,7 +3780,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3763 | /* If the workaround fails due to memory/mapping | 3780 | /* If the workaround fails due to memory/mapping |
3764 | * failure, silently drop this packet. | 3781 | * failure, silently drop this packet. |
3765 | */ | 3782 | */ |
3766 | if (tigon3_4gb_hwbug_workaround(tp, skb, last_plus_one, | 3783 | if (tigon3_dma_hwbug_workaround(tp, skb, last_plus_one, |
3767 | &start, base_flags, mss)) | 3784 | &start, base_flags, mss)) |
3768 | goto out_unlock; | 3785 | goto out_unlock; |
3769 | 3786 | ||
@@ -9408,6 +9425,15 @@ static int __devinit tg3_is_sun_570X(struct tg3 *tp) | |||
9408 | return 0; | 9425 | return 0; |
9409 | if (venid == PCI_VENDOR_ID_SUN) | 9426 | if (venid == PCI_VENDOR_ID_SUN) |
9410 | return 1; | 9427 | return 1; |
9428 | |||
9429 | /* TG3 chips onboard the SunBlade-2500 don't have the | ||
9430 | * subsystem-vendor-id set to PCI_VENDOR_ID_SUN but they | ||
9431 | * are distinguishable from non-Sun variants by being | ||
9432 | * named "network" by the firmware. Non-Sun cards will | ||
9433 | * show up as being named "ethernet". | ||
9434 | */ | ||
9435 | if (!strcmp(pcp->prom_name, "network")) | ||
9436 | return 1; | ||
9411 | } | 9437 | } |
9412 | return 0; | 9438 | return 0; |
9413 | } | 9439 | } |
@@ -9526,12 +9552,36 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9526 | } | 9552 | } |
9527 | } | 9553 | } |
9528 | 9554 | ||
9529 | /* Find msi capability. */ | 9555 | /* The EPB bridge inside 5714, 5715, and 5780 cannot support |
9556 | * DMA addresses > 40-bit. This bridge may have other additional | ||
9557 | * 57xx devices behind it in some 4-port NIC designs for example. | ||
9558 | * Any tg3 device found behind the bridge will also need the 40-bit | ||
9559 | * DMA workaround. | ||
9560 | */ | ||
9530 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 || | 9561 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 || |
9531 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) { | 9562 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) { |
9532 | tp->tg3_flags2 |= TG3_FLG2_5780_CLASS; | 9563 | tp->tg3_flags2 |= TG3_FLG2_5780_CLASS; |
9564 | tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG; | ||
9533 | tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); | 9565 | tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); |
9534 | } | 9566 | } |
9567 | else { | ||
9568 | struct pci_dev *bridge = NULL; | ||
9569 | |||
9570 | do { | ||
9571 | bridge = pci_get_device(PCI_VENDOR_ID_SERVERWORKS, | ||
9572 | PCI_DEVICE_ID_SERVERWORKS_EPB, | ||
9573 | bridge); | ||
9574 | if (bridge && bridge->subordinate && | ||
9575 | (bridge->subordinate->number <= | ||
9576 | tp->pdev->bus->number) && | ||
9577 | (bridge->subordinate->subordinate >= | ||
9578 | tp->pdev->bus->number)) { | ||
9579 | tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG; | ||
9580 | pci_dev_put(bridge); | ||
9581 | break; | ||
9582 | } | ||
9583 | } while (bridge); | ||
9584 | } | ||
9535 | 9585 | ||
9536 | /* Initialize misc host control in PCI block. */ | 9586 | /* Initialize misc host control in PCI block. */ |
9537 | tp->misc_host_ctrl |= (misc_ctrl_reg & | 9587 | tp->misc_host_ctrl |= (misc_ctrl_reg & |
@@ -10277,7 +10327,14 @@ static int __devinit tg3_test_dma(struct tg3 *tp) | |||
10277 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { | 10327 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { |
10278 | u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f); | 10328 | u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f); |
10279 | 10329 | ||
10280 | if (ccval == 0x6 || ccval == 0x7) | 10330 | /* If the 5704 is behind the EPB bridge, we can |
10331 | * do the less restrictive ONE_DMA workaround for | ||
10332 | * better performance. | ||
10333 | */ | ||
10334 | if ((tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) && | ||
10335 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) | ||
10336 | tp->dma_rwctrl |= 0x8000; | ||
10337 | else if (ccval == 0x6 || ccval == 0x7) | ||
10281 | tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; | 10338 | tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; |
10282 | 10339 | ||
10283 | /* Set bit 23 to enable PCIX hw bug fix */ | 10340 | /* Set bit 23 to enable PCIX hw bug fix */ |
@@ -10517,8 +10574,6 @@ static char * __devinit tg3_bus_string(struct tg3 *tp, char *str) | |||
10517 | strcat(str, "66MHz"); | 10574 | strcat(str, "66MHz"); |
10518 | else if (clock_ctrl == 6) | 10575 | else if (clock_ctrl == 6) |
10519 | strcat(str, "100MHz"); | 10576 | strcat(str, "100MHz"); |
10520 | else if (clock_ctrl == 7) | ||
10521 | strcat(str, "133MHz"); | ||
10522 | } else { | 10577 | } else { |
10523 | strcpy(str, "PCI:"); | 10578 | strcpy(str, "PCI:"); |
10524 | if (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED) | 10579 | if (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED) |
@@ -10599,8 +10654,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10599 | unsigned long tg3reg_base, tg3reg_len; | 10654 | unsigned long tg3reg_base, tg3reg_len; |
10600 | struct net_device *dev; | 10655 | struct net_device *dev; |
10601 | struct tg3 *tp; | 10656 | struct tg3 *tp; |
10602 | int i, err, pci_using_dac, pm_cap; | 10657 | int i, err, pm_cap; |
10603 | char str[40]; | 10658 | char str[40]; |
10659 | u64 dma_mask, persist_dma_mask; | ||
10604 | 10660 | ||
10605 | if (tg3_version_printed++ == 0) | 10661 | if (tg3_version_printed++ == 0) |
10606 | printk(KERN_INFO "%s", version); | 10662 | printk(KERN_INFO "%s", version); |
@@ -10637,26 +10693,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10637 | goto err_out_free_res; | 10693 | goto err_out_free_res; |
10638 | } | 10694 | } |
10639 | 10695 | ||
10640 | /* Configure DMA attributes. */ | ||
10641 | err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); | ||
10642 | if (!err) { | ||
10643 | pci_using_dac = 1; | ||
10644 | err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); | ||
10645 | if (err < 0) { | ||
10646 | printk(KERN_ERR PFX "Unable to obtain 64 bit DMA " | ||
10647 | "for consistent allocations\n"); | ||
10648 | goto err_out_free_res; | ||
10649 | } | ||
10650 | } else { | ||
10651 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
10652 | if (err) { | ||
10653 | printk(KERN_ERR PFX "No usable DMA configuration, " | ||
10654 | "aborting.\n"); | ||
10655 | goto err_out_free_res; | ||
10656 | } | ||
10657 | pci_using_dac = 0; | ||
10658 | } | ||
10659 | |||
10660 | tg3reg_base = pci_resource_start(pdev, 0); | 10696 | tg3reg_base = pci_resource_start(pdev, 0); |
10661 | tg3reg_len = pci_resource_len(pdev, 0); | 10697 | tg3reg_len = pci_resource_len(pdev, 0); |
10662 | 10698 | ||
@@ -10670,8 +10706,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10670 | SET_MODULE_OWNER(dev); | 10706 | SET_MODULE_OWNER(dev); |
10671 | SET_NETDEV_DEV(dev, &pdev->dev); | 10707 | SET_NETDEV_DEV(dev, &pdev->dev); |
10672 | 10708 | ||
10673 | if (pci_using_dac) | ||
10674 | dev->features |= NETIF_F_HIGHDMA; | ||
10675 | dev->features |= NETIF_F_LLTX; | 10709 | dev->features |= NETIF_F_LLTX; |
10676 | #if TG3_VLAN_TAG_USED | 10710 | #if TG3_VLAN_TAG_USED |
10677 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 10711 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
@@ -10756,6 +10790,45 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10756 | goto err_out_iounmap; | 10790 | goto err_out_iounmap; |
10757 | } | 10791 | } |
10758 | 10792 | ||
10793 | /* The EPB bridge inside 5714, 5715, and 5780 and any | ||
10794 | * device behind the EPB cannot support DMA addresses > 40-bit. | ||
10795 | * On 64-bit systems with IOMMU, use 40-bit dma_mask. | ||
10796 | * On 64-bit systems without IOMMU, use 64-bit dma_mask and | ||
10797 | * do DMA address check in tg3_start_xmit(). | ||
10798 | */ | ||
10799 | if (tp->tg3_flags2 & TG3_FLG2_IS_5788) | ||
10800 | persist_dma_mask = dma_mask = DMA_32BIT_MASK; | ||
10801 | else if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) { | ||
10802 | persist_dma_mask = dma_mask = DMA_40BIT_MASK; | ||
10803 | #ifdef CONFIG_HIGHMEM | ||
10804 | dma_mask = DMA_64BIT_MASK; | ||
10805 | #endif | ||
10806 | } else | ||
10807 | persist_dma_mask = dma_mask = DMA_64BIT_MASK; | ||
10808 | |||
10809 | /* Configure DMA attributes. */ | ||
10810 | if (dma_mask > DMA_32BIT_MASK) { | ||
10811 | err = pci_set_dma_mask(pdev, dma_mask); | ||
10812 | if (!err) { | ||
10813 | dev->features |= NETIF_F_HIGHDMA; | ||
10814 | err = pci_set_consistent_dma_mask(pdev, | ||
10815 | persist_dma_mask); | ||
10816 | if (err < 0) { | ||
10817 | printk(KERN_ERR PFX "Unable to obtain 64 bit " | ||
10818 | "DMA for consistent allocations\n"); | ||
10819 | goto err_out_iounmap; | ||
10820 | } | ||
10821 | } | ||
10822 | } | ||
10823 | if (err || dma_mask == DMA_32BIT_MASK) { | ||
10824 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
10825 | if (err) { | ||
10826 | printk(KERN_ERR PFX "No usable DMA configuration, " | ||
10827 | "aborting.\n"); | ||
10828 | goto err_out_iounmap; | ||
10829 | } | ||
10830 | } | ||
10831 | |||
10759 | tg3_init_bufmgr_config(tp); | 10832 | tg3_init_bufmgr_config(tp); |
10760 | 10833 | ||
10761 | #if TG3_TSO_SUPPORT != 0 | 10834 | #if TG3_TSO_SUPPORT != 0 |
@@ -10824,9 +10897,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10824 | } else | 10897 | } else |
10825 | tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; | 10898 | tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; |
10826 | 10899 | ||
10827 | if (tp->tg3_flags2 & TG3_FLG2_IS_5788) | ||
10828 | dev->features &= ~NETIF_F_HIGHDMA; | ||
10829 | |||
10830 | /* flow control autonegotiation is default behavior */ | 10900 | /* flow control autonegotiation is default behavior */ |
10831 | tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; | 10901 | tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; |
10832 | 10902 | ||
@@ -10870,8 +10940,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10870 | (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, | 10940 | (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, |
10871 | (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, | 10941 | (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, |
10872 | (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); | 10942 | (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); |
10873 | printk(KERN_INFO "%s: dma_rwctrl[%08x]\n", | 10943 | printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n", |
10874 | dev->name, tp->dma_rwctrl); | 10944 | dev->name, tp->dma_rwctrl, |
10945 | (pdev->dma_mask == DMA_32BIT_MASK) ? 32 : | ||
10946 | (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64)); | ||
10875 | 10947 | ||
10876 | return 0; | 10948 | return 0; |
10877 | 10949 | ||
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 7f4b7f6ac40d..7e3b613afb29 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -2163,6 +2163,7 @@ struct tg3 { | |||
2163 | #define TG3_FLAG_10_100_ONLY 0x01000000 | 2163 | #define TG3_FLAG_10_100_ONLY 0x01000000 |
2164 | #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 | 2164 | #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 |
2165 | #define TG3_FLAG_IN_RESET_TASK 0x04000000 | 2165 | #define TG3_FLAG_IN_RESET_TASK 0x04000000 |
2166 | #define TG3_FLAG_40BIT_DMA_BUG 0x08000000 | ||
2166 | #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 | 2167 | #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 |
2167 | #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 | 2168 | #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 |
2168 | #define TG3_FLAG_SPLIT_MODE 0x40000000 | 2169 | #define TG3_FLAG_SPLIT_MODE 0x40000000 |
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index c2506b56a186..12076f8f942c 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c | |||
@@ -536,6 +536,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, | |||
536 | u16 device_id; | 536 | u16 device_id; |
537 | int reg, rc = -ENODEV; | 537 | int reg, rc = -ENODEV; |
538 | 538 | ||
539 | #ifdef CONFIG_PCI | ||
539 | if (pdev) { | 540 | if (pdev) { |
540 | rc = pci_enable_device(pdev); | 541 | rc = pci_enable_device(pdev); |
541 | if (rc) | 542 | if (rc) |
@@ -547,6 +548,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, | |||
547 | goto err_out; | 548 | goto err_out; |
548 | } | 549 | } |
549 | } | 550 | } |
551 | #endif /* CONFIG_PCI */ | ||
550 | 552 | ||
551 | dev = alloc_etherdev(sizeof(TLanPrivateInfo)); | 553 | dev = alloc_etherdev(sizeof(TLanPrivateInfo)); |
552 | if (dev == NULL) { | 554 | if (dev == NULL) { |
diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h index b306c7e4c793..88dfa2e01d6e 100644 --- a/drivers/net/tokenring/smctr.h +++ b/drivers/net/tokenring/smctr.h | |||
@@ -1042,7 +1042,7 @@ typedef struct net_local { | |||
1042 | __u16 functional_address[2]; | 1042 | __u16 functional_address[2]; |
1043 | __u16 bitwise_group_address[2]; | 1043 | __u16 bitwise_group_address[2]; |
1044 | 1044 | ||
1045 | __u8 *ptr_ucode; | 1045 | const __u8 *ptr_ucode; |
1046 | 1046 | ||
1047 | __u8 cleanup; | 1047 | __u8 cleanup; |
1048 | 1048 | ||
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index d7fb3ffe06ac..2d0cfbceee22 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -1362,7 +1362,6 @@ static int de_open (struct net_device *dev) | |||
1362 | { | 1362 | { |
1363 | struct de_private *de = dev->priv; | 1363 | struct de_private *de = dev->priv; |
1364 | int rc; | 1364 | int rc; |
1365 | unsigned long flags; | ||
1366 | 1365 | ||
1367 | if (netif_msg_ifup(de)) | 1366 | if (netif_msg_ifup(de)) |
1368 | printk(KERN_DEBUG "%s: enabling interface\n", dev->name); | 1367 | printk(KERN_DEBUG "%s: enabling interface\n", dev->name); |
@@ -1376,18 +1375,20 @@ static int de_open (struct net_device *dev) | |||
1376 | return rc; | 1375 | return rc; |
1377 | } | 1376 | } |
1378 | 1377 | ||
1379 | rc = de_init_hw(de); | 1378 | dw32(IntrMask, 0); |
1380 | if (rc) { | ||
1381 | printk(KERN_ERR "%s: h/w init failure, err=%d\n", | ||
1382 | dev->name, rc); | ||
1383 | goto err_out_free; | ||
1384 | } | ||
1385 | 1379 | ||
1386 | rc = request_irq(dev->irq, de_interrupt, SA_SHIRQ, dev->name, dev); | 1380 | rc = request_irq(dev->irq, de_interrupt, SA_SHIRQ, dev->name, dev); |
1387 | if (rc) { | 1381 | if (rc) { |
1388 | printk(KERN_ERR "%s: IRQ %d request failure, err=%d\n", | 1382 | printk(KERN_ERR "%s: IRQ %d request failure, err=%d\n", |
1389 | dev->name, dev->irq, rc); | 1383 | dev->name, dev->irq, rc); |
1390 | goto err_out_hw; | 1384 | goto err_out_free; |
1385 | } | ||
1386 | |||
1387 | rc = de_init_hw(de); | ||
1388 | if (rc) { | ||
1389 | printk(KERN_ERR "%s: h/w init failure, err=%d\n", | ||
1390 | dev->name, rc); | ||
1391 | goto err_out_free_irq; | ||
1391 | } | 1392 | } |
1392 | 1393 | ||
1393 | netif_start_queue(dev); | 1394 | netif_start_queue(dev); |
@@ -1395,11 +1396,8 @@ static int de_open (struct net_device *dev) | |||
1395 | 1396 | ||
1396 | return 0; | 1397 | return 0; |
1397 | 1398 | ||
1398 | err_out_hw: | 1399 | err_out_free_irq: |
1399 | spin_lock_irqsave(&de->lock, flags); | 1400 | free_irq(dev->irq, dev); |
1400 | de_stop_hw(de); | ||
1401 | spin_unlock_irqrestore(&de->lock, flags); | ||
1402 | |||
1403 | err_out_free: | 1401 | err_out_free: |
1404 | de_free_rings(de); | 1402 | de_free_rings(de); |
1405 | return rc; | 1403 | return rc; |
@@ -1455,6 +1453,8 @@ static void de_tx_timeout (struct net_device *dev) | |||
1455 | synchronize_irq(dev->irq); | 1453 | synchronize_irq(dev->irq); |
1456 | de_clean_rings(de); | 1454 | de_clean_rings(de); |
1457 | 1455 | ||
1456 | de_init_rings(de); | ||
1457 | |||
1458 | de_init_hw(de); | 1458 | de_init_hw(de); |
1459 | 1459 | ||
1460 | netif_wake_queue(dev); | 1460 | netif_wake_queue(dev); |
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 983981666800..238e9c72cb3a 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c | |||
@@ -214,7 +214,7 @@ static u32 uli526x_cr6_user_set; | |||
214 | /* For module input parameter */ | 214 | /* For module input parameter */ |
215 | static int debug; | 215 | static int debug; |
216 | static u32 cr6set; | 216 | static u32 cr6set; |
217 | static unsigned char mode = 8; | 217 | static int mode = 8; |
218 | 218 | ||
219 | /* function declaration ------------------------------------- */ | 219 | /* function declaration ------------------------------------- */ |
220 | static int uli526x_open(struct net_device *); | 220 | static int uli526x_open(struct net_device *); |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 50b8c6754b1e..a1ed2d983740 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -249,8 +249,11 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, | |||
249 | 249 | ||
250 | if (align) | 250 | if (align) |
251 | skb_reserve(skb, align); | 251 | skb_reserve(skb, align); |
252 | if (memcpy_fromiovec(skb_put(skb, len), iv, len)) | 252 | if (memcpy_fromiovec(skb_put(skb, len), iv, len)) { |
253 | tun->stats.rx_dropped++; | ||
254 | kfree_skb(skb); | ||
253 | return -EFAULT; | 255 | return -EFAULT; |
256 | } | ||
254 | 257 | ||
255 | skb->dev = tun->dev; | 258 | skb->dev = tun->dev; |
256 | switch (tun->flags & TUN_TYPE_MASK) { | 259 | switch (tun->flags & TUN_TYPE_MASK) { |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index c2d5907dc8e0..ed1f837c8fda 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -1106,6 +1106,9 @@ static void velocity_free_rd_ring(struct velocity_info *vptr) | |||
1106 | 1106 | ||
1107 | for (i = 0; i < vptr->options.numrx; i++) { | 1107 | for (i = 0; i < vptr->options.numrx; i++) { |
1108 | struct velocity_rd_info *rd_info = &(vptr->rd_info[i]); | 1108 | struct velocity_rd_info *rd_info = &(vptr->rd_info[i]); |
1109 | struct rx_desc *rd = vptr->rd_ring + i; | ||
1110 | |||
1111 | memset(rd, 0, sizeof(*rd)); | ||
1109 | 1112 | ||
1110 | if (!rd_info->skb) | 1113 | if (!rd_info->skb) |
1111 | continue; | 1114 | continue; |
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 2f61a47b4716..1ff5de076d21 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c | |||
@@ -1943,7 +1943,7 @@ static int dscc4_init_ring(struct net_device *dev) | |||
1943 | (++i%TX_RING_SIZE)*sizeof(*tx_fd)); | 1943 | (++i%TX_RING_SIZE)*sizeof(*tx_fd)); |
1944 | } while (i < TX_RING_SIZE); | 1944 | } while (i < TX_RING_SIZE); |
1945 | 1945 | ||
1946 | if (dscc4_init_dummy_skb(dpriv) < 0) | 1946 | if (!dscc4_init_dummy_skb(dpriv)) |
1947 | goto err_free_dma_tx; | 1947 | goto err_free_dma_tx; |
1948 | 1948 | ||
1949 | memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE); | 1949 | memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE); |
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index 8dea07b47999..eba8e5cfacc2 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
30 | #include <linux/hdlc.h> | 30 | #include <linux/hdlc.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <asm/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <asm/io.h> | 33 | #include <asm/io.h> |
34 | 34 | ||
35 | #include "hd64572.h" | 35 | #include "hd64572.h" |
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 9c1e10602f2b..9d3b51c3ef54 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c | |||
@@ -27,8 +27,8 @@ | |||
27 | #include <linux/hdlc.h> | 27 | #include <linux/hdlc.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
30 | #include <linux/delay.h> | ||
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
31 | #include <asm/delay.h> | ||
32 | 32 | ||
33 | #include "wanxl.h" | 33 | #include "wanxl.h" |
34 | 34 | ||
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 233a4f608084..ef85d76575a2 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -148,7 +148,7 @@ config IPW2100 | |||
148 | In order to use this driver, you will need a firmware image for it. | 148 | In order to use this driver, you will need a firmware image for it. |
149 | You can obtain the firmware from | 149 | You can obtain the firmware from |
150 | <http://ipw2100.sf.net/>. Once you have the firmware image, you | 150 | <http://ipw2100.sf.net/>. Once you have the firmware image, you |
151 | will need to place it in /etc/firmware. | 151 | will need to place it in /lib/firmware. |
152 | 152 | ||
153 | You will also very likely need the Wireless Tools in order to | 153 | You will also very likely need the Wireless Tools in order to |
154 | configure your card: | 154 | configure your card: |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 98a76f10a0f7..dfc24016ba81 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -1872,7 +1872,7 @@ static int atmel_set_encodeext(struct net_device *dev, | |||
1872 | struct atmel_private *priv = netdev_priv(dev); | 1872 | struct atmel_private *priv = netdev_priv(dev); |
1873 | struct iw_point *encoding = &wrqu->encoding; | 1873 | struct iw_point *encoding = &wrqu->encoding; |
1874 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | 1874 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; |
1875 | int idx, key_len; | 1875 | int idx, key_len, alg = ext->alg, set_key = 1; |
1876 | 1876 | ||
1877 | /* Determine and validate the key index */ | 1877 | /* Determine and validate the key index */ |
1878 | idx = encoding->flags & IW_ENCODE_INDEX; | 1878 | idx = encoding->flags & IW_ENCODE_INDEX; |
@@ -1883,39 +1883,42 @@ static int atmel_set_encodeext(struct net_device *dev, | |||
1883 | } else | 1883 | } else |
1884 | idx = priv->default_key; | 1884 | idx = priv->default_key; |
1885 | 1885 | ||
1886 | if ((encoding->flags & IW_ENCODE_DISABLED) || | 1886 | if (encoding->flags & IW_ENCODE_DISABLED) |
1887 | ext->alg == IW_ENCODE_ALG_NONE) { | 1887 | alg = IW_ENCODE_ALG_NONE; |
1888 | priv->wep_is_on = 0; | ||
1889 | priv->encryption_level = 0; | ||
1890 | priv->pairwise_cipher_suite = CIPHER_SUITE_NONE; | ||
1891 | } | ||
1892 | 1888 | ||
1893 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) | 1889 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { |
1894 | priv->default_key = idx; | 1890 | priv->default_key = idx; |
1891 | set_key = ext->key_len > 0 ? 1 : 0; | ||
1892 | } | ||
1895 | 1893 | ||
1896 | /* Set the requested key */ | 1894 | if (set_key) { |
1897 | switch (ext->alg) { | 1895 | /* Set the requested key first */ |
1898 | case IW_ENCODE_ALG_NONE: | 1896 | switch (alg) { |
1899 | break; | 1897 | case IW_ENCODE_ALG_NONE: |
1900 | case IW_ENCODE_ALG_WEP: | 1898 | priv->wep_is_on = 0; |
1901 | if (ext->key_len > 5) { | 1899 | priv->encryption_level = 0; |
1902 | priv->wep_key_len[idx] = 13; | 1900 | priv->pairwise_cipher_suite = CIPHER_SUITE_NONE; |
1903 | priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128; | 1901 | break; |
1904 | priv->encryption_level = 2; | 1902 | case IW_ENCODE_ALG_WEP: |
1905 | } else if (ext->key_len > 0) { | 1903 | if (ext->key_len > 5) { |
1906 | priv->wep_key_len[idx] = 5; | 1904 | priv->wep_key_len[idx] = 13; |
1907 | priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64; | 1905 | priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128; |
1908 | priv->encryption_level = 1; | 1906 | priv->encryption_level = 2; |
1909 | } else { | 1907 | } else if (ext->key_len > 0) { |
1908 | priv->wep_key_len[idx] = 5; | ||
1909 | priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64; | ||
1910 | priv->encryption_level = 1; | ||
1911 | } else { | ||
1912 | return -EINVAL; | ||
1913 | } | ||
1914 | priv->wep_is_on = 1; | ||
1915 | memset(priv->wep_keys[idx], 0, 13); | ||
1916 | key_len = min ((int)ext->key_len, priv->wep_key_len[idx]); | ||
1917 | memcpy(priv->wep_keys[idx], ext->key, key_len); | ||
1918 | break; | ||
1919 | default: | ||
1910 | return -EINVAL; | 1920 | return -EINVAL; |
1911 | } | 1921 | } |
1912 | priv->wep_is_on = 1; | ||
1913 | memset(priv->wep_keys[idx], 0, 13); | ||
1914 | key_len = min ((int)ext->key_len, priv->wep_key_len[idx]); | ||
1915 | memcpy(priv->wep_keys[idx], ext->key, key_len); | ||
1916 | break; | ||
1917 | default: | ||
1918 | return -EINVAL; | ||
1919 | } | 1922 | } |
1920 | 1923 | ||
1921 | return -EINPROGRESS; | 1924 | return -EINPROGRESS; |
@@ -3061,17 +3064,26 @@ static void authenticate(struct atmel_private *priv, u16 frame_len) | |||
3061 | } | 3064 | } |
3062 | 3065 | ||
3063 | if (status == C80211_MGMT_SC_Success && priv->wep_is_on) { | 3066 | if (status == C80211_MGMT_SC_Success && priv->wep_is_on) { |
3067 | int should_associate = 0; | ||
3064 | /* WEP */ | 3068 | /* WEP */ |
3065 | if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum) | 3069 | if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum) |
3066 | return; | 3070 | return; |
3067 | 3071 | ||
3068 | if (trans_seq_no == 0x0002 && | 3072 | if (system == C80211_MGMT_AAN_OPENSYSTEM) { |
3069 | auth->el_id == C80211_MGMT_ElementID_ChallengeText) { | 3073 | if (trans_seq_no == 0x0002) { |
3070 | send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len); | 3074 | should_associate = 1; |
3071 | return; | 3075 | } |
3076 | } else if (system == C80211_MGMT_AAN_SHAREDKEY) { | ||
3077 | if (trans_seq_no == 0x0002 && | ||
3078 | auth->el_id == C80211_MGMT_ElementID_ChallengeText) { | ||
3079 | send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len); | ||
3080 | return; | ||
3081 | } else if (trans_seq_no == 0x0004) { | ||
3082 | should_associate = 1; | ||
3083 | } | ||
3072 | } | 3084 | } |
3073 | 3085 | ||
3074 | if (trans_seq_no == 0x0004) { | 3086 | if (should_associate) { |
3075 | if(priv->station_was_associated) { | 3087 | if(priv->station_was_associated) { |
3076 | atmel_enter_state(priv, STATION_STATE_REASSOCIATING); | 3088 | atmel_enter_state(priv, STATION_STATE_REASSOCIATING); |
3077 | send_association_request(priv, 1); | 3089 | send_association_request(priv, 1); |
@@ -3084,11 +3096,13 @@ static void authenticate(struct atmel_private *priv, u16 frame_len) | |||
3084 | } | 3096 | } |
3085 | } | 3097 | } |
3086 | 3098 | ||
3087 | if (status == C80211_MGMT_SC_AuthAlgNotSupported) { | 3099 | if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { |
3088 | /* Do opensystem first, then try sharedkey */ | 3100 | /* Do opensystem first, then try sharedkey */ |
3089 | if (system == C80211_MGMT_AAN_OPENSYSTEM) { | 3101 | if (system == WLAN_AUTH_OPEN) { |
3090 | priv->CurrentAuthentTransactionSeqNum = 0x001; | 3102 | priv->CurrentAuthentTransactionSeqNum = 0x001; |
3091 | send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0); | 3103 | priv->exclude_unencrypted = 1; |
3104 | send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0); | ||
3105 | return; | ||
3092 | } else if (priv->connect_to_any_BSS) { | 3106 | } else if (priv->connect_to_any_BSS) { |
3093 | int bss_index; | 3107 | int bss_index; |
3094 | 3108 | ||
@@ -3439,10 +3453,13 @@ static void atmel_management_timer(u_long a) | |||
3439 | priv->AuthenticationRequestRetryCnt = 0; | 3453 | priv->AuthenticationRequestRetryCnt = 0; |
3440 | restart_search(priv); | 3454 | restart_search(priv); |
3441 | } else { | 3455 | } else { |
3456 | int auth = C80211_MGMT_AAN_OPENSYSTEM; | ||
3442 | priv->AuthenticationRequestRetryCnt++; | 3457 | priv->AuthenticationRequestRetryCnt++; |
3443 | priv->CurrentAuthentTransactionSeqNum = 0x0001; | 3458 | priv->CurrentAuthentTransactionSeqNum = 0x0001; |
3444 | mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); | 3459 | mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); |
3445 | send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0); | 3460 | if (priv->wep_is_on && priv->exclude_unencrypted) |
3461 | auth = C80211_MGMT_AAN_SHAREDKEY; | ||
3462 | send_authentication_request(priv, auth, NULL, 0); | ||
3446 | } | 3463 | } |
3447 | break; | 3464 | break; |
3448 | 3465 | ||
@@ -3541,12 +3558,15 @@ static void atmel_command_irq(struct atmel_private *priv) | |||
3541 | priv->station_was_associated = priv->station_is_associated; | 3558 | priv->station_was_associated = priv->station_is_associated; |
3542 | atmel_enter_state(priv, STATION_STATE_READY); | 3559 | atmel_enter_state(priv, STATION_STATE_READY); |
3543 | } else { | 3560 | } else { |
3561 | int auth = C80211_MGMT_AAN_OPENSYSTEM; | ||
3544 | priv->AuthenticationRequestRetryCnt = 0; | 3562 | priv->AuthenticationRequestRetryCnt = 0; |
3545 | atmel_enter_state(priv, STATION_STATE_AUTHENTICATING); | 3563 | atmel_enter_state(priv, STATION_STATE_AUTHENTICATING); |
3546 | 3564 | ||
3547 | mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); | 3565 | mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); |
3548 | priv->CurrentAuthentTransactionSeqNum = 0x0001; | 3566 | priv->CurrentAuthentTransactionSeqNum = 0x0001; |
3549 | send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0); | 3567 | if (priv->wep_is_on && priv->exclude_unencrypted) |
3568 | auth = C80211_MGMT_AAN_SHAREDKEY; | ||
3569 | send_authentication_request(priv, auth, NULL, 0); | ||
3550 | } | 3570 | } |
3551 | return; | 3571 | return; |
3552 | } | 3572 | } |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 8bc0b528548f..f8f4503475f9 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -877,7 +877,6 @@ static struct pcmcia_device_id hostap_cs_ids[] = { | |||
877 | PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), | 877 | PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), |
878 | PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), | 878 | PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), |
879 | PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), | 879 | PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), |
880 | PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), | ||
881 | PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), | 880 | PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), |
882 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030b), | 881 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030b), |
883 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), | 882 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), |
@@ -891,6 +890,10 @@ static struct pcmcia_device_id hostap_cs_ids[] = { | |||
891 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), | 890 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), |
892 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), | 891 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), |
893 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), | 892 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), |
893 | PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "INTERSIL", | ||
894 | 0x74c5e40d), | ||
895 | PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "Intersil", | ||
896 | 0x4b801a17), | ||
894 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus", | 897 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus", |
895 | 0x7a954bd9, 0x74be00c6), | 898 | 0x7a954bd9, 0x74be00c6), |
896 | PCMCIA_DEVICE_PROD_ID1234( | 899 | PCMCIA_DEVICE_PROD_ID1234( |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 14beab4bc91c..287676ad80df 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -4616,9 +4616,9 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4616 | } | 4616 | } |
4617 | 4617 | ||
4618 | default: | 4618 | default: |
4619 | IPW_ERROR("Unknown notification: " | 4619 | IPW_DEBUG_NOTIF("Unknown notification: " |
4620 | "subtype=%d,flags=0x%2x,size=%d\n", | 4620 | "subtype=%d,flags=0x%2x,size=%d\n", |
4621 | notif->subtype, notif->flags, notif->size); | 4621 | notif->subtype, notif->flags, notif->size); |
4622 | } | 4622 | } |
4623 | } | 4623 | } |
4624 | 4624 | ||
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index 3c128b692bce..ec6f2a48895b 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c | |||
@@ -590,6 +590,7 @@ static struct pcmcia_device_id orinoco_cs_ids[] = { | |||
590 | PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9), | 590 | PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9), |
591 | PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26), | 591 | PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26), |
592 | PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b), | 592 | PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b), |
593 | PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), | ||
593 | PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), | 594 | PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), |
594 | PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e), | 595 | PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e), |
595 | PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39), | 596 | PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39), |
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index c5cd61c7f927..e5bb9f5ae429 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
@@ -748,7 +748,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, | |||
748 | if (essid->length) { | 748 | if (essid->length) { |
749 | dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ | 749 | dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ |
750 | /* if it is to big, trunk it */ | 750 | /* if it is to big, trunk it */ |
751 | dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length); | 751 | dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length); |
752 | } else { | 752 | } else { |
753 | dwrq->flags = 0; | 753 | dwrq->flags = 0; |
754 | dwrq->length = 0; | 754 | dwrq->length = 0; |
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index cf373625fc70..98122f3a4bc2 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c | |||
@@ -950,16 +950,8 @@ wv_82593_cmd(struct net_device * dev, | |||
950 | static inline int | 950 | static inline int |
951 | wv_diag(struct net_device * dev) | 951 | wv_diag(struct net_device * dev) |
952 | { | 952 | { |
953 | int ret = FALSE; | 953 | return(wv_82593_cmd(dev, "wv_diag(): diagnose", |
954 | 954 | OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED)); | |
955 | if(wv_82593_cmd(dev, "wv_diag(): diagnose", | ||
956 | OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED)) | ||
957 | ret = TRUE; | ||
958 | |||
959 | #ifdef DEBUG_CONFIG_ERRORS | ||
960 | printk(KERN_INFO "wavelan_cs: i82593 Self Test failed!\n"); | ||
961 | #endif | ||
962 | return(ret); | ||
963 | } /* wv_diag */ | 955 | } /* wv_diag */ |
964 | 956 | ||
965 | /*------------------------------------------------------------------*/ | 957 | /*------------------------------------------------------------------*/ |
@@ -3604,8 +3596,8 @@ wv_82593_config(struct net_device * dev) | |||
3604 | cfblk.lin_prio = 0; /* conform to 802.3 backoff algoritm */ | 3596 | cfblk.lin_prio = 0; /* conform to 802.3 backoff algoritm */ |
3605 | cfblk.exp_prio = 5; /* conform to 802.3 backoff algoritm */ | 3597 | cfblk.exp_prio = 5; /* conform to 802.3 backoff algoritm */ |
3606 | cfblk.bof_met = 1; /* conform to 802.3 backoff algoritm */ | 3598 | cfblk.bof_met = 1; /* conform to 802.3 backoff algoritm */ |
3607 | cfblk.ifrm_spc = 0x20; /* 32 bit times interframe spacing */ | 3599 | cfblk.ifrm_spc = 0x20 >> 4; /* 32 bit times interframe spacing */ |
3608 | cfblk.slottim_low = 0x20; /* 32 bit times slot time */ | 3600 | cfblk.slottim_low = 0x20 >> 5; /* 32 bit times slot time */ |
3609 | cfblk.slottim_hi = 0x0; | 3601 | cfblk.slottim_hi = 0x0; |
3610 | cfblk.max_retr = 15; | 3602 | cfblk.max_retr = 15; |
3611 | cfblk.prmisc = ((lp->promiscuous) ? TRUE: FALSE); /* Promiscuous mode */ | 3603 | cfblk.prmisc = ((lp->promiscuous) ? TRUE: FALSE); /* Promiscuous mode */ |
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 9e0229f7e25f..93f8a8fa8890 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
41 | #include <linux/pci.h> | 41 | #include <linux/pci.h> |
42 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
43 | #include <linux/proc_fs.h> | ||
44 | #include <linux/seq_file.h> | ||
43 | 45 | ||
44 | #include <asm/byteorder.h> | 46 | #include <asm/byteorder.h> |
45 | #include <asm/cache.h> /* for L1_CACHE_BYTES */ | 47 | #include <asm/cache.h> /* for L1_CACHE_BYTES */ |
@@ -1019,62 +1021,33 @@ static struct hppa_dma_ops ccio_ops = { | |||
1019 | }; | 1021 | }; |
1020 | 1022 | ||
1021 | #ifdef CONFIG_PROC_FS | 1023 | #ifdef CONFIG_PROC_FS |
1022 | static int proc_append(char *src, int len, char **dst, off_t *offset, int *max) | 1024 | static int ccio_proc_info(struct seq_file *m, void *p) |
1023 | { | ||
1024 | if (len < *offset) { | ||
1025 | *offset -= len; | ||
1026 | return 0; | ||
1027 | } | ||
1028 | if (*offset > 0) { | ||
1029 | src += *offset; | ||
1030 | len -= *offset; | ||
1031 | *offset = 0; | ||
1032 | } | ||
1033 | if (len > *max) { | ||
1034 | len = *max; | ||
1035 | } | ||
1036 | memcpy(*dst, src, len); | ||
1037 | *dst += len; | ||
1038 | *max -= len; | ||
1039 | return (*max == 0); | ||
1040 | } | ||
1041 | |||
1042 | static int ccio_proc_info(char *buf, char **start, off_t offset, int count, | ||
1043 | int *eof, void *data) | ||
1044 | { | 1025 | { |
1045 | int max = count; | 1026 | int len = 0; |
1046 | char tmp[80]; /* width of an ANSI-standard terminal */ | ||
1047 | struct ioc *ioc = ioc_list; | 1027 | struct ioc *ioc = ioc_list; |
1048 | 1028 | ||
1049 | while (ioc != NULL) { | 1029 | while (ioc != NULL) { |
1050 | unsigned int total_pages = ioc->res_size << 3; | 1030 | unsigned int total_pages = ioc->res_size << 3; |
1051 | unsigned long avg = 0, min, max; | 1031 | unsigned long avg = 0, min, max; |
1052 | int j, len; | 1032 | int j; |
1053 | 1033 | ||
1054 | len = sprintf(tmp, "%s\n", ioc->name); | 1034 | len += seq_printf(m, "%s\n", ioc->name); |
1055 | if (proc_append(tmp, len, &buf, &offset, &count)) | ||
1056 | break; | ||
1057 | 1035 | ||
1058 | len = sprintf(tmp, "Cujo 2.0 bug : %s\n", | 1036 | len += seq_printf(m, "Cujo 2.0 bug : %s\n", |
1059 | (ioc->cujo20_bug ? "yes" : "no")); | 1037 | (ioc->cujo20_bug ? "yes" : "no")); |
1060 | if (proc_append(tmp, len, &buf, &offset, &count)) | ||
1061 | break; | ||
1062 | 1038 | ||
1063 | len = sprintf(tmp, "IO PDIR size : %d bytes (%d entries)\n", | 1039 | len += seq_printf(m, "IO PDIR size : %d bytes (%d entries)\n", |
1064 | total_pages * 8, total_pages); | 1040 | total_pages * 8, total_pages); |
1065 | if (proc_append(tmp, len, &buf, &offset, &count)) | 1041 | |
1066 | break; | ||
1067 | #ifdef CCIO_MAP_STATS | 1042 | #ifdef CCIO_MAP_STATS |
1068 | len = sprintf(tmp, "IO PDIR entries : %ld free %ld used (%d%%)\n", | 1043 | len += seq_printf(m, "IO PDIR entries : %ld free %ld used (%d%%)\n", |
1069 | total_pages - ioc->used_pages, ioc->used_pages, | 1044 | total_pages - ioc->used_pages, ioc->used_pages, |
1070 | (int)(ioc->used_pages * 100 / total_pages)); | 1045 | (int)(ioc->used_pages * 100 / total_pages)); |
1071 | if (proc_append(tmp, len, &buf, &offset, &count)) | ||
1072 | break; | ||
1073 | #endif | 1046 | #endif |
1074 | len = sprintf(tmp, "Resource bitmap : %d bytes (%d pages)\n", | 1047 | |
1075 | ioc->res_size, total_pages); | 1048 | len += seq_printf(m, "Resource bitmap : %d bytes (%d pages)\n", |
1076 | if (proc_append(tmp, len, &buf, &offset, &count)) | 1049 | ioc->res_size, total_pages); |
1077 | break; | 1050 | |
1078 | #ifdef CCIO_SEARCH_TIME | 1051 | #ifdef CCIO_SEARCH_TIME |
1079 | min = max = ioc->avg_search[0]; | 1052 | min = max = ioc->avg_search[0]; |
1080 | for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) { | 1053 | for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) { |
@@ -1085,70 +1058,83 @@ static int ccio_proc_info(char *buf, char **start, off_t offset, int count, | |||
1085 | min = ioc->avg_search[j]; | 1058 | min = ioc->avg_search[j]; |
1086 | } | 1059 | } |
1087 | avg /= CCIO_SEARCH_SAMPLE; | 1060 | avg /= CCIO_SEARCH_SAMPLE; |
1088 | len = sprintf(tmp, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", | 1061 | len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", |
1089 | min, avg, max); | 1062 | min, avg, max); |
1090 | if (proc_append(tmp, len, &buf, &offset, &count)) | ||
1091 | break; | ||
1092 | #endif | 1063 | #endif |
1093 | #ifdef CCIO_MAP_STATS | 1064 | #ifdef CCIO_MAP_STATS |
1094 | len = sprintf(tmp, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n", | 1065 | len += seq_printf(m, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n", |
1095 | ioc->msingle_calls, ioc->msingle_pages, | 1066 | ioc->msingle_calls, ioc->msingle_pages, |
1096 | (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls)); | 1067 | (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls)); |
1097 | if (proc_append(tmp, len, &buf, &offset, &count)) | ||
1098 | break; | ||
1099 | |||
1100 | 1068 | ||
1101 | /* KLUGE - unmap_sg calls unmap_single for each mapped page */ | 1069 | /* KLUGE - unmap_sg calls unmap_single for each mapped page */ |
1102 | min = ioc->usingle_calls - ioc->usg_calls; | 1070 | min = ioc->usingle_calls - ioc->usg_calls; |
1103 | max = ioc->usingle_pages - ioc->usg_pages; | 1071 | max = ioc->usingle_pages - ioc->usg_pages; |
1104 | len = sprintf(tmp, "pci_unmap_single: %8ld calls %8ld pages (avg %d/1000)\n", | 1072 | len += seq_printf(m, "pci_unmap_single: %8ld calls %8ld pages (avg %d/1000)\n", |
1105 | min, max, (int)((max * 1000)/min)); | 1073 | min, max, (int)((max * 1000)/min)); |
1106 | if (proc_append(tmp, len, &buf, &offset, &count)) | ||
1107 | break; | ||
1108 | 1074 | ||
1109 | len = sprintf(tmp, "pci_map_sg() : %8ld calls %8ld pages (avg %d/1000)\n", | 1075 | len += seq_printf(m, "pci_map_sg() : %8ld calls %8ld pages (avg %d/1000)\n", |
1110 | ioc->msg_calls, ioc->msg_pages, | 1076 | ioc->msg_calls, ioc->msg_pages, |
1111 | (int)((ioc->msg_pages * 1000)/ioc->msg_calls)); | 1077 | (int)((ioc->msg_pages * 1000)/ioc->msg_calls)); |
1112 | if (proc_append(tmp, len, &buf, &offset, &count)) | 1078 | |
1113 | break; | 1079 | len += seq_printf(m, "pci_unmap_sg() : %8ld calls %8ld pages (avg %d/1000)\n\n\n", |
1114 | len = sprintf(tmp, "pci_unmap_sg() : %8ld calls %8ld pages (avg %d/1000)\n\n\n", | 1080 | ioc->usg_calls, ioc->usg_pages, |
1115 | ioc->usg_calls, ioc->usg_pages, | 1081 | (int)((ioc->usg_pages * 1000)/ioc->usg_calls)); |
1116 | (int)((ioc->usg_pages * 1000)/ioc->usg_calls)); | ||
1117 | if (proc_append(tmp, len, &buf, &offset, &count)) | ||
1118 | break; | ||
1119 | #endif /* CCIO_MAP_STATS */ | 1082 | #endif /* CCIO_MAP_STATS */ |
1083 | |||
1120 | ioc = ioc->next; | 1084 | ioc = ioc->next; |
1121 | } | 1085 | } |
1122 | 1086 | ||
1123 | if (count == 0) { | 1087 | return 0; |
1124 | *eof = 1; | 1088 | } |
1125 | } | 1089 | |
1126 | return (max - count); | 1090 | static int ccio_proc_info_open(struct inode *inode, struct file *file) |
1091 | { | ||
1092 | return single_open(file, &ccio_proc_info, NULL); | ||
1127 | } | 1093 | } |
1128 | 1094 | ||
1129 | static int ccio_resource_map(char *buf, char **start, off_t offset, int len, | 1095 | static struct file_operations ccio_proc_info_fops = { |
1130 | int *eof, void *data) | 1096 | .owner = THIS_MODULE, |
1097 | .open = ccio_proc_info_open, | ||
1098 | .read = seq_read, | ||
1099 | .llseek = seq_lseek, | ||
1100 | .release = single_release, | ||
1101 | }; | ||
1102 | |||
1103 | static int ccio_proc_bitmap_info(struct seq_file *m, void *p) | ||
1131 | { | 1104 | { |
1105 | int len = 0; | ||
1132 | struct ioc *ioc = ioc_list; | 1106 | struct ioc *ioc = ioc_list; |
1133 | 1107 | ||
1134 | buf[0] = '\0'; | ||
1135 | while (ioc != NULL) { | 1108 | while (ioc != NULL) { |
1136 | u32 *res_ptr = (u32 *)ioc->res_map; | 1109 | u32 *res_ptr = (u32 *)ioc->res_map; |
1137 | int j; | 1110 | int j; |
1138 | 1111 | ||
1139 | for (j = 0; j < (ioc->res_size / sizeof(u32)); j++) { | 1112 | for (j = 0; j < (ioc->res_size / sizeof(u32)); j++) { |
1140 | if ((j & 7) == 0) | 1113 | if ((j & 7) == 0) |
1141 | strcat(buf,"\n "); | 1114 | len += seq_puts(m, "\n "); |
1142 | sprintf(buf, "%s %08x", buf, *res_ptr); | 1115 | len += seq_printf(m, "%08x", *res_ptr); |
1143 | res_ptr++; | 1116 | res_ptr++; |
1144 | } | 1117 | } |
1145 | strcat(buf, "\n\n"); | 1118 | len += seq_puts(m, "\n\n"); |
1146 | ioc = ioc->next; | 1119 | ioc = ioc->next; |
1147 | break; /* XXX - remove me */ | 1120 | break; /* XXX - remove me */ |
1148 | } | 1121 | } |
1149 | 1122 | ||
1150 | return strlen(buf); | 1123 | return 0; |
1151 | } | 1124 | } |
1125 | |||
1126 | static int ccio_proc_bitmap_open(struct inode *inode, struct file *file) | ||
1127 | { | ||
1128 | return single_open(file, &ccio_proc_bitmap_info, NULL); | ||
1129 | } | ||
1130 | |||
1131 | static struct file_operations ccio_proc_bitmap_fops = { | ||
1132 | .owner = THIS_MODULE, | ||
1133 | .open = ccio_proc_bitmap_open, | ||
1134 | .read = seq_read, | ||
1135 | .llseek = seq_lseek, | ||
1136 | .release = single_release, | ||
1137 | }; | ||
1152 | #endif | 1138 | #endif |
1153 | 1139 | ||
1154 | /** | 1140 | /** |
@@ -1423,7 +1409,7 @@ static void __init ccio_init_resources(struct ioc *ioc) | |||
1423 | struct resource *res = ioc->mmio_region; | 1409 | struct resource *res = ioc->mmio_region; |
1424 | char *name = kmalloc(14, GFP_KERNEL); | 1410 | char *name = kmalloc(14, GFP_KERNEL); |
1425 | 1411 | ||
1426 | sprintf(name, "GSC Bus [%d/]", ioc->hw_path); | 1412 | snprintf(name, 14, "GSC Bus [%d/]", ioc->hw_path); |
1427 | 1413 | ||
1428 | ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low); | 1414 | ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low); |
1429 | ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv); | 1415 | ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv); |
@@ -1556,13 +1542,13 @@ static int ccio_probe(struct parisc_device *dev) | |||
1556 | { | 1542 | { |
1557 | int i; | 1543 | int i; |
1558 | struct ioc *ioc, **ioc_p = &ioc_list; | 1544 | struct ioc *ioc, **ioc_p = &ioc_list; |
1545 | struct proc_dir_entry *info_entry, *bitmap_entry; | ||
1559 | 1546 | ||
1560 | ioc = kmalloc(sizeof(struct ioc), GFP_KERNEL); | 1547 | ioc = kzalloc(sizeof(struct ioc), GFP_KERNEL); |
1561 | if (ioc == NULL) { | 1548 | if (ioc == NULL) { |
1562 | printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); | 1549 | printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); |
1563 | return 1; | 1550 | return 1; |
1564 | } | 1551 | } |
1565 | memset(ioc, 0, sizeof(struct ioc)); | ||
1566 | 1552 | ||
1567 | ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn"; | 1553 | ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn"; |
1568 | 1554 | ||
@@ -1578,19 +1564,20 @@ static int ccio_probe(struct parisc_device *dev) | |||
1578 | ccio_ioc_init(ioc); | 1564 | ccio_ioc_init(ioc); |
1579 | ccio_init_resources(ioc); | 1565 | ccio_init_resources(ioc); |
1580 | hppa_dma_ops = &ccio_ops; | 1566 | hppa_dma_ops = &ccio_ops; |
1581 | dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL); | 1567 | dev->dev.platform_data = kzalloc(sizeof(struct pci_hba_data), GFP_KERNEL); |
1582 | 1568 | ||
1583 | /* if this fails, no I/O cards will work, so may as well bug */ | 1569 | /* if this fails, no I/O cards will work, so may as well bug */ |
1584 | BUG_ON(dev->dev.platform_data == NULL); | 1570 | BUG_ON(dev->dev.platform_data == NULL); |
1585 | HBA_DATA(dev->dev.platform_data)->iommu = ioc; | 1571 | HBA_DATA(dev->dev.platform_data)->iommu = ioc; |
1586 | 1572 | ||
1587 | |||
1588 | if (ioc_count == 0) { | 1573 | if (ioc_count == 0) { |
1589 | /* FIXME: Create separate entries for each ioc */ | 1574 | info_entry = create_proc_entry(MODULE_NAME, 0, proc_runway_root); |
1590 | create_proc_read_entry(MODULE_NAME, S_IRWXU, proc_runway_root, | 1575 | if (info_entry) |
1591 | ccio_proc_info, NULL); | 1576 | info_entry->proc_fops = &ccio_proc_info_fops; |
1592 | create_proc_read_entry(MODULE_NAME"-bitmap", S_IRWXU, | 1577 | |
1593 | proc_runway_root, ccio_resource_map, NULL); | 1578 | bitmap_entry = create_proc_entry(MODULE_NAME"-bitmap", 0, proc_runway_root); |
1579 | if (bitmap_entry) | ||
1580 | bitmap_entry->proc_fops = &ccio_proc_bitmap_fops; | ||
1594 | } | 1581 | } |
1595 | 1582 | ||
1596 | ioc_count++; | 1583 | ioc_count++; |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 216d1d859326..3d1a7f98c676 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -989,14 +989,12 @@ static int __init dino_probe(struct parisc_device *dev) | |||
989 | */ | 989 | */ |
990 | } | 990 | } |
991 | 991 | ||
992 | dino_dev = kmalloc(sizeof(struct dino_device), GFP_KERNEL); | 992 | dino_dev = kzalloc(sizeof(struct dino_device), GFP_KERNEL); |
993 | if (!dino_dev) { | 993 | if (!dino_dev) { |
994 | printk("dino_init_chip - couldn't alloc dino_device\n"); | 994 | printk("dino_init_chip - couldn't alloc dino_device\n"); |
995 | return 1; | 995 | return 1; |
996 | } | 996 | } |
997 | 997 | ||
998 | memset(dino_dev, 0, sizeof(struct dino_device)); | ||
999 | |||
1000 | dino_dev->hba.dev = dev; | 998 | dino_dev->hba.dev = dev; |
1001 | dino_dev->hba.base_addr = ioremap(hpa, 4096); | 999 | dino_dev->hba.base_addr = ioremap(hpa, 4096); |
1002 | dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ | 1000 | dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ |
diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index 5edf93f80757..07dc2b6d4e93 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c | |||
@@ -60,12 +60,11 @@ static int hppb_probe(struct parisc_device *dev) | |||
60 | } | 60 | } |
61 | 61 | ||
62 | if(card->hpa) { | 62 | if(card->hpa) { |
63 | card->next = kmalloc(sizeof(struct hppb_card), GFP_KERNEL); | 63 | card->next = kzalloc(sizeof(struct hppb_card), GFP_KERNEL); |
64 | if(!card->next) { | 64 | if(!card->next) { |
65 | printk(KERN_ERR "HP-PB: Unable to allocate memory.\n"); | 65 | printk(KERN_ERR "HP-PB: Unable to allocate memory.\n"); |
66 | return 1; | 66 | return 1; |
67 | } | 67 | } |
68 | memset(card->next, '\0', sizeof(struct hppb_card)); | ||
69 | card = card->next; | 68 | card = card->next; |
70 | } | 69 | } |
71 | printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start); | 70 | printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start); |
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 19657efa8dc3..8d7a36392eb8 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -873,28 +873,24 @@ void *iosapic_register(unsigned long hpa) | |||
873 | return NULL; | 873 | return NULL; |
874 | } | 874 | } |
875 | 875 | ||
876 | isi = (struct iosapic_info *)kmalloc(sizeof(struct iosapic_info), GFP_KERNEL); | 876 | isi = (struct iosapic_info *)kzalloc(sizeof(struct iosapic_info), GFP_KERNEL); |
877 | if (!isi) { | 877 | if (!isi) { |
878 | BUG(); | 878 | BUG(); |
879 | return NULL; | 879 | return NULL; |
880 | } | 880 | } |
881 | 881 | ||
882 | memset(isi, 0, sizeof(struct iosapic_info)); | ||
883 | |||
884 | isi->addr = ioremap(hpa, 4096); | 882 | isi->addr = ioremap(hpa, 4096); |
885 | isi->isi_hpa = hpa; | 883 | isi->isi_hpa = hpa; |
886 | isi->isi_version = iosapic_rd_version(isi); | 884 | isi->isi_version = iosapic_rd_version(isi); |
887 | isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; | 885 | isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; |
888 | 886 | ||
889 | vip = isi->isi_vector = (struct vector_info *) | 887 | vip = isi->isi_vector = (struct vector_info *) |
890 | kmalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL); | 888 | kzalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL); |
891 | if (vip == NULL) { | 889 | if (vip == NULL) { |
892 | kfree(isi); | 890 | kfree(isi); |
893 | return NULL; | 891 | return NULL; |
894 | } | 892 | } |
895 | 893 | ||
896 | memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors); | ||
897 | |||
898 | for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) { | 894 | for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) { |
899 | vip->irqline = (unsigned char) cnt; | 895 | vip->irqline = (unsigned char) cnt; |
900 | vip->iosapic = isi; | 896 | vip->iosapic = isi; |
diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c index 2b3ba1dcf332..cb3d28176129 100644 --- a/drivers/parisc/lasi.c +++ b/drivers/parisc/lasi.c | |||
@@ -166,11 +166,12 @@ static void lasi_power_off(void) | |||
166 | int __init | 166 | int __init |
167 | lasi_init_chip(struct parisc_device *dev) | 167 | lasi_init_chip(struct parisc_device *dev) |
168 | { | 168 | { |
169 | extern void (*chassis_power_off)(void); | ||
169 | struct gsc_asic *lasi; | 170 | struct gsc_asic *lasi; |
170 | struct gsc_irq gsc_irq; | 171 | struct gsc_irq gsc_irq; |
171 | int ret; | 172 | int ret; |
172 | 173 | ||
173 | lasi = kmalloc(sizeof(*lasi), GFP_KERNEL); | 174 | lasi = kzalloc(sizeof(*lasi), GFP_KERNEL); |
174 | if (!lasi) | 175 | if (!lasi) |
175 | return -ENOMEM; | 176 | return -ENOMEM; |
176 | 177 | ||
@@ -222,7 +223,7 @@ lasi_init_chip(struct parisc_device *dev) | |||
222 | * ensure that only the first LASI (the one controlling the power off) | 223 | * ensure that only the first LASI (the one controlling the power off) |
223 | * should set the HPA here */ | 224 | * should set the HPA here */ |
224 | lasi_power_off_hpa = lasi->hpa; | 225 | lasi_power_off_hpa = lasi->hpa; |
225 | pm_power_off = lasi_power_off; | 226 | chassis_power_off = lasi_power_off; |
226 | 227 | ||
227 | return ret; | 228 | return ret; |
228 | } | 229 | } |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index cbae8c8963fa..e8a2a4a852f5 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -1565,7 +1565,7 @@ lba_driver_probe(struct parisc_device *dev) | |||
1565 | } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { | 1565 | } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { |
1566 | func_class &= 0xff; | 1566 | func_class &= 0xff; |
1567 | version = kmalloc(6, GFP_KERNEL); | 1567 | version = kmalloc(6, GFP_KERNEL); |
1568 | sprintf(version,"TR%d.%d",(func_class >> 4),(func_class & 0xf)); | 1568 | snprintf(version, 6, "TR%d.%d",(func_class >> 4),(func_class & 0xf)); |
1569 | /* We could use one printk for both Elroy and Mercury, | 1569 | /* We could use one printk for both Elroy and Mercury, |
1570 | * but for the mask for func_class. | 1570 | * but for the mask for func_class. |
1571 | */ | 1571 | */ |
@@ -1586,14 +1586,12 @@ lba_driver_probe(struct parisc_device *dev) | |||
1586 | ** have an IRT entry will get NULL back from iosapic code. | 1586 | ** have an IRT entry will get NULL back from iosapic code. |
1587 | */ | 1587 | */ |
1588 | 1588 | ||
1589 | lba_dev = kmalloc(sizeof(struct lba_device), GFP_KERNEL); | 1589 | lba_dev = kzalloc(sizeof(struct lba_device), GFP_KERNEL); |
1590 | if (!lba_dev) { | 1590 | if (!lba_dev) { |
1591 | printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n"); | 1591 | printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n"); |
1592 | return(1); | 1592 | return(1); |
1593 | } | 1593 | } |
1594 | 1594 | ||
1595 | memset(lba_dev, 0, sizeof(struct lba_device)); | ||
1596 | |||
1597 | 1595 | ||
1598 | /* ---------- First : initialize data we already have --------- */ | 1596 | /* ---------- First : initialize data we already have --------- */ |
1599 | 1597 | ||
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 42a3c54e8e6c..a28e17898fbd 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Interfaces to retrieve and set PDC Stable options (firmware) | 2 | * Interfaces to retrieve and set PDC Stable options (firmware) |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> | 4 | * Copyright (C) 2005-2006 Thibaut VARENE <varenet@parisc-linux.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -26,11 +26,19 @@ | |||
26 | * | 26 | * |
27 | * Since locations between 96 and 192 are the various paths, most (if not | 27 | * Since locations between 96 and 192 are the various paths, most (if not |
28 | * all) PA-RISC machines should have them. Anyway, for safety reasons, the | 28 | * all) PA-RISC machines should have them. Anyway, for safety reasons, the |
29 | * following code can deal with only 96 bytes of Stable Storage, and all | 29 | * following code can deal with just 96 bytes of Stable Storage, and all |
30 | * sizes between 96 and 192 bytes (provided they are multiple of struct | 30 | * sizes between 96 and 192 bytes (provided they are multiple of struct |
31 | * device_path size, eg: 128, 160 and 192) to provide full information. | 31 | * device_path size, eg: 128, 160 and 192) to provide full information. |
32 | * The code makes no use of data above 192 bytes. One last word: there's one | 32 | * The code makes no use of data above 192 bytes. One last word: there's one |
33 | * path we can always count on: the primary path. | 33 | * path we can always count on: the primary path. |
34 | * | ||
35 | * The current policy wrt file permissions is: | ||
36 | * - write: root only | ||
37 | * - read: (reading triggers PDC calls) ? root only : everyone | ||
38 | * The rationale is that PDC calls could hog (DoS) the machine. | ||
39 | * | ||
40 | * TODO: | ||
41 | * - timer/fastsize write calls | ||
34 | */ | 42 | */ |
35 | 43 | ||
36 | #undef PDCS_DEBUG | 44 | #undef PDCS_DEBUG |
@@ -50,13 +58,15 @@ | |||
50 | #include <linux/kobject.h> | 58 | #include <linux/kobject.h> |
51 | #include <linux/device.h> | 59 | #include <linux/device.h> |
52 | #include <linux/errno.h> | 60 | #include <linux/errno.h> |
61 | #include <linux/spinlock.h> | ||
53 | 62 | ||
54 | #include <asm/pdc.h> | 63 | #include <asm/pdc.h> |
55 | #include <asm/page.h> | 64 | #include <asm/page.h> |
56 | #include <asm/uaccess.h> | 65 | #include <asm/uaccess.h> |
57 | #include <asm/hardware.h> | 66 | #include <asm/hardware.h> |
58 | 67 | ||
59 | #define PDCS_VERSION "0.10" | 68 | #define PDCS_VERSION "0.22" |
69 | #define PDCS_PREFIX "PDC Stable Storage" | ||
60 | 70 | ||
61 | #define PDCS_ADDR_PPRI 0x00 | 71 | #define PDCS_ADDR_PPRI 0x00 |
62 | #define PDCS_ADDR_OSID 0x40 | 72 | #define PDCS_ADDR_OSID 0x40 |
@@ -70,10 +80,12 @@ MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); | |||
70 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
71 | MODULE_VERSION(PDCS_VERSION); | 81 | MODULE_VERSION(PDCS_VERSION); |
72 | 82 | ||
83 | /* holds Stable Storage size. Initialized once and for all, no lock needed */ | ||
73 | static unsigned long pdcs_size __read_mostly; | 84 | static unsigned long pdcs_size __read_mostly; |
74 | 85 | ||
75 | /* This struct defines what we need to deal with a parisc pdc path entry */ | 86 | /* This struct defines what we need to deal with a parisc pdc path entry */ |
76 | struct pdcspath_entry { | 87 | struct pdcspath_entry { |
88 | rwlock_t rw_lock; /* to protect path entry access */ | ||
77 | short ready; /* entry record is valid if != 0 */ | 89 | short ready; /* entry record is valid if != 0 */ |
78 | unsigned long addr; /* entry address in stable storage */ | 90 | unsigned long addr; /* entry address in stable storage */ |
79 | char *name; /* entry name */ | 91 | char *name; /* entry name */ |
@@ -121,6 +133,8 @@ struct pdcspath_attribute paths_attr_##_name = { \ | |||
121 | * content of the stable storage WRT various paths in these structs. We read | 133 | * content of the stable storage WRT various paths in these structs. We read |
122 | * these structs when reading the files, and we will write to these structs when | 134 | * these structs when reading the files, and we will write to these structs when |
123 | * writing to the files, and only then write them back to the Stable Storage. | 135 | * writing to the files, and only then write them back to the Stable Storage. |
136 | * | ||
137 | * This function expects to be called with @entry->rw_lock write-hold. | ||
124 | */ | 138 | */ |
125 | static int | 139 | static int |
126 | pdcspath_fetch(struct pdcspath_entry *entry) | 140 | pdcspath_fetch(struct pdcspath_entry *entry) |
@@ -160,14 +174,15 @@ pdcspath_fetch(struct pdcspath_entry *entry) | |||
160 | * pointer, from which it'll find out the corresponding hardware path. | 174 | * pointer, from which it'll find out the corresponding hardware path. |
161 | * For now we do not handle the case where there's an error in writing to the | 175 | * For now we do not handle the case where there's an error in writing to the |
162 | * Stable Storage area, so you'd better not mess up the data :P | 176 | * Stable Storage area, so you'd better not mess up the data :P |
177 | * | ||
178 | * This function expects to be called with @entry->rw_lock write-hold. | ||
163 | */ | 179 | */ |
164 | static int | 180 | static void |
165 | pdcspath_store(struct pdcspath_entry *entry) | 181 | pdcspath_store(struct pdcspath_entry *entry) |
166 | { | 182 | { |
167 | struct device_path *devpath; | 183 | struct device_path *devpath; |
168 | 184 | ||
169 | if (!entry) | 185 | BUG_ON(!entry); |
170 | return -EINVAL; | ||
171 | 186 | ||
172 | devpath = &entry->devpath; | 187 | devpath = &entry->devpath; |
173 | 188 | ||
@@ -176,10 +191,8 @@ pdcspath_store(struct pdcspath_entry *entry) | |||
176 | First case, we don't have a preset hwpath... */ | 191 | First case, we don't have a preset hwpath... */ |
177 | if (!entry->ready) { | 192 | if (!entry->ready) { |
178 | /* ...but we have a device, map it */ | 193 | /* ...but we have a device, map it */ |
179 | if (entry->dev) | 194 | BUG_ON(!entry->dev); |
180 | device_to_hwpath(entry->dev, (struct hardware_path *)devpath); | 195 | device_to_hwpath(entry->dev, (struct hardware_path *)devpath); |
181 | else | ||
182 | return -EINVAL; | ||
183 | } | 196 | } |
184 | /* else, we expect the provided hwpath to be valid. */ | 197 | /* else, we expect the provided hwpath to be valid. */ |
185 | 198 | ||
@@ -191,15 +204,13 @@ pdcspath_store(struct pdcspath_entry *entry) | |||
191 | printk(KERN_ERR "%s: an error occured when writing to PDC.\n" | 204 | printk(KERN_ERR "%s: an error occured when writing to PDC.\n" |
192 | "It is likely that the Stable Storage data has been corrupted.\n" | 205 | "It is likely that the Stable Storage data has been corrupted.\n" |
193 | "Please check it carefully upon next reboot.\n", __func__); | 206 | "Please check it carefully upon next reboot.\n", __func__); |
194 | return -EIO; | 207 | WARN_ON(1); |
195 | } | 208 | } |
196 | 209 | ||
197 | /* kobject is already registered */ | 210 | /* kobject is already registered */ |
198 | entry->ready = 2; | 211 | entry->ready = 2; |
199 | 212 | ||
200 | DPRINTK("%s: device: 0x%p\n", __func__, entry->dev); | 213 | DPRINTK("%s: device: 0x%p\n", __func__, entry->dev); |
201 | |||
202 | return 0; | ||
203 | } | 214 | } |
204 | 215 | ||
205 | /** | 216 | /** |
@@ -214,14 +225,17 @@ pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf) | |||
214 | { | 225 | { |
215 | char *out = buf; | 226 | char *out = buf; |
216 | struct device_path *devpath; | 227 | struct device_path *devpath; |
217 | unsigned short i; | 228 | short i; |
218 | 229 | ||
219 | if (!entry || !buf) | 230 | if (!entry || !buf) |
220 | return -EINVAL; | 231 | return -EINVAL; |
221 | 232 | ||
233 | read_lock(&entry->rw_lock); | ||
222 | devpath = &entry->devpath; | 234 | devpath = &entry->devpath; |
235 | i = entry->ready; | ||
236 | read_unlock(&entry->rw_lock); | ||
223 | 237 | ||
224 | if (!entry->ready) | 238 | if (!i) /* entry is not ready */ |
225 | return -ENODATA; | 239 | return -ENODATA; |
226 | 240 | ||
227 | for (i = 0; i < 6; i++) { | 241 | for (i = 0; i < 6; i++) { |
@@ -242,7 +256,7 @@ pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf) | |||
242 | * | 256 | * |
243 | * We will call this function to change the current hardware path. | 257 | * We will call this function to change the current hardware path. |
244 | * Hardware paths are to be given '/'-delimited, without brackets. | 258 | * Hardware paths are to be given '/'-delimited, without brackets. |
245 | * We take care to make sure that the provided path actually maps to an existing | 259 | * We make sure that the provided path actually maps to an existing |
246 | * device, BUT nothing would prevent some foolish user to set the path to some | 260 | * device, BUT nothing would prevent some foolish user to set the path to some |
247 | * PCI bridge or even a CPU... | 261 | * PCI bridge or even a CPU... |
248 | * A better work around would be to make sure we are at the end of a device tree | 262 | * A better work around would be to make sure we are at the end of a device tree |
@@ -298,17 +312,19 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun | |||
298 | } | 312 | } |
299 | 313 | ||
300 | /* So far so good, let's get in deep */ | 314 | /* So far so good, let's get in deep */ |
315 | write_lock(&entry->rw_lock); | ||
301 | entry->ready = 0; | 316 | entry->ready = 0; |
302 | entry->dev = dev; | 317 | entry->dev = dev; |
303 | 318 | ||
304 | /* Now, dive in. Write back to the hardware */ | 319 | /* Now, dive in. Write back to the hardware */ |
305 | WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */ | 320 | pdcspath_store(entry); |
306 | 321 | ||
307 | /* Update the symlink to the real device */ | 322 | /* Update the symlink to the real device */ |
308 | sysfs_remove_link(&entry->kobj, "device"); | 323 | sysfs_remove_link(&entry->kobj, "device"); |
309 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); | 324 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); |
325 | write_unlock(&entry->rw_lock); | ||
310 | 326 | ||
311 | printk(KERN_INFO "PDC Stable Storage: changed \"%s\" path to \"%s\"\n", | 327 | printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n", |
312 | entry->name, buf); | 328 | entry->name, buf); |
313 | 329 | ||
314 | return count; | 330 | return count; |
@@ -326,14 +342,17 @@ pdcspath_layer_read(struct pdcspath_entry *entry, char *buf) | |||
326 | { | 342 | { |
327 | char *out = buf; | 343 | char *out = buf; |
328 | struct device_path *devpath; | 344 | struct device_path *devpath; |
329 | unsigned short i; | 345 | short i; |
330 | 346 | ||
331 | if (!entry || !buf) | 347 | if (!entry || !buf) |
332 | return -EINVAL; | 348 | return -EINVAL; |
333 | 349 | ||
350 | read_lock(&entry->rw_lock); | ||
334 | devpath = &entry->devpath; | 351 | devpath = &entry->devpath; |
352 | i = entry->ready; | ||
353 | read_unlock(&entry->rw_lock); | ||
335 | 354 | ||
336 | if (!entry->ready) | 355 | if (!i) /* entry is not ready */ |
337 | return -ENODATA; | 356 | return -ENODATA; |
338 | 357 | ||
339 | for (i = 0; devpath->layers[i] && (likely(i < 6)); i++) | 358 | for (i = 0; devpath->layers[i] && (likely(i < 6)); i++) |
@@ -388,15 +407,17 @@ pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count | |||
388 | } | 407 | } |
389 | 408 | ||
390 | /* So far so good, let's get in deep */ | 409 | /* So far so good, let's get in deep */ |
410 | write_lock(&entry->rw_lock); | ||
391 | 411 | ||
392 | /* First, overwrite the current layers with the new ones, not touching | 412 | /* First, overwrite the current layers with the new ones, not touching |
393 | the hardware path. */ | 413 | the hardware path. */ |
394 | memcpy(&entry->devpath.layers, &layers, sizeof(layers)); | 414 | memcpy(&entry->devpath.layers, &layers, sizeof(layers)); |
395 | 415 | ||
396 | /* Now, dive in. Write back to the hardware */ | 416 | /* Now, dive in. Write back to the hardware */ |
397 | WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */ | 417 | pdcspath_store(entry); |
418 | write_unlock(&entry->rw_lock); | ||
398 | 419 | ||
399 | printk(KERN_INFO "PDC Stable Storage: changed \"%s\" layers to \"%s\"\n", | 420 | printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" layers to \"%s\"\n", |
400 | entry->name, buf); | 421 | entry->name, buf); |
401 | 422 | ||
402 | return count; | 423 | return count; |
@@ -415,9 +436,6 @@ pdcspath_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) | |||
415 | struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr); | 436 | struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr); |
416 | ssize_t ret = 0; | 437 | ssize_t ret = 0; |
417 | 438 | ||
418 | if (!capable(CAP_SYS_ADMIN)) | ||
419 | return -EACCES; | ||
420 | |||
421 | if (pdcs_attr->show) | 439 | if (pdcs_attr->show) |
422 | ret = pdcs_attr->show(entry, buf); | 440 | ret = pdcs_attr->show(entry, buf); |
423 | 441 | ||
@@ -454,8 +472,8 @@ static struct sysfs_ops pdcspath_attr_ops = { | |||
454 | }; | 472 | }; |
455 | 473 | ||
456 | /* These are the two attributes of any PDC path. */ | 474 | /* These are the two attributes of any PDC path. */ |
457 | static PATHS_ATTR(hwpath, 0600, pdcspath_hwpath_read, pdcspath_hwpath_write); | 475 | static PATHS_ATTR(hwpath, 0644, pdcspath_hwpath_read, pdcspath_hwpath_write); |
458 | static PATHS_ATTR(layer, 0600, pdcspath_layer_read, pdcspath_layer_write); | 476 | static PATHS_ATTR(layer, 0644, pdcspath_layer_read, pdcspath_layer_write); |
459 | 477 | ||
460 | static struct attribute *paths_subsys_attrs[] = { | 478 | static struct attribute *paths_subsys_attrs[] = { |
461 | &paths_attr_hwpath.attr, | 479 | &paths_attr_hwpath.attr, |
@@ -484,36 +502,119 @@ static struct pdcspath_entry *pdcspath_entries[] = { | |||
484 | NULL, | 502 | NULL, |
485 | }; | 503 | }; |
486 | 504 | ||
505 | |||
506 | /* For more insight of what's going on here, refer to PDC Procedures doc, | ||
507 | * Section PDC_STABLE */ | ||
508 | |||
487 | /** | 509 | /** |
488 | * pdcs_info_read - Pretty printing of the remaining useful data. | 510 | * pdcs_size_read - Stable Storage size output. |
489 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | 511 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
490 | * @buf: The output buffer to write to. | 512 | * @buf: The output buffer to write to. |
491 | * | ||
492 | * We will call this function to format the output of the 'info' attribute file. | ||
493 | * Please refer to PDC Procedures documentation, section PDC_STABLE to get a | ||
494 | * better insight of what we're doing here. | ||
495 | */ | 513 | */ |
496 | static ssize_t | 514 | static ssize_t |
497 | pdcs_info_read(struct subsystem *entry, char *buf) | 515 | pdcs_size_read(struct subsystem *entry, char *buf) |
498 | { | 516 | { |
499 | char *out = buf; | 517 | char *out = buf; |
500 | __u32 result; | ||
501 | struct device_path devpath; | ||
502 | char *tmpstr = NULL; | ||
503 | 518 | ||
504 | if (!entry || !buf) | 519 | if (!entry || !buf) |
505 | return -EINVAL; | 520 | return -EINVAL; |
506 | 521 | ||
507 | /* show the size of the stable storage */ | 522 | /* show the size of the stable storage */ |
508 | out += sprintf(out, "Stable Storage size: %ld bytes\n", pdcs_size); | 523 | out += sprintf(out, "%ld\n", pdcs_size); |
509 | 524 | ||
510 | /* deal with flags */ | 525 | return out - buf; |
511 | if (pdc_stable_read(PDCS_ADDR_PPRI, &devpath, sizeof(devpath)) != PDC_OK) | 526 | } |
512 | return -EIO; | 527 | |
528 | /** | ||
529 | * pdcs_auto_read - Stable Storage autoboot/search flag output. | ||
530 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
531 | * @buf: The output buffer to write to. | ||
532 | * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag | ||
533 | */ | ||
534 | static ssize_t | ||
535 | pdcs_auto_read(struct subsystem *entry, char *buf, int knob) | ||
536 | { | ||
537 | char *out = buf; | ||
538 | struct pdcspath_entry *pathentry; | ||
513 | 539 | ||
514 | out += sprintf(out, "Autoboot: %s\n", (devpath.flags & PF_AUTOBOOT) ? "On" : "Off"); | 540 | if (!entry || !buf) |
515 | out += sprintf(out, "Autosearch: %s\n", (devpath.flags & PF_AUTOSEARCH) ? "On" : "Off"); | 541 | return -EINVAL; |
516 | out += sprintf(out, "Timer: %u s\n", (devpath.flags & PF_TIMER) ? (1 << (devpath.flags & PF_TIMER)) : 0); | 542 | |
543 | /* Current flags are stored in primary boot path entry */ | ||
544 | pathentry = &pdcspath_entry_primary; | ||
545 | |||
546 | read_lock(&pathentry->rw_lock); | ||
547 | out += sprintf(out, "%s\n", (pathentry->devpath.flags & knob) ? | ||
548 | "On" : "Off"); | ||
549 | read_unlock(&pathentry->rw_lock); | ||
550 | |||
551 | return out - buf; | ||
552 | } | ||
553 | |||
554 | /** | ||
555 | * pdcs_autoboot_read - Stable Storage autoboot flag output. | ||
556 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
557 | * @buf: The output buffer to write to. | ||
558 | */ | ||
559 | static inline ssize_t | ||
560 | pdcs_autoboot_read(struct subsystem *entry, char *buf) | ||
561 | { | ||
562 | return pdcs_auto_read(entry, buf, PF_AUTOBOOT); | ||
563 | } | ||
564 | |||
565 | /** | ||
566 | * pdcs_autosearch_read - Stable Storage autoboot flag output. | ||
567 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
568 | * @buf: The output buffer to write to. | ||
569 | */ | ||
570 | static inline ssize_t | ||
571 | pdcs_autosearch_read(struct subsystem *entry, char *buf) | ||
572 | { | ||
573 | return pdcs_auto_read(entry, buf, PF_AUTOSEARCH); | ||
574 | } | ||
575 | |||
576 | /** | ||
577 | * pdcs_timer_read - Stable Storage timer count output (in seconds). | ||
578 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
579 | * @buf: The output buffer to write to. | ||
580 | * | ||
581 | * The value of the timer field correponds to a number of seconds in powers of 2. | ||
582 | */ | ||
583 | static ssize_t | ||
584 | pdcs_timer_read(struct subsystem *entry, char *buf) | ||
585 | { | ||
586 | char *out = buf; | ||
587 | struct pdcspath_entry *pathentry; | ||
588 | |||
589 | if (!entry || !buf) | ||
590 | return -EINVAL; | ||
591 | |||
592 | /* Current flags are stored in primary boot path entry */ | ||
593 | pathentry = &pdcspath_entry_primary; | ||
594 | |||
595 | /* print the timer value in seconds */ | ||
596 | read_lock(&pathentry->rw_lock); | ||
597 | out += sprintf(out, "%u\n", (pathentry->devpath.flags & PF_TIMER) ? | ||
598 | (1 << (pathentry->devpath.flags & PF_TIMER)) : 0); | ||
599 | read_unlock(&pathentry->rw_lock); | ||
600 | |||
601 | return out - buf; | ||
602 | } | ||
603 | |||
604 | /** | ||
605 | * pdcs_osid_read - Stable Storage OS ID register output. | ||
606 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
607 | * @buf: The output buffer to write to. | ||
608 | */ | ||
609 | static ssize_t | ||
610 | pdcs_osid_read(struct subsystem *entry, char *buf) | ||
611 | { | ||
612 | char *out = buf; | ||
613 | __u32 result; | ||
614 | char *tmpstr = NULL; | ||
615 | |||
616 | if (!entry || !buf) | ||
617 | return -EINVAL; | ||
517 | 618 | ||
518 | /* get OSID */ | 619 | /* get OSID */ |
519 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) | 620 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) |
@@ -529,13 +630,31 @@ pdcs_info_read(struct subsystem *entry, char *buf) | |||
529 | case 0x0005: tmpstr = "Novell Netware dependent data"; break; | 630 | case 0x0005: tmpstr = "Novell Netware dependent data"; break; |
530 | default: tmpstr = "Unknown"; break; | 631 | default: tmpstr = "Unknown"; break; |
531 | } | 632 | } |
532 | out += sprintf(out, "OS ID: %s (0x%.4x)\n", tmpstr, (result >> 16)); | 633 | out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16)); |
634 | |||
635 | return out - buf; | ||
636 | } | ||
637 | |||
638 | /** | ||
639 | * pdcs_fastsize_read - Stable Storage FastSize register output. | ||
640 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
641 | * @buf: The output buffer to write to. | ||
642 | * | ||
643 | * This register holds the amount of system RAM to be tested during boot sequence. | ||
644 | */ | ||
645 | static ssize_t | ||
646 | pdcs_fastsize_read(struct subsystem *entry, char *buf) | ||
647 | { | ||
648 | char *out = buf; | ||
649 | __u32 result; | ||
650 | |||
651 | if (!entry || !buf) | ||
652 | return -EINVAL; | ||
533 | 653 | ||
534 | /* get fast-size */ | 654 | /* get fast-size */ |
535 | if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK) | 655 | if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK) |
536 | return -EIO; | 656 | return -EIO; |
537 | 657 | ||
538 | out += sprintf(out, "Memory tested: "); | ||
539 | if ((result & 0x0F) < 0x0E) | 658 | if ((result & 0x0F) < 0x0E) |
540 | out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256); | 659 | out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256); |
541 | else | 660 | else |
@@ -546,22 +665,18 @@ pdcs_info_read(struct subsystem *entry, char *buf) | |||
546 | } | 665 | } |
547 | 666 | ||
548 | /** | 667 | /** |
549 | * pdcs_info_write - This function handles boot flag modifying. | 668 | * pdcs_auto_write - This function handles autoboot/search flag modifying. |
550 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | 669 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
551 | * @buf: The input buffer to read from. | 670 | * @buf: The input buffer to read from. |
552 | * @count: The number of bytes to be read. | 671 | * @count: The number of bytes to be read. |
672 | * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag | ||
553 | * | 673 | * |
554 | * We will call this function to change the current boot flags. | 674 | * We will call this function to change the current autoboot flag. |
555 | * We expect a precise syntax: | 675 | * We expect a precise syntax: |
556 | * \"n n\" (n == 0 or 1) to toggle respectively AutoBoot and AutoSearch | 676 | * \"n\" (n == 0 or 1) to toggle AutoBoot Off or On |
557 | * | ||
558 | * As of now there is no incentive on my side to provide more "knobs" to that | ||
559 | * interface, since modifying the rest of the data is pretty meaningless when | ||
560 | * the machine is running and for the expected use of that facility, such as | ||
561 | * PALO setting up the boot disk when installing a Linux distribution... | ||
562 | */ | 677 | */ |
563 | static ssize_t | 678 | static ssize_t |
564 | pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) | 679 | pdcs_auto_write(struct subsystem *entry, const char *buf, size_t count, int knob) |
565 | { | 680 | { |
566 | struct pdcspath_entry *pathentry; | 681 | struct pdcspath_entry *pathentry; |
567 | unsigned char flags; | 682 | unsigned char flags; |
@@ -582,7 +697,9 @@ pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) | |||
582 | pathentry = &pdcspath_entry_primary; | 697 | pathentry = &pdcspath_entry_primary; |
583 | 698 | ||
584 | /* Be nice to the existing flag record */ | 699 | /* Be nice to the existing flag record */ |
700 | read_lock(&pathentry->rw_lock); | ||
585 | flags = pathentry->devpath.flags; | 701 | flags = pathentry->devpath.flags; |
702 | read_unlock(&pathentry->rw_lock); | ||
586 | 703 | ||
587 | DPRINTK("%s: flags before: 0x%X\n", __func__, flags); | 704 | DPRINTK("%s: flags before: 0x%X\n", __func__, flags); |
588 | 705 | ||
@@ -595,50 +712,85 @@ pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) | |||
595 | if ((c != 0) && (c != 1)) | 712 | if ((c != 0) && (c != 1)) |
596 | goto parse_error; | 713 | goto parse_error; |
597 | if (c == 0) | 714 | if (c == 0) |
598 | flags &= ~PF_AUTOBOOT; | 715 | flags &= ~knob; |
599 | else | 716 | else |
600 | flags |= PF_AUTOBOOT; | 717 | flags |= knob; |
601 | |||
602 | if (*temp++ != ' ') | ||
603 | goto parse_error; | ||
604 | |||
605 | c = *temp++ - '0'; | ||
606 | if ((c != 0) && (c != 1)) | ||
607 | goto parse_error; | ||
608 | if (c == 0) | ||
609 | flags &= ~PF_AUTOSEARCH; | ||
610 | else | ||
611 | flags |= PF_AUTOSEARCH; | ||
612 | 718 | ||
613 | DPRINTK("%s: flags after: 0x%X\n", __func__, flags); | 719 | DPRINTK("%s: flags after: 0x%X\n", __func__, flags); |
614 | 720 | ||
615 | /* So far so good, let's get in deep */ | 721 | /* So far so good, let's get in deep */ |
722 | write_lock(&pathentry->rw_lock); | ||
616 | 723 | ||
617 | /* Change the path entry flags first */ | 724 | /* Change the path entry flags first */ |
618 | pathentry->devpath.flags = flags; | 725 | pathentry->devpath.flags = flags; |
619 | 726 | ||
620 | /* Now, dive in. Write back to the hardware */ | 727 | /* Now, dive in. Write back to the hardware */ |
621 | WARN_ON(pdcspath_store(pathentry)); /* this warn should *NEVER* happen */ | 728 | pdcspath_store(pathentry); |
729 | write_unlock(&pathentry->rw_lock); | ||
622 | 730 | ||
623 | printk(KERN_INFO "PDC Stable Storage: changed flags to \"%s\"\n", buf); | 731 | printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" to \"%s\"\n", |
732 | (knob & PF_AUTOBOOT) ? "autoboot" : "autosearch", | ||
733 | (flags & knob) ? "On" : "Off"); | ||
624 | 734 | ||
625 | return count; | 735 | return count; |
626 | 736 | ||
627 | parse_error: | 737 | parse_error: |
628 | printk(KERN_WARNING "%s: Parse error: expect \"n n\" (n == 0 or 1) for AB and AS\n", __func__); | 738 | printk(KERN_WARNING "%s: Parse error: expect \"n\" (n == 0 or 1)\n", __func__); |
629 | return -EINVAL; | 739 | return -EINVAL; |
630 | } | 740 | } |
631 | 741 | ||
632 | /* The last attribute (the 'root' one actually) with all remaining data. */ | 742 | /** |
633 | static PDCS_ATTR(info, 0600, pdcs_info_read, pdcs_info_write); | 743 | * pdcs_autoboot_write - This function handles autoboot flag modifying. |
744 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
745 | * @buf: The input buffer to read from. | ||
746 | * @count: The number of bytes to be read. | ||
747 | * | ||
748 | * We will call this function to change the current boot flags. | ||
749 | * We expect a precise syntax: | ||
750 | * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On | ||
751 | */ | ||
752 | static inline ssize_t | ||
753 | pdcs_autoboot_write(struct subsystem *entry, const char *buf, size_t count) | ||
754 | { | ||
755 | return pdcs_auto_write(entry, buf, count, PF_AUTOBOOT); | ||
756 | } | ||
757 | |||
758 | /** | ||
759 | * pdcs_autosearch_write - This function handles autosearch flag modifying. | ||
760 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
761 | * @buf: The input buffer to read from. | ||
762 | * @count: The number of bytes to be read. | ||
763 | * | ||
764 | * We will call this function to change the current boot flags. | ||
765 | * We expect a precise syntax: | ||
766 | * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On | ||
767 | */ | ||
768 | static inline ssize_t | ||
769 | pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count) | ||
770 | { | ||
771 | return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH); | ||
772 | } | ||
773 | |||
774 | /* The remaining attributes. */ | ||
775 | static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); | ||
776 | static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); | ||
777 | static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); | ||
778 | static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); | ||
779 | static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL); | ||
780 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); | ||
634 | 781 | ||
635 | static struct subsys_attribute *pdcs_subsys_attrs[] = { | 782 | static struct subsys_attribute *pdcs_subsys_attrs[] = { |
636 | &pdcs_attr_info, | 783 | &pdcs_attr_size, |
637 | NULL, /* maybe more in the future? */ | 784 | &pdcs_attr_autoboot, |
785 | &pdcs_attr_autosearch, | ||
786 | &pdcs_attr_timer, | ||
787 | &pdcs_attr_osid, | ||
788 | &pdcs_attr_fastsize, | ||
789 | NULL, | ||
638 | }; | 790 | }; |
639 | 791 | ||
640 | static decl_subsys(paths, &ktype_pdcspath, NULL); | 792 | static decl_subsys(paths, &ktype_pdcspath, NULL); |
641 | static decl_subsys(pdc, NULL, NULL); | 793 | static decl_subsys(stable, NULL, NULL); |
642 | 794 | ||
643 | /** | 795 | /** |
644 | * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage. | 796 | * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage. |
@@ -656,8 +808,16 @@ pdcs_register_pathentries(void) | |||
656 | struct pdcspath_entry *entry; | 808 | struct pdcspath_entry *entry; |
657 | int err; | 809 | int err; |
658 | 810 | ||
811 | /* Initialize the entries rw_lock before anything else */ | ||
812 | for (i = 0; (entry = pdcspath_entries[i]); i++) | ||
813 | rwlock_init(&entry->rw_lock); | ||
814 | |||
659 | for (i = 0; (entry = pdcspath_entries[i]); i++) { | 815 | for (i = 0; (entry = pdcspath_entries[i]); i++) { |
660 | if (pdcspath_fetch(entry) < 0) | 816 | write_lock(&entry->rw_lock); |
817 | err = pdcspath_fetch(entry); | ||
818 | write_unlock(&entry->rw_lock); | ||
819 | |||
820 | if (err < 0) | ||
661 | continue; | 821 | continue; |
662 | 822 | ||
663 | if ((err = kobject_set_name(&entry->kobj, "%s", entry->name))) | 823 | if ((err = kobject_set_name(&entry->kobj, "%s", entry->name))) |
@@ -667,13 +827,14 @@ pdcs_register_pathentries(void) | |||
667 | return err; | 827 | return err; |
668 | 828 | ||
669 | /* kobject is now registered */ | 829 | /* kobject is now registered */ |
830 | write_lock(&entry->rw_lock); | ||
670 | entry->ready = 2; | 831 | entry->ready = 2; |
671 | 832 | ||
672 | if (!entry->dev) | ||
673 | continue; | ||
674 | |||
675 | /* Add a nice symlink to the real device */ | 833 | /* Add a nice symlink to the real device */ |
676 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); | 834 | if (entry->dev) |
835 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); | ||
836 | |||
837 | write_unlock(&entry->rw_lock); | ||
677 | } | 838 | } |
678 | 839 | ||
679 | return 0; | 840 | return 0; |
@@ -688,14 +849,17 @@ pdcs_unregister_pathentries(void) | |||
688 | unsigned short i; | 849 | unsigned short i; |
689 | struct pdcspath_entry *entry; | 850 | struct pdcspath_entry *entry; |
690 | 851 | ||
691 | for (i = 0; (entry = pdcspath_entries[i]); i++) | 852 | for (i = 0; (entry = pdcspath_entries[i]); i++) { |
853 | read_lock(&entry->rw_lock); | ||
692 | if (entry->ready >= 2) | 854 | if (entry->ready >= 2) |
693 | kobject_unregister(&entry->kobj); | 855 | kobject_unregister(&entry->kobj); |
856 | read_unlock(&entry->rw_lock); | ||
857 | } | ||
694 | } | 858 | } |
695 | 859 | ||
696 | /* | 860 | /* |
697 | * For now we register the pdc subsystem with the firmware subsystem | 861 | * For now we register the stable subsystem with the firmware subsystem |
698 | * and the paths subsystem with the pdc subsystem | 862 | * and the paths subsystem with the stable subsystem |
699 | */ | 863 | */ |
700 | static int __init | 864 | static int __init |
701 | pdc_stable_init(void) | 865 | pdc_stable_init(void) |
@@ -707,19 +871,23 @@ pdc_stable_init(void) | |||
707 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) | 871 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) |
708 | return -ENODEV; | 872 | return -ENODEV; |
709 | 873 | ||
710 | printk(KERN_INFO "PDC Stable Storage facility v%s\n", PDCS_VERSION); | 874 | /* make sure we have enough data */ |
875 | if (pdcs_size < 96) | ||
876 | return -ENODATA; | ||
877 | |||
878 | printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION); | ||
711 | 879 | ||
712 | /* For now we'll register the pdc subsys within this driver */ | 880 | /* For now we'll register the stable subsys within this driver */ |
713 | if ((rc = firmware_register(&pdc_subsys))) | 881 | if ((rc = firmware_register(&stable_subsys))) |
714 | goto fail_firmreg; | 882 | goto fail_firmreg; |
715 | 883 | ||
716 | /* Don't forget the info entry */ | 884 | /* Don't forget the root entries */ |
717 | for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++) | 885 | for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++) |
718 | if (attr->show) | 886 | if (attr->show) |
719 | error = subsys_create_file(&pdc_subsys, attr); | 887 | error = subsys_create_file(&stable_subsys, attr); |
720 | 888 | ||
721 | /* register the paths subsys as a subsystem of pdc subsys */ | 889 | /* register the paths subsys as a subsystem of stable subsys */ |
722 | kset_set_kset_s(&paths_subsys, pdc_subsys); | 890 | kset_set_kset_s(&paths_subsys, stable_subsys); |
723 | if ((rc= subsystem_register(&paths_subsys))) | 891 | if ((rc= subsystem_register(&paths_subsys))) |
724 | goto fail_subsysreg; | 892 | goto fail_subsysreg; |
725 | 893 | ||
@@ -734,10 +902,10 @@ fail_pdcsreg: | |||
734 | subsystem_unregister(&paths_subsys); | 902 | subsystem_unregister(&paths_subsys); |
735 | 903 | ||
736 | fail_subsysreg: | 904 | fail_subsysreg: |
737 | firmware_unregister(&pdc_subsys); | 905 | firmware_unregister(&stable_subsys); |
738 | 906 | ||
739 | fail_firmreg: | 907 | fail_firmreg: |
740 | printk(KERN_INFO "PDC Stable Storage bailing out\n"); | 908 | printk(KERN_INFO PDCS_PREFIX " bailing out\n"); |
741 | return rc; | 909 | return rc; |
742 | } | 910 | } |
743 | 911 | ||
@@ -747,7 +915,7 @@ pdc_stable_exit(void) | |||
747 | pdcs_unregister_pathentries(); | 915 | pdcs_unregister_pathentries(); |
748 | subsystem_unregister(&paths_subsys); | 916 | subsystem_unregister(&paths_subsys); |
749 | 917 | ||
750 | firmware_unregister(&pdc_subsys); | 918 | firmware_unregister(&stable_subsys); |
751 | } | 919 | } |
752 | 920 | ||
753 | 921 | ||
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index c85653f315aa..5d47c5965c51 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <asm/hardware.h> /* for register_parisc_driver() stuff */ | 37 | #include <asm/hardware.h> /* for register_parisc_driver() stuff */ |
38 | 38 | ||
39 | #include <linux/proc_fs.h> | 39 | #include <linux/proc_fs.h> |
40 | #include <linux/seq_file.h> | ||
41 | |||
40 | #include <asm/runway.h> /* for proc_runway_root */ | 42 | #include <asm/runway.h> /* for proc_runway_root */ |
41 | #include <asm/pdc.h> /* for PDC_MODEL_* */ | 43 | #include <asm/pdc.h> /* for PDC_MODEL_* */ |
42 | #include <asm/pdcpat.h> /* for is_pdc_pat() */ | 44 | #include <asm/pdcpat.h> /* for is_pdc_pat() */ |
@@ -1892,46 +1894,43 @@ sba_common_init(struct sba_device *sba_dev) | |||
1892 | } | 1894 | } |
1893 | 1895 | ||
1894 | #ifdef CONFIG_PROC_FS | 1896 | #ifdef CONFIG_PROC_FS |
1895 | static int sba_proc_info(char *buf, char **start, off_t offset, int len) | 1897 | static int sba_proc_info(struct seq_file *m, void *p) |
1896 | { | 1898 | { |
1897 | struct sba_device *sba_dev = sba_list; | 1899 | struct sba_device *sba_dev = sba_list; |
1898 | struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Multi-IOC support! */ | 1900 | struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Multi-IOC support! */ |
1899 | int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */ | 1901 | int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */ |
1900 | unsigned long i; | ||
1901 | #ifdef SBA_COLLECT_STATS | 1902 | #ifdef SBA_COLLECT_STATS |
1902 | unsigned long avg = 0, min, max; | 1903 | unsigned long avg = 0, min, max; |
1903 | #endif | 1904 | #endif |
1905 | int i, len = 0; | ||
1904 | 1906 | ||
1905 | sprintf(buf, "%s rev %d.%d\n", | 1907 | len += seq_printf(m, "%s rev %d.%d\n", |
1906 | sba_dev->name, | 1908 | sba_dev->name, |
1907 | (sba_dev->hw_rev & 0x7) + 1, | 1909 | (sba_dev->hw_rev & 0x7) + 1, |
1908 | (sba_dev->hw_rev & 0x18) >> 3 | 1910 | (sba_dev->hw_rev & 0x18) >> 3 |
1909 | ); | 1911 | ); |
1910 | sprintf(buf, "%sIO PDIR size : %d bytes (%d entries)\n", | 1912 | len += seq_printf(m, "IO PDIR size : %d bytes (%d entries)\n", |
1911 | buf, | ||
1912 | (int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */ | 1913 | (int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */ |
1913 | total_pages); | 1914 | total_pages); |
1914 | 1915 | ||
1915 | sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", | 1916 | len += seq_printf(m, "Resource bitmap : %d bytes (%d pages)\n", |
1916 | buf, ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */ | 1917 | ioc->res_size, ioc->res_size << 3); /* 8 bits per byte */ |
1917 | 1918 | ||
1918 | sprintf(buf, "%sLMMIO_BASE/MASK/ROUTE %08x %08x %08x\n", | 1919 | len += seq_printf(m, "LMMIO_BASE/MASK/ROUTE %08x %08x %08x\n", |
1919 | buf, | ||
1920 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_BASE), | 1920 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_BASE), |
1921 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_MASK), | 1921 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_MASK), |
1922 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_ROUTE) | 1922 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIST_ROUTE) |
1923 | ); | 1923 | ); |
1924 | 1924 | ||
1925 | for (i=0; i<4; i++) | 1925 | for (i=0; i<4; i++) |
1926 | sprintf(buf, "%sDIR%ld_BASE/MASK/ROUTE %08x %08x %08x\n", | 1926 | len += seq_printf(m, "DIR%d_BASE/MASK/ROUTE %08x %08x %08x\n", i, |
1927 | buf, i, | ||
1928 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_BASE + i*0x18), | 1927 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_BASE + i*0x18), |
1929 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_MASK + i*0x18), | 1928 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_MASK + i*0x18), |
1930 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_ROUTE + i*0x18) | 1929 | READ_REG32(sba_dev->sba_hpa + LMMIO_DIRECT0_ROUTE + i*0x18) |
1931 | ); | 1930 | ); |
1932 | 1931 | ||
1933 | #ifdef SBA_COLLECT_STATS | 1932 | #ifdef SBA_COLLECT_STATS |
1934 | sprintf(buf, "%sIO PDIR entries : %ld free %ld used (%d%%)\n", buf, | 1933 | len += seq_printf(m, "IO PDIR entries : %ld free %ld used (%d%%)\n", |
1935 | total_pages - ioc->used_pages, ioc->used_pages, | 1934 | total_pages - ioc->used_pages, ioc->used_pages, |
1936 | (int) (ioc->used_pages * 100 / total_pages)); | 1935 | (int) (ioc->used_pages * 100 / total_pages)); |
1937 | 1936 | ||
@@ -1942,53 +1941,76 @@ static int sba_proc_info(char *buf, char **start, off_t offset, int len) | |||
1942 | if (ioc->avg_search[i] < min) min = ioc->avg_search[i]; | 1941 | if (ioc->avg_search[i] < min) min = ioc->avg_search[i]; |
1943 | } | 1942 | } |
1944 | avg /= SBA_SEARCH_SAMPLE; | 1943 | avg /= SBA_SEARCH_SAMPLE; |
1945 | sprintf(buf, "%s Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", | 1944 | len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", |
1946 | buf, min, avg, max); | 1945 | min, avg, max); |
1947 | 1946 | ||
1948 | sprintf(buf, "%spci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", | 1947 | len += seq_printf(m, "pci_map_single(): %12ld calls %12ld pages (avg %d/1000)\n", |
1949 | buf, ioc->msingle_calls, ioc->msingle_pages, | 1948 | ioc->msingle_calls, ioc->msingle_pages, |
1950 | (int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls)); | 1949 | (int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls)); |
1951 | 1950 | ||
1952 | /* KLUGE - unmap_sg calls unmap_single for each mapped page */ | 1951 | /* KLUGE - unmap_sg calls unmap_single for each mapped page */ |
1953 | min = ioc->usingle_calls; | 1952 | min = ioc->usingle_calls; |
1954 | max = ioc->usingle_pages - ioc->usg_pages; | 1953 | max = ioc->usingle_pages - ioc->usg_pages; |
1955 | sprintf(buf, "%spci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", | 1954 | len += seq_printf(m, "pci_unmap_single: %12ld calls %12ld pages (avg %d/1000)\n", |
1956 | buf, min, max, | 1955 | min, max, (int) ((max * 1000)/min)); |
1957 | (int) ((max * 1000)/min)); | ||
1958 | 1956 | ||
1959 | sprintf(buf, "%spci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", | 1957 | len += seq_printf(m, "pci_map_sg() : %12ld calls %12ld pages (avg %d/1000)\n", |
1960 | buf, ioc->msg_calls, ioc->msg_pages, | 1958 | ioc->msg_calls, ioc->msg_pages, |
1961 | (int) ((ioc->msg_pages * 1000)/ioc->msg_calls)); | 1959 | (int) ((ioc->msg_pages * 1000)/ioc->msg_calls)); |
1962 | 1960 | ||
1963 | sprintf(buf, "%spci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", | 1961 | len += seq_printf(m, "pci_unmap_sg() : %12ld calls %12ld pages (avg %d/1000)\n", |
1964 | buf, ioc->usg_calls, ioc->usg_pages, | 1962 | ioc->usg_calls, ioc->usg_pages, |
1965 | (int) ((ioc->usg_pages * 1000)/ioc->usg_calls)); | 1963 | (int) ((ioc->usg_pages * 1000)/ioc->usg_calls)); |
1966 | #endif | 1964 | #endif |
1967 | 1965 | ||
1968 | return strlen(buf); | 1966 | return 0; |
1969 | } | 1967 | } |
1970 | 1968 | ||
1971 | #if 0 | ||
1972 | /* XXX too much output - exceeds 4k limit and needs to be re-written */ | ||
1973 | static int | 1969 | static int |
1974 | sba_resource_map(char *buf, char **start, off_t offset, int len) | 1970 | sba_proc_open(struct inode *i, struct file *f) |
1971 | { | ||
1972 | return single_open(f, &sba_proc_info, NULL); | ||
1973 | } | ||
1974 | |||
1975 | static struct file_operations sba_proc_fops = { | ||
1976 | .owner = THIS_MODULE, | ||
1977 | .open = sba_proc_open, | ||
1978 | .read = seq_read, | ||
1979 | .llseek = seq_lseek, | ||
1980 | .release = single_release, | ||
1981 | }; | ||
1982 | |||
1983 | static int | ||
1984 | sba_proc_bitmap_info(struct seq_file *m, void *p) | ||
1975 | { | 1985 | { |
1976 | struct sba_device *sba_dev = sba_list; | 1986 | struct sba_device *sba_dev = sba_list; |
1977 | struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Mutli-IOC suppoer! */ | 1987 | struct ioc *ioc = &sba_dev->ioc[0]; /* FIXME: Multi-IOC support! */ |
1978 | unsigned int *res_ptr = (unsigned int *)ioc->res_map; | 1988 | unsigned int *res_ptr = (unsigned int *)ioc->res_map; |
1979 | int i; | 1989 | int i, len = 0; |
1980 | 1990 | ||
1981 | buf[0] = '\0'; | 1991 | for (i = 0; i < (ioc->res_size/sizeof(unsigned int)); ++i, ++res_ptr) { |
1982 | for(i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) { | ||
1983 | if ((i & 7) == 0) | 1992 | if ((i & 7) == 0) |
1984 | strcat(buf,"\n "); | 1993 | len += seq_printf(m, "\n "); |
1985 | sprintf(buf, "%s %08x", buf, *res_ptr); | 1994 | len += seq_printf(m, " %08x", *res_ptr); |
1986 | } | 1995 | } |
1987 | strcat(buf, "\n"); | 1996 | len += seq_printf(m, "\n"); |
1988 | 1997 | ||
1989 | return strlen(buf); | 1998 | return 0; |
1990 | } | 1999 | } |
1991 | #endif /* 0 */ | 2000 | |
2001 | static int | ||
2002 | sba_proc_bitmap_open(struct inode *i, struct file *f) | ||
2003 | { | ||
2004 | return single_open(f, &sba_proc_bitmap_info, NULL); | ||
2005 | } | ||
2006 | |||
2007 | static struct file_operations sba_proc_bitmap_fops = { | ||
2008 | .owner = THIS_MODULE, | ||
2009 | .open = sba_proc_bitmap_open, | ||
2010 | .read = seq_read, | ||
2011 | .llseek = seq_lseek, | ||
2012 | .release = single_release, | ||
2013 | }; | ||
1992 | #endif /* CONFIG_PROC_FS */ | 2014 | #endif /* CONFIG_PROC_FS */ |
1993 | 2015 | ||
1994 | static struct parisc_device_id sba_tbl[] = { | 2016 | static struct parisc_device_id sba_tbl[] = { |
@@ -2021,6 +2043,7 @@ sba_driver_callback(struct parisc_device *dev) | |||
2021 | int i; | 2043 | int i; |
2022 | char *version; | 2044 | char *version; |
2023 | void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); | 2045 | void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); |
2046 | struct proc_dir_entry *info_entry, *bitmap_entry, *root; | ||
2024 | 2047 | ||
2025 | sba_dump_ranges(sba_addr); | 2048 | sba_dump_ranges(sba_addr); |
2026 | 2049 | ||
@@ -2064,14 +2087,13 @@ sba_driver_callback(struct parisc_device *dev) | |||
2064 | printk(KERN_INFO "%s found %s at 0x%lx\n", | 2087 | printk(KERN_INFO "%s found %s at 0x%lx\n", |
2065 | MODULE_NAME, version, dev->hpa.start); | 2088 | MODULE_NAME, version, dev->hpa.start); |
2066 | 2089 | ||
2067 | sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL); | 2090 | sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL); |
2068 | if (!sba_dev) { | 2091 | if (!sba_dev) { |
2069 | printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n"); | 2092 | printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n"); |
2070 | return -ENOMEM; | 2093 | return -ENOMEM; |
2071 | } | 2094 | } |
2072 | 2095 | ||
2073 | parisc_set_drvdata(dev, sba_dev); | 2096 | parisc_set_drvdata(dev, sba_dev); |
2074 | memset(sba_dev, 0, sizeof(struct sba_device)); | ||
2075 | 2097 | ||
2076 | for(i=0; i<MAX_IOC; i++) | 2098 | for(i=0; i<MAX_IOC; i++) |
2077 | spin_lock_init(&(sba_dev->ioc[i].res_lock)); | 2099 | spin_lock_init(&(sba_dev->ioc[i].res_lock)); |
@@ -2089,19 +2111,27 @@ sba_driver_callback(struct parisc_device *dev) | |||
2089 | hppa_dma_ops = &sba_ops; | 2111 | hppa_dma_ops = &sba_ops; |
2090 | 2112 | ||
2091 | #ifdef CONFIG_PROC_FS | 2113 | #ifdef CONFIG_PROC_FS |
2092 | if (IS_ASTRO(&dev->id)) { | 2114 | switch (dev->id.hversion) { |
2093 | create_proc_info_entry("Astro", 0, proc_runway_root, sba_proc_info); | 2115 | case PLUTO_MCKINLEY_PORT: |
2094 | } else if (IS_IKE(&dev->id)) { | 2116 | root = proc_mckinley_root; |
2095 | create_proc_info_entry("Ike", 0, proc_runway_root, sba_proc_info); | 2117 | break; |
2096 | } else if (IS_PLUTO(&dev->id)) { | 2118 | case ASTRO_RUNWAY_PORT: |
2097 | create_proc_info_entry("Pluto", 0, proc_mckinley_root, sba_proc_info); | 2119 | case IKE_MERCED_PORT: |
2098 | } else { | 2120 | default: |
2099 | create_proc_info_entry("Reo", 0, proc_runway_root, sba_proc_info); | 2121 | root = proc_runway_root; |
2122 | break; | ||
2100 | } | 2123 | } |
2101 | #if 0 | 2124 | |
2102 | create_proc_info_entry("bitmap", 0, proc_runway_root, sba_resource_map); | 2125 | info_entry = create_proc_entry("sba_iommu", 0, root); |
2103 | #endif | 2126 | bitmap_entry = create_proc_entry("sba_iommu-bitmap", 0, root); |
2127 | |||
2128 | if (info_entry) | ||
2129 | info_entry->proc_fops = &sba_proc_fops; | ||
2130 | |||
2131 | if (bitmap_entry) | ||
2132 | bitmap_entry->proc_fops = &sba_proc_bitmap_fops; | ||
2104 | #endif | 2133 | #endif |
2134 | |||
2105 | parisc_vmerge_boundary = IOVP_SIZE; | 2135 | parisc_vmerge_boundary = IOVP_SIZE; |
2106 | parisc_vmerge_max_size = IOVP_SIZE * BITS_PER_LONG; | 2136 | parisc_vmerge_max_size = IOVP_SIZE * BITS_PER_LONG; |
2107 | parisc_has_iommu(); | 2137 | parisc_has_iommu(); |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index d14888e149bb..ba971fecd0d8 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -89,6 +89,9 @@ static struct superio_device sio_dev; | |||
89 | #define DBG_INIT(x...) | 89 | #define DBG_INIT(x...) |
90 | #endif | 90 | #endif |
91 | 91 | ||
92 | #define SUPERIO "SuperIO" | ||
93 | #define PFX SUPERIO ": " | ||
94 | |||
92 | static irqreturn_t | 95 | static irqreturn_t |
93 | superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) | 96 | superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) |
94 | { | 97 | { |
@@ -117,7 +120,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) | |||
117 | local_irq = results & 0x0f; | 120 | local_irq = results & 0x0f; |
118 | 121 | ||
119 | if (local_irq == 2 || local_irq > 7) { | 122 | if (local_irq == 2 || local_irq > 7) { |
120 | printk(KERN_ERR "SuperIO: slave interrupted!\n"); | 123 | printk(KERN_ERR PFX "slave interrupted!\n"); |
121 | return IRQ_HANDLED; | 124 | return IRQ_HANDLED; |
122 | } | 125 | } |
123 | 126 | ||
@@ -128,7 +131,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) | |||
128 | outb(OCW3_ISR,IC_PIC1+0); | 131 | outb(OCW3_ISR,IC_PIC1+0); |
129 | results = inb(IC_PIC1+0); | 132 | results = inb(IC_PIC1+0); |
130 | if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */ | 133 | if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */ |
131 | printk(KERN_WARNING "SuperIO: spurious interrupt!\n"); | 134 | printk(KERN_WARNING PFX "spurious interrupt!\n"); |
132 | return IRQ_HANDLED; | 135 | return IRQ_HANDLED; |
133 | } | 136 | } |
134 | } | 137 | } |
@@ -163,27 +166,27 @@ superio_init(struct pci_dev *pcidev) | |||
163 | /* ...then properly fixup the USB to point at suckyio PIC */ | 166 | /* ...then properly fixup the USB to point at suckyio PIC */ |
164 | sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); | 167 | sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); |
165 | 168 | ||
166 | printk(KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n", | 169 | printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n", |
167 | pci_name(pdev), pdev->irq); | 170 | pci_name(pdev), pdev->irq); |
168 | 171 | ||
169 | pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); | 172 | pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); |
170 | sio->sp1_base &= ~1; | 173 | sio->sp1_base &= ~1; |
171 | printk (KERN_INFO "SuperIO: Serial port 1 at 0x%x\n", sio->sp1_base); | 174 | printk(KERN_INFO PFX "Serial port 1 at 0x%x\n", sio->sp1_base); |
172 | 175 | ||
173 | pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base); | 176 | pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base); |
174 | sio->sp2_base &= ~1; | 177 | sio->sp2_base &= ~1; |
175 | printk (KERN_INFO "SuperIO: Serial port 2 at 0x%x\n", sio->sp2_base); | 178 | printk(KERN_INFO PFX "Serial port 2 at 0x%x\n", sio->sp2_base); |
176 | 179 | ||
177 | pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base); | 180 | pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base); |
178 | sio->pp_base &= ~1; | 181 | sio->pp_base &= ~1; |
179 | printk (KERN_INFO "SuperIO: Parallel port at 0x%x\n", sio->pp_base); | 182 | printk(KERN_INFO PFX "Parallel port at 0x%x\n", sio->pp_base); |
180 | 183 | ||
181 | pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base); | 184 | pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base); |
182 | sio->fdc_base &= ~1; | 185 | sio->fdc_base &= ~1; |
183 | printk (KERN_INFO "SuperIO: Floppy controller at 0x%x\n", sio->fdc_base); | 186 | printk(KERN_INFO PFX "Floppy controller at 0x%x\n", sio->fdc_base); |
184 | pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base); | 187 | pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base); |
185 | sio->acpi_base &= ~1; | 188 | sio->acpi_base &= ~1; |
186 | printk (KERN_INFO "SuperIO: ACPI at 0x%x\n", sio->acpi_base); | 189 | printk(KERN_INFO PFX "ACPI at 0x%x\n", sio->acpi_base); |
187 | 190 | ||
188 | request_region (IC_PIC1, 0x1f, "pic1"); | 191 | request_region (IC_PIC1, 0x1f, "pic1"); |
189 | request_region (IC_PIC2, 0x1f, "pic2"); | 192 | request_region (IC_PIC2, 0x1f, "pic2"); |
@@ -263,14 +266,14 @@ superio_init(struct pci_dev *pcidev) | |||
263 | /* Setup USB power regulation */ | 266 | /* Setup USB power regulation */ |
264 | outb(1, sio->acpi_base + USB_REG_CR); | 267 | outb(1, sio->acpi_base + USB_REG_CR); |
265 | if (inb(sio->acpi_base + USB_REG_CR) & 1) | 268 | if (inb(sio->acpi_base + USB_REG_CR) & 1) |
266 | printk(KERN_INFO "SuperIO: USB regulator enabled\n"); | 269 | printk(KERN_INFO PFX "USB regulator enabled\n"); |
267 | else | 270 | else |
268 | printk(KERN_ERR "USB regulator not initialized!\n"); | 271 | printk(KERN_ERR PFX "USB regulator not initialized!\n"); |
269 | 272 | ||
270 | if (request_irq(pdev->irq, superio_interrupt, SA_INTERRUPT, | 273 | if (request_irq(pdev->irq, superio_interrupt, SA_INTERRUPT, |
271 | "SuperIO", (void *)sio)) { | 274 | SUPERIO, (void *)sio)) { |
272 | 275 | ||
273 | printk(KERN_ERR "SuperIO: could not get irq\n"); | 276 | printk(KERN_ERR PFX "could not get irq\n"); |
274 | BUG(); | 277 | BUG(); |
275 | return; | 278 | return; |
276 | } | 279 | } |
@@ -284,7 +287,7 @@ static void superio_disable_irq(unsigned int irq) | |||
284 | u8 r8; | 287 | u8 r8; |
285 | 288 | ||
286 | if ((irq < 1) || (irq == 2) || (irq > 7)) { | 289 | if ((irq < 1) || (irq == 2) || (irq > 7)) { |
287 | printk(KERN_ERR "SuperIO: Illegal irq number.\n"); | 290 | printk(KERN_ERR PFX "Illegal irq number.\n"); |
288 | BUG(); | 291 | BUG(); |
289 | return; | 292 | return; |
290 | } | 293 | } |
@@ -301,7 +304,7 @@ static void superio_enable_irq(unsigned int irq) | |||
301 | u8 r8; | 304 | u8 r8; |
302 | 305 | ||
303 | if ((irq < 1) || (irq == 2) || (irq > 7)) { | 306 | if ((irq < 1) || (irq == 2) || (irq > 7)) { |
304 | printk(KERN_ERR "SuperIO: Illegal irq number (%d).\n", irq); | 307 | printk(KERN_ERR PFX "Illegal irq number (%d).\n", irq); |
305 | BUG(); | 308 | BUG(); |
306 | return; | 309 | return; |
307 | } | 310 | } |
@@ -319,7 +322,7 @@ static unsigned int superio_startup_irq(unsigned int irq) | |||
319 | } | 322 | } |
320 | 323 | ||
321 | static struct hw_interrupt_type superio_interrupt_type = { | 324 | static struct hw_interrupt_type superio_interrupt_type = { |
322 | .typename = "SuperIO", | 325 | .typename = SUPERIO, |
323 | .startup = superio_startup_irq, | 326 | .startup = superio_startup_irq, |
324 | .shutdown = superio_disable_irq, | 327 | .shutdown = superio_disable_irq, |
325 | .enable = superio_enable_irq, | 328 | .enable = superio_enable_irq, |
@@ -413,7 +416,7 @@ static void __devinit superio_serial_init(void) | |||
413 | 416 | ||
414 | retval = early_serial_setup(&serial[0]); | 417 | retval = early_serial_setup(&serial[0]); |
415 | if (retval < 0) { | 418 | if (retval < 0) { |
416 | printk(KERN_WARNING "SuperIO: Register Serial #0 failed.\n"); | 419 | printk(KERN_WARNING PFX "Register Serial #0 failed.\n"); |
417 | return; | 420 | return; |
418 | } | 421 | } |
419 | 422 | ||
@@ -423,7 +426,7 @@ static void __devinit superio_serial_init(void) | |||
423 | retval = early_serial_setup(&serial[1]); | 426 | retval = early_serial_setup(&serial[1]); |
424 | 427 | ||
425 | if (retval < 0) | 428 | if (retval < 0) |
426 | printk(KERN_WARNING "SuperIO: Register Serial #1 failed.\n"); | 429 | printk(KERN_WARNING PFX "Register Serial #1 failed.\n"); |
427 | #endif /* CONFIG_SERIAL_8250 */ | 430 | #endif /* CONFIG_SERIAL_8250 */ |
428 | } | 431 | } |
429 | 432 | ||
@@ -437,7 +440,7 @@ static void __devinit superio_parport_init(void) | |||
437 | PARPORT_DMA_NONE /* dma */, | 440 | PARPORT_DMA_NONE /* dma */, |
438 | NULL /*struct pci_dev* */) ) | 441 | NULL /*struct pci_dev* */) ) |
439 | 442 | ||
440 | printk(KERN_WARNING "SuperIO: Probing parallel port failed.\n"); | 443 | printk(KERN_WARNING PFX "Probing parallel port failed.\n"); |
441 | #endif /* CONFIG_PARPORT_PC */ | 444 | #endif /* CONFIG_PARPORT_PC */ |
442 | } | 445 | } |
443 | 446 | ||
@@ -499,7 +502,7 @@ static struct pci_device_id superio_tbl[] = { | |||
499 | }; | 502 | }; |
500 | 503 | ||
501 | static struct pci_driver superio_driver = { | 504 | static struct pci_driver superio_driver = { |
502 | .name = "SuperIO", | 505 | .name = SUPERIO, |
503 | .id_table = superio_tbl, | 506 | .id_table = superio_tbl, |
504 | .probe = superio_probe, | 507 | .probe = superio_probe, |
505 | }; | 508 | }; |
diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c index 17dce2adf7fe..813c2c24ab1e 100644 --- a/drivers/parisc/wax.c +++ b/drivers/parisc/wax.c | |||
@@ -76,7 +76,7 @@ wax_init_chip(struct parisc_device *dev) | |||
76 | struct gsc_irq gsc_irq; | 76 | struct gsc_irq gsc_irq; |
77 | int ret; | 77 | int ret; |
78 | 78 | ||
79 | wax = kmalloc(sizeof(*wax), GFP_KERNEL); | 79 | wax = kzalloc(sizeof(*wax), GFP_KERNEL); |
80 | if (!wax) | 80 | if (!wax) |
81 | return -ENOMEM; | 81 | return -ENOMEM; |
82 | 82 | ||
diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index fde29a75f888..1de52d9febf9 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c | |||
@@ -249,7 +249,7 @@ struct parport *__devinit parport_gsc_probe_port (unsigned long base, | |||
249 | struct parport tmp; | 249 | struct parport tmp; |
250 | struct parport *p = &tmp; | 250 | struct parport *p = &tmp; |
251 | 251 | ||
252 | priv = kmalloc (sizeof (struct parport_gsc_private), GFP_KERNEL); | 252 | priv = kzalloc (sizeof (struct parport_gsc_private), GFP_KERNEL); |
253 | if (!priv) { | 253 | if (!priv) { |
254 | printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); | 254 | printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); |
255 | return NULL; | 255 | return NULL; |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 166de3507780..10845253c9e0 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -312,8 +312,7 @@ static int __devinit parport_register (struct pci_dev *dev, | |||
312 | { | 312 | { |
313 | struct parport_pc_pci *card; | 313 | struct parport_pc_pci *card; |
314 | struct parport_serial_private *priv = pci_get_drvdata (dev); | 314 | struct parport_serial_private *priv = pci_get_drvdata (dev); |
315 | int i = id->driver_data, n; | 315 | int n, success = 0; |
316 | int success = 0; | ||
317 | 316 | ||
318 | priv->par = cards[id->driver_data]; | 317 | priv->par = cards[id->driver_data]; |
319 | card = &priv->par; | 318 | card = &priv->par; |
@@ -344,10 +343,8 @@ static int __devinit parport_register (struct pci_dev *dev, | |||
344 | "hi" as an offset (see SYBA | 343 | "hi" as an offset (see SYBA |
345 | def.) */ | 344 | def.) */ |
346 | /* TODO: test if sharing interrupts works */ | 345 | /* TODO: test if sharing interrupts works */ |
347 | printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, " | 346 | dev_dbg(&dev->dev, "PCI parallel port detected: I/O at " |
348 | "I/O at %#lx(%#lx)\n", | 347 | "%#lx(%#lx)\n", io_lo, io_hi); |
349 | parport_serial_pci_tbl[i].vendor, | ||
350 | parport_serial_pci_tbl[i].device, io_lo, io_hi); | ||
351 | port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, | 348 | port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, |
352 | PARPORT_DMA_NONE, dev); | 349 | PARPORT_DMA_NONE, dev); |
353 | if (port) { | 350 | if (port) { |
@@ -359,7 +356,7 @@ static int __devinit parport_register (struct pci_dev *dev, | |||
359 | if (card->postinit_hook) | 356 | if (card->postinit_hook) |
360 | card->postinit_hook (dev, card, !success); | 357 | card->postinit_hook (dev, card, !success); |
361 | 358 | ||
362 | return success ? 0 : 1; | 359 | return 0; |
363 | } | 360 | } |
364 | 361 | ||
365 | static int __devinit parport_serial_pci_probe (struct pci_dev *dev, | 362 | static int __devinit parport_serial_pci_probe (struct pci_dev *dev, |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 0a424a4e8187..bb96ce1db08c 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -352,11 +352,20 @@ static void pcmcia_release_dev(struct device *dev) | |||
352 | kfree(p_dev); | 352 | kfree(p_dev); |
353 | } | 353 | } |
354 | 354 | ||
355 | static void pcmcia_add_pseudo_device(struct pcmcia_socket *s) | ||
356 | { | ||
357 | if (!s->pcmcia_state.device_add_pending) { | ||
358 | s->pcmcia_state.device_add_pending = 1; | ||
359 | schedule_work(&s->device_add); | ||
360 | } | ||
361 | return; | ||
362 | } | ||
355 | 363 | ||
356 | static int pcmcia_device_probe(struct device * dev) | 364 | static int pcmcia_device_probe(struct device * dev) |
357 | { | 365 | { |
358 | struct pcmcia_device *p_dev; | 366 | struct pcmcia_device *p_dev; |
359 | struct pcmcia_driver *p_drv; | 367 | struct pcmcia_driver *p_drv; |
368 | struct pcmcia_device_id *did; | ||
360 | struct pcmcia_socket *s; | 369 | struct pcmcia_socket *s; |
361 | int ret = 0; | 370 | int ret = 0; |
362 | 371 | ||
@@ -392,6 +401,19 @@ static int pcmcia_device_probe(struct device * dev) | |||
392 | } | 401 | } |
393 | 402 | ||
394 | ret = p_drv->probe(p_dev); | 403 | ret = p_drv->probe(p_dev); |
404 | if (ret) | ||
405 | goto put_module; | ||
406 | |||
407 | /* handle pseudo multifunction devices: | ||
408 | * there are at most two pseudo multifunction devices. | ||
409 | * if we're matching against the first, schedule a | ||
410 | * call which will then check whether there are two | ||
411 | * pseudo devices, and if not, add the second one. | ||
412 | */ | ||
413 | did = (struct pcmcia_device_id *) p_dev->dev.driver_data; | ||
414 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && | ||
415 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) | ||
416 | pcmcia_add_pseudo_device(p_dev->socket); | ||
395 | 417 | ||
396 | put_module: | 418 | put_module: |
397 | if (ret) | 419 | if (ret) |
@@ -660,15 +682,6 @@ static void pcmcia_delayed_add_pseudo_device(void *data) | |||
660 | s->pcmcia_state.device_add_pending = 0; | 682 | s->pcmcia_state.device_add_pending = 0; |
661 | } | 683 | } |
662 | 684 | ||
663 | static inline void pcmcia_add_pseudo_device(struct pcmcia_socket *s) | ||
664 | { | ||
665 | if (!s->pcmcia_state.device_add_pending) { | ||
666 | s->pcmcia_state.device_add_pending = 1; | ||
667 | schedule_work(&s->device_add); | ||
668 | } | ||
669 | return; | ||
670 | } | ||
671 | |||
672 | static int pcmcia_requery(struct device *dev, void * _data) | 685 | static int pcmcia_requery(struct device *dev, void * _data) |
673 | { | 686 | { |
674 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 687 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
@@ -755,15 +768,6 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
755 | } | 768 | } |
756 | 769 | ||
757 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { | 770 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { |
758 | /* handle pseudo multifunction devices: | ||
759 | * there are at most two pseudo multifunction devices. | ||
760 | * if we're matching against the first, schedule a | ||
761 | * call which will then check whether there are two | ||
762 | * pseudo devices, and if not, add the second one. | ||
763 | */ | ||
764 | if (dev->device_no == 0) | ||
765 | pcmcia_add_pseudo_device(dev->socket); | ||
766 | |||
767 | if (dev->device_no != did->device_no) | 771 | if (dev->device_no != did->device_no) |
768 | return 0; | 772 | return 0; |
769 | } | 773 | } |
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index aaa568a3806e..b68eef251614 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c | |||
@@ -303,13 +303,11 @@ found: | |||
303 | down_write(&dev->dev.bus->subsys.rwsem); | 303 | down_write(&dev->dev.bus->subsys.rwsem); |
304 | dev->card_link = clink; | 304 | dev->card_link = clink; |
305 | dev->dev.driver = &drv->link.driver; | 305 | dev->dev.driver = &drv->link.driver; |
306 | if (drv->link.driver.probe) { | 306 | if (pnp_bus_type.probe(&dev->dev)) { |
307 | if (drv->link.driver.probe(&dev->dev)) { | 307 | dev->dev.driver = NULL; |
308 | dev->dev.driver = NULL; | 308 | dev->card_link = NULL; |
309 | dev->card_link = NULL; | 309 | up_write(&dev->dev.bus->subsys.rwsem); |
310 | up_write(&dev->dev.bus->subsys.rwsem); | 310 | return NULL; |
311 | return NULL; | ||
312 | } | ||
313 | } | 311 | } |
314 | device_bind_driver(&dev->dev); | 312 | device_bind_driver(&dev->dev); |
315 | up_write(&dev->dev.bus->subsys.rwsem); | 313 | up_write(&dev->dev.bus->subsys.rwsem); |
diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig index 6912399d0937..6f50cc9323d9 100644 --- a/drivers/s390/block/Kconfig +++ b/drivers/s390/block/Kconfig | |||
@@ -55,21 +55,13 @@ config DASD_DIAG | |||
55 | Disks under VM. If you are not running under VM or unsure what it is, | 55 | Disks under VM. If you are not running under VM or unsure what it is, |
56 | say "N". | 56 | say "N". |
57 | 57 | ||
58 | config DASD_EER | ||
59 | tristate "Extended error reporting (EER)" | ||
60 | depends on DASD | ||
61 | help | ||
62 | This driver provides a character device interface to the | ||
63 | DASD extended error reporting. This is only needed if you want to | ||
64 | use applications written for the EER facility. | ||
65 | |||
66 | config DASD_CMB | 58 | config DASD_CMB |
67 | tristate "Compatibility interface for DASD channel measurement blocks" | 59 | tristate "Compatibility interface for DASD channel measurement blocks" |
68 | depends on DASD | 60 | depends on DASD |
69 | help | 61 | help |
70 | This driver provides an additional interface to the channel | 62 | This driver provides an additional interface to the channel measurement |
71 | measurement facility, which is normally accessed though sysfs, with | 63 | facility, which is normally accessed though sysfs, with a set of |
72 | a set of ioctl functions specific to the dasd driver. | 64 | ioctl functions specific to the dasd driver. |
73 | This is only needed if you want to use applications written for | 65 | This is only needed if you want to use applications written for |
74 | linux-2.4 dasd channel measurement facility interface. | 66 | linux-2.4 dasd channel measurement facility interface. |
75 | 67 | ||
diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile index 0c0d871e8f51..58c6780134f7 100644 --- a/drivers/s390/block/Makefile +++ b/drivers/s390/block/Makefile | |||
@@ -5,7 +5,6 @@ | |||
5 | dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o | 5 | dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o |
6 | dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o | 6 | dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o |
7 | dasd_diag_mod-objs := dasd_diag.o | 7 | dasd_diag_mod-objs := dasd_diag.o |
8 | dasd_eer_mod-objs := dasd_eer.o | ||
9 | dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \ | 8 | dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \ |
10 | dasd_genhd.o dasd_erp.o | 9 | dasd_genhd.o dasd_erp.o |
11 | 10 | ||
@@ -14,6 +13,5 @@ obj-$(CONFIG_DASD_DIAG) += dasd_diag_mod.o | |||
14 | obj-$(CONFIG_DASD_ECKD) += dasd_eckd_mod.o | 13 | obj-$(CONFIG_DASD_ECKD) += dasd_eckd_mod.o |
15 | obj-$(CONFIG_DASD_FBA) += dasd_fba_mod.o | 14 | obj-$(CONFIG_DASD_FBA) += dasd_fba_mod.o |
16 | obj-$(CONFIG_DASD_CMB) += dasd_cmb.o | 15 | obj-$(CONFIG_DASD_CMB) += dasd_cmb.o |
17 | obj-$(CONFIG_DASD_EER) += dasd_eer.o | ||
18 | obj-$(CONFIG_BLK_DEV_XPRAM) += xpram.o | 16 | obj-$(CONFIG_BLK_DEV_XPRAM) += xpram.o |
19 | obj-$(CONFIG_DCSSBLK) += dcssblk.o | 17 | obj-$(CONFIG_DCSSBLK) += dcssblk.o |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 08c88fcd8963..33157c84d1d3 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
20 | #include <linux/hdreg.h> | 20 | #include <linux/hdreg.h> |
21 | #include <linux/notifier.h> | ||
22 | 21 | ||
23 | #include <asm/ccwdev.h> | 22 | #include <asm/ccwdev.h> |
24 | #include <asm/ebcdic.h> | 23 | #include <asm/ebcdic.h> |
@@ -58,7 +57,6 @@ static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *); | |||
58 | static void dasd_flush_ccw_queue(struct dasd_device *, int); | 57 | static void dasd_flush_ccw_queue(struct dasd_device *, int); |
59 | static void dasd_tasklet(struct dasd_device *); | 58 | static void dasd_tasklet(struct dasd_device *); |
60 | static void do_kick_device(void *data); | 59 | static void do_kick_device(void *data); |
61 | static void dasd_disable_eer(struct dasd_device *device); | ||
62 | 60 | ||
63 | /* | 61 | /* |
64 | * SECTION: Operations on the device structure. | 62 | * SECTION: Operations on the device structure. |
@@ -153,10 +151,13 @@ dasd_state_new_to_known(struct dasd_device *device) | |||
153 | static inline void | 151 | static inline void |
154 | dasd_state_known_to_new(struct dasd_device * device) | 152 | dasd_state_known_to_new(struct dasd_device * device) |
155 | { | 153 | { |
156 | /* disable extended error reporting for this device */ | ||
157 | dasd_disable_eer(device); | ||
158 | /* Forget the discipline information. */ | 154 | /* Forget the discipline information. */ |
155 | if (device->discipline) | ||
156 | module_put(device->discipline->owner); | ||
159 | device->discipline = NULL; | 157 | device->discipline = NULL; |
158 | if (device->base_discipline) | ||
159 | module_put(device->base_discipline->owner); | ||
160 | device->base_discipline = NULL; | ||
160 | device->state = DASD_STATE_NEW; | 161 | device->state = DASD_STATE_NEW; |
161 | 162 | ||
162 | dasd_free_queue(device); | 163 | dasd_free_queue(device); |
@@ -214,9 +215,10 @@ dasd_state_basic_to_known(struct dasd_device * device) | |||
214 | * interrupt for this detection ccw uses the kernel event daemon to | 215 | * interrupt for this detection ccw uses the kernel event daemon to |
215 | * trigger the call to dasd_change_state. All this is done in the | 216 | * trigger the call to dasd_change_state. All this is done in the |
216 | * discipline code, see dasd_eckd.c. | 217 | * discipline code, see dasd_eckd.c. |
217 | * After the analysis ccw is done (do_analysis returned 0 or error) | 218 | * After the analysis ccw is done (do_analysis returned 0) the block |
218 | * the block device is setup. Either a fake disk is added to allow | 219 | * device is setup. |
219 | * formatting or a proper device request queue is created. | 220 | * In case the analysis returns an error, the device setup is stopped |
221 | * (a fake disk was already added to allow formatting). | ||
220 | */ | 222 | */ |
221 | static inline int | 223 | static inline int |
222 | dasd_state_basic_to_ready(struct dasd_device * device) | 224 | dasd_state_basic_to_ready(struct dasd_device * device) |
@@ -226,13 +228,19 @@ dasd_state_basic_to_ready(struct dasd_device * device) | |||
226 | rc = 0; | 228 | rc = 0; |
227 | if (device->discipline->do_analysis != NULL) | 229 | if (device->discipline->do_analysis != NULL) |
228 | rc = device->discipline->do_analysis(device); | 230 | rc = device->discipline->do_analysis(device); |
229 | if (rc) | 231 | if (rc) { |
232 | if (rc != -EAGAIN) | ||
233 | device->state = DASD_STATE_UNFMT; | ||
230 | return rc; | 234 | return rc; |
235 | } | ||
236 | /* make disk known with correct capacity */ | ||
231 | dasd_setup_queue(device); | 237 | dasd_setup_queue(device); |
238 | set_capacity(device->gdp, device->blocks << device->s2b_shift); | ||
232 | device->state = DASD_STATE_READY; | 239 | device->state = DASD_STATE_READY; |
233 | if (dasd_scan_partitions(device) != 0) | 240 | rc = dasd_scan_partitions(device); |
241 | if (rc) | ||
234 | device->state = DASD_STATE_BASIC; | 242 | device->state = DASD_STATE_BASIC; |
235 | return 0; | 243 | return rc; |
236 | } | 244 | } |
237 | 245 | ||
238 | /* | 246 | /* |
@@ -253,6 +261,15 @@ dasd_state_ready_to_basic(struct dasd_device * device) | |||
253 | } | 261 | } |
254 | 262 | ||
255 | /* | 263 | /* |
264 | * Back to basic. | ||
265 | */ | ||
266 | static inline void | ||
267 | dasd_state_unfmt_to_basic(struct dasd_device * device) | ||
268 | { | ||
269 | device->state = DASD_STATE_BASIC; | ||
270 | } | ||
271 | |||
272 | /* | ||
256 | * Make the device online and schedule the bottom half to start | 273 | * Make the device online and schedule the bottom half to start |
257 | * the requeueing of requests from the linux request queue to the | 274 | * the requeueing of requests from the linux request queue to the |
258 | * ccw queue. | 275 | * ccw queue. |
@@ -318,8 +335,12 @@ dasd_decrease_state(struct dasd_device *device) | |||
318 | if (device->state == DASD_STATE_READY && | 335 | if (device->state == DASD_STATE_READY && |
319 | device->target <= DASD_STATE_BASIC) | 336 | device->target <= DASD_STATE_BASIC) |
320 | dasd_state_ready_to_basic(device); | 337 | dasd_state_ready_to_basic(device); |
321 | 338 | ||
322 | if (device->state == DASD_STATE_BASIC && | 339 | if (device->state == DASD_STATE_UNFMT && |
340 | device->target <= DASD_STATE_BASIC) | ||
341 | dasd_state_unfmt_to_basic(device); | ||
342 | |||
343 | if (device->state == DASD_STATE_BASIC && | ||
323 | device->target <= DASD_STATE_KNOWN) | 344 | device->target <= DASD_STATE_KNOWN) |
324 | dasd_state_basic_to_known(device); | 345 | dasd_state_basic_to_known(device); |
325 | 346 | ||
@@ -871,9 +892,6 @@ dasd_handle_state_change_pending(struct dasd_device *device) | |||
871 | struct dasd_ccw_req *cqr; | 892 | struct dasd_ccw_req *cqr; |
872 | struct list_head *l, *n; | 893 | struct list_head *l, *n; |
873 | 894 | ||
874 | /* first of all call extended error reporting */ | ||
875 | dasd_write_eer_trigger(DASD_EER_STATECHANGE, device, NULL); | ||
876 | |||
877 | device->stopped &= ~DASD_STOPPED_PENDING; | 895 | device->stopped &= ~DASD_STOPPED_PENDING; |
878 | 896 | ||
879 | /* restart all 'running' IO on queue */ | 897 | /* restart all 'running' IO on queue */ |
@@ -1093,19 +1111,6 @@ restart: | |||
1093 | } | 1111 | } |
1094 | goto restart; | 1112 | goto restart; |
1095 | } | 1113 | } |
1096 | |||
1097 | /* first of all call extended error reporting */ | ||
1098 | if (device->eer && cqr->status == DASD_CQR_FAILED) { | ||
1099 | dasd_write_eer_trigger(DASD_EER_FATALERROR, | ||
1100 | device, cqr); | ||
1101 | |||
1102 | /* restart request */ | ||
1103 | cqr->status = DASD_CQR_QUEUED; | ||
1104 | cqr->retries = 255; | ||
1105 | device->stopped |= DASD_STOPPED_QUIESCE; | ||
1106 | goto restart; | ||
1107 | } | ||
1108 | |||
1109 | /* Process finished ERP request. */ | 1114 | /* Process finished ERP request. */ |
1110 | if (cqr->refers) { | 1115 | if (cqr->refers) { |
1111 | __dasd_process_erp(device, cqr); | 1116 | __dasd_process_erp(device, cqr); |
@@ -1243,8 +1248,7 @@ __dasd_start_head(struct dasd_device * device) | |||
1243 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); | 1248 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); |
1244 | /* check FAILFAST */ | 1249 | /* check FAILFAST */ |
1245 | if (device->stopped & ~DASD_STOPPED_PENDING && | 1250 | if (device->stopped & ~DASD_STOPPED_PENDING && |
1246 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && | 1251 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags)) { |
1247 | (!device->eer)) { | ||
1248 | cqr->status = DASD_CQR_FAILED; | 1252 | cqr->status = DASD_CQR_FAILED; |
1249 | dasd_schedule_bh(device); | 1253 | dasd_schedule_bh(device); |
1250 | } | 1254 | } |
@@ -1738,7 +1742,7 @@ dasd_open(struct inode *inp, struct file *filp) | |||
1738 | goto out; | 1742 | goto out; |
1739 | } | 1743 | } |
1740 | 1744 | ||
1741 | if (device->state < DASD_STATE_BASIC) { | 1745 | if (device->state <= DASD_STATE_BASIC) { |
1742 | DBF_DEV_EVENT(DBF_ERR, device, " %s", | 1746 | DBF_DEV_EVENT(DBF_ERR, device, " %s", |
1743 | " Cannot open unrecognized device"); | 1747 | " Cannot open unrecognized device"); |
1744 | rc = -ENODEV; | 1748 | rc = -ENODEV; |
@@ -1880,9 +1884,10 @@ dasd_generic_remove (struct ccw_device *cdev) | |||
1880 | */ | 1884 | */ |
1881 | int | 1885 | int |
1882 | dasd_generic_set_online (struct ccw_device *cdev, | 1886 | dasd_generic_set_online (struct ccw_device *cdev, |
1883 | struct dasd_discipline *discipline) | 1887 | struct dasd_discipline *base_discipline) |
1884 | 1888 | ||
1885 | { | 1889 | { |
1890 | struct dasd_discipline *discipline; | ||
1886 | struct dasd_device *device; | 1891 | struct dasd_device *device; |
1887 | int rc; | 1892 | int rc; |
1888 | 1893 | ||
@@ -1890,6 +1895,7 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1890 | if (IS_ERR(device)) | 1895 | if (IS_ERR(device)) |
1891 | return PTR_ERR(device); | 1896 | return PTR_ERR(device); |
1892 | 1897 | ||
1898 | discipline = base_discipline; | ||
1893 | if (device->features & DASD_FEATURE_USEDIAG) { | 1899 | if (device->features & DASD_FEATURE_USEDIAG) { |
1894 | if (!dasd_diag_discipline_pointer) { | 1900 | if (!dasd_diag_discipline_pointer) { |
1895 | printk (KERN_WARNING | 1901 | printk (KERN_WARNING |
@@ -1901,6 +1907,16 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1901 | } | 1907 | } |
1902 | discipline = dasd_diag_discipline_pointer; | 1908 | discipline = dasd_diag_discipline_pointer; |
1903 | } | 1909 | } |
1910 | if (!try_module_get(base_discipline->owner)) { | ||
1911 | dasd_delete_device(device); | ||
1912 | return -EINVAL; | ||
1913 | } | ||
1914 | if (!try_module_get(discipline->owner)) { | ||
1915 | module_put(base_discipline->owner); | ||
1916 | dasd_delete_device(device); | ||
1917 | return -EINVAL; | ||
1918 | } | ||
1919 | device->base_discipline = base_discipline; | ||
1904 | device->discipline = discipline; | 1920 | device->discipline = discipline; |
1905 | 1921 | ||
1906 | rc = discipline->check_device(device); | 1922 | rc = discipline->check_device(device); |
@@ -1909,6 +1925,8 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1909 | "dasd_generic couldn't online device %s " | 1925 | "dasd_generic couldn't online device %s " |
1910 | "with discipline %s rc=%i\n", | 1926 | "with discipline %s rc=%i\n", |
1911 | cdev->dev.bus_id, discipline->name, rc); | 1927 | cdev->dev.bus_id, discipline->name, rc); |
1928 | module_put(discipline->owner); | ||
1929 | module_put(base_discipline->owner); | ||
1912 | dasd_delete_device(device); | 1930 | dasd_delete_device(device); |
1913 | return rc; | 1931 | return rc; |
1914 | } | 1932 | } |
@@ -1986,9 +2004,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
1986 | switch (event) { | 2004 | switch (event) { |
1987 | case CIO_GONE: | 2005 | case CIO_GONE: |
1988 | case CIO_NO_PATH: | 2006 | case CIO_NO_PATH: |
1989 | /* first of all call extended error reporting */ | ||
1990 | dasd_write_eer_trigger(DASD_EER_NOPATH, device, NULL); | ||
1991 | |||
1992 | if (device->state < DASD_STATE_BASIC) | 2007 | if (device->state < DASD_STATE_BASIC) |
1993 | break; | 2008 | break; |
1994 | /* Device is active. We want to keep it. */ | 2009 | /* Device is active. We want to keep it. */ |
@@ -2046,51 +2061,6 @@ dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) | |||
2046 | put_driver(drv); | 2061 | put_driver(drv); |
2047 | } | 2062 | } |
2048 | 2063 | ||
2049 | /* | ||
2050 | * notifications for extended error reports | ||
2051 | */ | ||
2052 | static struct notifier_block *dasd_eer_chain; | ||
2053 | |||
2054 | int | ||
2055 | dasd_register_eer_notifier(struct notifier_block *nb) | ||
2056 | { | ||
2057 | return notifier_chain_register(&dasd_eer_chain, nb); | ||
2058 | } | ||
2059 | |||
2060 | int | ||
2061 | dasd_unregister_eer_notifier(struct notifier_block *nb) | ||
2062 | { | ||
2063 | return notifier_chain_unregister(&dasd_eer_chain, nb); | ||
2064 | } | ||
2065 | |||
2066 | /* | ||
2067 | * Notify the registered error reporting module of a problem | ||
2068 | */ | ||
2069 | void | ||
2070 | dasd_write_eer_trigger(unsigned int id, struct dasd_device *device, | ||
2071 | struct dasd_ccw_req *cqr) | ||
2072 | { | ||
2073 | if (device->eer) { | ||
2074 | struct dasd_eer_trigger temp; | ||
2075 | temp.id = id; | ||
2076 | temp.device = device; | ||
2077 | temp.cqr = cqr; | ||
2078 | notifier_call_chain(&dasd_eer_chain, DASD_EER_TRIGGER, | ||
2079 | (void *)&temp); | ||
2080 | } | ||
2081 | } | ||
2082 | |||
2083 | /* | ||
2084 | * Tell the registered error reporting module to disable error reporting for | ||
2085 | * a given device and to cleanup any private data structures on that device. | ||
2086 | */ | ||
2087 | static void | ||
2088 | dasd_disable_eer(struct dasd_device *device) | ||
2089 | { | ||
2090 | notifier_call_chain(&dasd_eer_chain, DASD_EER_DISABLE, (void *)device); | ||
2091 | } | ||
2092 | |||
2093 | |||
2094 | static int __init | 2064 | static int __init |
2095 | dasd_init(void) | 2065 | dasd_init(void) |
2096 | { | 2066 | { |
@@ -2172,11 +2142,6 @@ EXPORT_SYMBOL_GPL(dasd_generic_set_online); | |||
2172 | EXPORT_SYMBOL_GPL(dasd_generic_set_offline); | 2142 | EXPORT_SYMBOL_GPL(dasd_generic_set_offline); |
2173 | EXPORT_SYMBOL_GPL(dasd_generic_auto_online); | 2143 | EXPORT_SYMBOL_GPL(dasd_generic_auto_online); |
2174 | 2144 | ||
2175 | EXPORT_SYMBOL(dasd_register_eer_notifier); | ||
2176 | EXPORT_SYMBOL(dasd_unregister_eer_notifier); | ||
2177 | EXPORT_SYMBOL(dasd_write_eer_trigger); | ||
2178 | |||
2179 | |||
2180 | /* | 2145 | /* |
2181 | * Overrides for Emacs so that we follow Linus's tabbing style. | 2146 | * Overrides for Emacs so that we follow Linus's tabbing style. |
2182 | * Emacs will notice this stuff at the end of the file and automatically | 2147 | * Emacs will notice this stuff at the end of the file and automatically |
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index c811380b9079..4ee0f934e325 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c | |||
@@ -1108,9 +1108,6 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense) | |||
1108 | case 0x0B: | 1108 | case 0x0B: |
1109 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 1109 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
1110 | "FORMAT F - Volume is suspended duplex"); | 1110 | "FORMAT F - Volume is suspended duplex"); |
1111 | /* call extended error reporting (EER) */ | ||
1112 | dasd_write_eer_trigger(DASD_EER_PPRCSUSPEND, device, | ||
1113 | erp->refers); | ||
1114 | break; | 1111 | break; |
1115 | case 0x0C: | 1112 | case 0x0C: |
1116 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 1113 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h index e15dd7978050..bc3823d35223 100644 --- a/drivers/s390/block/dasd_eckd.h +++ b/drivers/s390/block/dasd_eckd.h | |||
@@ -29,7 +29,6 @@ | |||
29 | #define DASD_ECKD_CCW_PSF 0x27 | 29 | #define DASD_ECKD_CCW_PSF 0x27 |
30 | #define DASD_ECKD_CCW_RSSD 0x3e | 30 | #define DASD_ECKD_CCW_RSSD 0x3e |
31 | #define DASD_ECKD_CCW_LOCATE_RECORD 0x47 | 31 | #define DASD_ECKD_CCW_LOCATE_RECORD 0x47 |
32 | #define DASD_ECKD_CCW_SNSS 0x54 | ||
33 | #define DASD_ECKD_CCW_DEFINE_EXTENT 0x63 | 32 | #define DASD_ECKD_CCW_DEFINE_EXTENT 0x63 |
34 | #define DASD_ECKD_CCW_WRITE_MT 0x85 | 33 | #define DASD_ECKD_CCW_WRITE_MT 0x85 |
35 | #define DASD_ECKD_CCW_READ_MT 0x86 | 34 | #define DASD_ECKD_CCW_READ_MT 0x86 |
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c deleted file mode 100644 index f70cd7716b24..000000000000 --- a/drivers/s390/block/dasd_eer.c +++ /dev/null | |||
@@ -1,1090 +0,0 @@ | |||
1 | /* | ||
2 | * character device driver for extended error reporting | ||
3 | * | ||
4 | * | ||
5 | * Copyright (C) 2005 IBM Corporation | ||
6 | * extended error reporting for DASD ECKD devices | ||
7 | * Author(s): Stefan Weinhuber <wein@de.ibm.com> | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/fs.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/miscdevice.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/moduleparam.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/workqueue.h> | ||
19 | #include <linux/poll.h> | ||
20 | #include <linux/notifier.h> | ||
21 | |||
22 | #include <asm/uaccess.h> | ||
23 | #include <asm/semaphore.h> | ||
24 | #include <asm/atomic.h> | ||
25 | #include <asm/ebcdic.h> | ||
26 | |||
27 | #include "dasd_int.h" | ||
28 | #include "dasd_eckd.h" | ||
29 | |||
30 | |||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | MODULE_AUTHOR("Stefan Weinhuber <wein@de.ibm.com>"); | ||
34 | MODULE_DESCRIPTION("DASD extended error reporting module"); | ||
35 | |||
36 | |||
37 | #ifdef PRINTK_HEADER | ||
38 | #undef PRINTK_HEADER | ||
39 | #endif /* PRINTK_HEADER */ | ||
40 | #define PRINTK_HEADER "dasd(eer):" | ||
41 | |||
42 | |||
43 | |||
44 | |||
45 | |||
46 | /*****************************************************************************/ | ||
47 | /* the internal buffer */ | ||
48 | /*****************************************************************************/ | ||
49 | |||
50 | /* | ||
51 | * The internal buffer is meant to store obaque blobs of data, so it doesn't | ||
52 | * know of higher level concepts like triggers. | ||
53 | * It consists of a number of pages that are used as a ringbuffer. Each data | ||
54 | * blob is stored in a simple record that consists of an integer, which | ||
55 | * contains the size of the following data, and the data bytes themselfes. | ||
56 | * | ||
57 | * To allow for multiple independent readers we create one internal buffer | ||
58 | * each time the device is opened and destroy the buffer when the file is | ||
59 | * closed again. | ||
60 | * | ||
61 | * One record can be written to a buffer by using the functions | ||
62 | * - dasd_eer_start_record (one time per record to write the size to the buffer | ||
63 | * and reserve the space for the data) | ||
64 | * - dasd_eer_write_buffer (one or more times per record to write the data) | ||
65 | * The data can be written in several steps but you will have to compute | ||
66 | * the total size up front for the invocation of dasd_eer_start_record. | ||
67 | * If the ringbuffer is full, dasd_eer_start_record will remove the required | ||
68 | * number of old records. | ||
69 | * | ||
70 | * A record is typically read in two steps, first read the integer that | ||
71 | * specifies the size of the following data, then read the data. | ||
72 | * Both can be done by | ||
73 | * - dasd_eer_read_buffer | ||
74 | * | ||
75 | * For all mentioned functions you need to get the bufferlock first and keep it | ||
76 | * until a complete record is written or read. | ||
77 | */ | ||
78 | |||
79 | |||
80 | /* | ||
81 | * Alle information necessary to keep track of an internal buffer is kept in | ||
82 | * a struct eerbuffer. The buffer specific to a file pointer is strored in | ||
83 | * the private_data field of that file. To be able to write data to all | ||
84 | * existing buffers, each buffer is also added to the bufferlist. | ||
85 | * If the user doesn't want to read a complete record in one go, we have to | ||
86 | * keep track of the rest of the record. residual stores the number of bytes | ||
87 | * that are still to deliver. If the rest of the record is invalidated between | ||
88 | * two reads then residual will be set to -1 so that the next read will fail. | ||
89 | * All entries in the eerbuffer structure are protected with the bufferlock. | ||
90 | * To avoid races between writing to a buffer on the one side and creating | ||
91 | * and destroying buffers on the other side, the bufferlock must also be used | ||
92 | * to protect the bufferlist. | ||
93 | */ | ||
94 | |||
95 | struct eerbuffer { | ||
96 | struct list_head list; | ||
97 | char **buffer; | ||
98 | int buffersize; | ||
99 | int buffer_page_count; | ||
100 | int head; | ||
101 | int tail; | ||
102 | int residual; | ||
103 | }; | ||
104 | |||
105 | LIST_HEAD(bufferlist); | ||
106 | |||
107 | static spinlock_t bufferlock = SPIN_LOCK_UNLOCKED; | ||
108 | |||
109 | DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue); | ||
110 | |||
111 | /* | ||
112 | * How many free bytes are available on the buffer. | ||
113 | * needs to be called with bufferlock held | ||
114 | */ | ||
115 | static int | ||
116 | dasd_eer_get_free_bytes(struct eerbuffer *eerb) | ||
117 | { | ||
118 | if (eerb->head < eerb->tail) { | ||
119 | return eerb->tail - eerb->head - 1; | ||
120 | } else | ||
121 | return eerb->buffersize - eerb->head + eerb->tail -1; | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * How many bytes of buffer space are used. | ||
126 | * needs to be called with bufferlock held | ||
127 | */ | ||
128 | static int | ||
129 | dasd_eer_get_filled_bytes(struct eerbuffer *eerb) | ||
130 | { | ||
131 | |||
132 | if (eerb->head >= eerb->tail) { | ||
133 | return eerb->head - eerb->tail; | ||
134 | } else | ||
135 | return eerb->buffersize - eerb->tail + eerb->head; | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * The dasd_eer_write_buffer function just copies count bytes of data | ||
140 | * to the buffer. Make sure to call dasd_eer_start_record first, to | ||
141 | * make sure that enough free space is available. | ||
142 | * needs to be called with bufferlock held | ||
143 | */ | ||
144 | static void | ||
145 | dasd_eer_write_buffer(struct eerbuffer *eerb, int count, char *data) | ||
146 | { | ||
147 | |||
148 | unsigned long headindex,localhead; | ||
149 | unsigned long rest, len; | ||
150 | char *nextdata; | ||
151 | |||
152 | nextdata = data; | ||
153 | rest = count; | ||
154 | while (rest > 0) { | ||
155 | headindex = eerb->head / PAGE_SIZE; | ||
156 | localhead = eerb->head % PAGE_SIZE; | ||
157 | len = min(rest, (PAGE_SIZE - localhead)); | ||
158 | memcpy(eerb->buffer[headindex]+localhead, nextdata, len); | ||
159 | nextdata += len; | ||
160 | rest -= len; | ||
161 | eerb->head += len; | ||
162 | if ( eerb->head == eerb->buffersize ) | ||
163 | eerb->head = 0; /* wrap around */ | ||
164 | if (eerb->head > eerb->buffersize) { | ||
165 | MESSAGE(KERN_ERR, "%s", "runaway buffer head."); | ||
166 | BUG(); | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | /* | ||
172 | * needs to be called with bufferlock held | ||
173 | */ | ||
174 | static int | ||
175 | dasd_eer_read_buffer(struct eerbuffer *eerb, int count, char *data) | ||
176 | { | ||
177 | |||
178 | unsigned long tailindex,localtail; | ||
179 | unsigned long rest, len, finalcount; | ||
180 | char *nextdata; | ||
181 | |||
182 | finalcount = min(count, dasd_eer_get_filled_bytes(eerb)); | ||
183 | nextdata = data; | ||
184 | rest = finalcount; | ||
185 | while (rest > 0) { | ||
186 | tailindex = eerb->tail / PAGE_SIZE; | ||
187 | localtail = eerb->tail % PAGE_SIZE; | ||
188 | len = min(rest, (PAGE_SIZE - localtail)); | ||
189 | memcpy(nextdata, eerb->buffer[tailindex]+localtail, len); | ||
190 | nextdata += len; | ||
191 | rest -= len; | ||
192 | eerb->tail += len; | ||
193 | if ( eerb->tail == eerb->buffersize ) | ||
194 | eerb->tail = 0; /* wrap around */ | ||
195 | if (eerb->tail > eerb->buffersize) { | ||
196 | MESSAGE(KERN_ERR, "%s", "runaway buffer tail."); | ||
197 | BUG(); | ||
198 | } | ||
199 | } | ||
200 | return finalcount; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * Whenever you want to write a blob of data to the internal buffer you | ||
205 | * have to start by using this function first. It will write the number | ||
206 | * of bytes that will be written to the buffer. If necessary it will remove | ||
207 | * old records to make room for the new one. | ||
208 | * needs to be called with bufferlock held | ||
209 | */ | ||
210 | static int | ||
211 | dasd_eer_start_record(struct eerbuffer *eerb, int count) | ||
212 | { | ||
213 | int tailcount; | ||
214 | if (count + sizeof(count) > eerb->buffersize) | ||
215 | return -ENOMEM; | ||
216 | while (dasd_eer_get_free_bytes(eerb) < count + sizeof(count)) { | ||
217 | if (eerb->residual > 0) { | ||
218 | eerb->tail += eerb->residual; | ||
219 | if (eerb->tail >= eerb->buffersize) | ||
220 | eerb->tail -= eerb->buffersize; | ||
221 | eerb->residual = -1; | ||
222 | } | ||
223 | dasd_eer_read_buffer(eerb, sizeof(tailcount), | ||
224 | (char*)(&tailcount)); | ||
225 | eerb->tail += tailcount; | ||
226 | if (eerb->tail >= eerb->buffersize) | ||
227 | eerb->tail -= eerb->buffersize; | ||
228 | } | ||
229 | dasd_eer_write_buffer(eerb, sizeof(count), (char*)(&count)); | ||
230 | |||
231 | return 0; | ||
232 | }; | ||
233 | |||
234 | /* | ||
235 | * release pages that are not used anymore | ||
236 | */ | ||
237 | static void | ||
238 | dasd_eer_free_buffer_pages(char **buf, int no_pages) | ||
239 | { | ||
240 | int i; | ||
241 | |||
242 | for (i = 0; i < no_pages; ++i) { | ||
243 | free_page((unsigned long)buf[i]); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | /* | ||
248 | * allocate a new set of memory pages | ||
249 | */ | ||
250 | static int | ||
251 | dasd_eer_allocate_buffer_pages(char **buf, int no_pages) | ||
252 | { | ||
253 | int i; | ||
254 | |||
255 | for (i = 0; i < no_pages; ++i) { | ||
256 | buf[i] = (char *) get_zeroed_page(GFP_KERNEL); | ||
257 | if (!buf[i]) { | ||
258 | dasd_eer_free_buffer_pages(buf, i); | ||
259 | return -ENOMEM; | ||
260 | } | ||
261 | } | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * empty the buffer by resetting head and tail | ||
267 | * In case there is a half read data blob in the buffer, we set residual | ||
268 | * to -1 to indicate that the remainder of the blob is lost. | ||
269 | */ | ||
270 | static void | ||
271 | dasd_eer_purge_buffer(struct eerbuffer *eerb) | ||
272 | { | ||
273 | unsigned long flags; | ||
274 | |||
275 | spin_lock_irqsave(&bufferlock, flags); | ||
276 | if (eerb->residual > 0) | ||
277 | eerb->residual = -1; | ||
278 | eerb->tail=0; | ||
279 | eerb->head=0; | ||
280 | spin_unlock_irqrestore(&bufferlock, flags); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * set the size of the buffer, newsize is the new number of pages to be used | ||
285 | * we don't try to copy any data back an forth, so any resize will also purge | ||
286 | * the buffer | ||
287 | */ | ||
288 | static int | ||
289 | dasd_eer_resize_buffer(struct eerbuffer *eerb, int newsize) | ||
290 | { | ||
291 | int i, oldcount, reuse; | ||
292 | char **new; | ||
293 | char **old; | ||
294 | unsigned long flags; | ||
295 | |||
296 | if (newsize < 1) | ||
297 | return -EINVAL; | ||
298 | if (eerb->buffer_page_count == newsize) { | ||
299 | /* documented behaviour is that any successfull invocation | ||
300 | * will purge all records */ | ||
301 | dasd_eer_purge_buffer(eerb); | ||
302 | return 0; | ||
303 | } | ||
304 | new = kmalloc(newsize*sizeof(char*), GFP_KERNEL); | ||
305 | if (!new) | ||
306 | return -ENOMEM; | ||
307 | |||
308 | reuse=min(eerb->buffer_page_count, newsize); | ||
309 | for (i = 0; i < reuse; ++i) { | ||
310 | new[i] = eerb->buffer[i]; | ||
311 | } | ||
312 | if (eerb->buffer_page_count < newsize) { | ||
313 | if (dasd_eer_allocate_buffer_pages( | ||
314 | &new[eerb->buffer_page_count], | ||
315 | newsize - eerb->buffer_page_count)) { | ||
316 | kfree(new); | ||
317 | return -ENOMEM; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | spin_lock_irqsave(&bufferlock, flags); | ||
322 | old = eerb->buffer; | ||
323 | eerb->buffer = new; | ||
324 | if (eerb->residual > 0) | ||
325 | eerb->residual = -1; | ||
326 | eerb->tail = 0; | ||
327 | eerb->head = 0; | ||
328 | oldcount = eerb->buffer_page_count; | ||
329 | eerb->buffer_page_count = newsize; | ||
330 | spin_unlock_irqrestore(&bufferlock, flags); | ||
331 | |||
332 | if (oldcount > newsize) { | ||
333 | for (i = newsize; i < oldcount; ++i) { | ||
334 | free_page((unsigned long)old[i]); | ||
335 | } | ||
336 | } | ||
337 | kfree(old); | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | |||
343 | /*****************************************************************************/ | ||
344 | /* The extended error reporting functionality */ | ||
345 | /*****************************************************************************/ | ||
346 | |||
347 | /* | ||
348 | * When a DASD device driver wants to report an error, it calls the | ||
349 | * function dasd_eer_write_trigger (via a notifier mechanism) and gives the | ||
350 | * respective trigger ID as parameter. | ||
351 | * Currently there are four kinds of triggers: | ||
352 | * | ||
353 | * DASD_EER_FATALERROR: all kinds of unrecoverable I/O problems | ||
354 | * DASD_EER_PPRCSUSPEND: PPRC was suspended | ||
355 | * DASD_EER_NOPATH: There is no path to the device left. | ||
356 | * DASD_EER_STATECHANGE: The state of the device has changed. | ||
357 | * | ||
358 | * For the first three triggers all required information can be supplied by | ||
359 | * the caller. For these triggers a record is written by the function | ||
360 | * dasd_eer_write_standard_trigger. | ||
361 | * | ||
362 | * When dasd_eer_write_trigger is called to write a DASD_EER_STATECHANGE | ||
363 | * trigger, we have to gather the necessary sense data first. We cannot queue | ||
364 | * the necessary SNSS (sense subsystem status) request immediatly, since we | ||
365 | * are likely to run in a deadlock situation. Instead, we schedule a | ||
366 | * work_struct that calls the function dasd_eer_sense_subsystem_status to | ||
367 | * create and start an SNSS request asynchronously. | ||
368 | * | ||
369 | * To avoid memory allocations at runtime, the necessary memory is allocated | ||
370 | * when the extended error reporting is enabled for a device (by | ||
371 | * dasd_eer_probe). There is one private eer data structure for each eer | ||
372 | * enabled DASD device. It contains memory for the work_struct, one SNSS cqr | ||
373 | * and a flags field that is used to coordinate the use of the cqr. The call | ||
374 | * to write a state change trigger can come in at any time, so we have one flag | ||
375 | * CQR_IN_USE that protects the cqr itself. When this flag indicates that the | ||
376 | * cqr is currently in use, dasd_eer_sense_subsystem_status cannot start a | ||
377 | * second request but sets the SNSS_REQUESTED flag instead. | ||
378 | * | ||
379 | * When the request is finished, the callback function dasd_eer_SNSS_cb | ||
380 | * is called. This function will invoke the function | ||
381 | * dasd_eer_write_SNSS_trigger to finally write the trigger. It will also | ||
382 | * check the SNSS_REQUESTED flag and if it is set it will call | ||
383 | * dasd_eer_sense_subsystem_status again. | ||
384 | * | ||
385 | * To avoid race conditions during the handling of the lock, the flags must | ||
386 | * be protected by the snsslock. | ||
387 | */ | ||
388 | |||
389 | struct dasd_eer_private { | ||
390 | struct dasd_ccw_req *cqr; | ||
391 | unsigned long flags; | ||
392 | struct work_struct worker; | ||
393 | }; | ||
394 | |||
395 | static void dasd_eer_destroy(struct dasd_device *device, | ||
396 | struct dasd_eer_private *eer); | ||
397 | static int | ||
398 | dasd_eer_write_trigger(struct dasd_eer_trigger *trigger); | ||
399 | static void dasd_eer_sense_subsystem_status(void *data); | ||
400 | static int dasd_eer_notify(struct notifier_block *self, | ||
401 | unsigned long action, void *data); | ||
402 | |||
403 | struct workqueue_struct *dasd_eer_workqueue; | ||
404 | |||
405 | #define SNSS_DATA_SIZE 44 | ||
406 | static spinlock_t snsslock = SPIN_LOCK_UNLOCKED; | ||
407 | |||
408 | #define DASD_EER_BUSID_SIZE 10 | ||
409 | struct dasd_eer_header { | ||
410 | __u32 total_size; | ||
411 | __u32 trigger; | ||
412 | __u64 tv_sec; | ||
413 | __u64 tv_usec; | ||
414 | char busid[DASD_EER_BUSID_SIZE]; | ||
415 | } __attribute__ ((packed)); | ||
416 | |||
417 | static struct notifier_block dasd_eer_nb = { | ||
418 | .notifier_call = dasd_eer_notify, | ||
419 | }; | ||
420 | |||
421 | /* | ||
422 | * flags for use with dasd_eer_private | ||
423 | */ | ||
424 | #define CQR_IN_USE 0 | ||
425 | #define SNSS_REQUESTED 1 | ||
426 | |||
427 | /* | ||
428 | * This function checks if extended error reporting is available for a given | ||
429 | * dasd_device. If yes, then it creates and returns a struct dasd_eer, | ||
430 | * otherwise it returns an -EPERM error pointer. | ||
431 | */ | ||
432 | struct dasd_eer_private * | ||
433 | dasd_eer_probe(struct dasd_device *device) | ||
434 | { | ||
435 | struct dasd_eer_private *private; | ||
436 | |||
437 | if (!(device && device->discipline | ||
438 | && !strcmp(device->discipline->name, "ECKD"))) { | ||
439 | return ERR_PTR(-EPERM); | ||
440 | } | ||
441 | /* allocate the private data structure */ | ||
442 | private = (struct dasd_eer_private *)kmalloc( | ||
443 | sizeof(struct dasd_eer_private), GFP_KERNEL); | ||
444 | if (!private) { | ||
445 | return ERR_PTR(-ENOMEM); | ||
446 | } | ||
447 | INIT_WORK(&private->worker, dasd_eer_sense_subsystem_status, | ||
448 | (void *)device); | ||
449 | private->cqr = dasd_kmalloc_request("ECKD", | ||
450 | 1 /* SNSS */ , | ||
451 | SNSS_DATA_SIZE , | ||
452 | device); | ||
453 | if (!private->cqr) { | ||
454 | kfree(private); | ||
455 | return ERR_PTR(-ENOMEM); | ||
456 | } | ||
457 | private->flags = 0; | ||
458 | return private; | ||
459 | }; | ||
460 | |||
461 | /* | ||
462 | * If our private SNSS request is queued, remove it from the | ||
463 | * dasd ccw queue so we can free the requests memory. | ||
464 | */ | ||
465 | static void | ||
466 | dasd_eer_dequeue_SNSS_request(struct dasd_device *device, | ||
467 | struct dasd_eer_private *eer) | ||
468 | { | ||
469 | struct list_head *lst, *nxt; | ||
470 | struct dasd_ccw_req *cqr, *erpcqr; | ||
471 | dasd_erp_fn_t erp_fn; | ||
472 | |||
473 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | ||
474 | list_for_each_safe(lst, nxt, &device->ccw_queue) { | ||
475 | cqr = list_entry(lst, struct dasd_ccw_req, list); | ||
476 | /* we are looking for two kinds or requests */ | ||
477 | /* first kind: our SNSS request: */ | ||
478 | if (cqr == eer->cqr) { | ||
479 | if (cqr->status == DASD_CQR_IN_IO) | ||
480 | device->discipline->term_IO(cqr); | ||
481 | list_del(&cqr->list); | ||
482 | break; | ||
483 | } | ||
484 | /* second kind: ERP requests for our SNSS request */ | ||
485 | if (cqr->refers) { | ||
486 | /* If this erp request chain ends in our cqr, then */ | ||
487 | /* cal the erp_postaction to clean it up */ | ||
488 | erpcqr = cqr; | ||
489 | while (erpcqr->refers) { | ||
490 | erpcqr = erpcqr->refers; | ||
491 | } | ||
492 | if (erpcqr == eer->cqr) { | ||
493 | erp_fn = device->discipline->erp_postaction( | ||
494 | cqr); | ||
495 | erp_fn(cqr); | ||
496 | } | ||
497 | continue; | ||
498 | } | ||
499 | } | ||
500 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | ||
501 | } | ||
502 | |||
503 | /* | ||
504 | * This function dismantles a struct dasd_eer that was created by | ||
505 | * dasd_eer_probe. Since we want to free our private data structure, | ||
506 | * we must make sure that the memory is not in use anymore. | ||
507 | * We have to flush the work queue and remove a possible SNSS request | ||
508 | * from the dasd queue. | ||
509 | */ | ||
510 | static void | ||
511 | dasd_eer_destroy(struct dasd_device *device, struct dasd_eer_private *eer) | ||
512 | { | ||
513 | flush_workqueue(dasd_eer_workqueue); | ||
514 | dasd_eer_dequeue_SNSS_request(device, eer); | ||
515 | dasd_kfree_request(eer->cqr, device); | ||
516 | kfree(eer); | ||
517 | }; | ||
518 | |||
519 | /* | ||
520 | * enable the extended error reporting for a particular device | ||
521 | */ | ||
522 | static int | ||
523 | dasd_eer_enable_on_device(struct dasd_device *device) | ||
524 | { | ||
525 | void *eer; | ||
526 | if (!device) | ||
527 | return -ENODEV; | ||
528 | if (device->eer) | ||
529 | return 0; | ||
530 | if (!try_module_get(THIS_MODULE)) { | ||
531 | return -EINVAL; | ||
532 | } | ||
533 | eer = (void *)dasd_eer_probe(device); | ||
534 | if (IS_ERR(eer)) { | ||
535 | module_put(THIS_MODULE); | ||
536 | return PTR_ERR(eer); | ||
537 | } | ||
538 | device->eer = eer; | ||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | /* | ||
543 | * enable the extended error reporting for a particular device | ||
544 | */ | ||
545 | static int | ||
546 | dasd_eer_disable_on_device(struct dasd_device *device) | ||
547 | { | ||
548 | struct dasd_eer_private *eer = device->eer; | ||
549 | |||
550 | if (!device) | ||
551 | return -ENODEV; | ||
552 | if (!device->eer) | ||
553 | return 0; | ||
554 | device->eer = NULL; | ||
555 | dasd_eer_destroy(device,eer); | ||
556 | module_put(THIS_MODULE); | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * Set extended error reporting (eer) | ||
563 | * Note: This will be registered as a DASD ioctl, to be called on DASD devices. | ||
564 | */ | ||
565 | static int | ||
566 | dasd_ioctl_set_eer(struct block_device *bdev, int no, long args) | ||
567 | { | ||
568 | struct dasd_device *device; | ||
569 | int intval; | ||
570 | |||
571 | if (!capable(CAP_SYS_ADMIN)) | ||
572 | return -EACCES; | ||
573 | if (bdev != bdev->bd_contains) | ||
574 | /* Error-reporting is not allowed for partitions */ | ||
575 | return -EINVAL; | ||
576 | if (get_user(intval, (int __user *) args)) | ||
577 | return -EFAULT; | ||
578 | device = bdev->bd_disk->private_data; | ||
579 | if (device == NULL) | ||
580 | return -ENODEV; | ||
581 | |||
582 | intval = (intval != 0); | ||
583 | DEV_MESSAGE (KERN_DEBUG, device, | ||
584 | "set eer on device to %d", intval); | ||
585 | if (intval) | ||
586 | return dasd_eer_enable_on_device(device); | ||
587 | else | ||
588 | return dasd_eer_disable_on_device(device); | ||
589 | } | ||
590 | |||
591 | /* | ||
592 | * Get value of extended error reporting. | ||
593 | * Note: This will be registered as a DASD ioctl, to be called on DASD devices. | ||
594 | */ | ||
595 | static int | ||
596 | dasd_ioctl_get_eer(struct block_device *bdev, int no, long args) | ||
597 | { | ||
598 | struct dasd_device *device; | ||
599 | |||
600 | device = bdev->bd_disk->private_data; | ||
601 | if (device == NULL) | ||
602 | return -ENODEV; | ||
603 | return put_user((device->eer != NULL), (int __user *) args); | ||
604 | } | ||
605 | |||
606 | /* | ||
607 | * The following function can be used for those triggers that have | ||
608 | * all necessary data available when the function is called. | ||
609 | * If the parameter cqr is not NULL, the chain of requests will be searched | ||
610 | * for valid sense data, and all valid sense data sets will be added to | ||
611 | * the triggers data. | ||
612 | */ | ||
613 | static int | ||
614 | dasd_eer_write_standard_trigger(int trigger, struct dasd_device *device, | ||
615 | struct dasd_ccw_req *cqr) | ||
616 | { | ||
617 | struct dasd_ccw_req *temp_cqr; | ||
618 | int data_size; | ||
619 | struct timeval tv; | ||
620 | struct dasd_eer_header header; | ||
621 | unsigned long flags; | ||
622 | struct eerbuffer *eerb; | ||
623 | |||
624 | /* go through cqr chain and count the valid sense data sets */ | ||
625 | temp_cqr = cqr; | ||
626 | data_size = 0; | ||
627 | while (temp_cqr) { | ||
628 | if (temp_cqr->irb.esw.esw0.erw.cons) | ||
629 | data_size += 32; | ||
630 | temp_cqr = temp_cqr->refers; | ||
631 | } | ||
632 | |||
633 | header.total_size = sizeof(header) + data_size + 4; /* "EOR" */ | ||
634 | header.trigger = trigger; | ||
635 | do_gettimeofday(&tv); | ||
636 | header.tv_sec = tv.tv_sec; | ||
637 | header.tv_usec = tv.tv_usec; | ||
638 | strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE); | ||
639 | |||
640 | spin_lock_irqsave(&bufferlock, flags); | ||
641 | list_for_each_entry(eerb, &bufferlist, list) { | ||
642 | dasd_eer_start_record(eerb, header.total_size); | ||
643 | dasd_eer_write_buffer(eerb, sizeof(header), (char*)(&header)); | ||
644 | temp_cqr = cqr; | ||
645 | while (temp_cqr) { | ||
646 | if (temp_cqr->irb.esw.esw0.erw.cons) | ||
647 | dasd_eer_write_buffer(eerb, 32, cqr->irb.ecw); | ||
648 | temp_cqr = temp_cqr->refers; | ||
649 | } | ||
650 | dasd_eer_write_buffer(eerb, 4,"EOR"); | ||
651 | } | ||
652 | spin_unlock_irqrestore(&bufferlock, flags); | ||
653 | |||
654 | wake_up_interruptible(&dasd_eer_read_wait_queue); | ||
655 | |||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | /* | ||
660 | * This function writes a DASD_EER_STATECHANGE trigger. | ||
661 | */ | ||
662 | static void | ||
663 | dasd_eer_write_SNSS_trigger(struct dasd_device *device, | ||
664 | struct dasd_ccw_req *cqr) | ||
665 | { | ||
666 | int data_size; | ||
667 | int snss_rc; | ||
668 | struct timeval tv; | ||
669 | struct dasd_eer_header header; | ||
670 | unsigned long flags; | ||
671 | struct eerbuffer *eerb; | ||
672 | |||
673 | snss_rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; | ||
674 | if (snss_rc) | ||
675 | data_size = 0; | ||
676 | else | ||
677 | data_size = SNSS_DATA_SIZE; | ||
678 | |||
679 | header.total_size = sizeof(header) + data_size + 4; /* "EOR" */ | ||
680 | header.trigger = DASD_EER_STATECHANGE; | ||
681 | do_gettimeofday(&tv); | ||
682 | header.tv_sec = tv.tv_sec; | ||
683 | header.tv_usec = tv.tv_usec; | ||
684 | strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE); | ||
685 | |||
686 | spin_lock_irqsave(&bufferlock, flags); | ||
687 | list_for_each_entry(eerb, &bufferlist, list) { | ||
688 | dasd_eer_start_record(eerb, header.total_size); | ||
689 | dasd_eer_write_buffer(eerb, sizeof(header),(char*)(&header)); | ||
690 | if (!snss_rc) | ||
691 | dasd_eer_write_buffer(eerb, SNSS_DATA_SIZE, cqr->data); | ||
692 | dasd_eer_write_buffer(eerb, 4,"EOR"); | ||
693 | } | ||
694 | spin_unlock_irqrestore(&bufferlock, flags); | ||
695 | |||
696 | wake_up_interruptible(&dasd_eer_read_wait_queue); | ||
697 | } | ||
698 | |||
699 | /* | ||
700 | * callback function for use with SNSS request | ||
701 | */ | ||
702 | static void | ||
703 | dasd_eer_SNSS_cb(struct dasd_ccw_req *cqr, void *data) | ||
704 | { | ||
705 | struct dasd_device *device; | ||
706 | struct dasd_eer_private *private; | ||
707 | unsigned long irqflags; | ||
708 | |||
709 | device = (struct dasd_device *)data; | ||
710 | private = (struct dasd_eer_private *)device->eer; | ||
711 | dasd_eer_write_SNSS_trigger(device, cqr); | ||
712 | spin_lock_irqsave(&snsslock, irqflags); | ||
713 | if(!test_and_clear_bit(SNSS_REQUESTED, &private->flags)) { | ||
714 | clear_bit(CQR_IN_USE, &private->flags); | ||
715 | spin_unlock_irqrestore(&snsslock, irqflags); | ||
716 | return; | ||
717 | }; | ||
718 | clear_bit(CQR_IN_USE, &private->flags); | ||
719 | spin_unlock_irqrestore(&snsslock, irqflags); | ||
720 | dasd_eer_sense_subsystem_status(device); | ||
721 | return; | ||
722 | } | ||
723 | |||
724 | /* | ||
725 | * clean a used cqr before using it again | ||
726 | */ | ||
727 | static void | ||
728 | dasd_eer_clean_SNSS_request(struct dasd_ccw_req *cqr) | ||
729 | { | ||
730 | struct ccw1 *cpaddr = cqr->cpaddr; | ||
731 | void *data = cqr->data; | ||
732 | |||
733 | memset(cqr, 0, sizeof(struct dasd_ccw_req)); | ||
734 | memset(cpaddr, 0, sizeof(struct ccw1)); | ||
735 | memset(data, 0, SNSS_DATA_SIZE); | ||
736 | cqr->cpaddr = cpaddr; | ||
737 | cqr->data = data; | ||
738 | strncpy((char *) &cqr->magic, "ECKD", 4); | ||
739 | ASCEBC((char *) &cqr->magic, 4); | ||
740 | set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | ||
741 | } | ||
742 | |||
743 | /* | ||
744 | * build and start an SNSS request | ||
745 | * This function is called from a work queue so we have to | ||
746 | * pass the dasd_device pointer as a void pointer. | ||
747 | */ | ||
748 | static void | ||
749 | dasd_eer_sense_subsystem_status(void *data) | ||
750 | { | ||
751 | struct dasd_device *device; | ||
752 | struct dasd_eer_private *private; | ||
753 | struct dasd_ccw_req *cqr; | ||
754 | struct ccw1 *ccw; | ||
755 | unsigned long irqflags; | ||
756 | |||
757 | device = (struct dasd_device *)data; | ||
758 | private = (struct dasd_eer_private *)device->eer; | ||
759 | if (!private) /* device not eer enabled any more */ | ||
760 | return; | ||
761 | cqr = private->cqr; | ||
762 | spin_lock_irqsave(&snsslock, irqflags); | ||
763 | if(test_and_set_bit(CQR_IN_USE, &private->flags)) { | ||
764 | set_bit(SNSS_REQUESTED, &private->flags); | ||
765 | spin_unlock_irqrestore(&snsslock, irqflags); | ||
766 | return; | ||
767 | }; | ||
768 | spin_unlock_irqrestore(&snsslock, irqflags); | ||
769 | dasd_eer_clean_SNSS_request(cqr); | ||
770 | cqr->device = device; | ||
771 | cqr->retries = 255; | ||
772 | cqr->expires = 10 * HZ; | ||
773 | |||
774 | ccw = cqr->cpaddr; | ||
775 | ccw->cmd_code = DASD_ECKD_CCW_SNSS; | ||
776 | ccw->count = SNSS_DATA_SIZE; | ||
777 | ccw->flags = 0; | ||
778 | ccw->cda = (__u32)(addr_t)cqr->data; | ||
779 | |||
780 | cqr->buildclk = get_clock(); | ||
781 | cqr->status = DASD_CQR_FILLED; | ||
782 | cqr->callback = dasd_eer_SNSS_cb; | ||
783 | cqr->callback_data = (void *)device; | ||
784 | dasd_add_request_head(cqr); | ||
785 | |||
786 | return; | ||
787 | } | ||
788 | |||
789 | /* | ||
790 | * This function is called for all triggers. It calls the appropriate | ||
791 | * function that writes the actual trigger records. | ||
792 | */ | ||
793 | static int | ||
794 | dasd_eer_write_trigger(struct dasd_eer_trigger *trigger) | ||
795 | { | ||
796 | int rc; | ||
797 | struct dasd_eer_private *private = trigger->device->eer; | ||
798 | |||
799 | switch (trigger->id) { | ||
800 | case DASD_EER_FATALERROR: | ||
801 | case DASD_EER_PPRCSUSPEND: | ||
802 | rc = dasd_eer_write_standard_trigger( | ||
803 | trigger->id, trigger->device, trigger->cqr); | ||
804 | break; | ||
805 | case DASD_EER_NOPATH: | ||
806 | rc = dasd_eer_write_standard_trigger( | ||
807 | trigger->id, trigger->device, NULL); | ||
808 | break; | ||
809 | case DASD_EER_STATECHANGE: | ||
810 | if (queue_work(dasd_eer_workqueue, &private->worker)) { | ||
811 | rc=0; | ||
812 | } else { | ||
813 | /* If the work_struct was already queued, it can't | ||
814 | * be queued again. But this is OK since we don't | ||
815 | * need to have it queued twice. | ||
816 | */ | ||
817 | rc = -EBUSY; | ||
818 | } | ||
819 | break; | ||
820 | default: /* unknown trigger, so we write it without any sense data */ | ||
821 | rc = dasd_eer_write_standard_trigger( | ||
822 | trigger->id, trigger->device, NULL); | ||
823 | break; | ||
824 | } | ||
825 | return rc; | ||
826 | } | ||
827 | |||
828 | /* | ||
829 | * This function is registered with the dasd device driver and gets called | ||
830 | * for all dasd eer notifications. | ||
831 | */ | ||
832 | static int dasd_eer_notify(struct notifier_block *self, | ||
833 | unsigned long action, void *data) | ||
834 | { | ||
835 | switch (action) { | ||
836 | case DASD_EER_DISABLE: | ||
837 | dasd_eer_disable_on_device((struct dasd_device *)data); | ||
838 | break; | ||
839 | case DASD_EER_TRIGGER: | ||
840 | dasd_eer_write_trigger((struct dasd_eer_trigger *)data); | ||
841 | break; | ||
842 | } | ||
843 | return NOTIFY_OK; | ||
844 | } | ||
845 | |||
846 | |||
847 | /*****************************************************************************/ | ||
848 | /* the device operations */ | ||
849 | /*****************************************************************************/ | ||
850 | |||
851 | /* | ||
852 | * On the one side we need a lock to access our internal buffer, on the | ||
853 | * other side a copy_to_user can sleep. So we need to copy the data we have | ||
854 | * to transfer in a readbuffer, which is protected by the readbuffer_mutex. | ||
855 | */ | ||
856 | static char readbuffer[PAGE_SIZE]; | ||
857 | DECLARE_MUTEX(readbuffer_mutex); | ||
858 | |||
859 | |||
860 | static int | ||
861 | dasd_eer_open(struct inode *inp, struct file *filp) | ||
862 | { | ||
863 | struct eerbuffer *eerb; | ||
864 | unsigned long flags; | ||
865 | |||
866 | eerb = kmalloc(sizeof(struct eerbuffer), GFP_KERNEL); | ||
867 | eerb->head = 0; | ||
868 | eerb->tail = 0; | ||
869 | eerb->residual = 0; | ||
870 | eerb->buffer_page_count = 1; | ||
871 | eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE; | ||
872 | eerb->buffer = kmalloc(eerb->buffer_page_count*sizeof(char*), | ||
873 | GFP_KERNEL); | ||
874 | if (!eerb->buffer) | ||
875 | return -ENOMEM; | ||
876 | if (dasd_eer_allocate_buffer_pages(eerb->buffer, | ||
877 | eerb->buffer_page_count)) { | ||
878 | kfree(eerb->buffer); | ||
879 | return -ENOMEM; | ||
880 | } | ||
881 | filp->private_data = eerb; | ||
882 | spin_lock_irqsave(&bufferlock, flags); | ||
883 | list_add(&eerb->list, &bufferlist); | ||
884 | spin_unlock_irqrestore(&bufferlock, flags); | ||
885 | |||
886 | return nonseekable_open(inp,filp); | ||
887 | } | ||
888 | |||
889 | static int | ||
890 | dasd_eer_close(struct inode *inp, struct file *filp) | ||
891 | { | ||
892 | struct eerbuffer *eerb; | ||
893 | unsigned long flags; | ||
894 | |||
895 | eerb = (struct eerbuffer *)filp->private_data; | ||
896 | spin_lock_irqsave(&bufferlock, flags); | ||
897 | list_del(&eerb->list); | ||
898 | spin_unlock_irqrestore(&bufferlock, flags); | ||
899 | dasd_eer_free_buffer_pages(eerb->buffer, eerb->buffer_page_count); | ||
900 | kfree(eerb->buffer); | ||
901 | kfree(eerb); | ||
902 | |||
903 | return 0; | ||
904 | } | ||
905 | |||
906 | static long | ||
907 | dasd_eer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
908 | { | ||
909 | int intval; | ||
910 | struct eerbuffer *eerb; | ||
911 | |||
912 | eerb = (struct eerbuffer *)filp->private_data; | ||
913 | switch (cmd) { | ||
914 | case DASD_EER_PURGE: | ||
915 | dasd_eer_purge_buffer(eerb); | ||
916 | return 0; | ||
917 | case DASD_EER_SETBUFSIZE: | ||
918 | if (get_user(intval, (int __user *)arg)) | ||
919 | return -EFAULT; | ||
920 | return dasd_eer_resize_buffer(eerb, intval); | ||
921 | default: | ||
922 | return -ENOIOCTLCMD; | ||
923 | } | ||
924 | } | ||
925 | |||
926 | static ssize_t | ||
927 | dasd_eer_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | ||
928 | { | ||
929 | int tc,rc; | ||
930 | int tailcount,effective_count; | ||
931 | unsigned long flags; | ||
932 | struct eerbuffer *eerb; | ||
933 | |||
934 | eerb = (struct eerbuffer *)filp->private_data; | ||
935 | if(down_interruptible(&readbuffer_mutex)) | ||
936 | return -ERESTARTSYS; | ||
937 | |||
938 | spin_lock_irqsave(&bufferlock, flags); | ||
939 | |||
940 | if (eerb->residual < 0) { /* the remainder of this record */ | ||
941 | /* has been deleted */ | ||
942 | eerb->residual = 0; | ||
943 | spin_unlock_irqrestore(&bufferlock, flags); | ||
944 | up(&readbuffer_mutex); | ||
945 | return -EIO; | ||
946 | } else if (eerb->residual > 0) { | ||
947 | /* OK we still have a second half of a record to deliver */ | ||
948 | effective_count = min(eerb->residual, (int)count); | ||
949 | eerb->residual -= effective_count; | ||
950 | } else { | ||
951 | tc = 0; | ||
952 | while (!tc) { | ||
953 | tc = dasd_eer_read_buffer(eerb, | ||
954 | sizeof(tailcount), (char*)(&tailcount)); | ||
955 | if (!tc) { | ||
956 | /* no data available */ | ||
957 | spin_unlock_irqrestore(&bufferlock, flags); | ||
958 | up(&readbuffer_mutex); | ||
959 | if (filp->f_flags & O_NONBLOCK) | ||
960 | return -EAGAIN; | ||
961 | rc = wait_event_interruptible( | ||
962 | dasd_eer_read_wait_queue, | ||
963 | eerb->head != eerb->tail); | ||
964 | if (rc) { | ||
965 | return rc; | ||
966 | } | ||
967 | if(down_interruptible(&readbuffer_mutex)) | ||
968 | return -ERESTARTSYS; | ||
969 | spin_lock_irqsave(&bufferlock, flags); | ||
970 | } | ||
971 | } | ||
972 | WARN_ON(tc != sizeof(tailcount)); | ||
973 | effective_count = min(tailcount,(int)count); | ||
974 | eerb->residual = tailcount - effective_count; | ||
975 | } | ||
976 | |||
977 | tc = dasd_eer_read_buffer(eerb, effective_count, readbuffer); | ||
978 | WARN_ON(tc != effective_count); | ||
979 | |||
980 | spin_unlock_irqrestore(&bufferlock, flags); | ||
981 | |||
982 | if (copy_to_user(buf, readbuffer, effective_count)) { | ||
983 | up(&readbuffer_mutex); | ||
984 | return -EFAULT; | ||
985 | } | ||
986 | |||
987 | up(&readbuffer_mutex); | ||
988 | return effective_count; | ||
989 | } | ||
990 | |||
991 | static unsigned int | ||
992 | dasd_eer_poll (struct file *filp, poll_table *ptable) | ||
993 | { | ||
994 | unsigned int mask; | ||
995 | unsigned long flags; | ||
996 | struct eerbuffer *eerb; | ||
997 | |||
998 | eerb = (struct eerbuffer *)filp->private_data; | ||
999 | poll_wait(filp, &dasd_eer_read_wait_queue, ptable); | ||
1000 | spin_lock_irqsave(&bufferlock, flags); | ||
1001 | if (eerb->head != eerb->tail) | ||
1002 | mask = POLLIN | POLLRDNORM ; | ||
1003 | else | ||
1004 | mask = 0; | ||
1005 | spin_unlock_irqrestore(&bufferlock, flags); | ||
1006 | return mask; | ||
1007 | } | ||
1008 | |||
1009 | static struct file_operations dasd_eer_fops = { | ||
1010 | .open = &dasd_eer_open, | ||
1011 | .release = &dasd_eer_close, | ||
1012 | .unlocked_ioctl = &dasd_eer_ioctl, | ||
1013 | .compat_ioctl = &dasd_eer_ioctl, | ||
1014 | .read = &dasd_eer_read, | ||
1015 | .poll = &dasd_eer_poll, | ||
1016 | .owner = THIS_MODULE, | ||
1017 | }; | ||
1018 | |||
1019 | static struct miscdevice dasd_eer_dev = { | ||
1020 | .minor = MISC_DYNAMIC_MINOR, | ||
1021 | .name = "dasd_eer", | ||
1022 | .fops = &dasd_eer_fops, | ||
1023 | }; | ||
1024 | |||
1025 | |||
1026 | /*****************************************************************************/ | ||
1027 | /* Init and exit */ | ||
1028 | /*****************************************************************************/ | ||
1029 | |||
1030 | static int | ||
1031 | __init dasd_eer_init(void) | ||
1032 | { | ||
1033 | int rc; | ||
1034 | |||
1035 | dasd_eer_workqueue = create_singlethread_workqueue("dasd_eer"); | ||
1036 | if (!dasd_eer_workqueue) { | ||
1037 | MESSAGE(KERN_ERR , "%s", "dasd_eer_init could not " | ||
1038 | "create workqueue \n"); | ||
1039 | rc = -ENOMEM; | ||
1040 | goto out; | ||
1041 | } | ||
1042 | |||
1043 | rc = dasd_register_eer_notifier(&dasd_eer_nb); | ||
1044 | if (rc) { | ||
1045 | MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not " | ||
1046 | "register error reporting"); | ||
1047 | goto queue; | ||
1048 | } | ||
1049 | |||
1050 | dasd_ioctl_no_register(THIS_MODULE, BIODASDEERSET, dasd_ioctl_set_eer); | ||
1051 | dasd_ioctl_no_register(THIS_MODULE, BIODASDEERGET, dasd_ioctl_get_eer); | ||
1052 | |||
1053 | /* we don't need our own character device, | ||
1054 | * so we just register as misc device */ | ||
1055 | rc = misc_register(&dasd_eer_dev); | ||
1056 | if (rc) { | ||
1057 | MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not " | ||
1058 | "register misc device"); | ||
1059 | goto unregister; | ||
1060 | } | ||
1061 | |||
1062 | return 0; | ||
1063 | |||
1064 | unregister: | ||
1065 | dasd_unregister_eer_notifier(&dasd_eer_nb); | ||
1066 | dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERSET, | ||
1067 | dasd_ioctl_set_eer); | ||
1068 | dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERGET, | ||
1069 | dasd_ioctl_get_eer); | ||
1070 | queue: | ||
1071 | destroy_workqueue(dasd_eer_workqueue); | ||
1072 | out: | ||
1073 | return rc; | ||
1074 | |||
1075 | } | ||
1076 | module_init(dasd_eer_init); | ||
1077 | |||
1078 | static void | ||
1079 | __exit dasd_eer_exit(void) | ||
1080 | { | ||
1081 | dasd_unregister_eer_notifier(&dasd_eer_nb); | ||
1082 | dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERSET, | ||
1083 | dasd_ioctl_set_eer); | ||
1084 | dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERGET, | ||
1085 | dasd_ioctl_get_eer); | ||
1086 | destroy_workqueue(dasd_eer_workqueue); | ||
1087 | |||
1088 | WARN_ON(misc_deregister(&dasd_eer_dev) != 0); | ||
1089 | } | ||
1090 | module_exit(dasd_eer_exit); | ||
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 65dc844b975c..fce2835e7d19 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c | |||
@@ -100,8 +100,6 @@ dasd_scan_partitions(struct dasd_device * device) | |||
100 | { | 100 | { |
101 | struct block_device *bdev; | 101 | struct block_device *bdev; |
102 | 102 | ||
103 | /* Make the disk known. */ | ||
104 | set_capacity(device->gdp, device->blocks << device->s2b_shift); | ||
105 | bdev = bdget_disk(device->gdp, 0); | 103 | bdev = bdget_disk(device->gdp, 0); |
106 | if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0) | 104 | if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0) |
107 | return -ENODEV; | 105 | return -ENODEV; |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index d1b08fa13fd2..7cb0b9e78a6a 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -26,7 +26,7 @@ | |||
26 | * new: the dasd_device structure is allocated. | 26 | * new: the dasd_device structure is allocated. |
27 | * known: the discipline for the device is identified. | 27 | * known: the discipline for the device is identified. |
28 | * basic: the device can do basic i/o. | 28 | * basic: the device can do basic i/o. |
29 | * accept: the device is analysed (format is known). | 29 | * unfmt: the device could not be analyzed (format is unknown). |
30 | * ready: partition detection is done and the device is can do block io. | 30 | * ready: partition detection is done and the device is can do block io. |
31 | * online: the device accepts requests from the block device queue. | 31 | * online: the device accepts requests from the block device queue. |
32 | * | 32 | * |
@@ -47,8 +47,9 @@ | |||
47 | #define DASD_STATE_NEW 0 | 47 | #define DASD_STATE_NEW 0 |
48 | #define DASD_STATE_KNOWN 1 | 48 | #define DASD_STATE_KNOWN 1 |
49 | #define DASD_STATE_BASIC 2 | 49 | #define DASD_STATE_BASIC 2 |
50 | #define DASD_STATE_READY 3 | 50 | #define DASD_STATE_UNFMT 3 |
51 | #define DASD_STATE_ONLINE 4 | 51 | #define DASD_STATE_READY 4 |
52 | #define DASD_STATE_ONLINE 5 | ||
52 | 53 | ||
53 | #include <linux/module.h> | 54 | #include <linux/module.h> |
54 | #include <linux/wait.h> | 55 | #include <linux/wait.h> |
@@ -275,34 +276,6 @@ struct dasd_discipline { | |||
275 | 276 | ||
276 | extern struct dasd_discipline *dasd_diag_discipline_pointer; | 277 | extern struct dasd_discipline *dasd_diag_discipline_pointer; |
277 | 278 | ||
278 | |||
279 | /* | ||
280 | * Notification numbers for extended error reporting notifications: | ||
281 | * The DASD_EER_DISABLE notification is sent before a dasd_device (and it's | ||
282 | * eer pointer) is freed. The error reporting module needs to do all necessary | ||
283 | * cleanup steps. | ||
284 | * The DASD_EER_TRIGGER notification sends the actual error reports (triggers). | ||
285 | */ | ||
286 | #define DASD_EER_DISABLE 0 | ||
287 | #define DASD_EER_TRIGGER 1 | ||
288 | |||
289 | /* Trigger IDs for extended error reporting DASD_EER_TRIGGER notification */ | ||
290 | #define DASD_EER_FATALERROR 1 | ||
291 | #define DASD_EER_NOPATH 2 | ||
292 | #define DASD_EER_STATECHANGE 3 | ||
293 | #define DASD_EER_PPRCSUSPEND 4 | ||
294 | |||
295 | /* | ||
296 | * The dasd_eer_trigger structure contains all data that we need to send | ||
297 | * along with an DASD_EER_TRIGGER notification. | ||
298 | */ | ||
299 | struct dasd_eer_trigger { | ||
300 | unsigned int id; | ||
301 | struct dasd_device *device; | ||
302 | struct dasd_ccw_req *cqr; | ||
303 | }; | ||
304 | |||
305 | |||
306 | struct dasd_device { | 279 | struct dasd_device { |
307 | /* Block device stuff. */ | 280 | /* Block device stuff. */ |
308 | struct gendisk *gdp; | 281 | struct gendisk *gdp; |
@@ -316,11 +289,9 @@ struct dasd_device { | |||
316 | unsigned long flags; /* per device flags */ | 289 | unsigned long flags; /* per device flags */ |
317 | unsigned short features; /* copy of devmap-features (read-only!) */ | 290 | unsigned short features; /* copy of devmap-features (read-only!) */ |
318 | 291 | ||
319 | /* extended error reporting stuff (eer) */ | ||
320 | void *eer; | ||
321 | |||
322 | /* Device discipline stuff. */ | 292 | /* Device discipline stuff. */ |
323 | struct dasd_discipline *discipline; | 293 | struct dasd_discipline *discipline; |
294 | struct dasd_discipline *base_discipline; | ||
324 | char *private; | 295 | char *private; |
325 | 296 | ||
326 | /* Device state and target state. */ | 297 | /* Device state and target state. */ |
@@ -519,12 +490,6 @@ int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); | |||
519 | int dasd_generic_set_offline (struct ccw_device *cdev); | 490 | int dasd_generic_set_offline (struct ccw_device *cdev); |
520 | int dasd_generic_notify(struct ccw_device *, int); | 491 | int dasd_generic_notify(struct ccw_device *, int); |
521 | void dasd_generic_auto_online (struct ccw_driver *); | 492 | void dasd_generic_auto_online (struct ccw_driver *); |
522 | int dasd_register_eer_notifier(struct notifier_block *); | ||
523 | int dasd_unregister_eer_notifier(struct notifier_block *); | ||
524 | void dasd_write_eer_trigger(unsigned int , struct dasd_device *, | ||
525 | struct dasd_ccw_req *); | ||
526 | |||
527 | |||
528 | 493 | ||
529 | /* externals in dasd_devmap.c */ | 494 | /* externals in dasd_devmap.c */ |
530 | extern int dasd_max_devindex; | 495 | extern int dasd_max_devindex; |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 2d5da3c75ca7..1aa3c261718a 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -93,6 +93,9 @@ dasd_devices_show(struct seq_file *m, void *v) | |||
93 | case DASD_STATE_BASIC: | 93 | case DASD_STATE_BASIC: |
94 | seq_printf(m, "basic"); | 94 | seq_printf(m, "basic"); |
95 | break; | 95 | break; |
96 | case DASD_STATE_UNFMT: | ||
97 | seq_printf(m, "unformatted"); | ||
98 | break; | ||
96 | case DASD_STATE_READY: | 99 | case DASD_STATE_READY: |
97 | case DASD_STATE_ONLINE: | 100 | case DASD_STATE_ONLINE: |
98 | seq_printf(m, "active "); | 101 | seq_printf(m, "active "); |
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index ceb0e474fde4..4138564402b8 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c | |||
@@ -85,11 +85,10 @@ static volatile enum sclp_mask_state_t { | |||
85 | /* Maximum retry counts */ | 85 | /* Maximum retry counts */ |
86 | #define SCLP_INIT_RETRY 3 | 86 | #define SCLP_INIT_RETRY 3 |
87 | #define SCLP_MASK_RETRY 3 | 87 | #define SCLP_MASK_RETRY 3 |
88 | #define SCLP_REQUEST_RETRY 3 | ||
89 | 88 | ||
90 | /* Timeout intervals in seconds.*/ | 89 | /* Timeout intervals in seconds.*/ |
91 | #define SCLP_BUSY_INTERVAL 2 | 90 | #define SCLP_BUSY_INTERVAL 10 |
92 | #define SCLP_RETRY_INTERVAL 5 | 91 | #define SCLP_RETRY_INTERVAL 15 |
93 | 92 | ||
94 | static void sclp_process_queue(void); | 93 | static void sclp_process_queue(void); |
95 | static int sclp_init_mask(int calculate); | 94 | static int sclp_init_mask(int calculate); |
@@ -153,11 +152,9 @@ __sclp_start_request(struct sclp_req *req) | |||
153 | if (sclp_running_state != sclp_running_state_idle) | 152 | if (sclp_running_state != sclp_running_state_idle) |
154 | return 0; | 153 | return 0; |
155 | del_timer(&sclp_request_timer); | 154 | del_timer(&sclp_request_timer); |
156 | if (req->start_count <= SCLP_REQUEST_RETRY) { | 155 | rc = service_call(req->command, req->sccb); |
157 | rc = service_call(req->command, req->sccb); | 156 | req->start_count++; |
158 | req->start_count++; | 157 | |
159 | } else | ||
160 | rc = -EIO; | ||
161 | if (rc == 0) { | 158 | if (rc == 0) { |
162 | /* Sucessfully started request */ | 159 | /* Sucessfully started request */ |
163 | req->status = SCLP_REQ_RUNNING; | 160 | req->status = SCLP_REQ_RUNNING; |
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 92be75d99a56..f4183d660258 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -232,7 +232,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) | |||
232 | return 0; | 232 | return 0; |
233 | 233 | ||
234 | mask = 0x80 >> j; | 234 | mask = 0x80 >> j; |
235 | spin_lock(&sch->lock); | 235 | spin_lock_irq(&sch->lock); |
236 | 236 | ||
237 | stsch(sch->schid, &schib); | 237 | stsch(sch->schid, &schib); |
238 | if (!schib.pmcw.dnv) | 238 | if (!schib.pmcw.dnv) |
@@ -281,10 +281,10 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) | |||
281 | if (sch->driver && sch->driver->verify) | 281 | if (sch->driver && sch->driver->verify) |
282 | sch->driver->verify(&sch->dev); | 282 | sch->driver->verify(&sch->dev); |
283 | out_unlock: | 283 | out_unlock: |
284 | spin_unlock(&sch->lock); | 284 | spin_unlock_irq(&sch->lock); |
285 | return 0; | 285 | return 0; |
286 | out_unreg: | 286 | out_unreg: |
287 | spin_unlock(&sch->lock); | 287 | spin_unlock_irq(&sch->lock); |
288 | sch->lpm = 0; | 288 | sch->lpm = 0; |
289 | if (css_enqueue_subchannel_slow(sch->schid)) { | 289 | if (css_enqueue_subchannel_slow(sch->schid)) { |
290 | css_clear_subchannel_slow_list(); | 290 | css_clear_subchannel_slow_list(); |
@@ -652,7 +652,7 @@ __chp_add(struct subchannel_id schid, void *data) | |||
652 | if (!sch) | 652 | if (!sch) |
653 | /* Check if the subchannel is now available. */ | 653 | /* Check if the subchannel is now available. */ |
654 | return __chp_add_new_sch(schid); | 654 | return __chp_add_new_sch(schid); |
655 | spin_lock(&sch->lock); | 655 | spin_lock_irq(&sch->lock); |
656 | for (i=0; i<8; i++) | 656 | for (i=0; i<8; i++) |
657 | if (sch->schib.pmcw.chpid[i] == chp->id) { | 657 | if (sch->schib.pmcw.chpid[i] == chp->id) { |
658 | if (stsch(sch->schid, &sch->schib) != 0) { | 658 | if (stsch(sch->schid, &sch->schib) != 0) { |
@@ -674,7 +674,7 @@ __chp_add(struct subchannel_id schid, void *data) | |||
674 | if (sch->driver && sch->driver->verify) | 674 | if (sch->driver && sch->driver->verify) |
675 | sch->driver->verify(&sch->dev); | 675 | sch->driver->verify(&sch->dev); |
676 | 676 | ||
677 | spin_unlock(&sch->lock); | 677 | spin_unlock_irq(&sch->lock); |
678 | put_device(&sch->dev); | 678 | put_device(&sch->dev); |
679 | return 0; | 679 | return 0; |
680 | } | 680 | } |
@@ -1115,6 +1115,9 @@ chsc_enable_facility(int operation_code) | |||
1115 | goto out; | 1115 | goto out; |
1116 | } | 1116 | } |
1117 | switch (sda_area->response.code) { | 1117 | switch (sda_area->response.code) { |
1118 | case 0x0001: /* everything ok */ | ||
1119 | ret = 0; | ||
1120 | break; | ||
1118 | case 0x0003: /* invalid request block */ | 1121 | case 0x0003: /* invalid request block */ |
1119 | case 0x0007: | 1122 | case 0x0007: |
1120 | ret = -EINVAL; | 1123 | ret = -EINVAL; |
@@ -1123,6 +1126,8 @@ chsc_enable_facility(int operation_code) | |||
1123 | case 0x0101: /* facility not provided */ | 1126 | case 0x0101: /* facility not provided */ |
1124 | ret = -EOPNOTSUPP; | 1127 | ret = -EOPNOTSUPP; |
1125 | break; | 1128 | break; |
1129 | default: /* something went wrong */ | ||
1130 | ret = -EIO; | ||
1126 | } | 1131 | } |
1127 | out: | 1132 | out: |
1128 | free_page((unsigned long)sda_area); | 1133 | free_page((unsigned long)sda_area); |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 1bbf231f8aaf..3c77d65960db 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -409,6 +409,9 @@ __init_channel_subsystem(struct subchannel_id schid, void *data) | |||
409 | /* -ENXIO: no more subchannels. */ | 409 | /* -ENXIO: no more subchannels. */ |
410 | case -ENXIO: | 410 | case -ENXIO: |
411 | return ret; | 411 | return ret; |
412 | /* -EIO: this subchannel set not supported. */ | ||
413 | case -EIO: | ||
414 | return ret; | ||
412 | default: | 415 | default: |
413 | return 0; | 416 | return 0; |
414 | } | 417 | } |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 062fb100d94c..afc4e88551ad 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -359,7 +359,7 @@ ccw_device_set_online(struct ccw_device *cdev) | |||
359 | else | 359 | else |
360 | pr_debug("ccw_device_offline returned %d, device %s\n", | 360 | pr_debug("ccw_device_offline returned %d, device %s\n", |
361 | ret, cdev->dev.bus_id); | 361 | ret, cdev->dev.bus_id); |
362 | return (ret = 0) ? -ENODEV : ret; | 362 | return (ret == 0) ? -ENODEV : ret; |
363 | } | 363 | } |
364 | 364 | ||
365 | static ssize_t | 365 | static ssize_t |
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index d2a5b04d7cba..85b1020a1fcc 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
@@ -405,7 +405,7 @@ __ccw_device_disband_start(struct ccw_device *cdev) | |||
405 | cdev->private->iretry = 5; | 405 | cdev->private->iretry = 5; |
406 | cdev->private->imask >>= 1; | 406 | cdev->private->imask >>= 1; |
407 | } | 407 | } |
408 | ccw_device_verify_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV); | 408 | ccw_device_disband_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV); |
409 | } | 409 | } |
410 | 410 | ||
411 | /* | 411 | /* |
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c index dad4dd9887c9..6c762b43f921 100644 --- a/drivers/s390/cio/device_status.c +++ b/drivers/s390/cio/device_status.c | |||
@@ -317,7 +317,6 @@ ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb) | |||
317 | /* | 317 | /* |
318 | * We have ending status but no sense information. Do a basic sense. | 318 | * We have ending status but no sense information. Do a basic sense. |
319 | */ | 319 | */ |
320 | sch = to_subchannel(cdev->dev.parent); | ||
321 | sch->sense_ccw.cmd_code = CCW_CMD_BASIC_SENSE; | 320 | sch->sense_ccw.cmd_code = CCW_CMD_BASIC_SENSE; |
322 | sch->sense_ccw.cda = (__u32) __pa(cdev->private->irb.ecw); | 321 | sch->sense_ccw.cda = (__u32) __pa(cdev->private->irb.ecw); |
323 | sch->sense_ccw.count = SENSE_MAX_COUNT; | 322 | sch->sense_ccw.count = SENSE_MAX_COUNT; |
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 45ce032772f4..9ed37dc9a1b0 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c | |||
@@ -165,8 +165,13 @@ qdio_do_eqbs(struct qdio_q *q, unsigned char *state, | |||
165 | q_no = q->q_no; | 165 | q_no = q->q_no; |
166 | if(!q->is_input_q) | 166 | if(!q->is_input_q) |
167 | q_no += irq->no_input_qs; | 167 | q_no += irq->no_input_qs; |
168 | again: | ||
168 | ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); | 169 | ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); |
169 | rc = qdio_check_ccq(q, ccq); | 170 | rc = qdio_check_ccq(q, ccq); |
171 | if (rc == 1) { | ||
172 | QDIO_DBF_TEXT5(1,trace,"eqAGAIN"); | ||
173 | goto again; | ||
174 | } | ||
170 | if (rc < 0) { | 175 | if (rc < 0) { |
171 | QDIO_DBF_TEXT2(1,trace,"eqberr"); | 176 | QDIO_DBF_TEXT2(1,trace,"eqberr"); |
172 | sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt, *cnt, ccq, q_no); | 177 | sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt, *cnt, ccq, q_no); |
@@ -195,8 +200,13 @@ qdio_do_sqbs(struct qdio_q *q, unsigned char state, | |||
195 | q_no = q->q_no; | 200 | q_no = q->q_no; |
196 | if(!q->is_input_q) | 201 | if(!q->is_input_q) |
197 | q_no += irq->no_input_qs; | 202 | q_no += irq->no_input_qs; |
203 | again: | ||
198 | ccq = do_sqbs(irq->sch_token, state, q_no, start, cnt); | 204 | ccq = do_sqbs(irq->sch_token, state, q_no, start, cnt); |
199 | rc = qdio_check_ccq(q, ccq); | 205 | rc = qdio_check_ccq(q, ccq); |
206 | if (rc == 1) { | ||
207 | QDIO_DBF_TEXT5(1,trace,"sqAGAIN"); | ||
208 | goto again; | ||
209 | } | ||
200 | if (rc < 0) { | 210 | if (rc < 0) { |
201 | QDIO_DBF_TEXT3(1,trace,"sqberr"); | 211 | QDIO_DBF_TEXT3(1,trace,"sqberr"); |
202 | sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt,*cnt,ccq,q_no); | 212 | sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt,*cnt,ccq,q_no); |
@@ -1187,8 +1197,7 @@ tiqdio_is_inbound_q_done(struct qdio_q *q) | |||
1187 | 1197 | ||
1188 | if (!no_used) | 1198 | if (!no_used) |
1189 | return 1; | 1199 | return 1; |
1190 | 1200 | if (!q->siga_sync && !irq->is_qebsm) | |
1191 | if (!q->siga_sync) | ||
1192 | /* we'll check for more primed buffers in qeth_stop_polling */ | 1201 | /* we'll check for more primed buffers in qeth_stop_polling */ |
1193 | return 0; | 1202 | return 0; |
1194 | if (irq->is_qebsm) { | 1203 | if (irq->is_qebsm) { |
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 6229ba4995ad..9cf88d7201d3 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -98,9 +98,9 @@ lcs_register_debug_facility(void) | |||
98 | return -ENOMEM; | 98 | return -ENOMEM; |
99 | } | 99 | } |
100 | debug_register_view(lcs_dbf_setup, &debug_hex_ascii_view); | 100 | debug_register_view(lcs_dbf_setup, &debug_hex_ascii_view); |
101 | debug_set_level(lcs_dbf_setup, 4); | 101 | debug_set_level(lcs_dbf_setup, 2); |
102 | debug_register_view(lcs_dbf_trace, &debug_hex_ascii_view); | 102 | debug_register_view(lcs_dbf_trace, &debug_hex_ascii_view); |
103 | debug_set_level(lcs_dbf_trace, 4); | 103 | debug_set_level(lcs_dbf_trace, 2); |
104 | return 0; | 104 | return 0; |
105 | } | 105 | } |
106 | 106 | ||
@@ -1292,9 +1292,8 @@ lcs_set_multicast_list(struct net_device *dev) | |||
1292 | LCS_DBF_TEXT(4, trace, "setmulti"); | 1292 | LCS_DBF_TEXT(4, trace, "setmulti"); |
1293 | card = (struct lcs_card *) dev->priv; | 1293 | card = (struct lcs_card *) dev->priv; |
1294 | 1294 | ||
1295 | if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) { | 1295 | if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) |
1296 | schedule_work(&card->kernel_thread_starter); | 1296 | schedule_work(&card->kernel_thread_starter); |
1297 | } | ||
1298 | } | 1297 | } |
1299 | 1298 | ||
1300 | #endif /* CONFIG_IP_MULTICAST */ | 1299 | #endif /* CONFIG_IP_MULTICAST */ |
@@ -1459,6 +1458,8 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) | |||
1459 | lcs_release_buffer(channel, buffer); | 1458 | lcs_release_buffer(channel, buffer); |
1460 | card = (struct lcs_card *) | 1459 | card = (struct lcs_card *) |
1461 | ((char *) channel - offsetof(struct lcs_card, write)); | 1460 | ((char *) channel - offsetof(struct lcs_card, write)); |
1461 | if (netif_queue_stopped(card->dev)) | ||
1462 | netif_wake_queue(card->dev); | ||
1462 | spin_lock(&card->lock); | 1463 | spin_lock(&card->lock); |
1463 | card->tx_emitted--; | 1464 | card->tx_emitted--; |
1464 | if (card->tx_emitted <= 0 && card->tx_buffer != NULL) | 1465 | if (card->tx_emitted <= 0 && card->tx_buffer != NULL) |
@@ -1478,6 +1479,7 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, | |||
1478 | struct net_device *dev) | 1479 | struct net_device *dev) |
1479 | { | 1480 | { |
1480 | struct lcs_header *header; | 1481 | struct lcs_header *header; |
1482 | int rc = 0; | ||
1481 | 1483 | ||
1482 | LCS_DBF_TEXT(5, trace, "hardxmit"); | 1484 | LCS_DBF_TEXT(5, trace, "hardxmit"); |
1483 | if (skb == NULL) { | 1485 | if (skb == NULL) { |
@@ -1492,10 +1494,8 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, | |||
1492 | card->stats.tx_carrier_errors++; | 1494 | card->stats.tx_carrier_errors++; |
1493 | return 0; | 1495 | return 0; |
1494 | } | 1496 | } |
1495 | if (netif_queue_stopped(dev) ) { | 1497 | netif_stop_queue(card->dev); |
1496 | card->stats.tx_dropped++; | 1498 | spin_lock(&card->lock); |
1497 | return -EBUSY; | ||
1498 | } | ||
1499 | if (card->tx_buffer != NULL && | 1499 | if (card->tx_buffer != NULL && |
1500 | card->tx_buffer->count + sizeof(struct lcs_header) + | 1500 | card->tx_buffer->count + sizeof(struct lcs_header) + |
1501 | skb->len + sizeof(u16) > LCS_IOBUFFERSIZE) | 1501 | skb->len + sizeof(u16) > LCS_IOBUFFERSIZE) |
@@ -1506,7 +1506,8 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, | |||
1506 | card->tx_buffer = lcs_get_buffer(&card->write); | 1506 | card->tx_buffer = lcs_get_buffer(&card->write); |
1507 | if (card->tx_buffer == NULL) { | 1507 | if (card->tx_buffer == NULL) { |
1508 | card->stats.tx_dropped++; | 1508 | card->stats.tx_dropped++; |
1509 | return -EBUSY; | 1509 | rc = -EBUSY; |
1510 | goto out; | ||
1510 | } | 1511 | } |
1511 | card->tx_buffer->callback = lcs_txbuffer_cb; | 1512 | card->tx_buffer->callback = lcs_txbuffer_cb; |
1512 | card->tx_buffer->count = 0; | 1513 | card->tx_buffer->count = 0; |
@@ -1518,13 +1519,18 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, | |||
1518 | header->type = card->lan_type; | 1519 | header->type = card->lan_type; |
1519 | header->slot = card->portno; | 1520 | header->slot = card->portno; |
1520 | memcpy(header + 1, skb->data, skb->len); | 1521 | memcpy(header + 1, skb->data, skb->len); |
1522 | spin_unlock(&card->lock); | ||
1521 | card->stats.tx_bytes += skb->len; | 1523 | card->stats.tx_bytes += skb->len; |
1522 | card->stats.tx_packets++; | 1524 | card->stats.tx_packets++; |
1523 | dev_kfree_skb(skb); | 1525 | dev_kfree_skb(skb); |
1524 | if (card->tx_emitted <= 0) | 1526 | netif_wake_queue(card->dev); |
1527 | spin_lock(&card->lock); | ||
1528 | if (card->tx_emitted <= 0 && card->tx_buffer != NULL) | ||
1525 | /* If this is the first tx buffer emit it immediately. */ | 1529 | /* If this is the first tx buffer emit it immediately. */ |
1526 | __lcs_emit_txbuffer(card); | 1530 | __lcs_emit_txbuffer(card); |
1527 | return 0; | 1531 | out: |
1532 | spin_unlock(&card->lock); | ||
1533 | return rc; | ||
1528 | } | 1534 | } |
1529 | 1535 | ||
1530 | static int | 1536 | static int |
@@ -1535,9 +1541,7 @@ lcs_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1535 | 1541 | ||
1536 | LCS_DBF_TEXT(5, trace, "pktxmit"); | 1542 | LCS_DBF_TEXT(5, trace, "pktxmit"); |
1537 | card = (struct lcs_card *) dev->priv; | 1543 | card = (struct lcs_card *) dev->priv; |
1538 | spin_lock(&card->lock); | ||
1539 | rc = __lcs_start_xmit(card, skb, dev); | 1544 | rc = __lcs_start_xmit(card, skb, dev); |
1540 | spin_unlock(&card->lock); | ||
1541 | return rc; | 1545 | return rc; |
1542 | } | 1546 | } |
1543 | 1547 | ||
@@ -2319,7 +2323,6 @@ __init lcs_init_module(void) | |||
2319 | PRINT_ERR("Initialization failed\n"); | 2323 | PRINT_ERR("Initialization failed\n"); |
2320 | return rc; | 2324 | return rc; |
2321 | } | 2325 | } |
2322 | |||
2323 | return 0; | 2326 | return 0; |
2324 | } | 2327 | } |
2325 | 2328 | ||
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h index 08e60ad43916..2fad5e40c2e4 100644 --- a/drivers/s390/net/lcs.h +++ b/drivers/s390/net/lcs.h | |||
@@ -95,7 +95,7 @@ do { \ | |||
95 | */ | 95 | */ |
96 | #define LCS_ILLEGAL_OFFSET 0xffff | 96 | #define LCS_ILLEGAL_OFFSET 0xffff |
97 | #define LCS_IOBUFFERSIZE 0x5000 | 97 | #define LCS_IOBUFFERSIZE 0x5000 |
98 | #define LCS_NUM_BUFFS 8 /* needs to be power of 2 */ | 98 | #define LCS_NUM_BUFFS 32 /* needs to be power of 2 */ |
99 | #define LCS_MAC_LENGTH 6 | 99 | #define LCS_MAC_LENGTH 6 |
100 | #define LCS_INVALID_PORT_NO -1 | 100 | #define LCS_INVALID_PORT_NO -1 |
101 | #define LCS_LANCMD_TIMEOUT_DEFAULT 5 | 101 | #define LCS_LANCMD_TIMEOUT_DEFAULT 5 |
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 9a064d4727ad..4df0fcd7b10b 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h | |||
@@ -1076,16 +1076,6 @@ qeth_get_qdio_q_format(struct qeth_card *card) | |||
1076 | } | 1076 | } |
1077 | 1077 | ||
1078 | static inline int | 1078 | static inline int |
1079 | qeth_isdigit(char * buf) | ||
1080 | { | ||
1081 | while (*buf) { | ||
1082 | if (!isdigit(*buf++)) | ||
1083 | return 0; | ||
1084 | } | ||
1085 | return 1; | ||
1086 | } | ||
1087 | |||
1088 | static inline int | ||
1089 | qeth_isxdigit(char * buf) | 1079 | qeth_isxdigit(char * buf) |
1090 | { | 1080 | { |
1091 | while (*buf) { | 1081 | while (*buf) { |
@@ -1104,33 +1094,17 @@ qeth_ipaddr4_to_string(const __u8 *addr, char *buf) | |||
1104 | static inline int | 1094 | static inline int |
1105 | qeth_string_to_ipaddr4(const char *buf, __u8 *addr) | 1095 | qeth_string_to_ipaddr4(const char *buf, __u8 *addr) |
1106 | { | 1096 | { |
1107 | const char *start, *end; | 1097 | int count = 0, rc = 0; |
1108 | char abuf[4]; | 1098 | int in[4]; |
1109 | char *tmp; | 1099 | |
1110 | int len; | 1100 | rc = sscanf(buf, "%d.%d.%d.%d%n", |
1111 | int i; | 1101 | &in[0], &in[1], &in[2], &in[3], &count); |
1112 | 1102 | if (rc != 4 || count) | |
1113 | start = buf; | 1103 | return -EINVAL; |
1114 | for (i = 0; i < 4; i++) { | 1104 | for (count = 0; count < 4; count++) { |
1115 | if (i == 3) { | 1105 | if (in[count] > 255) |
1116 | end = strchr(start,0xa); | ||
1117 | if (end) | ||
1118 | len = end - start; | ||
1119 | else | ||
1120 | len = strlen(start); | ||
1121 | } | ||
1122 | else { | ||
1123 | end = strchr(start, '.'); | ||
1124 | len = end - start; | ||
1125 | } | ||
1126 | if ((len <= 0) || (len > 3)) | ||
1127 | return -EINVAL; | ||
1128 | memset(abuf, 0, 4); | ||
1129 | strncpy(abuf, start, len); | ||
1130 | if (!qeth_isdigit(abuf)) | ||
1131 | return -EINVAL; | 1106 | return -EINVAL; |
1132 | addr[i] = simple_strtoul(abuf, &tmp, 10); | 1107 | addr[count] = in[count]; |
1133 | start = end + 1; | ||
1134 | } | 1108 | } |
1135 | return 0; | 1109 | return 0; |
1136 | } | 1110 | } |
@@ -1149,36 +1123,44 @@ qeth_ipaddr6_to_string(const __u8 *addr, char *buf) | |||
1149 | static inline int | 1123 | static inline int |
1150 | qeth_string_to_ipaddr6(const char *buf, __u8 *addr) | 1124 | qeth_string_to_ipaddr6(const char *buf, __u8 *addr) |
1151 | { | 1125 | { |
1152 | const char *start, *end; | 1126 | char *end, *start; |
1153 | u16 *tmp_addr; | 1127 | __u16 *in; |
1154 | char abuf[5]; | 1128 | char num[5]; |
1155 | char *tmp; | 1129 | int num2, cnt, out, found, save_cnt; |
1156 | int len; | 1130 | unsigned short in_tmp[8] = {0, }; |
1157 | int i; | 1131 | |
1158 | 1132 | cnt = out = found = save_cnt = num2 = 0; | |
1159 | tmp_addr = (u16 *)addr; | 1133 | end = start = (char *) buf; |
1160 | start = buf; | 1134 | in = (__u16 *) addr; |
1161 | for (i = 0; i < 8; i++) { | 1135 | memset(in, 0, 16); |
1162 | if (i == 7) { | 1136 | while (end) { |
1163 | end = strchr(start,0xa); | 1137 | end = strchr(end,':'); |
1164 | if (end) | 1138 | if (end == NULL) { |
1165 | len = end - start; | 1139 | end = (char *)buf + (strlen(buf)); |
1166 | else | 1140 | out = 1; |
1167 | len = strlen(start); | 1141 | } |
1168 | } | 1142 | if ((end - start)) { |
1169 | else { | 1143 | memset(num, 0, 5); |
1170 | end = strchr(start, ':'); | 1144 | memcpy(num, start, end - start); |
1171 | len = end - start; | 1145 | if (!qeth_isxdigit(num)) |
1146 | return -EINVAL; | ||
1147 | sscanf(start, "%x", &num2); | ||
1148 | if (found) | ||
1149 | in_tmp[save_cnt++] = num2; | ||
1150 | else | ||
1151 | in[cnt++] = num2; | ||
1152 | if (out) | ||
1153 | break; | ||
1154 | } else { | ||
1155 | if (found) | ||
1156 | return -EINVAL; | ||
1157 | found = 1; | ||
1172 | } | 1158 | } |
1173 | if ((len <= 0) || (len > 4)) | 1159 | start = ++end; |
1174 | return -EINVAL; | 1160 | } |
1175 | memset(abuf, 0, 5); | 1161 | cnt = 7; |
1176 | strncpy(abuf, start, len); | 1162 | while (save_cnt) |
1177 | if (!qeth_isxdigit(abuf)) | 1163 | in[cnt--] = in_tmp[--save_cnt]; |
1178 | return -EINVAL; | ||
1179 | tmp_addr[i] = simple_strtoul(abuf, &tmp, 16); | ||
1180 | start = end + 1; | ||
1181 | } | ||
1182 | return 0; | 1164 | return 0; |
1183 | } | 1165 | } |
1184 | 1166 | ||
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c index b02313127780..82cb4af2f0e7 100644 --- a/drivers/s390/net/qeth_eddp.c +++ b/drivers/s390/net/qeth_eddp.c | |||
@@ -59,8 +59,7 @@ qeth_eddp_free_context(struct qeth_eddp_context *ctx) | |||
59 | for (i = 0; i < ctx->num_pages; ++i) | 59 | for (i = 0; i < ctx->num_pages; ++i) |
60 | free_page((unsigned long)ctx->pages[i]); | 60 | free_page((unsigned long)ctx->pages[i]); |
61 | kfree(ctx->pages); | 61 | kfree(ctx->pages); |
62 | if (ctx->elements != NULL) | 62 | kfree(ctx->elements); |
63 | kfree(ctx->elements); | ||
64 | kfree(ctx); | 63 | kfree(ctx); |
65 | } | 64 | } |
66 | 65 | ||
@@ -413,6 +412,13 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, | |||
413 | 412 | ||
414 | QETH_DBF_TEXT(trace, 5, "eddpftcp"); | 413 | QETH_DBF_TEXT(trace, 5, "eddpftcp"); |
415 | eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl; | 414 | eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl; |
415 | if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) { | ||
416 | eddp->skb_offset += sizeof(struct ethhdr); | ||
417 | #ifdef CONFIG_QETH_VLAN | ||
418 | if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) | ||
419 | eddp->skb_offset += VLAN_HLEN; | ||
420 | #endif /* CONFIG_QETH_VLAN */ | ||
421 | } | ||
416 | tcph = eddp->skb->h.th; | 422 | tcph = eddp->skb->h.th; |
417 | while (eddp->skb_offset < eddp->skb->len) { | 423 | while (eddp->skb_offset < eddp->skb->len) { |
418 | data_len = min((int)skb_shinfo(eddp->skb)->tso_size, | 424 | data_len = min((int)skb_shinfo(eddp->skb)->tso_size, |
@@ -483,6 +489,7 @@ qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, | |||
483 | return -ENOMEM; | 489 | return -ENOMEM; |
484 | } | 490 | } |
485 | if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) { | 491 | if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) { |
492 | skb->mac.raw = (skb->data) + sizeof(struct qeth_hdr); | ||
486 | memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN); | 493 | memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN); |
487 | #ifdef CONFIG_QETH_VLAN | 494 | #ifdef CONFIG_QETH_VLAN |
488 | if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) { | 495 | if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) { |
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 410abeada6c4..dba7f7f02e79 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -516,7 +516,8 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) | |||
516 | QETH_DBF_TEXT(setup, 3, "setoffl"); | 516 | QETH_DBF_TEXT(setup, 3, "setoffl"); |
517 | QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); | 517 | QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); |
518 | 518 | ||
519 | netif_carrier_off(card->dev); | 519 | if (card->dev && netif_carrier_ok(card->dev)) |
520 | netif_carrier_off(card->dev); | ||
520 | recover_flag = card->state; | 521 | recover_flag = card->state; |
521 | if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){ | 522 | if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){ |
522 | PRINT_WARN("Stopping card %s interrupted by user!\n", | 523 | PRINT_WARN("Stopping card %s interrupted by user!\n", |
@@ -1679,6 +1680,7 @@ qeth_cmd_timeout(unsigned long data) | |||
1679 | spin_unlock_irqrestore(&reply->card->lock, flags); | 1680 | spin_unlock_irqrestore(&reply->card->lock, flags); |
1680 | } | 1681 | } |
1681 | 1682 | ||
1683 | |||
1682 | static struct qeth_ipa_cmd * | 1684 | static struct qeth_ipa_cmd * |
1683 | qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) | 1685 | qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) |
1684 | { | 1686 | { |
@@ -1699,7 +1701,8 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) | |||
1699 | QETH_CARD_IFNAME(card), | 1701 | QETH_CARD_IFNAME(card), |
1700 | card->info.chpid); | 1702 | card->info.chpid); |
1701 | card->lan_online = 0; | 1703 | card->lan_online = 0; |
1702 | netif_carrier_off(card->dev); | 1704 | if (card->dev && netif_carrier_ok(card->dev)) |
1705 | netif_carrier_off(card->dev); | ||
1703 | return NULL; | 1706 | return NULL; |
1704 | case IPA_CMD_STARTLAN: | 1707 | case IPA_CMD_STARTLAN: |
1705 | PRINT_INFO("Link reestablished on %s " | 1708 | PRINT_INFO("Link reestablished on %s " |
@@ -5562,7 +5565,7 @@ qeth_set_multicast_list(struct net_device *dev) | |||
5562 | if (card->info.type == QETH_CARD_TYPE_OSN) | 5565 | if (card->info.type == QETH_CARD_TYPE_OSN) |
5563 | return ; | 5566 | return ; |
5564 | 5567 | ||
5565 | QETH_DBF_TEXT(trace,3,"setmulti"); | 5568 | QETH_DBF_TEXT(trace, 3, "setmulti"); |
5566 | qeth_delete_mc_addresses(card); | 5569 | qeth_delete_mc_addresses(card); |
5567 | if (card->options.layer2) { | 5570 | if (card->options.layer2) { |
5568 | qeth_layer2_add_multicast(card); | 5571 | qeth_layer2_add_multicast(card); |
@@ -5579,7 +5582,6 @@ out: | |||
5579 | return; | 5582 | return; |
5580 | if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0) | 5583 | if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0) |
5581 | schedule_work(&card->kernel_thread_starter); | 5584 | schedule_work(&card->kernel_thread_starter); |
5582 | |||
5583 | } | 5585 | } |
5584 | 5586 | ||
5585 | static int | 5587 | static int |
@@ -7452,6 +7454,7 @@ qeth_softsetup_card(struct qeth_card *card) | |||
7452 | card->lan_online = 1; | 7454 | card->lan_online = 1; |
7453 | if (card->info.type==QETH_CARD_TYPE_OSN) | 7455 | if (card->info.type==QETH_CARD_TYPE_OSN) |
7454 | goto out; | 7456 | goto out; |
7457 | qeth_set_large_send(card, card->options.large_send); | ||
7455 | if (card->options.layer2) { | 7458 | if (card->options.layer2) { |
7456 | card->dev->features |= | 7459 | card->dev->features |= |
7457 | NETIF_F_HW_VLAN_FILTER | | 7460 | NETIF_F_HW_VLAN_FILTER | |
@@ -7468,12 +7471,6 @@ qeth_softsetup_card(struct qeth_card *card) | |||
7468 | #endif | 7471 | #endif |
7469 | goto out; | 7472 | goto out; |
7470 | } | 7473 | } |
7471 | if ((card->options.large_send == QETH_LARGE_SEND_EDDP) || | ||
7472 | (card->options.large_send == QETH_LARGE_SEND_TSO)) | ||
7473 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG; | ||
7474 | else | ||
7475 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); | ||
7476 | |||
7477 | if ((rc = qeth_setadapter_parms(card))) | 7474 | if ((rc = qeth_setadapter_parms(card))) |
7478 | QETH_DBF_TEXT_(setup, 2, "2err%d", rc); | 7475 | QETH_DBF_TEXT_(setup, 2, "2err%d", rc); |
7479 | if ((rc = qeth_start_ipassists(card))) | 7476 | if ((rc = qeth_start_ipassists(card))) |
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index d6469baa7e16..72118ee68954 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -168,7 +168,7 @@ smsg_init(void) | |||
168 | driver_unregister(&smsg_driver); | 168 | driver_unregister(&smsg_driver); |
169 | return -EIO; /* better errno ? */ | 169 | return -EIO; /* better errno ? */ |
170 | } | 170 | } |
171 | rc = iucv_connect (&smsg_pathid, 1, 0, "*MSG ", 0, 0, 0, 0, | 171 | rc = iucv_connect (&smsg_pathid, 255, 0, "*MSG ", 0, 0, 0, 0, |
172 | smsg_handle, 0); | 172 | smsg_handle, 0); |
173 | if (rc) { | 173 | if (rc) { |
174 | printk(KERN_ERR "SMSGIUCV: failed to connect to *MSG"); | 174 | printk(KERN_ERR "SMSGIUCV: failed to connect to *MSG"); |
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 4d7d47cf2394..a5f2ba9a8fdb 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
@@ -710,10 +710,9 @@ static inline void | |||
710 | _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | 710 | _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, |
711 | struct zfcp_adapter *adapter, | 711 | struct zfcp_adapter *adapter, |
712 | struct scsi_cmnd *scsi_cmnd, | 712 | struct scsi_cmnd *scsi_cmnd, |
713 | struct zfcp_fsf_req *new_fsf_req) | 713 | struct zfcp_fsf_req *fsf_req, |
714 | struct zfcp_fsf_req *old_fsf_req) | ||
714 | { | 715 | { |
715 | struct zfcp_fsf_req *fsf_req = | ||
716 | (struct zfcp_fsf_req *)scsi_cmnd->host_scribble; | ||
717 | struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; | 716 | struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; |
718 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; | 717 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; |
719 | unsigned long flags; | 718 | unsigned long flags; |
@@ -727,19 +726,20 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | |||
727 | if (offset == 0) { | 726 | if (offset == 0) { |
728 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); | 727 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); |
729 | strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); | 728 | strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); |
730 | if (scsi_cmnd->device) { | 729 | if (scsi_cmnd != NULL) { |
731 | rec->scsi_id = scsi_cmnd->device->id; | 730 | if (scsi_cmnd->device) { |
732 | rec->scsi_lun = scsi_cmnd->device->lun; | 731 | rec->scsi_id = scsi_cmnd->device->id; |
732 | rec->scsi_lun = scsi_cmnd->device->lun; | ||
733 | } | ||
734 | rec->scsi_result = scsi_cmnd->result; | ||
735 | rec->scsi_cmnd = (unsigned long)scsi_cmnd; | ||
736 | rec->scsi_serial = scsi_cmnd->serial_number; | ||
737 | memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd, | ||
738 | min((int)scsi_cmnd->cmd_len, | ||
739 | ZFCP_DBF_SCSI_OPCODE)); | ||
740 | rec->scsi_retries = scsi_cmnd->retries; | ||
741 | rec->scsi_allowed = scsi_cmnd->allowed; | ||
733 | } | 742 | } |
734 | rec->scsi_result = scsi_cmnd->result; | ||
735 | rec->scsi_cmnd = (unsigned long)scsi_cmnd; | ||
736 | rec->scsi_serial = scsi_cmnd->serial_number; | ||
737 | memcpy(rec->scsi_opcode, | ||
738 | &scsi_cmnd->cmnd, | ||
739 | min((int)scsi_cmnd->cmd_len, | ||
740 | ZFCP_DBF_SCSI_OPCODE)); | ||
741 | rec->scsi_retries = scsi_cmnd->retries; | ||
742 | rec->scsi_allowed = scsi_cmnd->allowed; | ||
743 | if (fsf_req != NULL) { | 743 | if (fsf_req != NULL) { |
744 | fcp_rsp = (struct fcp_rsp_iu *) | 744 | fcp_rsp = (struct fcp_rsp_iu *) |
745 | &(fsf_req->qtcb->bottom.io.fcp_rsp); | 745 | &(fsf_req->qtcb->bottom.io.fcp_rsp); |
@@ -772,15 +772,8 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | |||
772 | rec->fsf_seqno = fsf_req->seq_no; | 772 | rec->fsf_seqno = fsf_req->seq_no; |
773 | rec->fsf_issued = fsf_req->issued; | 773 | rec->fsf_issued = fsf_req->issued; |
774 | } | 774 | } |
775 | if (new_fsf_req != NULL) { | 775 | rec->type.old_fsf_reqid = |
776 | rec->type.new_fsf_req.fsf_reqid = | 776 | (unsigned long) old_fsf_req; |
777 | (unsigned long) | ||
778 | new_fsf_req; | ||
779 | rec->type.new_fsf_req.fsf_seqno = | ||
780 | new_fsf_req->seq_no; | ||
781 | rec->type.new_fsf_req.fsf_issued = | ||
782 | new_fsf_req->issued; | ||
783 | } | ||
784 | } else { | 777 | } else { |
785 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); | 778 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); |
786 | dump->total_size = buflen; | 779 | dump->total_size = buflen; |
@@ -801,19 +794,21 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | |||
801 | inline void | 794 | inline void |
802 | zfcp_scsi_dbf_event_result(const char *tag, int level, | 795 | zfcp_scsi_dbf_event_result(const char *tag, int level, |
803 | struct zfcp_adapter *adapter, | 796 | struct zfcp_adapter *adapter, |
804 | struct scsi_cmnd *scsi_cmnd) | 797 | struct scsi_cmnd *scsi_cmnd, |
798 | struct zfcp_fsf_req *fsf_req) | ||
805 | { | 799 | { |
806 | _zfcp_scsi_dbf_event_common("rslt", | 800 | _zfcp_scsi_dbf_event_common("rslt", tag, level, |
807 | tag, level, adapter, scsi_cmnd, NULL); | 801 | adapter, scsi_cmnd, fsf_req, NULL); |
808 | } | 802 | } |
809 | 803 | ||
810 | inline void | 804 | inline void |
811 | zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, | 805 | zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, |
812 | struct scsi_cmnd *scsi_cmnd, | 806 | struct scsi_cmnd *scsi_cmnd, |
813 | struct zfcp_fsf_req *new_fsf_req) | 807 | struct zfcp_fsf_req *new_fsf_req, |
808 | struct zfcp_fsf_req *old_fsf_req) | ||
814 | { | 809 | { |
815 | _zfcp_scsi_dbf_event_common("abrt", | 810 | _zfcp_scsi_dbf_event_common("abrt", tag, 1, |
816 | tag, 1, adapter, scsi_cmnd, new_fsf_req); | 811 | adapter, scsi_cmnd, new_fsf_req, old_fsf_req); |
817 | } | 812 | } |
818 | 813 | ||
819 | inline void | 814 | inline void |
@@ -823,7 +818,7 @@ zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, | |||
823 | struct zfcp_adapter *adapter = unit->port->adapter; | 818 | struct zfcp_adapter *adapter = unit->port->adapter; |
824 | 819 | ||
825 | _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst", | 820 | _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst", |
826 | tag, 1, adapter, scsi_cmnd, NULL); | 821 | tag, 1, adapter, scsi_cmnd, NULL, NULL); |
827 | } | 822 | } |
828 | 823 | ||
829 | static int | 824 | static int |
@@ -856,6 +851,10 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, | |||
856 | rec->scsi_retries); | 851 | rec->scsi_retries); |
857 | len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x", | 852 | len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x", |
858 | rec->scsi_allowed); | 853 | rec->scsi_allowed); |
854 | if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) { | ||
855 | len += zfcp_dbf_view(out_buf + len, "old_fsf_reqid", "0x%0Lx", | ||
856 | rec->type.old_fsf_reqid); | ||
857 | } | ||
859 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", | 858 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", |
860 | rec->fsf_reqid); | 859 | rec->fsf_reqid); |
861 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", | 860 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", |
@@ -883,21 +882,6 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, | |||
883 | min((int)rec->type.fcp.sns_info_len, | 882 | min((int)rec->type.fcp.sns_info_len, |
884 | ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, | 883 | ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, |
885 | rec->type.fcp.sns_info_len); | 884 | rec->type.fcp.sns_info_len); |
886 | } else if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) { | ||
887 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid_abort", "0x%0Lx", | ||
888 | rec->type.new_fsf_req.fsf_reqid); | ||
889 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno_abort", "0x%08x", | ||
890 | rec->type.new_fsf_req.fsf_seqno); | ||
891 | len += zfcp_dbf_stck(out_buf + len, "fsf_issued", | ||
892 | rec->type.new_fsf_req.fsf_issued); | ||
893 | } else if ((strncmp(rec->tag, "trst", ZFCP_DBF_TAG_SIZE) == 0) || | ||
894 | (strncmp(rec->tag, "lrst", ZFCP_DBF_TAG_SIZE) == 0)) { | ||
895 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid_reset", "0x%0Lx", | ||
896 | rec->type.new_fsf_req.fsf_reqid); | ||
897 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno_reset", "0x%08x", | ||
898 | rec->type.new_fsf_req.fsf_seqno); | ||
899 | len += zfcp_dbf_stck(out_buf + len, "fsf_issued", | ||
900 | rec->type.new_fsf_req.fsf_issued); | ||
901 | } | 885 | } |
902 | 886 | ||
903 | len += sprintf(out_buf + len, "\n"); | 887 | len += sprintf(out_buf + len, "\n"); |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index e260d19fa717..6eba56cd89ba 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -152,11 +152,6 @@ typedef u32 scsi_lun_t; | |||
152 | #define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP 100 | 152 | #define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP 100 |
153 | #define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES 7 | 153 | #define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES 7 |
154 | 154 | ||
155 | /* Retry 5 times every 2 second, then every minute */ | ||
156 | #define ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES 5 | ||
157 | #define ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP 200 | ||
158 | #define ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP 6000 | ||
159 | |||
160 | /* timeout value for "default timer" for fsf requests */ | 155 | /* timeout value for "default timer" for fsf requests */ |
161 | #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ); | 156 | #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ); |
162 | 157 | ||
@@ -429,11 +424,7 @@ struct zfcp_scsi_dbf_record { | |||
429 | u32 fsf_seqno; | 424 | u32 fsf_seqno; |
430 | u64 fsf_issued; | 425 | u64 fsf_issued; |
431 | union { | 426 | union { |
432 | struct { | 427 | u64 old_fsf_reqid; |
433 | u64 fsf_reqid; | ||
434 | u32 fsf_seqno; | ||
435 | u64 fsf_issued; | ||
436 | } new_fsf_req; | ||
437 | struct { | 428 | struct { |
438 | u8 rsp_validity; | 429 | u8 rsp_validity; |
439 | u8 rsp_scsi_status; | 430 | u8 rsp_scsi_status; |
@@ -673,6 +664,7 @@ do { \ | |||
673 | #define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002 | 664 | #define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002 |
674 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 | 665 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 |
675 | #define ZFCP_STATUS_UNIT_READONLY 0x00000008 | 666 | #define ZFCP_STATUS_UNIT_READONLY 0x00000008 |
667 | #define ZFCP_STATUS_UNIT_REGISTERED 0x00000010 | ||
676 | 668 | ||
677 | /* FSF request status (this does not have a common part) */ | 669 | /* FSF request status (this does not have a common part) */ |
678 | #define ZFCP_STATUS_FSFREQ_NOT_INIT 0x00000000 | 670 | #define ZFCP_STATUS_FSFREQ_NOT_INIT 0x00000000 |
@@ -915,8 +907,6 @@ struct zfcp_adapter { | |||
915 | wwn_t peer_wwnn; /* P2P peer WWNN */ | 907 | wwn_t peer_wwnn; /* P2P peer WWNN */ |
916 | wwn_t peer_wwpn; /* P2P peer WWPN */ | 908 | wwn_t peer_wwpn; /* P2P peer WWPN */ |
917 | u32 peer_d_id; /* P2P peer D_ID */ | 909 | u32 peer_d_id; /* P2P peer D_ID */ |
918 | wwn_t physical_wwpn; /* WWPN of physical port */ | ||
919 | u32 physical_s_id; /* local FC port ID */ | ||
920 | struct ccw_device *ccw_device; /* S/390 ccw device */ | 910 | struct ccw_device *ccw_device; /* S/390 ccw device */ |
921 | u8 fc_service_class; | 911 | u8 fc_service_class; |
922 | u32 hydra_version; /* Hydra version */ | 912 | u32 hydra_version; /* Hydra version */ |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index da947e662031..57cb628a05aa 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -2246,15 +2246,6 @@ zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action) | |||
2246 | { | 2246 | { |
2247 | int retval; | 2247 | int retval; |
2248 | 2248 | ||
2249 | if ((atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | ||
2250 | &erp_action->adapter->status)) && | ||
2251 | (erp_action->adapter->adapter_features & | ||
2252 | FSF_FEATURE_HBAAPI_MANAGEMENT)) { | ||
2253 | zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); | ||
2254 | atomic_set(&erp_action->adapter->erp_counter, 0); | ||
2255 | return ZFCP_ERP_FAILED; | ||
2256 | } | ||
2257 | |||
2258 | retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action); | 2249 | retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action); |
2259 | if (retval == ZFCP_ERP_FAILED) | 2250 | if (retval == ZFCP_ERP_FAILED) |
2260 | return ZFCP_ERP_FAILED; | 2251 | return ZFCP_ERP_FAILED; |
@@ -2266,13 +2257,6 @@ zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action) | |||
2266 | return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); | 2257 | return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); |
2267 | } | 2258 | } |
2268 | 2259 | ||
2269 | /* | ||
2270 | * function: | ||
2271 | * | ||
2272 | * purpose: | ||
2273 | * | ||
2274 | * returns: | ||
2275 | */ | ||
2276 | static int | 2260 | static int |
2277 | zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) | 2261 | zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) |
2278 | { | 2262 | { |
@@ -2350,48 +2334,40 @@ static int | |||
2350 | zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) | 2334 | zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) |
2351 | { | 2335 | { |
2352 | int ret; | 2336 | int ret; |
2353 | int retries; | 2337 | struct zfcp_adapter *adapter; |
2354 | int sleep; | ||
2355 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2356 | 2338 | ||
2339 | adapter = erp_action->adapter; | ||
2357 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | 2340 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); |
2358 | 2341 | ||
2359 | retries = 0; | 2342 | write_lock(&adapter->erp_lock); |
2360 | do { | 2343 | zfcp_erp_action_to_running(erp_action); |
2361 | write_lock(&adapter->erp_lock); | 2344 | write_unlock(&adapter->erp_lock); |
2362 | zfcp_erp_action_to_running(erp_action); | ||
2363 | write_unlock(&adapter->erp_lock); | ||
2364 | zfcp_erp_timeout_init(erp_action); | ||
2365 | ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); | ||
2366 | if (ret == -EOPNOTSUPP) { | ||
2367 | debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); | ||
2368 | return ZFCP_ERP_SUCCEEDED; | ||
2369 | } else if (ret) { | ||
2370 | debug_text_event(adapter->erp_dbf, 3, "a_xport_failed"); | ||
2371 | return ZFCP_ERP_FAILED; | ||
2372 | } | ||
2373 | debug_text_event(adapter->erp_dbf, 6, "a_xport_ok"); | ||
2374 | 2345 | ||
2375 | down(&adapter->erp_ready_sem); | 2346 | zfcp_erp_timeout_init(erp_action); |
2376 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { | 2347 | ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); |
2377 | ZFCP_LOG_INFO("error: exchange of port data " | 2348 | if (ret == -EOPNOTSUPP) { |
2378 | "for adapter %s timed out\n", | 2349 | debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); |
2379 | zfcp_get_busid_by_adapter(adapter)); | 2350 | return ZFCP_ERP_SUCCEEDED; |
2380 | break; | 2351 | } else if (ret) { |
2381 | } | 2352 | debug_text_event(adapter->erp_dbf, 3, "a_xport_failed"); |
2382 | if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | 2353 | return ZFCP_ERP_FAILED; |
2383 | &adapter->status)) | 2354 | } |
2384 | break; | 2355 | debug_text_event(adapter->erp_dbf, 6, "a_xport_ok"); |
2385 | 2356 | ||
2386 | if (retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES) { | 2357 | ret = ZFCP_ERP_SUCCEEDED; |
2387 | sleep = ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP; | 2358 | down(&adapter->erp_ready_sem); |
2388 | retries++; | 2359 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { |
2389 | } else | 2360 | ZFCP_LOG_INFO("error: exchange port data timed out (adapter " |
2390 | sleep = ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP; | 2361 | "%s)\n", zfcp_get_busid_by_adapter(adapter)); |
2391 | schedule_timeout(sleep); | 2362 | ret = ZFCP_ERP_FAILED; |
2392 | } while (1); | 2363 | } |
2364 | if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status)) { | ||
2365 | ZFCP_LOG_INFO("error: exchange port data failed (adapter " | ||
2366 | "%s\n", zfcp_get_busid_by_adapter(adapter)); | ||
2367 | ret = ZFCP_ERP_FAILED; | ||
2368 | } | ||
2393 | 2369 | ||
2394 | return ZFCP_ERP_SUCCEEDED; | 2370 | return ret; |
2395 | } | 2371 | } |
2396 | 2372 | ||
2397 | /* | 2373 | /* |
@@ -3415,10 +3391,13 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, | |||
3415 | && (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY, | 3391 | && (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY, |
3416 | &unit->status)) | 3392 | &unit->status)) |
3417 | && !unit->device | 3393 | && !unit->device |
3418 | && port->rport) | 3394 | && port->rport) { |
3419 | scsi_add_device(port->adapter->scsi_host, 0, | 3395 | atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED, |
3420 | port->rport->scsi_target_id, | 3396 | &unit->status); |
3421 | unit->scsi_lun); | 3397 | scsi_scan_target(&port->rport->dev, 0, |
3398 | port->rport->scsi_target_id, | ||
3399 | unit->scsi_lun, 0); | ||
3400 | } | ||
3422 | zfcp_unit_put(unit); | 3401 | zfcp_unit_put(unit); |
3423 | break; | 3402 | break; |
3424 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: | 3403 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
@@ -3439,6 +3418,8 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, | |||
3439 | "(adapter %s, wwpn=0x%016Lx)\n", | 3418 | "(adapter %s, wwpn=0x%016Lx)\n", |
3440 | zfcp_get_busid_by_port(port), | 3419 | zfcp_get_busid_by_port(port), |
3441 | port->wwpn); | 3420 | port->wwpn); |
3421 | else | ||
3422 | scsi_flush_work(adapter->scsi_host); | ||
3442 | } | 3423 | } |
3443 | zfcp_port_put(port); | 3424 | zfcp_port_put(port); |
3444 | break; | 3425 | break; |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index c1ba7cf1b496..700f5402a978 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -194,9 +194,10 @@ extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *); | |||
194 | extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *); | 194 | extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *); |
195 | 195 | ||
196 | extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *, | 196 | extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *, |
197 | struct scsi_cmnd *); | 197 | struct scsi_cmnd *, |
198 | struct zfcp_fsf_req *); | ||
198 | extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, | 199 | extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, |
199 | struct scsi_cmnd *, | 200 | struct scsi_cmnd *, struct zfcp_fsf_req *, |
200 | struct zfcp_fsf_req *); | 201 | struct zfcp_fsf_req *); |
201 | extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, | 202 | extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, |
202 | struct scsi_cmnd *); | 203 | struct scsi_cmnd *); |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 9f0cb3d820c0..662ec571d73b 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -388,6 +388,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
388 | case FSF_PROT_LINK_DOWN: | 388 | case FSF_PROT_LINK_DOWN: |
389 | zfcp_fsf_link_down_info_eval(adapter, | 389 | zfcp_fsf_link_down_info_eval(adapter, |
390 | &prot_status_qual->link_down_info); | 390 | &prot_status_qual->link_down_info); |
391 | zfcp_erp_adapter_reopen(adapter, 0); | ||
391 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 392 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
392 | break; | 393 | break; |
393 | 394 | ||
@@ -558,10 +559,8 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, | |||
558 | 559 | ||
559 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); | 560 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); |
560 | 561 | ||
561 | if (link_down == NULL) { | 562 | if (link_down == NULL) |
562 | zfcp_erp_adapter_reopen(adapter, 0); | 563 | goto out; |
563 | return; | ||
564 | } | ||
565 | 564 | ||
566 | switch (link_down->error_code) { | 565 | switch (link_down->error_code) { |
567 | case FSF_PSQ_LINK_NO_LIGHT: | 566 | case FSF_PSQ_LINK_NO_LIGHT: |
@@ -643,16 +642,8 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, | |||
643 | link_down->explanation_code, | 642 | link_down->explanation_code, |
644 | link_down->vendor_specific_code); | 643 | link_down->vendor_specific_code); |
645 | 644 | ||
646 | switch (link_down->error_code) { | 645 | out: |
647 | case FSF_PSQ_LINK_NO_LIGHT: | 646 | zfcp_erp_adapter_failed(adapter); |
648 | case FSF_PSQ_LINK_WRAP_PLUG: | ||
649 | case FSF_PSQ_LINK_NO_FCP: | ||
650 | case FSF_PSQ_LINK_FIRMWARE_UPDATE: | ||
651 | zfcp_erp_adapter_reopen(adapter, 0); | ||
652 | break; | ||
653 | default: | ||
654 | zfcp_erp_adapter_failed(adapter); | ||
655 | } | ||
656 | } | 647 | } |
657 | 648 | ||
658 | /* | 649 | /* |
@@ -2304,6 +2295,35 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, | |||
2304 | return retval; | 2295 | return retval; |
2305 | } | 2296 | } |
2306 | 2297 | ||
2298 | /** | ||
2299 | * zfcp_fsf_exchange_port_evaluate | ||
2300 | * @fsf_req: fsf_req which belongs to xchg port data request | ||
2301 | * @xchg_ok: specifies if xchg port data was incomplete or complete (0/1) | ||
2302 | */ | ||
2303 | static void | ||
2304 | zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | ||
2305 | { | ||
2306 | struct zfcp_adapter *adapter; | ||
2307 | struct fsf_qtcb *qtcb; | ||
2308 | struct fsf_qtcb_bottom_port *bottom, *data; | ||
2309 | struct Scsi_Host *shost; | ||
2310 | |||
2311 | adapter = fsf_req->adapter; | ||
2312 | qtcb = fsf_req->qtcb; | ||
2313 | bottom = &qtcb->bottom.port; | ||
2314 | shost = adapter->scsi_host; | ||
2315 | |||
2316 | data = (struct fsf_qtcb_bottom_port*) fsf_req->data; | ||
2317 | if (data) | ||
2318 | memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); | ||
2319 | |||
2320 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) | ||
2321 | fc_host_permanent_port_name(shost) = bottom->wwpn; | ||
2322 | else | ||
2323 | fc_host_permanent_port_name(shost) = fc_host_port_name(shost); | ||
2324 | fc_host_maxframe_size(shost) = bottom->maximum_frame_size; | ||
2325 | fc_host_supported_speeds(shost) = bottom->supported_speed; | ||
2326 | } | ||
2307 | 2327 | ||
2308 | /** | 2328 | /** |
2309 | * zfcp_fsf_exchange_port_data_handler - handler for exchange_port_data request | 2329 | * zfcp_fsf_exchange_port_data_handler - handler for exchange_port_data request |
@@ -2312,38 +2332,26 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, | |||
2312 | static void | 2332 | static void |
2313 | zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) | 2333 | zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) |
2314 | { | 2334 | { |
2315 | struct zfcp_adapter *adapter = fsf_req->adapter; | 2335 | struct zfcp_adapter *adapter; |
2316 | struct Scsi_Host *shost = adapter->scsi_host; | 2336 | struct fsf_qtcb *qtcb; |
2317 | struct fsf_qtcb *qtcb = fsf_req->qtcb; | 2337 | |
2318 | struct fsf_qtcb_bottom_port *bottom, *data; | 2338 | adapter = fsf_req->adapter; |
2339 | qtcb = fsf_req->qtcb; | ||
2319 | 2340 | ||
2320 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) | 2341 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) |
2321 | return; | 2342 | return; |
2322 | 2343 | ||
2323 | switch (qtcb->header.fsf_status) { | 2344 | switch (qtcb->header.fsf_status) { |
2324 | case FSF_GOOD: | 2345 | case FSF_GOOD: |
2346 | zfcp_fsf_exchange_port_evaluate(fsf_req, 1); | ||
2325 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | 2347 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); |
2326 | |||
2327 | bottom = &qtcb->bottom.port; | ||
2328 | data = (struct fsf_qtcb_bottom_port*) fsf_req->data; | ||
2329 | if (data) | ||
2330 | memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); | ||
2331 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) | ||
2332 | fc_host_permanent_port_name(shost) = bottom->wwpn; | ||
2333 | else | ||
2334 | fc_host_permanent_port_name(shost) = | ||
2335 | fc_host_port_name(shost); | ||
2336 | fc_host_maxframe_size(shost) = bottom->maximum_frame_size; | ||
2337 | fc_host_supported_speeds(shost) = bottom->supported_speed; | ||
2338 | break; | 2348 | break; |
2339 | |||
2340 | case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: | 2349 | case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: |
2350 | zfcp_fsf_exchange_port_evaluate(fsf_req, 0); | ||
2341 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | 2351 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); |
2342 | |||
2343 | zfcp_fsf_link_down_info_eval(adapter, | 2352 | zfcp_fsf_link_down_info_eval(adapter, |
2344 | &qtcb->header.fsf_status_qual.link_down_info); | 2353 | &qtcb->header.fsf_status_qual.link_down_info); |
2345 | break; | 2354 | break; |
2346 | |||
2347 | default: | 2355 | default: |
2348 | debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng"); | 2356 | debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng"); |
2349 | debug_event(adapter->erp_dbf, 0, | 2357 | debug_event(adapter->erp_dbf, 0, |
@@ -4203,11 +4211,11 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
4203 | ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); | 4211 | ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); |
4204 | 4212 | ||
4205 | if (scpnt->result != 0) | 4213 | if (scpnt->result != 0) |
4206 | zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt); | 4214 | zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt, fsf_req); |
4207 | else if (scpnt->retries > 0) | 4215 | else if (scpnt->retries > 0) |
4208 | zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt); | 4216 | zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt, fsf_req); |
4209 | else | 4217 | else |
4210 | zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt); | 4218 | zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt, fsf_req); |
4211 | 4219 | ||
4212 | /* cleanup pointer (need this especially for abort) */ | 4220 | /* cleanup pointer (need this especially for abort) */ |
4213 | scpnt->host_scribble = NULL; | 4221 | scpnt->host_scribble = NULL; |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index e0803757c0fa..9e6d07d7b3c8 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -68,7 +68,7 @@ struct zfcp_data zfcp_data = { | |||
68 | eh_host_reset_handler: zfcp_scsi_eh_host_reset_handler, | 68 | eh_host_reset_handler: zfcp_scsi_eh_host_reset_handler, |
69 | /* FIXME(openfcp): Tune */ | 69 | /* FIXME(openfcp): Tune */ |
70 | can_queue: 4096, | 70 | can_queue: 4096, |
71 | this_id: 0, | 71 | this_id: -1, |
72 | /* | 72 | /* |
73 | * FIXME: | 73 | * FIXME: |
74 | * one less? can zfcp_create_sbale cope with it? | 74 | * one less? can zfcp_create_sbale cope with it? |
@@ -183,7 +183,8 @@ zfcp_scsi_slave_alloc(struct scsi_device *sdp) | |||
183 | 183 | ||
184 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 184 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
185 | unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun); | 185 | unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun); |
186 | if (unit) { | 186 | if (unit && atomic_test_mask(ZFCP_STATUS_UNIT_REGISTERED, |
187 | &unit->status)) { | ||
187 | sdp->hostdata = unit; | 188 | sdp->hostdata = unit; |
188 | unit->device = sdp; | 189 | unit->device = sdp; |
189 | zfcp_unit_get(unit); | 190 | zfcp_unit_get(unit); |
@@ -208,6 +209,7 @@ zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | |||
208 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; | 209 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; |
209 | 210 | ||
210 | if (unit) { | 211 | if (unit) { |
212 | atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); | ||
211 | sdpnt->hostdata = NULL; | 213 | sdpnt->hostdata = NULL; |
212 | unit->device = NULL; | 214 | unit->device = NULL; |
213 | zfcp_unit_put(unit); | 215 | zfcp_unit_put(unit); |
@@ -242,7 +244,7 @@ zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) | |||
242 | if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) | 244 | if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) |
243 | zfcp_scsi_dbf_event_result("fail", 4, | 245 | zfcp_scsi_dbf_event_result("fail", 4, |
244 | (struct zfcp_adapter*) scpnt->device->host->hostdata[0], | 246 | (struct zfcp_adapter*) scpnt->device->host->hostdata[0], |
245 | scpnt); | 247 | scpnt, NULL); |
246 | /* return directly */ | 248 | /* return directly */ |
247 | scpnt->scsi_done(scpnt); | 249 | scpnt->scsi_done(scpnt); |
248 | } | 250 | } |
@@ -291,7 +293,7 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit, | |||
291 | "on port 0x%016Lx in recovery\n", | 293 | "on port 0x%016Lx in recovery\n", |
292 | zfcp_get_busid_by_unit(unit), | 294 | zfcp_get_busid_by_unit(unit), |
293 | unit->fcp_lun, unit->port->wwpn); | 295 | unit->fcp_lun, unit->port->wwpn); |
294 | retval = SCSI_MLQUEUE_DEVICE_BUSY; | 296 | zfcp_scsi_command_fail(scpnt, DID_NO_CONNECT); |
295 | goto out; | 297 | goto out; |
296 | } | 298 | } |
297 | 299 | ||
@@ -446,7 +448,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
446 | old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble; | 448 | old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble; |
447 | if (!old_fsf_req) { | 449 | if (!old_fsf_req) { |
448 | write_unlock_irqrestore(&adapter->abort_lock, flags); | 450 | write_unlock_irqrestore(&adapter->abort_lock, flags); |
449 | zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, new_fsf_req); | 451 | zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, NULL); |
450 | retval = SUCCESS; | 452 | retval = SUCCESS; |
451 | goto out; | 453 | goto out; |
452 | } | 454 | } |
@@ -460,6 +462,8 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
460 | adapter, unit, 0); | 462 | adapter, unit, 0); |
461 | if (!new_fsf_req) { | 463 | if (!new_fsf_req) { |
462 | ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n"); | 464 | ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n"); |
465 | zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL, | ||
466 | old_fsf_req); | ||
463 | retval = FAILED; | 467 | retval = FAILED; |
464 | goto out; | 468 | goto out; |
465 | } | 469 | } |
@@ -470,13 +474,16 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
470 | 474 | ||
471 | /* status should be valid since signals were not permitted */ | 475 | /* status should be valid since signals were not permitted */ |
472 | if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) { | 476 | if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) { |
473 | zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req); | 477 | zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req, |
478 | NULL); | ||
474 | retval = SUCCESS; | 479 | retval = SUCCESS; |
475 | } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) { | 480 | } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) { |
476 | zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req); | 481 | zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req, |
482 | NULL); | ||
477 | retval = SUCCESS; | 483 | retval = SUCCESS; |
478 | } else { | 484 | } else { |
479 | zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req); | 485 | zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req, |
486 | NULL); | ||
480 | retval = FAILED; | 487 | retval = FAILED; |
481 | } | 488 | } |
482 | zfcp_fsf_req_free(new_fsf_req); | 489 | zfcp_fsf_req_free(new_fsf_req); |
diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c index dfc07370f412..b29ac25e07f3 100644 --- a/drivers/s390/scsi/zfcp_sysfs_adapter.c +++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c | |||
@@ -55,8 +55,6 @@ ZFCP_DEFINE_ADAPTER_ATTR(status, "0x%08x\n", atomic_read(&adapter->status)); | |||
55 | ZFCP_DEFINE_ADAPTER_ATTR(peer_wwnn, "0x%016llx\n", adapter->peer_wwnn); | 55 | ZFCP_DEFINE_ADAPTER_ATTR(peer_wwnn, "0x%016llx\n", adapter->peer_wwnn); |
56 | ZFCP_DEFINE_ADAPTER_ATTR(peer_wwpn, "0x%016llx\n", adapter->peer_wwpn); | 56 | ZFCP_DEFINE_ADAPTER_ATTR(peer_wwpn, "0x%016llx\n", adapter->peer_wwpn); |
57 | ZFCP_DEFINE_ADAPTER_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id); | 57 | ZFCP_DEFINE_ADAPTER_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id); |
58 | ZFCP_DEFINE_ADAPTER_ATTR(physical_wwpn, "0x%016llx\n", adapter->physical_wwpn); | ||
59 | ZFCP_DEFINE_ADAPTER_ATTR(physical_s_id, "0x%06x\n", adapter->physical_s_id); | ||
60 | ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version); | 58 | ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version); |
61 | ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version); | 59 | ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version); |
62 | ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n", | 60 | ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n", |
@@ -241,8 +239,6 @@ static struct attribute *zfcp_adapter_attrs[] = { | |||
241 | &dev_attr_peer_wwnn.attr, | 239 | &dev_attr_peer_wwnn.attr, |
242 | &dev_attr_peer_wwpn.attr, | 240 | &dev_attr_peer_wwpn.attr, |
243 | &dev_attr_peer_d_id.attr, | 241 | &dev_attr_peer_d_id.attr, |
244 | &dev_attr_physical_wwpn.attr, | ||
245 | &dev_attr_physical_s_id.attr, | ||
246 | &dev_attr_card_version.attr, | 242 | &dev_attr_card_version.attr, |
247 | &dev_attr_lic_version.attr, | 243 | &dev_attr_lic_version.attr, |
248 | &dev_attr_status.attr, | 244 | &dev_attr_status.attr, |
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 31c497542272..d9152d02088c 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
@@ -61,6 +61,7 @@ | |||
61 | Add support for embedded firmware error strings. | 61 | Add support for embedded firmware error strings. |
62 | 2.26.02.003 - Correctly handle single sgl's with use_sg=1. | 62 | 2.26.02.003 - Correctly handle single sgl's with use_sg=1. |
63 | 2.26.02.004 - Add support for 9550SX controllers. | 63 | 2.26.02.004 - Add support for 9550SX controllers. |
64 | 2.26.02.005 - Fix use_sg == 0 mapping on systems with 4GB or higher. | ||
64 | */ | 65 | */ |
65 | 66 | ||
66 | #include <linux/module.h> | 67 | #include <linux/module.h> |
@@ -84,7 +85,7 @@ | |||
84 | #include "3w-9xxx.h" | 85 | #include "3w-9xxx.h" |
85 | 86 | ||
86 | /* Globals */ | 87 | /* Globals */ |
87 | #define TW_DRIVER_VERSION "2.26.02.004" | 88 | #define TW_DRIVER_VERSION "2.26.02.005" |
88 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; | 89 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; |
89 | static unsigned int twa_device_extension_count; | 90 | static unsigned int twa_device_extension_count; |
90 | static int twa_major = -1; | 91 | static int twa_major = -1; |
@@ -1408,7 +1409,7 @@ static dma_addr_t twa_map_scsi_single_data(TW_Device_Extension *tw_dev, int requ | |||
1408 | dma_addr_t mapping; | 1409 | dma_addr_t mapping; |
1409 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; | 1410 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; |
1410 | struct pci_dev *pdev = tw_dev->tw_pci_dev; | 1411 | struct pci_dev *pdev = tw_dev->tw_pci_dev; |
1411 | int retval = 0; | 1412 | dma_addr_t retval = 0; |
1412 | 1413 | ||
1413 | if (cmd->request_bufflen == 0) { | 1414 | if (cmd->request_bufflen == 0) { |
1414 | retval = 0; | 1415 | retval = 0; |
@@ -1798,7 +1799,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, | |||
1798 | int i, sg_count; | 1799 | int i, sg_count; |
1799 | struct scsi_cmnd *srb = NULL; | 1800 | struct scsi_cmnd *srb = NULL; |
1800 | struct scatterlist *sglist = NULL; | 1801 | struct scatterlist *sglist = NULL; |
1801 | u32 buffaddr = 0x0; | 1802 | dma_addr_t buffaddr = 0x0; |
1802 | int retval = 1; | 1803 | int retval = 1; |
1803 | 1804 | ||
1804 | if (tw_dev->srb[request_id]) { | 1805 | if (tw_dev->srb[request_id]) { |
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 7139659dd952..a16f8ded8f1d 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -173,10 +173,10 @@ int aac_get_config_status(struct aac_dev *dev) | |||
173 | int status = 0; | 173 | int status = 0; |
174 | struct fib * fibptr; | 174 | struct fib * fibptr; |
175 | 175 | ||
176 | if (!(fibptr = fib_alloc(dev))) | 176 | if (!(fibptr = aac_fib_alloc(dev))) |
177 | return -ENOMEM; | 177 | return -ENOMEM; |
178 | 178 | ||
179 | fib_init(fibptr); | 179 | aac_fib_init(fibptr); |
180 | { | 180 | { |
181 | struct aac_get_config_status *dinfo; | 181 | struct aac_get_config_status *dinfo; |
182 | dinfo = (struct aac_get_config_status *) fib_data(fibptr); | 182 | dinfo = (struct aac_get_config_status *) fib_data(fibptr); |
@@ -186,7 +186,7 @@ int aac_get_config_status(struct aac_dev *dev) | |||
186 | dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data)); | 186 | dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data)); |
187 | } | 187 | } |
188 | 188 | ||
189 | status = fib_send(ContainerCommand, | 189 | status = aac_fib_send(ContainerCommand, |
190 | fibptr, | 190 | fibptr, |
191 | sizeof (struct aac_get_config_status), | 191 | sizeof (struct aac_get_config_status), |
192 | FsaNormal, | 192 | FsaNormal, |
@@ -209,30 +209,30 @@ int aac_get_config_status(struct aac_dev *dev) | |||
209 | status = -EINVAL; | 209 | status = -EINVAL; |
210 | } | 210 | } |
211 | } | 211 | } |
212 | fib_complete(fibptr); | 212 | aac_fib_complete(fibptr); |
213 | /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ | 213 | /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ |
214 | if (status >= 0) { | 214 | if (status >= 0) { |
215 | if (commit == 1) { | 215 | if (commit == 1) { |
216 | struct aac_commit_config * dinfo; | 216 | struct aac_commit_config * dinfo; |
217 | fib_init(fibptr); | 217 | aac_fib_init(fibptr); |
218 | dinfo = (struct aac_commit_config *) fib_data(fibptr); | 218 | dinfo = (struct aac_commit_config *) fib_data(fibptr); |
219 | 219 | ||
220 | dinfo->command = cpu_to_le32(VM_ContainerConfig); | 220 | dinfo->command = cpu_to_le32(VM_ContainerConfig); |
221 | dinfo->type = cpu_to_le32(CT_COMMIT_CONFIG); | 221 | dinfo->type = cpu_to_le32(CT_COMMIT_CONFIG); |
222 | 222 | ||
223 | status = fib_send(ContainerCommand, | 223 | status = aac_fib_send(ContainerCommand, |
224 | fibptr, | 224 | fibptr, |
225 | sizeof (struct aac_commit_config), | 225 | sizeof (struct aac_commit_config), |
226 | FsaNormal, | 226 | FsaNormal, |
227 | 1, 1, | 227 | 1, 1, |
228 | NULL, NULL); | 228 | NULL, NULL); |
229 | fib_complete(fibptr); | 229 | aac_fib_complete(fibptr); |
230 | } else if (commit == 0) { | 230 | } else if (commit == 0) { |
231 | printk(KERN_WARNING | 231 | printk(KERN_WARNING |
232 | "aac_get_config_status: Foreign device configurations are being ignored\n"); | 232 | "aac_get_config_status: Foreign device configurations are being ignored\n"); |
233 | } | 233 | } |
234 | } | 234 | } |
235 | fib_free(fibptr); | 235 | aac_fib_free(fibptr); |
236 | return status; | 236 | return status; |
237 | } | 237 | } |
238 | 238 | ||
@@ -255,15 +255,15 @@ int aac_get_containers(struct aac_dev *dev) | |||
255 | 255 | ||
256 | instance = dev->scsi_host_ptr->unique_id; | 256 | instance = dev->scsi_host_ptr->unique_id; |
257 | 257 | ||
258 | if (!(fibptr = fib_alloc(dev))) | 258 | if (!(fibptr = aac_fib_alloc(dev))) |
259 | return -ENOMEM; | 259 | return -ENOMEM; |
260 | 260 | ||
261 | fib_init(fibptr); | 261 | aac_fib_init(fibptr); |
262 | dinfo = (struct aac_get_container_count *) fib_data(fibptr); | 262 | dinfo = (struct aac_get_container_count *) fib_data(fibptr); |
263 | dinfo->command = cpu_to_le32(VM_ContainerConfig); | 263 | dinfo->command = cpu_to_le32(VM_ContainerConfig); |
264 | dinfo->type = cpu_to_le32(CT_GET_CONTAINER_COUNT); | 264 | dinfo->type = cpu_to_le32(CT_GET_CONTAINER_COUNT); |
265 | 265 | ||
266 | status = fib_send(ContainerCommand, | 266 | status = aac_fib_send(ContainerCommand, |
267 | fibptr, | 267 | fibptr, |
268 | sizeof (struct aac_get_container_count), | 268 | sizeof (struct aac_get_container_count), |
269 | FsaNormal, | 269 | FsaNormal, |
@@ -272,7 +272,7 @@ int aac_get_containers(struct aac_dev *dev) | |||
272 | if (status >= 0) { | 272 | if (status >= 0) { |
273 | dresp = (struct aac_get_container_count_resp *)fib_data(fibptr); | 273 | dresp = (struct aac_get_container_count_resp *)fib_data(fibptr); |
274 | maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); | 274 | maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); |
275 | fib_complete(fibptr); | 275 | aac_fib_complete(fibptr); |
276 | } | 276 | } |
277 | 277 | ||
278 | if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) | 278 | if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) |
@@ -280,7 +280,7 @@ int aac_get_containers(struct aac_dev *dev) | |||
280 | fsa_dev_ptr = (struct fsa_dev_info *) kmalloc( | 280 | fsa_dev_ptr = (struct fsa_dev_info *) kmalloc( |
281 | sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL); | 281 | sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL); |
282 | if (!fsa_dev_ptr) { | 282 | if (!fsa_dev_ptr) { |
283 | fib_free(fibptr); | 283 | aac_fib_free(fibptr); |
284 | return -ENOMEM; | 284 | return -ENOMEM; |
285 | } | 285 | } |
286 | memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers); | 286 | memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers); |
@@ -294,14 +294,14 @@ int aac_get_containers(struct aac_dev *dev) | |||
294 | 294 | ||
295 | fsa_dev_ptr[index].devname[0] = '\0'; | 295 | fsa_dev_ptr[index].devname[0] = '\0'; |
296 | 296 | ||
297 | fib_init(fibptr); | 297 | aac_fib_init(fibptr); |
298 | dinfo = (struct aac_query_mount *) fib_data(fibptr); | 298 | dinfo = (struct aac_query_mount *) fib_data(fibptr); |
299 | 299 | ||
300 | dinfo->command = cpu_to_le32(VM_NameServe); | 300 | dinfo->command = cpu_to_le32(VM_NameServe); |
301 | dinfo->count = cpu_to_le32(index); | 301 | dinfo->count = cpu_to_le32(index); |
302 | dinfo->type = cpu_to_le32(FT_FILESYS); | 302 | dinfo->type = cpu_to_le32(FT_FILESYS); |
303 | 303 | ||
304 | status = fib_send(ContainerCommand, | 304 | status = aac_fib_send(ContainerCommand, |
305 | fibptr, | 305 | fibptr, |
306 | sizeof (struct aac_query_mount), | 306 | sizeof (struct aac_query_mount), |
307 | FsaNormal, | 307 | FsaNormal, |
@@ -319,7 +319,7 @@ int aac_get_containers(struct aac_dev *dev) | |||
319 | dinfo->count = cpu_to_le32(index); | 319 | dinfo->count = cpu_to_le32(index); |
320 | dinfo->type = cpu_to_le32(FT_FILESYS); | 320 | dinfo->type = cpu_to_le32(FT_FILESYS); |
321 | 321 | ||
322 | if (fib_send(ContainerCommand, | 322 | if (aac_fib_send(ContainerCommand, |
323 | fibptr, | 323 | fibptr, |
324 | sizeof(struct aac_query_mount), | 324 | sizeof(struct aac_query_mount), |
325 | FsaNormal, | 325 | FsaNormal, |
@@ -347,7 +347,7 @@ int aac_get_containers(struct aac_dev *dev) | |||
347 | if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) | 347 | if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) |
348 | fsa_dev_ptr[index].ro = 1; | 348 | fsa_dev_ptr[index].ro = 1; |
349 | } | 349 | } |
350 | fib_complete(fibptr); | 350 | aac_fib_complete(fibptr); |
351 | /* | 351 | /* |
352 | * If there are no more containers, then stop asking. | 352 | * If there are no more containers, then stop asking. |
353 | */ | 353 | */ |
@@ -355,7 +355,7 @@ int aac_get_containers(struct aac_dev *dev) | |||
355 | break; | 355 | break; |
356 | } | 356 | } |
357 | } | 357 | } |
358 | fib_free(fibptr); | 358 | aac_fib_free(fibptr); |
359 | return status; | 359 | return status; |
360 | } | 360 | } |
361 | 361 | ||
@@ -413,8 +413,8 @@ static void get_container_name_callback(void *context, struct fib * fibptr) | |||
413 | 413 | ||
414 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 414 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
415 | 415 | ||
416 | fib_complete(fibptr); | 416 | aac_fib_complete(fibptr); |
417 | fib_free(fibptr); | 417 | aac_fib_free(fibptr); |
418 | scsicmd->scsi_done(scsicmd); | 418 | scsicmd->scsi_done(scsicmd); |
419 | } | 419 | } |
420 | 420 | ||
@@ -430,10 +430,10 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) | |||
430 | 430 | ||
431 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; | 431 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; |
432 | 432 | ||
433 | if (!(cmd_fibcontext = fib_alloc(dev))) | 433 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) |
434 | return -ENOMEM; | 434 | return -ENOMEM; |
435 | 435 | ||
436 | fib_init(cmd_fibcontext); | 436 | aac_fib_init(cmd_fibcontext); |
437 | dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext); | 437 | dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext); |
438 | 438 | ||
439 | dinfo->command = cpu_to_le32(VM_ContainerConfig); | 439 | dinfo->command = cpu_to_le32(VM_ContainerConfig); |
@@ -441,7 +441,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) | |||
441 | dinfo->cid = cpu_to_le32(cid); | 441 | dinfo->cid = cpu_to_le32(cid); |
442 | dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); | 442 | dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); |
443 | 443 | ||
444 | status = fib_send(ContainerCommand, | 444 | status = aac_fib_send(ContainerCommand, |
445 | cmd_fibcontext, | 445 | cmd_fibcontext, |
446 | sizeof (struct aac_get_name), | 446 | sizeof (struct aac_get_name), |
447 | FsaNormal, | 447 | FsaNormal, |
@@ -455,14 +455,14 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) | |||
455 | if (status == -EINPROGRESS) | 455 | if (status == -EINPROGRESS) |
456 | return 0; | 456 | return 0; |
457 | 457 | ||
458 | printk(KERN_WARNING "aac_get_container_name: fib_send failed with status: %d.\n", status); | 458 | printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status); |
459 | fib_complete(cmd_fibcontext); | 459 | aac_fib_complete(cmd_fibcontext); |
460 | fib_free(cmd_fibcontext); | 460 | aac_fib_free(cmd_fibcontext); |
461 | return -1; | 461 | return -1; |
462 | } | 462 | } |
463 | 463 | ||
464 | /** | 464 | /** |
465 | * probe_container - query a logical volume | 465 | * aac_probe_container - query a logical volume |
466 | * @dev: device to query | 466 | * @dev: device to query |
467 | * @cid: container identifier | 467 | * @cid: container identifier |
468 | * | 468 | * |
@@ -470,7 +470,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) | |||
470 | * is updated in the struct fsa_dev_info structure rather than returned. | 470 | * is updated in the struct fsa_dev_info structure rather than returned. |
471 | */ | 471 | */ |
472 | 472 | ||
473 | int probe_container(struct aac_dev *dev, int cid) | 473 | int aac_probe_container(struct aac_dev *dev, int cid) |
474 | { | 474 | { |
475 | struct fsa_dev_info *fsa_dev_ptr; | 475 | struct fsa_dev_info *fsa_dev_ptr; |
476 | int status; | 476 | int status; |
@@ -482,10 +482,10 @@ int probe_container(struct aac_dev *dev, int cid) | |||
482 | fsa_dev_ptr = dev->fsa_dev; | 482 | fsa_dev_ptr = dev->fsa_dev; |
483 | instance = dev->scsi_host_ptr->unique_id; | 483 | instance = dev->scsi_host_ptr->unique_id; |
484 | 484 | ||
485 | if (!(fibptr = fib_alloc(dev))) | 485 | if (!(fibptr = aac_fib_alloc(dev))) |
486 | return -ENOMEM; | 486 | return -ENOMEM; |
487 | 487 | ||
488 | fib_init(fibptr); | 488 | aac_fib_init(fibptr); |
489 | 489 | ||
490 | dinfo = (struct aac_query_mount *)fib_data(fibptr); | 490 | dinfo = (struct aac_query_mount *)fib_data(fibptr); |
491 | 491 | ||
@@ -493,14 +493,14 @@ int probe_container(struct aac_dev *dev, int cid) | |||
493 | dinfo->count = cpu_to_le32(cid); | 493 | dinfo->count = cpu_to_le32(cid); |
494 | dinfo->type = cpu_to_le32(FT_FILESYS); | 494 | dinfo->type = cpu_to_le32(FT_FILESYS); |
495 | 495 | ||
496 | status = fib_send(ContainerCommand, | 496 | status = aac_fib_send(ContainerCommand, |
497 | fibptr, | 497 | fibptr, |
498 | sizeof(struct aac_query_mount), | 498 | sizeof(struct aac_query_mount), |
499 | FsaNormal, | 499 | FsaNormal, |
500 | 1, 1, | 500 | 1, 1, |
501 | NULL, NULL); | 501 | NULL, NULL); |
502 | if (status < 0) { | 502 | if (status < 0) { |
503 | printk(KERN_WARNING "aacraid: probe_container query failed.\n"); | 503 | printk(KERN_WARNING "aacraid: aac_probe_container query failed.\n"); |
504 | goto error; | 504 | goto error; |
505 | } | 505 | } |
506 | 506 | ||
@@ -512,7 +512,7 @@ int probe_container(struct aac_dev *dev, int cid) | |||
512 | dinfo->count = cpu_to_le32(cid); | 512 | dinfo->count = cpu_to_le32(cid); |
513 | dinfo->type = cpu_to_le32(FT_FILESYS); | 513 | dinfo->type = cpu_to_le32(FT_FILESYS); |
514 | 514 | ||
515 | if (fib_send(ContainerCommand, | 515 | if (aac_fib_send(ContainerCommand, |
516 | fibptr, | 516 | fibptr, |
517 | sizeof(struct aac_query_mount), | 517 | sizeof(struct aac_query_mount), |
518 | FsaNormal, | 518 | FsaNormal, |
@@ -535,8 +535,8 @@ int probe_container(struct aac_dev *dev, int cid) | |||
535 | } | 535 | } |
536 | 536 | ||
537 | error: | 537 | error: |
538 | fib_complete(fibptr); | 538 | aac_fib_complete(fibptr); |
539 | fib_free(fibptr); | 539 | aac_fib_free(fibptr); |
540 | 540 | ||
541 | return status; | 541 | return status; |
542 | } | 542 | } |
@@ -700,14 +700,14 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
700 | struct aac_bus_info *command; | 700 | struct aac_bus_info *command; |
701 | struct aac_bus_info_response *bus_info; | 701 | struct aac_bus_info_response *bus_info; |
702 | 702 | ||
703 | if (!(fibptr = fib_alloc(dev))) | 703 | if (!(fibptr = aac_fib_alloc(dev))) |
704 | return -ENOMEM; | 704 | return -ENOMEM; |
705 | 705 | ||
706 | fib_init(fibptr); | 706 | aac_fib_init(fibptr); |
707 | info = (struct aac_adapter_info *) fib_data(fibptr); | 707 | info = (struct aac_adapter_info *) fib_data(fibptr); |
708 | memset(info,0,sizeof(*info)); | 708 | memset(info,0,sizeof(*info)); |
709 | 709 | ||
710 | rcode = fib_send(RequestAdapterInfo, | 710 | rcode = aac_fib_send(RequestAdapterInfo, |
711 | fibptr, | 711 | fibptr, |
712 | sizeof(*info), | 712 | sizeof(*info), |
713 | FsaNormal, | 713 | FsaNormal, |
@@ -716,8 +716,8 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
716 | NULL); | 716 | NULL); |
717 | 717 | ||
718 | if (rcode < 0) { | 718 | if (rcode < 0) { |
719 | fib_complete(fibptr); | 719 | aac_fib_complete(fibptr); |
720 | fib_free(fibptr); | 720 | aac_fib_free(fibptr); |
721 | return rcode; | 721 | return rcode; |
722 | } | 722 | } |
723 | memcpy(&dev->adapter_info, info, sizeof(*info)); | 723 | memcpy(&dev->adapter_info, info, sizeof(*info)); |
@@ -725,13 +725,13 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
725 | if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) { | 725 | if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) { |
726 | struct aac_supplement_adapter_info * info; | 726 | struct aac_supplement_adapter_info * info; |
727 | 727 | ||
728 | fib_init(fibptr); | 728 | aac_fib_init(fibptr); |
729 | 729 | ||
730 | info = (struct aac_supplement_adapter_info *) fib_data(fibptr); | 730 | info = (struct aac_supplement_adapter_info *) fib_data(fibptr); |
731 | 731 | ||
732 | memset(info,0,sizeof(*info)); | 732 | memset(info,0,sizeof(*info)); |
733 | 733 | ||
734 | rcode = fib_send(RequestSupplementAdapterInfo, | 734 | rcode = aac_fib_send(RequestSupplementAdapterInfo, |
735 | fibptr, | 735 | fibptr, |
736 | sizeof(*info), | 736 | sizeof(*info), |
737 | FsaNormal, | 737 | FsaNormal, |
@@ -748,7 +748,7 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
748 | * GetBusInfo | 748 | * GetBusInfo |
749 | */ | 749 | */ |
750 | 750 | ||
751 | fib_init(fibptr); | 751 | aac_fib_init(fibptr); |
752 | 752 | ||
753 | bus_info = (struct aac_bus_info_response *) fib_data(fibptr); | 753 | bus_info = (struct aac_bus_info_response *) fib_data(fibptr); |
754 | 754 | ||
@@ -761,7 +761,7 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
761 | command->MethodId = cpu_to_le32(1); | 761 | command->MethodId = cpu_to_le32(1); |
762 | command->CtlCmd = cpu_to_le32(GetBusInfo); | 762 | command->CtlCmd = cpu_to_le32(GetBusInfo); |
763 | 763 | ||
764 | rcode = fib_send(ContainerCommand, | 764 | rcode = aac_fib_send(ContainerCommand, |
765 | fibptr, | 765 | fibptr, |
766 | sizeof (*bus_info), | 766 | sizeof (*bus_info), |
767 | FsaNormal, | 767 | FsaNormal, |
@@ -891,8 +891,8 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
891 | } | 891 | } |
892 | } | 892 | } |
893 | 893 | ||
894 | fib_complete(fibptr); | 894 | aac_fib_complete(fibptr); |
895 | fib_free(fibptr); | 895 | aac_fib_free(fibptr); |
896 | 896 | ||
897 | return rcode; | 897 | return rcode; |
898 | } | 898 | } |
@@ -976,8 +976,8 @@ static void io_callback(void *context, struct fib * fibptr) | |||
976 | ? sizeof(scsicmd->sense_buffer) | 976 | ? sizeof(scsicmd->sense_buffer) |
977 | : sizeof(dev->fsa_dev[cid].sense_data)); | 977 | : sizeof(dev->fsa_dev[cid].sense_data)); |
978 | } | 978 | } |
979 | fib_complete(fibptr); | 979 | aac_fib_complete(fibptr); |
980 | fib_free(fibptr); | 980 | aac_fib_free(fibptr); |
981 | 981 | ||
982 | scsicmd->scsi_done(scsicmd); | 982 | scsicmd->scsi_done(scsicmd); |
983 | } | 983 | } |
@@ -1062,11 +1062,11 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
1062 | /* | 1062 | /* |
1063 | * Alocate and initialize a Fib | 1063 | * Alocate and initialize a Fib |
1064 | */ | 1064 | */ |
1065 | if (!(cmd_fibcontext = fib_alloc(dev))) { | 1065 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { |
1066 | return -1; | 1066 | return -1; |
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | fib_init(cmd_fibcontext); | 1069 | aac_fib_init(cmd_fibcontext); |
1070 | 1070 | ||
1071 | if (dev->raw_io_interface) { | 1071 | if (dev->raw_io_interface) { |
1072 | struct aac_raw_io *readcmd; | 1072 | struct aac_raw_io *readcmd; |
@@ -1086,7 +1086,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
1086 | /* | 1086 | /* |
1087 | * Now send the Fib to the adapter | 1087 | * Now send the Fib to the adapter |
1088 | */ | 1088 | */ |
1089 | status = fib_send(ContainerRawIo, | 1089 | status = aac_fib_send(ContainerRawIo, |
1090 | cmd_fibcontext, | 1090 | cmd_fibcontext, |
1091 | fibsize, | 1091 | fibsize, |
1092 | FsaNormal, | 1092 | FsaNormal, |
@@ -1112,7 +1112,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
1112 | /* | 1112 | /* |
1113 | * Now send the Fib to the adapter | 1113 | * Now send the Fib to the adapter |
1114 | */ | 1114 | */ |
1115 | status = fib_send(ContainerCommand64, | 1115 | status = aac_fib_send(ContainerCommand64, |
1116 | cmd_fibcontext, | 1116 | cmd_fibcontext, |
1117 | fibsize, | 1117 | fibsize, |
1118 | FsaNormal, | 1118 | FsaNormal, |
@@ -1136,7 +1136,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
1136 | /* | 1136 | /* |
1137 | * Now send the Fib to the adapter | 1137 | * Now send the Fib to the adapter |
1138 | */ | 1138 | */ |
1139 | status = fib_send(ContainerCommand, | 1139 | status = aac_fib_send(ContainerCommand, |
1140 | cmd_fibcontext, | 1140 | cmd_fibcontext, |
1141 | fibsize, | 1141 | fibsize, |
1142 | FsaNormal, | 1142 | FsaNormal, |
@@ -1153,14 +1153,14 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
1153 | if (status == -EINPROGRESS) | 1153 | if (status == -EINPROGRESS) |
1154 | return 0; | 1154 | return 0; |
1155 | 1155 | ||
1156 | printk(KERN_WARNING "aac_read: fib_send failed with status: %d.\n", status); | 1156 | printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status); |
1157 | /* | 1157 | /* |
1158 | * For some reason, the Fib didn't queue, return QUEUE_FULL | 1158 | * For some reason, the Fib didn't queue, return QUEUE_FULL |
1159 | */ | 1159 | */ |
1160 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; | 1160 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; |
1161 | scsicmd->scsi_done(scsicmd); | 1161 | scsicmd->scsi_done(scsicmd); |
1162 | fib_complete(cmd_fibcontext); | 1162 | aac_fib_complete(cmd_fibcontext); |
1163 | fib_free(cmd_fibcontext); | 1163 | aac_fib_free(cmd_fibcontext); |
1164 | return 0; | 1164 | return 0; |
1165 | } | 1165 | } |
1166 | 1166 | ||
@@ -1228,12 +1228,12 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1228 | /* | 1228 | /* |
1229 | * Allocate and initialize a Fib then setup a BlockWrite command | 1229 | * Allocate and initialize a Fib then setup a BlockWrite command |
1230 | */ | 1230 | */ |
1231 | if (!(cmd_fibcontext = fib_alloc(dev))) { | 1231 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { |
1232 | scsicmd->result = DID_ERROR << 16; | 1232 | scsicmd->result = DID_ERROR << 16; |
1233 | scsicmd->scsi_done(scsicmd); | 1233 | scsicmd->scsi_done(scsicmd); |
1234 | return 0; | 1234 | return 0; |
1235 | } | 1235 | } |
1236 | fib_init(cmd_fibcontext); | 1236 | aac_fib_init(cmd_fibcontext); |
1237 | 1237 | ||
1238 | if (dev->raw_io_interface) { | 1238 | if (dev->raw_io_interface) { |
1239 | struct aac_raw_io *writecmd; | 1239 | struct aac_raw_io *writecmd; |
@@ -1253,7 +1253,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1253 | /* | 1253 | /* |
1254 | * Now send the Fib to the adapter | 1254 | * Now send the Fib to the adapter |
1255 | */ | 1255 | */ |
1256 | status = fib_send(ContainerRawIo, | 1256 | status = aac_fib_send(ContainerRawIo, |
1257 | cmd_fibcontext, | 1257 | cmd_fibcontext, |
1258 | fibsize, | 1258 | fibsize, |
1259 | FsaNormal, | 1259 | FsaNormal, |
@@ -1279,7 +1279,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1279 | /* | 1279 | /* |
1280 | * Now send the Fib to the adapter | 1280 | * Now send the Fib to the adapter |
1281 | */ | 1281 | */ |
1282 | status = fib_send(ContainerCommand64, | 1282 | status = aac_fib_send(ContainerCommand64, |
1283 | cmd_fibcontext, | 1283 | cmd_fibcontext, |
1284 | fibsize, | 1284 | fibsize, |
1285 | FsaNormal, | 1285 | FsaNormal, |
@@ -1305,7 +1305,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1305 | /* | 1305 | /* |
1306 | * Now send the Fib to the adapter | 1306 | * Now send the Fib to the adapter |
1307 | */ | 1307 | */ |
1308 | status = fib_send(ContainerCommand, | 1308 | status = aac_fib_send(ContainerCommand, |
1309 | cmd_fibcontext, | 1309 | cmd_fibcontext, |
1310 | fibsize, | 1310 | fibsize, |
1311 | FsaNormal, | 1311 | FsaNormal, |
@@ -1322,15 +1322,15 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1322 | return 0; | 1322 | return 0; |
1323 | } | 1323 | } |
1324 | 1324 | ||
1325 | printk(KERN_WARNING "aac_write: fib_send failed with status: %d\n", status); | 1325 | printk(KERN_WARNING "aac_write: aac_fib_send failed with status: %d\n", status); |
1326 | /* | 1326 | /* |
1327 | * For some reason, the Fib didn't queue, return QUEUE_FULL | 1327 | * For some reason, the Fib didn't queue, return QUEUE_FULL |
1328 | */ | 1328 | */ |
1329 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; | 1329 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; |
1330 | scsicmd->scsi_done(scsicmd); | 1330 | scsicmd->scsi_done(scsicmd); |
1331 | 1331 | ||
1332 | fib_complete(cmd_fibcontext); | 1332 | aac_fib_complete(cmd_fibcontext); |
1333 | fib_free(cmd_fibcontext); | 1333 | aac_fib_free(cmd_fibcontext); |
1334 | return 0; | 1334 | return 0; |
1335 | } | 1335 | } |
1336 | 1336 | ||
@@ -1369,8 +1369,8 @@ static void synchronize_callback(void *context, struct fib *fibptr) | |||
1369 | sizeof(cmd->sense_buffer))); | 1369 | sizeof(cmd->sense_buffer))); |
1370 | } | 1370 | } |
1371 | 1371 | ||
1372 | fib_complete(fibptr); | 1372 | aac_fib_complete(fibptr); |
1373 | fib_free(fibptr); | 1373 | aac_fib_free(fibptr); |
1374 | cmd->scsi_done(cmd); | 1374 | cmd->scsi_done(cmd); |
1375 | } | 1375 | } |
1376 | 1376 | ||
@@ -1407,10 +1407,10 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) | |||
1407 | * Allocate and initialize a Fib | 1407 | * Allocate and initialize a Fib |
1408 | */ | 1408 | */ |
1409 | if (!(cmd_fibcontext = | 1409 | if (!(cmd_fibcontext = |
1410 | fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) | 1410 | aac_fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) |
1411 | return SCSI_MLQUEUE_HOST_BUSY; | 1411 | return SCSI_MLQUEUE_HOST_BUSY; |
1412 | 1412 | ||
1413 | fib_init(cmd_fibcontext); | 1413 | aac_fib_init(cmd_fibcontext); |
1414 | 1414 | ||
1415 | synchronizecmd = fib_data(cmd_fibcontext); | 1415 | synchronizecmd = fib_data(cmd_fibcontext); |
1416 | synchronizecmd->command = cpu_to_le32(VM_ContainerConfig); | 1416 | synchronizecmd->command = cpu_to_le32(VM_ContainerConfig); |
@@ -1422,7 +1422,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) | |||
1422 | /* | 1422 | /* |
1423 | * Now send the Fib to the adapter | 1423 | * Now send the Fib to the adapter |
1424 | */ | 1424 | */ |
1425 | status = fib_send(ContainerCommand, | 1425 | status = aac_fib_send(ContainerCommand, |
1426 | cmd_fibcontext, | 1426 | cmd_fibcontext, |
1427 | sizeof(struct aac_synchronize), | 1427 | sizeof(struct aac_synchronize), |
1428 | FsaNormal, | 1428 | FsaNormal, |
@@ -1437,9 +1437,9 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) | |||
1437 | return 0; | 1437 | return 0; |
1438 | 1438 | ||
1439 | printk(KERN_WARNING | 1439 | printk(KERN_WARNING |
1440 | "aac_synchronize: fib_send failed with status: %d.\n", status); | 1440 | "aac_synchronize: aac_fib_send failed with status: %d.\n", status); |
1441 | fib_complete(cmd_fibcontext); | 1441 | aac_fib_complete(cmd_fibcontext); |
1442 | fib_free(cmd_fibcontext); | 1442 | aac_fib_free(cmd_fibcontext); |
1443 | return SCSI_MLQUEUE_HOST_BUSY; | 1443 | return SCSI_MLQUEUE_HOST_BUSY; |
1444 | } | 1444 | } |
1445 | 1445 | ||
@@ -1465,7 +1465,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1465 | * itself. | 1465 | * itself. |
1466 | */ | 1466 | */ |
1467 | if (scmd_id(scsicmd) != host->this_id) { | 1467 | if (scmd_id(scsicmd) != host->this_id) { |
1468 | if ((scsicmd->device->channel == 0) ){ | 1468 | if ((scsicmd->device->channel == CONTAINER_CHANNEL)) { |
1469 | if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){ | 1469 | if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){ |
1470 | scsicmd->result = DID_NO_CONNECT << 16; | 1470 | scsicmd->result = DID_NO_CONNECT << 16; |
1471 | scsicmd->scsi_done(scsicmd); | 1471 | scsicmd->scsi_done(scsicmd); |
@@ -1488,7 +1488,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1488 | case READ_CAPACITY: | 1488 | case READ_CAPACITY: |
1489 | case TEST_UNIT_READY: | 1489 | case TEST_UNIT_READY: |
1490 | spin_unlock_irq(host->host_lock); | 1490 | spin_unlock_irq(host->host_lock); |
1491 | probe_container(dev, cid); | 1491 | aac_probe_container(dev, cid); |
1492 | if ((fsa_dev_ptr[cid].valid & 1) == 0) | 1492 | if ((fsa_dev_ptr[cid].valid & 1) == 0) |
1493 | fsa_dev_ptr[cid].valid = 0; | 1493 | fsa_dev_ptr[cid].valid = 0; |
1494 | spin_lock_irq(host->host_lock); | 1494 | spin_lock_irq(host->host_lock); |
@@ -1935,33 +1935,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) | |||
1935 | case SRB_STATUS_ERROR_RECOVERY: | 1935 | case SRB_STATUS_ERROR_RECOVERY: |
1936 | case SRB_STATUS_PENDING: | 1936 | case SRB_STATUS_PENDING: |
1937 | case SRB_STATUS_SUCCESS: | 1937 | case SRB_STATUS_SUCCESS: |
1938 | if(scsicmd->cmnd[0] == INQUIRY ){ | 1938 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; |
1939 | u8 b; | ||
1940 | u8 b1; | ||
1941 | /* We can't expose disk devices because we can't tell whether they | ||
1942 | * are the raw container drives or stand alone drives. If they have | ||
1943 | * the removable bit set then we should expose them though. | ||
1944 | */ | ||
1945 | b = (*(u8*)scsicmd->buffer)&0x1f; | ||
1946 | b1 = ((u8*)scsicmd->buffer)[1]; | ||
1947 | if( b==TYPE_TAPE || b==TYPE_WORM || b==TYPE_ROM || b==TYPE_MOD|| b==TYPE_MEDIUM_CHANGER | ||
1948 | || (b==TYPE_DISK && (b1&0x80)) ){ | ||
1949 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | ||
1950 | /* | ||
1951 | * We will allow disk devices if in RAID/SCSI mode and | ||
1952 | * the channel is 2 | ||
1953 | */ | ||
1954 | } else if ((dev->raid_scsi_mode) && | ||
1955 | (scmd_channel(scsicmd) == 2)) { | ||
1956 | scsicmd->result = DID_OK << 16 | | ||
1957 | COMMAND_COMPLETE << 8; | ||
1958 | } else { | ||
1959 | scsicmd->result = DID_NO_CONNECT << 16 | | ||
1960 | COMMAND_COMPLETE << 8; | ||
1961 | } | ||
1962 | } else { | ||
1963 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | ||
1964 | } | ||
1965 | break; | 1939 | break; |
1966 | case SRB_STATUS_DATA_OVERRUN: | 1940 | case SRB_STATUS_DATA_OVERRUN: |
1967 | switch(scsicmd->cmnd[0]){ | 1941 | switch(scsicmd->cmnd[0]){ |
@@ -1981,28 +1955,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) | |||
1981 | scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8; | 1955 | scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8; |
1982 | break; | 1956 | break; |
1983 | case INQUIRY: { | 1957 | case INQUIRY: { |
1984 | u8 b; | 1958 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; |
1985 | u8 b1; | ||
1986 | /* We can't expose disk devices because we can't tell whether they | ||
1987 | * are the raw container drives or stand alone drives | ||
1988 | */ | ||
1989 | b = (*(u8*)scsicmd->buffer)&0x0f; | ||
1990 | b1 = ((u8*)scsicmd->buffer)[1]; | ||
1991 | if( b==TYPE_TAPE || b==TYPE_WORM || b==TYPE_ROM || b==TYPE_MOD|| b==TYPE_MEDIUM_CHANGER | ||
1992 | || (b==TYPE_DISK && (b1&0x80)) ){ | ||
1993 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | ||
1994 | /* | ||
1995 | * We will allow disk devices if in RAID/SCSI mode and | ||
1996 | * the channel is 2 | ||
1997 | */ | ||
1998 | } else if ((dev->raid_scsi_mode) && | ||
1999 | (scmd_channel(scsicmd) == 2)) { | ||
2000 | scsicmd->result = DID_OK << 16 | | ||
2001 | COMMAND_COMPLETE << 8; | ||
2002 | } else { | ||
2003 | scsicmd->result = DID_NO_CONNECT << 16 | | ||
2004 | COMMAND_COMPLETE << 8; | ||
2005 | } | ||
2006 | break; | 1959 | break; |
2007 | } | 1960 | } |
2008 | default: | 1961 | default: |
@@ -2089,8 +2042,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr) | |||
2089 | */ | 2042 | */ |
2090 | scsicmd->result |= le32_to_cpu(srbreply->scsi_status); | 2043 | scsicmd->result |= le32_to_cpu(srbreply->scsi_status); |
2091 | 2044 | ||
2092 | fib_complete(fibptr); | 2045 | aac_fib_complete(fibptr); |
2093 | fib_free(fibptr); | 2046 | aac_fib_free(fibptr); |
2094 | scsicmd->scsi_done(scsicmd); | 2047 | scsicmd->scsi_done(scsicmd); |
2095 | } | 2048 | } |
2096 | 2049 | ||
@@ -2142,10 +2095,10 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) | |||
2142 | /* | 2095 | /* |
2143 | * Allocate and initialize a Fib then setup a BlockWrite command | 2096 | * Allocate and initialize a Fib then setup a BlockWrite command |
2144 | */ | 2097 | */ |
2145 | if (!(cmd_fibcontext = fib_alloc(dev))) { | 2098 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { |
2146 | return -1; | 2099 | return -1; |
2147 | } | 2100 | } |
2148 | fib_init(cmd_fibcontext); | 2101 | aac_fib_init(cmd_fibcontext); |
2149 | 2102 | ||
2150 | srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext); | 2103 | srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext); |
2151 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); | 2104 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); |
@@ -2179,7 +2132,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) | |||
2179 | /* | 2132 | /* |
2180 | * Now send the Fib to the adapter | 2133 | * Now send the Fib to the adapter |
2181 | */ | 2134 | */ |
2182 | status = fib_send(ScsiPortCommand64, cmd_fibcontext, | 2135 | status = aac_fib_send(ScsiPortCommand64, cmd_fibcontext, |
2183 | fibsize, FsaNormal, 0, 1, | 2136 | fibsize, FsaNormal, 0, 1, |
2184 | (fib_callback) aac_srb_callback, | 2137 | (fib_callback) aac_srb_callback, |
2185 | (void *) scsicmd); | 2138 | (void *) scsicmd); |
@@ -2201,7 +2154,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) | |||
2201 | /* | 2154 | /* |
2202 | * Now send the Fib to the adapter | 2155 | * Now send the Fib to the adapter |
2203 | */ | 2156 | */ |
2204 | status = fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1, | 2157 | status = aac_fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1, |
2205 | (fib_callback) aac_srb_callback, (void *) scsicmd); | 2158 | (fib_callback) aac_srb_callback, (void *) scsicmd); |
2206 | } | 2159 | } |
2207 | /* | 2160 | /* |
@@ -2211,9 +2164,9 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) | |||
2211 | return 0; | 2164 | return 0; |
2212 | } | 2165 | } |
2213 | 2166 | ||
2214 | printk(KERN_WARNING "aac_srb: fib_send failed with status: %d\n", status); | 2167 | printk(KERN_WARNING "aac_srb: aac_fib_send failed with status: %d\n", status); |
2215 | fib_complete(cmd_fibcontext); | 2168 | aac_fib_complete(cmd_fibcontext); |
2216 | fib_free(cmd_fibcontext); | 2169 | aac_fib_free(cmd_fibcontext); |
2217 | 2170 | ||
2218 | return -1; | 2171 | return -1; |
2219 | } | 2172 | } |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 66dbb6d2c506..2d430b7e8cf4 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -1774,16 +1774,16 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor) | |||
1774 | struct scsi_cmnd; | 1774 | struct scsi_cmnd; |
1775 | 1775 | ||
1776 | const char *aac_driverinfo(struct Scsi_Host *); | 1776 | const char *aac_driverinfo(struct Scsi_Host *); |
1777 | struct fib *fib_alloc(struct aac_dev *dev); | 1777 | struct fib *aac_fib_alloc(struct aac_dev *dev); |
1778 | int fib_setup(struct aac_dev *dev); | 1778 | int aac_fib_setup(struct aac_dev *dev); |
1779 | void fib_map_free(struct aac_dev *dev); | 1779 | void aac_fib_map_free(struct aac_dev *dev); |
1780 | void fib_free(struct fib * context); | 1780 | void aac_fib_free(struct fib * context); |
1781 | void fib_init(struct fib * context); | 1781 | void aac_fib_init(struct fib * context); |
1782 | void aac_printf(struct aac_dev *dev, u32 val); | 1782 | void aac_printf(struct aac_dev *dev, u32 val); |
1783 | int fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt); | 1783 | int aac_fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt); |
1784 | int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry); | 1784 | int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry); |
1785 | void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); | 1785 | void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); |
1786 | int fib_complete(struct fib * context); | 1786 | int aac_fib_complete(struct fib * context); |
1787 | #define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) | 1787 | #define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) |
1788 | struct aac_dev *aac_init_adapter(struct aac_dev *dev); | 1788 | struct aac_dev *aac_init_adapter(struct aac_dev *dev); |
1789 | int aac_get_config_status(struct aac_dev *dev); | 1789 | int aac_get_config_status(struct aac_dev *dev); |
@@ -1799,11 +1799,11 @@ unsigned int aac_command_normal(struct aac_queue * q); | |||
1799 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); | 1799 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index); |
1800 | int aac_command_thread(struct aac_dev * dev); | 1800 | int aac_command_thread(struct aac_dev * dev); |
1801 | int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); | 1801 | int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); |
1802 | int fib_adapter_complete(struct fib * fibptr, unsigned short size); | 1802 | int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size); |
1803 | struct aac_driver_ident* aac_get_driver_ident(int devtype); | 1803 | struct aac_driver_ident* aac_get_driver_ident(int devtype); |
1804 | int aac_get_adapter_info(struct aac_dev* dev); | 1804 | int aac_get_adapter_info(struct aac_dev* dev); |
1805 | int aac_send_shutdown(struct aac_dev *dev); | 1805 | int aac_send_shutdown(struct aac_dev *dev); |
1806 | int probe_container(struct aac_dev *dev, int cid); | 1806 | int aac_probe_container(struct aac_dev *dev, int cid); |
1807 | extern int numacb; | 1807 | extern int numacb; |
1808 | extern int acbsize; | 1808 | extern int acbsize; |
1809 | extern char aac_driver_version[]; | 1809 | extern char aac_driver_version[]; |
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 4fe79cd7c957..47fefca72695 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
@@ -63,7 +63,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
63 | unsigned size; | 63 | unsigned size; |
64 | int retval; | 64 | int retval; |
65 | 65 | ||
66 | fibptr = fib_alloc(dev); | 66 | fibptr = aac_fib_alloc(dev); |
67 | if(fibptr == NULL) { | 67 | if(fibptr == NULL) { |
68 | return -ENOMEM; | 68 | return -ENOMEM; |
69 | } | 69 | } |
@@ -73,7 +73,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
73 | * First copy in the header so that we can check the size field. | 73 | * First copy in the header so that we can check the size field. |
74 | */ | 74 | */ |
75 | if (copy_from_user((void *)kfib, arg, sizeof(struct aac_fibhdr))) { | 75 | if (copy_from_user((void *)kfib, arg, sizeof(struct aac_fibhdr))) { |
76 | fib_free(fibptr); | 76 | aac_fib_free(fibptr); |
77 | return -EFAULT; | 77 | return -EFAULT; |
78 | } | 78 | } |
79 | /* | 79 | /* |
@@ -110,13 +110,13 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
110 | */ | 110 | */ |
111 | kfib->header.XferState = 0; | 111 | kfib->header.XferState = 0; |
112 | } else { | 112 | } else { |
113 | retval = fib_send(le16_to_cpu(kfib->header.Command), fibptr, | 113 | retval = aac_fib_send(le16_to_cpu(kfib->header.Command), fibptr, |
114 | le16_to_cpu(kfib->header.Size) , FsaNormal, | 114 | le16_to_cpu(kfib->header.Size) , FsaNormal, |
115 | 1, 1, NULL, NULL); | 115 | 1, 1, NULL, NULL); |
116 | if (retval) { | 116 | if (retval) { |
117 | goto cleanup; | 117 | goto cleanup; |
118 | } | 118 | } |
119 | if (fib_complete(fibptr) != 0) { | 119 | if (aac_fib_complete(fibptr) != 0) { |
120 | retval = -EINVAL; | 120 | retval = -EINVAL; |
121 | goto cleanup; | 121 | goto cleanup; |
122 | } | 122 | } |
@@ -138,7 +138,7 @@ cleanup: | |||
138 | fibptr->hw_fib_pa = hw_fib_pa; | 138 | fibptr->hw_fib_pa = hw_fib_pa; |
139 | fibptr->hw_fib = hw_fib; | 139 | fibptr->hw_fib = hw_fib; |
140 | } | 140 | } |
141 | fib_free(fibptr); | 141 | aac_fib_free(fibptr); |
142 | return retval; | 142 | return retval; |
143 | } | 143 | } |
144 | 144 | ||
@@ -464,10 +464,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
464 | /* | 464 | /* |
465 | * Allocate and initialize a Fib then setup a BlockWrite command | 465 | * Allocate and initialize a Fib then setup a BlockWrite command |
466 | */ | 466 | */ |
467 | if (!(srbfib = fib_alloc(dev))) { | 467 | if (!(srbfib = aac_fib_alloc(dev))) { |
468 | return -ENOMEM; | 468 | return -ENOMEM; |
469 | } | 469 | } |
470 | fib_init(srbfib); | 470 | aac_fib_init(srbfib); |
471 | 471 | ||
472 | srbcmd = (struct aac_srb*) fib_data(srbfib); | 472 | srbcmd = (struct aac_srb*) fib_data(srbfib); |
473 | 473 | ||
@@ -601,7 +601,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
601 | 601 | ||
602 | srbcmd->count = cpu_to_le32(byte_count); | 602 | srbcmd->count = cpu_to_le32(byte_count); |
603 | psg->count = cpu_to_le32(sg_indx+1); | 603 | psg->count = cpu_to_le32(sg_indx+1); |
604 | status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); | 604 | status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); |
605 | } else { | 605 | } else { |
606 | struct user_sgmap* upsg = &user_srbcmd->sg; | 606 | struct user_sgmap* upsg = &user_srbcmd->sg; |
607 | struct sgmap* psg = &srbcmd->sg; | 607 | struct sgmap* psg = &srbcmd->sg; |
@@ -649,7 +649,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
649 | } | 649 | } |
650 | srbcmd->count = cpu_to_le32(byte_count); | 650 | srbcmd->count = cpu_to_le32(byte_count); |
651 | psg->count = cpu_to_le32(sg_indx+1); | 651 | psg->count = cpu_to_le32(sg_indx+1); |
652 | status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); | 652 | status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); |
653 | } | 653 | } |
654 | 654 | ||
655 | if (status != 0){ | 655 | if (status != 0){ |
@@ -684,8 +684,8 @@ cleanup: | |||
684 | for(i=0; i <= sg_indx; i++){ | 684 | for(i=0; i <= sg_indx; i++){ |
685 | kfree(sg_list[i]); | 685 | kfree(sg_list[i]); |
686 | } | 686 | } |
687 | fib_complete(srbfib); | 687 | aac_fib_complete(srbfib); |
688 | fib_free(srbfib); | 688 | aac_fib_free(srbfib); |
689 | 689 | ||
690 | return rcode; | 690 | return rcode; |
691 | } | 691 | } |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 82821d331c07..1628d094943d 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -185,17 +185,17 @@ int aac_send_shutdown(struct aac_dev * dev) | |||
185 | struct aac_close *cmd; | 185 | struct aac_close *cmd; |
186 | int status; | 186 | int status; |
187 | 187 | ||
188 | fibctx = fib_alloc(dev); | 188 | fibctx = aac_fib_alloc(dev); |
189 | if (!fibctx) | 189 | if (!fibctx) |
190 | return -ENOMEM; | 190 | return -ENOMEM; |
191 | fib_init(fibctx); | 191 | aac_fib_init(fibctx); |
192 | 192 | ||
193 | cmd = (struct aac_close *) fib_data(fibctx); | 193 | cmd = (struct aac_close *) fib_data(fibctx); |
194 | 194 | ||
195 | cmd->command = cpu_to_le32(VM_CloseAll); | 195 | cmd->command = cpu_to_le32(VM_CloseAll); |
196 | cmd->cid = cpu_to_le32(0xffffffff); | 196 | cmd->cid = cpu_to_le32(0xffffffff); |
197 | 197 | ||
198 | status = fib_send(ContainerCommand, | 198 | status = aac_fib_send(ContainerCommand, |
199 | fibctx, | 199 | fibctx, |
200 | sizeof(struct aac_close), | 200 | sizeof(struct aac_close), |
201 | FsaNormal, | 201 | FsaNormal, |
@@ -203,8 +203,8 @@ int aac_send_shutdown(struct aac_dev * dev) | |||
203 | NULL, NULL); | 203 | NULL, NULL); |
204 | 204 | ||
205 | if (status == 0) | 205 | if (status == 0) |
206 | fib_complete(fibctx); | 206 | aac_fib_complete(fibctx); |
207 | fib_free(fibctx); | 207 | aac_fib_free(fibctx); |
208 | return status; | 208 | return status; |
209 | } | 209 | } |
210 | 210 | ||
@@ -427,7 +427,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) | |||
427 | /* | 427 | /* |
428 | * Initialize the list of fibs | 428 | * Initialize the list of fibs |
429 | */ | 429 | */ |
430 | if(fib_setup(dev)<0){ | 430 | if (aac_fib_setup(dev) < 0) { |
431 | kfree(dev->queues); | 431 | kfree(dev->queues); |
432 | return NULL; | 432 | return NULL; |
433 | } | 433 | } |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 38d6d00fb0fc..609fd19b1844 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -38,10 +38,10 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/completion.h> | 39 | #include <linux/completion.h> |
40 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
41 | #include <linux/delay.h> | ||
41 | #include <scsi/scsi_host.h> | 42 | #include <scsi/scsi_host.h> |
42 | #include <scsi/scsi_device.h> | 43 | #include <scsi/scsi_device.h> |
43 | #include <asm/semaphore.h> | 44 | #include <asm/semaphore.h> |
44 | #include <asm/delay.h> | ||
45 | 45 | ||
46 | #include "aacraid.h" | 46 | #include "aacraid.h" |
47 | 47 | ||
@@ -67,27 +67,27 @@ static int fib_map_alloc(struct aac_dev *dev) | |||
67 | } | 67 | } |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * fib_map_free - free the fib objects | 70 | * aac_fib_map_free - free the fib objects |
71 | * @dev: Adapter to free | 71 | * @dev: Adapter to free |
72 | * | 72 | * |
73 | * Free the PCI mappings and the memory allocated for FIB blocks | 73 | * Free the PCI mappings and the memory allocated for FIB blocks |
74 | * on this adapter. | 74 | * on this adapter. |
75 | */ | 75 | */ |
76 | 76 | ||
77 | void fib_map_free(struct aac_dev *dev) | 77 | void aac_fib_map_free(struct aac_dev *dev) |
78 | { | 78 | { |
79 | pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa); | 79 | pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa); |
80 | } | 80 | } |
81 | 81 | ||
82 | /** | 82 | /** |
83 | * fib_setup - setup the fibs | 83 | * aac_fib_setup - setup the fibs |
84 | * @dev: Adapter to set up | 84 | * @dev: Adapter to set up |
85 | * | 85 | * |
86 | * Allocate the PCI space for the fibs, map it and then intialise the | 86 | * Allocate the PCI space for the fibs, map it and then intialise the |
87 | * fib area, the unmapped fib data and also the free list | 87 | * fib area, the unmapped fib data and also the free list |
88 | */ | 88 | */ |
89 | 89 | ||
90 | int fib_setup(struct aac_dev * dev) | 90 | int aac_fib_setup(struct aac_dev * dev) |
91 | { | 91 | { |
92 | struct fib *fibptr; | 92 | struct fib *fibptr; |
93 | struct hw_fib *hw_fib_va; | 93 | struct hw_fib *hw_fib_va; |
@@ -134,14 +134,14 @@ int fib_setup(struct aac_dev * dev) | |||
134 | } | 134 | } |
135 | 135 | ||
136 | /** | 136 | /** |
137 | * fib_alloc - allocate a fib | 137 | * aac_fib_alloc - allocate a fib |
138 | * @dev: Adapter to allocate the fib for | 138 | * @dev: Adapter to allocate the fib for |
139 | * | 139 | * |
140 | * Allocate a fib from the adapter fib pool. If the pool is empty we | 140 | * Allocate a fib from the adapter fib pool. If the pool is empty we |
141 | * return NULL. | 141 | * return NULL. |
142 | */ | 142 | */ |
143 | 143 | ||
144 | struct fib * fib_alloc(struct aac_dev *dev) | 144 | struct fib *aac_fib_alloc(struct aac_dev *dev) |
145 | { | 145 | { |
146 | struct fib * fibptr; | 146 | struct fib * fibptr; |
147 | unsigned long flags; | 147 | unsigned long flags; |
@@ -170,14 +170,14 @@ struct fib * fib_alloc(struct aac_dev *dev) | |||
170 | } | 170 | } |
171 | 171 | ||
172 | /** | 172 | /** |
173 | * fib_free - free a fib | 173 | * aac_fib_free - free a fib |
174 | * @fibptr: fib to free up | 174 | * @fibptr: fib to free up |
175 | * | 175 | * |
176 | * Frees up a fib and places it on the appropriate queue | 176 | * Frees up a fib and places it on the appropriate queue |
177 | * (either free or timed out) | 177 | * (either free or timed out) |
178 | */ | 178 | */ |
179 | 179 | ||
180 | void fib_free(struct fib * fibptr) | 180 | void aac_fib_free(struct fib *fibptr) |
181 | { | 181 | { |
182 | unsigned long flags; | 182 | unsigned long flags; |
183 | 183 | ||
@@ -188,7 +188,7 @@ void fib_free(struct fib * fibptr) | |||
188 | fibptr->dev->timeout_fib = fibptr; | 188 | fibptr->dev->timeout_fib = fibptr; |
189 | } else { | 189 | } else { |
190 | if (fibptr->hw_fib->header.XferState != 0) { | 190 | if (fibptr->hw_fib->header.XferState != 0) { |
191 | printk(KERN_WARNING "fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", | 191 | printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", |
192 | (void*)fibptr, | 192 | (void*)fibptr, |
193 | le32_to_cpu(fibptr->hw_fib->header.XferState)); | 193 | le32_to_cpu(fibptr->hw_fib->header.XferState)); |
194 | } | 194 | } |
@@ -199,13 +199,13 @@ void fib_free(struct fib * fibptr) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | /** | 201 | /** |
202 | * fib_init - initialise a fib | 202 | * aac_fib_init - initialise a fib |
203 | * @fibptr: The fib to initialize | 203 | * @fibptr: The fib to initialize |
204 | * | 204 | * |
205 | * Set up the generic fib fields ready for use | 205 | * Set up the generic fib fields ready for use |
206 | */ | 206 | */ |
207 | 207 | ||
208 | void fib_init(struct fib *fibptr) | 208 | void aac_fib_init(struct fib *fibptr) |
209 | { | 209 | { |
210 | struct hw_fib *hw_fib = fibptr->hw_fib; | 210 | struct hw_fib *hw_fib = fibptr->hw_fib; |
211 | 211 | ||
@@ -362,7 +362,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f | |||
362 | */ | 362 | */ |
363 | 363 | ||
364 | /** | 364 | /** |
365 | * fib_send - send a fib to the adapter | 365 | * aac_fib_send - send a fib to the adapter |
366 | * @command: Command to send | 366 | * @command: Command to send |
367 | * @fibptr: The fib | 367 | * @fibptr: The fib |
368 | * @size: Size of fib data area | 368 | * @size: Size of fib data area |
@@ -378,7 +378,9 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f | |||
378 | * response FIB is received from the adapter. | 378 | * response FIB is received from the adapter. |
379 | */ | 379 | */ |
380 | 380 | ||
381 | int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void * callback_data) | 381 | int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, |
382 | int priority, int wait, int reply, fib_callback callback, | ||
383 | void *callback_data) | ||
382 | { | 384 | { |
383 | struct aac_dev * dev = fibptr->dev; | 385 | struct aac_dev * dev = fibptr->dev; |
384 | struct hw_fib * hw_fib = fibptr->hw_fib; | 386 | struct hw_fib * hw_fib = fibptr->hw_fib; |
@@ -493,7 +495,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority | |||
493 | q->numpending++; | 495 | q->numpending++; |
494 | *(q->headers.producer) = cpu_to_le32(index + 1); | 496 | *(q->headers.producer) = cpu_to_le32(index + 1); |
495 | spin_unlock_irqrestore(q->lock, qflags); | 497 | spin_unlock_irqrestore(q->lock, qflags); |
496 | dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index)); | 498 | dprintk((KERN_DEBUG "aac_fib_send: inserting a queue entry at index %d.\n",index)); |
497 | if (!(nointr & aac_config.irq_mod)) | 499 | if (!(nointr & aac_config.irq_mod)) |
498 | aac_adapter_notify(dev, AdapNormCmdQueue); | 500 | aac_adapter_notify(dev, AdapNormCmdQueue); |
499 | } | 501 | } |
@@ -520,7 +522,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority | |||
520 | list_del(&fibptr->queue); | 522 | list_del(&fibptr->queue); |
521 | spin_unlock_irqrestore(q->lock, qflags); | 523 | spin_unlock_irqrestore(q->lock, qflags); |
522 | if (wait == -1) { | 524 | if (wait == -1) { |
523 | printk(KERN_ERR "aacraid: fib_send: first asynchronous command timed out.\n" | 525 | printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n" |
524 | "Usually a result of a PCI interrupt routing problem;\n" | 526 | "Usually a result of a PCI interrupt routing problem;\n" |
525 | "update mother board BIOS or consider utilizing one of\n" | 527 | "update mother board BIOS or consider utilizing one of\n" |
526 | "the SAFE mode kernel options (acpi, apic etc)\n"); | 528 | "the SAFE mode kernel options (acpi, apic etc)\n"); |
@@ -624,7 +626,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) | |||
624 | } | 626 | } |
625 | 627 | ||
626 | /** | 628 | /** |
627 | * fib_adapter_complete - complete adapter issued fib | 629 | * aac_fib_adapter_complete - complete adapter issued fib |
628 | * @fibptr: fib to complete | 630 | * @fibptr: fib to complete |
629 | * @size: size of fib | 631 | * @size: size of fib |
630 | * | 632 | * |
@@ -632,7 +634,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) | |||
632 | * the adapter. | 634 | * the adapter. |
633 | */ | 635 | */ |
634 | 636 | ||
635 | int fib_adapter_complete(struct fib * fibptr, unsigned short size) | 637 | int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) |
636 | { | 638 | { |
637 | struct hw_fib * hw_fib = fibptr->hw_fib; | 639 | struct hw_fib * hw_fib = fibptr->hw_fib; |
638 | struct aac_dev * dev = fibptr->dev; | 640 | struct aac_dev * dev = fibptr->dev; |
@@ -683,20 +685,20 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size) | |||
683 | } | 685 | } |
684 | else | 686 | else |
685 | { | 687 | { |
686 | printk(KERN_WARNING "fib_adapter_complete: Unknown xferstate detected.\n"); | 688 | printk(KERN_WARNING "aac_fib_adapter_complete: Unknown xferstate detected.\n"); |
687 | BUG(); | 689 | BUG(); |
688 | } | 690 | } |
689 | return 0; | 691 | return 0; |
690 | } | 692 | } |
691 | 693 | ||
692 | /** | 694 | /** |
693 | * fib_complete - fib completion handler | 695 | * aac_fib_complete - fib completion handler |
694 | * @fib: FIB to complete | 696 | * @fib: FIB to complete |
695 | * | 697 | * |
696 | * Will do all necessary work to complete a FIB. | 698 | * Will do all necessary work to complete a FIB. |
697 | */ | 699 | */ |
698 | 700 | ||
699 | int fib_complete(struct fib * fibptr) | 701 | int aac_fib_complete(struct fib *fibptr) |
700 | { | 702 | { |
701 | struct hw_fib * hw_fib = fibptr->hw_fib; | 703 | struct hw_fib * hw_fib = fibptr->hw_fib; |
702 | 704 | ||
@@ -995,14 +997,14 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
995 | if (!dev || !dev->scsi_host_ptr) | 997 | if (!dev || !dev->scsi_host_ptr) |
996 | return; | 998 | return; |
997 | /* | 999 | /* |
998 | * force reload of disk info via probe_container | 1000 | * force reload of disk info via aac_probe_container |
999 | */ | 1001 | */ |
1000 | if ((device_config_needed == CHANGE) | 1002 | if ((device_config_needed == CHANGE) |
1001 | && (dev->fsa_dev[container].valid == 1)) | 1003 | && (dev->fsa_dev[container].valid == 1)) |
1002 | dev->fsa_dev[container].valid = 2; | 1004 | dev->fsa_dev[container].valid = 2; |
1003 | if ((device_config_needed == CHANGE) || | 1005 | if ((device_config_needed == CHANGE) || |
1004 | (device_config_needed == ADD)) | 1006 | (device_config_needed == ADD)) |
1005 | probe_container(dev, container); | 1007 | aac_probe_container(dev, container); |
1006 | device = scsi_device_lookup(dev->scsi_host_ptr, | 1008 | device = scsi_device_lookup(dev->scsi_host_ptr, |
1007 | CONTAINER_TO_CHANNEL(container), | 1009 | CONTAINER_TO_CHANNEL(container), |
1008 | CONTAINER_TO_ID(container), | 1010 | CONTAINER_TO_ID(container), |
@@ -1104,7 +1106,7 @@ int aac_command_thread(struct aac_dev * dev) | |||
1104 | /* Handle Driver Notify Events */ | 1106 | /* Handle Driver Notify Events */ |
1105 | aac_handle_aif(dev, fib); | 1107 | aac_handle_aif(dev, fib); |
1106 | *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); | 1108 | *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); |
1107 | fib_adapter_complete(fib, (u16)sizeof(u32)); | 1109 | aac_fib_adapter_complete(fib, (u16)sizeof(u32)); |
1108 | } else { | 1110 | } else { |
1109 | struct list_head *entry; | 1111 | struct list_head *entry; |
1110 | /* The u32 here is important and intended. We are using | 1112 | /* The u32 here is important and intended. We are using |
@@ -1241,7 +1243,7 @@ int aac_command_thread(struct aac_dev * dev) | |||
1241 | * Set the status of this FIB | 1243 | * Set the status of this FIB |
1242 | */ | 1244 | */ |
1243 | *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); | 1245 | *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); |
1244 | fib_adapter_complete(fib, sizeof(u32)); | 1246 | aac_fib_adapter_complete(fib, sizeof(u32)); |
1245 | spin_unlock_irqrestore(&dev->fib_lock, flagv); | 1247 | spin_unlock_irqrestore(&dev->fib_lock, flagv); |
1246 | /* Free up the remaining resources */ | 1248 | /* Free up the remaining resources */ |
1247 | hw_fib_p = hw_fib_pool; | 1249 | hw_fib_p = hw_fib_pool; |
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index 439948ef8251..f6bcb9486f85 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c | |||
@@ -206,7 +206,7 @@ unsigned int aac_command_normal(struct aac_queue *q) | |||
206 | * Set the status of this FIB | 206 | * Set the status of this FIB |
207 | */ | 207 | */ |
208 | *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); | 208 | *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); |
209 | fib_adapter_complete(fib, sizeof(u32)); | 209 | aac_fib_adapter_complete(fib, sizeof(u32)); |
210 | spin_lock_irqsave(q->lock, flags); | 210 | spin_lock_irqsave(q->lock, flags); |
211 | } | 211 | } |
212 | } | 212 | } |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 0bf5f9a943e8..271617890562 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -385,17 +385,45 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, | |||
385 | 385 | ||
386 | static int aac_slave_configure(struct scsi_device *sdev) | 386 | static int aac_slave_configure(struct scsi_device *sdev) |
387 | { | 387 | { |
388 | struct Scsi_Host *host = sdev->host; | 388 | if (sdev_channel(sdev) == CONTAINER_CHANNEL) { |
389 | sdev->skip_ms_page_8 = 1; | ||
390 | sdev->skip_ms_page_3f = 1; | ||
391 | } | ||
392 | if ((sdev->type == TYPE_DISK) && | ||
393 | (sdev_channel(sdev) != CONTAINER_CHANNEL)) { | ||
394 | struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; | ||
395 | if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) | ||
396 | sdev->no_uld_attach = 1; | ||
397 | } | ||
398 | if (sdev->tagged_supported && (sdev->type == TYPE_DISK) && | ||
399 | (sdev_channel(sdev) == CONTAINER_CHANNEL)) { | ||
400 | struct scsi_device * dev; | ||
401 | struct Scsi_Host *host = sdev->host; | ||
402 | unsigned num_lsu = 0; | ||
403 | unsigned num_one = 0; | ||
404 | unsigned depth; | ||
389 | 405 | ||
390 | if (sdev->tagged_supported) | 406 | __shost_for_each_device(dev, host) { |
391 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128); | 407 | if (dev->tagged_supported && (dev->type == TYPE_DISK) && |
392 | else | 408 | (sdev_channel(dev) == CONTAINER_CHANNEL)) |
409 | ++num_lsu; | ||
410 | else | ||
411 | ++num_one; | ||
412 | } | ||
413 | if (num_lsu == 0) | ||
414 | ++num_lsu; | ||
415 | depth = (host->can_queue - num_one) / num_lsu; | ||
416 | if (depth > 256) | ||
417 | depth = 256; | ||
418 | else if (depth < 2) | ||
419 | depth = 2; | ||
420 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth); | ||
421 | if (!(((struct aac_dev *)host->hostdata)->adapter_info.options & | ||
422 | AAC_OPT_NEW_COMM)) | ||
423 | blk_queue_max_segment_size(sdev->request_queue, 65536); | ||
424 | } else | ||
393 | scsi_adjust_queue_depth(sdev, 0, 1); | 425 | scsi_adjust_queue_depth(sdev, 0, 1); |
394 | 426 | ||
395 | if (!(((struct aac_dev *)host->hostdata)->adapter_info.options | ||
396 | & AAC_OPT_NEW_COMM)) | ||
397 | blk_queue_max_segment_size(sdev->request_queue, 65536); | ||
398 | |||
399 | return 0; | 427 | return 0; |
400 | } | 428 | } |
401 | 429 | ||
@@ -870,7 +898,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
870 | 898 | ||
871 | /* | 899 | /* |
872 | * max channel will be the physical channels plus 1 virtual channel | 900 | * max channel will be the physical channels plus 1 virtual channel |
873 | * all containers are on the virtual channel 0 | 901 | * all containers are on the virtual channel 0 (CONTAINER_CHANNEL) |
874 | * physical channels are address by their actual physical number+1 | 902 | * physical channels are address by their actual physical number+1 |
875 | */ | 903 | */ |
876 | if (aac->nondasd_support == 1) | 904 | if (aac->nondasd_support == 1) |
@@ -913,7 +941,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
913 | aac_adapter_disable_int(aac); | 941 | aac_adapter_disable_int(aac); |
914 | free_irq(pdev->irq, aac); | 942 | free_irq(pdev->irq, aac); |
915 | out_unmap: | 943 | out_unmap: |
916 | fib_map_free(aac); | 944 | aac_fib_map_free(aac); |
917 | pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); | 945 | pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); |
918 | kfree(aac->queues); | 946 | kfree(aac->queues); |
919 | iounmap(aac->regs.sa); | 947 | iounmap(aac->regs.sa); |
@@ -947,7 +975,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev) | |||
947 | 975 | ||
948 | aac_send_shutdown(aac); | 976 | aac_send_shutdown(aac); |
949 | aac_adapter_disable_int(aac); | 977 | aac_adapter_disable_int(aac); |
950 | fib_map_free(aac); | 978 | aac_fib_map_free(aac); |
951 | pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, | 979 | pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, |
952 | aac->comm_phys); | 980 | aac->comm_phys); |
953 | kfree(aac->queues); | 981 | kfree(aac->queues); |
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index cb2ee25f213f..531a1f9ceb51 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c | |||
@@ -1260,16 +1260,15 @@ static void free_hard_reset_SCs(struct Scsi_Host *shpnt, Scsi_Cmnd **SCs) | |||
1260 | * Reset the bus | 1260 | * Reset the bus |
1261 | * | 1261 | * |
1262 | */ | 1262 | */ |
1263 | static int aha152x_bus_reset(Scsi_Cmnd *SCpnt) | 1263 | static int aha152x_bus_reset_host(struct Scsi_Host *shpnt) |
1264 | { | 1264 | { |
1265 | struct Scsi_Host *shpnt = SCpnt->device->host; | ||
1266 | unsigned long flags; | 1265 | unsigned long flags; |
1267 | 1266 | ||
1268 | DO_LOCK(flags); | 1267 | DO_LOCK(flags); |
1269 | 1268 | ||
1270 | #if defined(AHA152X_DEBUG) | 1269 | #if defined(AHA152X_DEBUG) |
1271 | if(HOSTDATA(shpnt)->debug & debug_eh) { | 1270 | if(HOSTDATA(shpnt)->debug & debug_eh) { |
1272 | printk(DEBUG_LEAD "aha152x_bus_reset(%p)", CMDINFO(SCpnt), SCpnt); | 1271 | printk(KERN_DEBUG "scsi%d: bus reset", shpnt->host_no); |
1273 | show_queues(shpnt); | 1272 | show_queues(shpnt); |
1274 | } | 1273 | } |
1275 | #endif | 1274 | #endif |
@@ -1277,14 +1276,14 @@ static int aha152x_bus_reset(Scsi_Cmnd *SCpnt) | |||
1277 | free_hard_reset_SCs(shpnt, &ISSUE_SC); | 1276 | free_hard_reset_SCs(shpnt, &ISSUE_SC); |
1278 | free_hard_reset_SCs(shpnt, &DISCONNECTED_SC); | 1277 | free_hard_reset_SCs(shpnt, &DISCONNECTED_SC); |
1279 | 1278 | ||
1280 | DPRINTK(debug_eh, DEBUG_LEAD "resetting bus\n", CMDINFO(SCpnt)); | 1279 | DPRINTK(debug_eh, KERN_DEBUG "scsi%d: resetting bus\n", shpnt->host_no); |
1281 | 1280 | ||
1282 | SETPORT(SCSISEQ, SCSIRSTO); | 1281 | SETPORT(SCSISEQ, SCSIRSTO); |
1283 | mdelay(256); | 1282 | mdelay(256); |
1284 | SETPORT(SCSISEQ, 0); | 1283 | SETPORT(SCSISEQ, 0); |
1285 | mdelay(DELAY); | 1284 | mdelay(DELAY); |
1286 | 1285 | ||
1287 | DPRINTK(debug_eh, DEBUG_LEAD "bus resetted\n", CMDINFO(SCpnt)); | 1286 | DPRINTK(debug_eh, KERN_DEBUG "scsi%d: bus resetted\n", shpnt->host_no); |
1288 | 1287 | ||
1289 | setup_expected_interrupts(shpnt); | 1288 | setup_expected_interrupts(shpnt); |
1290 | if(HOSTDATA(shpnt)->commands==0) | 1289 | if(HOSTDATA(shpnt)->commands==0) |
@@ -1295,6 +1294,14 @@ static int aha152x_bus_reset(Scsi_Cmnd *SCpnt) | |||
1295 | return SUCCESS; | 1294 | return SUCCESS; |
1296 | } | 1295 | } |
1297 | 1296 | ||
1297 | /* | ||
1298 | * Reset the bus | ||
1299 | * | ||
1300 | */ | ||
1301 | static int aha152x_bus_reset(Scsi_Cmnd *SCpnt) | ||
1302 | { | ||
1303 | return aha152x_bus_reset_host(SCpnt->device->host); | ||
1304 | } | ||
1298 | 1305 | ||
1299 | /* | 1306 | /* |
1300 | * Restore default values to the AIC-6260 registers and reset the fifos | 1307 | * Restore default values to the AIC-6260 registers and reset the fifos |
@@ -1337,23 +1344,28 @@ static void reset_ports(struct Scsi_Host *shpnt) | |||
1337 | * Reset the host (bus and controller) | 1344 | * Reset the host (bus and controller) |
1338 | * | 1345 | * |
1339 | */ | 1346 | */ |
1340 | int aha152x_host_reset(Scsi_Cmnd * SCpnt) | 1347 | int aha152x_host_reset_host(struct Scsi_Host *shpnt) |
1341 | { | 1348 | { |
1342 | #if defined(AHA152X_DEBUG) | 1349 | DPRINTK(debug_eh, KERN_DEBUG "scsi%d: host reset\n", shpnt->host_no); |
1343 | struct Scsi_Host *shpnt = SCpnt->device->host; | ||
1344 | #endif | ||
1345 | |||
1346 | DPRINTK(debug_eh, DEBUG_LEAD "aha152x_host_reset(%p)\n", CMDINFO(SCpnt), SCpnt); | ||
1347 | 1350 | ||
1348 | aha152x_bus_reset(SCpnt); | 1351 | aha152x_bus_reset_host(shpnt); |
1349 | 1352 | ||
1350 | DPRINTK(debug_eh, DEBUG_LEAD "resetting ports\n", CMDINFO(SCpnt)); | 1353 | DPRINTK(debug_eh, KERN_DEBUG "scsi%d: resetting ports\n", shpnt->host_no); |
1351 | reset_ports(SCpnt->device->host); | 1354 | reset_ports(shpnt); |
1352 | 1355 | ||
1353 | return SUCCESS; | 1356 | return SUCCESS; |
1354 | } | 1357 | } |
1355 | 1358 | ||
1356 | /* | 1359 | /* |
1360 | * Reset the host (bus and controller) | ||
1361 | * | ||
1362 | */ | ||
1363 | static int aha152x_host_reset(Scsi_Cmnd *SCpnt) | ||
1364 | { | ||
1365 | return aha152x_host_reset_host(SCpnt->device->host); | ||
1366 | } | ||
1367 | |||
1368 | /* | ||
1357 | * Return the "logical geometry" | 1369 | * Return the "logical geometry" |
1358 | * | 1370 | * |
1359 | */ | 1371 | */ |
@@ -1431,22 +1443,18 @@ static void run(void) | |||
1431 | { | 1443 | { |
1432 | int i; | 1444 | int i; |
1433 | for (i = 0; i<ARRAY_SIZE(aha152x_host); i++) { | 1445 | for (i = 0; i<ARRAY_SIZE(aha152x_host); i++) { |
1434 | struct Scsi_Host *shpnt = aha152x_host[i]; | 1446 | is_complete(aha152x_host[i]); |
1435 | if (shpnt && HOSTDATA(shpnt)->service) { | ||
1436 | HOSTDATA(shpnt)->service=0; | ||
1437 | is_complete(shpnt); | ||
1438 | } | ||
1439 | } | 1447 | } |
1440 | } | 1448 | } |
1441 | 1449 | ||
1442 | /* | 1450 | /* |
1443 | * Interrupts handler | 1451 | * Interrupt handler |
1444 | * | 1452 | * |
1445 | */ | 1453 | */ |
1446 | |||
1447 | static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs) | 1454 | static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs) |
1448 | { | 1455 | { |
1449 | struct Scsi_Host *shpnt = lookup_irq(irqno); | 1456 | struct Scsi_Host *shpnt = lookup_irq(irqno); |
1457 | unsigned long flags; | ||
1450 | unsigned char rev, dmacntrl0; | 1458 | unsigned char rev, dmacntrl0; |
1451 | 1459 | ||
1452 | if (!shpnt) { | 1460 | if (!shpnt) { |
@@ -1472,23 +1480,23 @@ static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs) | |||
1472 | if ((rev == 0xFF) && (dmacntrl0 == 0xFF)) | 1480 | if ((rev == 0xFF) && (dmacntrl0 == 0xFF)) |
1473 | return IRQ_NONE; | 1481 | return IRQ_NONE; |
1474 | 1482 | ||
1483 | if( TESTLO(DMASTAT, INTSTAT) ) | ||
1484 | return IRQ_NONE; | ||
1485 | |||
1475 | /* no more interrupts from the controller, while we're busy. | 1486 | /* no more interrupts from the controller, while we're busy. |
1476 | INTEN is restored by the BH handler */ | 1487 | INTEN is restored by the BH handler */ |
1477 | CLRBITS(DMACNTRL0, INTEN); | 1488 | CLRBITS(DMACNTRL0, INTEN); |
1478 | 1489 | ||
1479 | #if 0 | 1490 | DO_LOCK(flags); |
1480 | /* check if there is already something to be | 1491 | if( HOSTDATA(shpnt)->service==0 ) { |
1481 | serviced; should not happen */ | 1492 | HOSTDATA(shpnt)->service=1; |
1482 | if(HOSTDATA(shpnt)->service) { | 1493 | |
1483 | printk(KERN_ERR "aha152x%d: lost interrupt (%d)\n", HOSTNO, HOSTDATA(shpnt)->service); | 1494 | /* Poke the BH handler */ |
1484 | show_queues(shpnt); | 1495 | INIT_WORK(&aha152x_tq, (void *) run, NULL); |
1496 | schedule_work(&aha152x_tq); | ||
1485 | } | 1497 | } |
1486 | #endif | 1498 | DO_UNLOCK(flags); |
1487 | 1499 | ||
1488 | /* Poke the BH handler */ | ||
1489 | HOSTDATA(shpnt)->service++; | ||
1490 | INIT_WORK(&aha152x_tq, (void *) run, NULL); | ||
1491 | schedule_work(&aha152x_tq); | ||
1492 | return IRQ_HANDLED; | 1500 | return IRQ_HANDLED; |
1493 | } | 1501 | } |
1494 | 1502 | ||
@@ -2527,7 +2535,18 @@ static void is_complete(struct Scsi_Host *shpnt) | |||
2527 | unsigned long flags; | 2535 | unsigned long flags; |
2528 | int pending; | 2536 | int pending; |
2529 | 2537 | ||
2538 | if(!shpnt) | ||
2539 | return; | ||
2540 | |||
2530 | DO_LOCK(flags); | 2541 | DO_LOCK(flags); |
2542 | |||
2543 | if( HOSTDATA(shpnt)->service==0 ) { | ||
2544 | DO_UNLOCK(flags); | ||
2545 | return; | ||
2546 | } | ||
2547 | |||
2548 | HOSTDATA(shpnt)->service = 0; | ||
2549 | |||
2531 | if(HOSTDATA(shpnt)->in_intr) { | 2550 | if(HOSTDATA(shpnt)->in_intr) { |
2532 | DO_UNLOCK(flags); | 2551 | DO_UNLOCK(flags); |
2533 | /* aha152x_error never returns.. */ | 2552 | /* aha152x_error never returns.. */ |
diff --git a/drivers/scsi/aha152x.h b/drivers/scsi/aha152x.h index d277613af29b..d2add24d02a3 100644 --- a/drivers/scsi/aha152x.h +++ b/drivers/scsi/aha152x.h | |||
@@ -332,6 +332,6 @@ struct aha152x_setup { | |||
332 | 332 | ||
333 | struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *); | 333 | struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *); |
334 | void aha152x_release(struct Scsi_Host *); | 334 | void aha152x_release(struct Scsi_Host *); |
335 | int aha152x_host_reset(Scsi_Cmnd *); | 335 | int aha152x_host_reset_host(struct Scsi_Host *); |
336 | 336 | ||
337 | #endif /* _AHA152X_H */ | 337 | #endif /* _AHA152X_H */ |
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index a800fb51168b..559ff7aae3f1 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -742,23 +742,17 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs * | |||
742 | struct ata_queued_cmd *qc; | 742 | struct ata_queued_cmd *qc; |
743 | qc = ata_qc_from_tag(ap, ap->active_tag); | 743 | qc = ata_qc_from_tag(ap, ap->active_tag); |
744 | if (!ahci_host_intr(ap, qc)) | 744 | if (!ahci_host_intr(ap, qc)) |
745 | if (ata_ratelimit()) { | 745 | if (ata_ratelimit()) |
746 | struct pci_dev *pdev = | 746 | dev_printk(KERN_WARNING, host_set->dev, |
747 | to_pci_dev(ap->host_set->dev); | ||
748 | dev_printk(KERN_WARNING, &pdev->dev, | ||
749 | "unhandled interrupt on port %u\n", | 747 | "unhandled interrupt on port %u\n", |
750 | i); | 748 | i); |
751 | } | ||
752 | 749 | ||
753 | VPRINTK("port %u\n", i); | 750 | VPRINTK("port %u\n", i); |
754 | } else { | 751 | } else { |
755 | VPRINTK("port %u (no irq)\n", i); | 752 | VPRINTK("port %u (no irq)\n", i); |
756 | if (ata_ratelimit()) { | 753 | if (ata_ratelimit()) |
757 | struct pci_dev *pdev = | 754 | dev_printk(KERN_WARNING, host_set->dev, |
758 | to_pci_dev(ap->host_set->dev); | ||
759 | dev_printk(KERN_WARNING, &pdev->dev, | ||
760 | "interrupt on disabled port %u\n", i); | 755 | "interrupt on disabled port %u\n", i); |
761 | } | ||
762 | } | 756 | } |
763 | 757 | ||
764 | irq_ack |= (1 << i); | 758 | irq_ack |= (1 << i); |
diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c index f6900538be90..87a8c3d2072c 100644 --- a/drivers/scsi/esp.c +++ b/drivers/scsi/esp.c | |||
@@ -2068,14 +2068,12 @@ static int esp_reset(struct scsi_cmnd *SCptr) | |||
2068 | { | 2068 | { |
2069 | struct esp *esp = (struct esp *) SCptr->device->host->hostdata; | 2069 | struct esp *esp = (struct esp *) SCptr->device->host->hostdata; |
2070 | 2070 | ||
2071 | spin_lock_irq(esp->ehost->host_lock); | ||
2071 | (void) esp_do_resetbus(esp); | 2072 | (void) esp_do_resetbus(esp); |
2072 | |||
2073 | spin_unlock_irq(esp->ehost->host_lock); | 2073 | spin_unlock_irq(esp->ehost->host_lock); |
2074 | 2074 | ||
2075 | wait_event(esp->reset_queue, (esp->resetting_bus == 0)); | 2075 | wait_event(esp->reset_queue, (esp->resetting_bus == 0)); |
2076 | 2076 | ||
2077 | spin_lock_irq(esp->ehost->host_lock); | ||
2078 | |||
2079 | return SUCCESS; | 2077 | return SUCCESS; |
2080 | } | 2078 | } |
2081 | 2079 | ||
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index bd3ffdf6c800..62e3cda859af 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -2816,7 +2816,7 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
2816 | } | 2816 | } |
2817 | #endif | 2817 | #endif |
2818 | 2818 | ||
2819 | } else { | 2819 | } else if (scp->request_bufflen) { |
2820 | scp->SCp.Status = GDTH_MAP_SINGLE; | 2820 | scp->SCp.Status = GDTH_MAP_SINGLE; |
2821 | scp->SCp.Message = (read_write == 1 ? | 2821 | scp->SCp.Message = (read_write == 1 ? |
2822 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | 2822 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 27acf78cf8d8..2bba5e55d7bc 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -4236,35 +4236,6 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd) | |||
4236 | } | 4236 | } |
4237 | 4237 | ||
4238 | /** | 4238 | /** |
4239 | * ipr_save_ioafp_mode_select - Save adapters mode select data | ||
4240 | * @ioa_cfg: ioa config struct | ||
4241 | * @scsi_cmd: scsi command struct | ||
4242 | * | ||
4243 | * This function saves mode select data for the adapter to | ||
4244 | * use following an adapter reset. | ||
4245 | * | ||
4246 | * Return value: | ||
4247 | * 0 on success / SCSI_MLQUEUE_HOST_BUSY on failure | ||
4248 | **/ | ||
4249 | static int ipr_save_ioafp_mode_select(struct ipr_ioa_cfg *ioa_cfg, | ||
4250 | struct scsi_cmnd *scsi_cmd) | ||
4251 | { | ||
4252 | if (!ioa_cfg->saved_mode_pages) { | ||
4253 | ioa_cfg->saved_mode_pages = kmalloc(sizeof(struct ipr_mode_pages), | ||
4254 | GFP_ATOMIC); | ||
4255 | if (!ioa_cfg->saved_mode_pages) { | ||
4256 | dev_err(&ioa_cfg->pdev->dev, | ||
4257 | "IOA mode select buffer allocation failed\n"); | ||
4258 | return SCSI_MLQUEUE_HOST_BUSY; | ||
4259 | } | ||
4260 | } | ||
4261 | |||
4262 | memcpy(ioa_cfg->saved_mode_pages, scsi_cmd->buffer, scsi_cmd->cmnd[4]); | ||
4263 | ioa_cfg->saved_mode_page_len = scsi_cmd->cmnd[4]; | ||
4264 | return 0; | ||
4265 | } | ||
4266 | |||
4267 | /** | ||
4268 | * ipr_queuecommand - Queue a mid-layer request | 4239 | * ipr_queuecommand - Queue a mid-layer request |
4269 | * @scsi_cmd: scsi command struct | 4240 | * @scsi_cmd: scsi command struct |
4270 | * @done: done function | 4241 | * @done: done function |
@@ -4338,9 +4309,6 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, | |||
4338 | (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) | 4309 | (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) |
4339 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 4310 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
4340 | 4311 | ||
4341 | if (ipr_is_ioa_resource(res) && scsi_cmd->cmnd[0] == MODE_SELECT) | ||
4342 | rc = ipr_save_ioafp_mode_select(ioa_cfg, scsi_cmd); | ||
4343 | |||
4344 | if (likely(rc == 0)) | 4312 | if (likely(rc == 0)) |
4345 | rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); | 4313 | rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); |
4346 | 4314 | ||
@@ -4829,17 +4797,11 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd) | |||
4829 | int length; | 4797 | int length; |
4830 | 4798 | ||
4831 | ENTER; | 4799 | ENTER; |
4832 | if (ioa_cfg->saved_mode_pages) { | 4800 | ipr_scsi_bus_speed_limit(ioa_cfg); |
4833 | memcpy(mode_pages, ioa_cfg->saved_mode_pages, | 4801 | ipr_check_term_power(ioa_cfg, mode_pages); |
4834 | ioa_cfg->saved_mode_page_len); | 4802 | ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages); |
4835 | length = ioa_cfg->saved_mode_page_len; | 4803 | length = mode_pages->hdr.length + 1; |
4836 | } else { | 4804 | mode_pages->hdr.length = 0; |
4837 | ipr_scsi_bus_speed_limit(ioa_cfg); | ||
4838 | ipr_check_term_power(ioa_cfg, mode_pages); | ||
4839 | ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages); | ||
4840 | length = mode_pages->hdr.length + 1; | ||
4841 | mode_pages->hdr.length = 0; | ||
4842 | } | ||
4843 | 4805 | ||
4844 | ipr_build_mode_select(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x11, | 4806 | ipr_build_mode_select(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x11, |
4845 | ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), | 4807 | ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), |
@@ -5969,7 +5931,6 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
5969 | } | 5931 | } |
5970 | 5932 | ||
5971 | ipr_free_dump(ioa_cfg); | 5933 | ipr_free_dump(ioa_cfg); |
5972 | kfree(ioa_cfg->saved_mode_pages); | ||
5973 | kfree(ioa_cfg->trace); | 5934 | kfree(ioa_cfg->trace); |
5974 | } | 5935 | } |
5975 | 5936 | ||
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index b639332131f1..fd360bfe56dd 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
@@ -36,8 +36,8 @@ | |||
36 | /* | 36 | /* |
37 | * Literals | 37 | * Literals |
38 | */ | 38 | */ |
39 | #define IPR_DRIVER_VERSION "2.1.1" | 39 | #define IPR_DRIVER_VERSION "2.1.2" |
40 | #define IPR_DRIVER_DATE "(November 15, 2005)" | 40 | #define IPR_DRIVER_DATE "(February 8, 2006)" |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding | 43 | * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding |
@@ -1000,7 +1000,6 @@ struct ipr_ioa_cfg { | |||
1000 | struct Scsi_Host *host; | 1000 | struct Scsi_Host *host; |
1001 | struct pci_dev *pdev; | 1001 | struct pci_dev *pdev; |
1002 | struct ipr_sglist *ucode_sglist; | 1002 | struct ipr_sglist *ucode_sglist; |
1003 | struct ipr_mode_pages *saved_mode_pages; | ||
1004 | u8 saved_mode_page_len; | 1003 | u8 saved_mode_page_len; |
1005 | 1004 | ||
1006 | struct work_struct work_q; | 1005 | struct work_struct work_q; |
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 780bfcc67096..ff79e68b347c 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -146,7 +146,7 @@ iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) | |||
146 | spin_unlock_irqrestore(&session->lock, flags); | 146 | spin_unlock_irqrestore(&session->lock, flags); |
147 | set_bit(SUSPEND_BIT, &conn->suspend_tx); | 147 | set_bit(SUSPEND_BIT, &conn->suspend_tx); |
148 | set_bit(SUSPEND_BIT, &conn->suspend_rx); | 148 | set_bit(SUSPEND_BIT, &conn->suspend_rx); |
149 | iscsi_conn_error(iscsi_handle(conn), err); | 149 | iscsi_conn_error(conn->cls_conn, err); |
150 | } | 150 | } |
151 | 151 | ||
152 | static inline int | 152 | static inline int |
@@ -244,12 +244,10 @@ iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
244 | if (sc->sc_data_direction == DMA_TO_DEVICE) { | 244 | if (sc->sc_data_direction == DMA_TO_DEVICE) { |
245 | struct iscsi_data_task *dtask, *n; | 245 | struct iscsi_data_task *dtask, *n; |
246 | /* WRITE: cleanup Data-Out's if any */ | 246 | /* WRITE: cleanup Data-Out's if any */ |
247 | spin_lock(&conn->lock); | ||
248 | list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) { | 247 | list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) { |
249 | list_del(&dtask->item); | 248 | list_del(&dtask->item); |
250 | mempool_free(dtask, ctask->datapool); | 249 | mempool_free(dtask, ctask->datapool); |
251 | } | 250 | } |
252 | spin_unlock(&conn->lock); | ||
253 | } | 251 | } |
254 | ctask->xmstate = XMSTATE_IDLE; | 252 | ctask->xmstate = XMSTATE_IDLE; |
255 | ctask->r2t = NULL; | 253 | ctask->r2t = NULL; |
@@ -689,7 +687,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) | |||
689 | break; | 687 | break; |
690 | 688 | ||
691 | if (!conn->in.datalen) { | 689 | if (!conn->in.datalen) { |
692 | rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, | 690 | rc = iscsi_recv_pdu(conn->cls_conn, hdr, |
693 | NULL, 0); | 691 | NULL, 0); |
694 | if (conn->login_mtask != mtask) { | 692 | if (conn->login_mtask != mtask) { |
695 | spin_lock(&session->lock); | 693 | spin_lock(&session->lock); |
@@ -737,7 +735,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) | |||
737 | if (!conn->in.datalen) { | 735 | if (!conn->in.datalen) { |
738 | struct iscsi_mgmt_task *mtask; | 736 | struct iscsi_mgmt_task *mtask; |
739 | 737 | ||
740 | rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, | 738 | rc = iscsi_recv_pdu(conn->cls_conn, hdr, |
741 | NULL, 0); | 739 | NULL, 0); |
742 | mtask = (struct iscsi_mgmt_task *) | 740 | mtask = (struct iscsi_mgmt_task *) |
743 | session->mgmt_cmds[conn->in.itt - | 741 | session->mgmt_cmds[conn->in.itt - |
@@ -761,7 +759,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) | |||
761 | rc = iscsi_check_assign_cmdsn(session, | 759 | rc = iscsi_check_assign_cmdsn(session, |
762 | (struct iscsi_nopin*)hdr); | 760 | (struct iscsi_nopin*)hdr); |
763 | if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) | 761 | if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) |
764 | rc = iscsi_recv_pdu(iscsi_handle(conn), | 762 | rc = iscsi_recv_pdu(conn->cls_conn, |
765 | hdr, NULL, 0); | 763 | hdr, NULL, 0); |
766 | } else | 764 | } else |
767 | rc = ISCSI_ERR_PROTO; | 765 | rc = ISCSI_ERR_PROTO; |
@@ -1044,7 +1042,7 @@ iscsi_data_recv(struct iscsi_conn *conn) | |||
1044 | goto exit; | 1042 | goto exit; |
1045 | } | 1043 | } |
1046 | 1044 | ||
1047 | rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr, | 1045 | rc = iscsi_recv_pdu(conn->cls_conn, conn->in.hdr, |
1048 | conn->data, conn->in.datalen); | 1046 | conn->data, conn->in.datalen); |
1049 | 1047 | ||
1050 | if (!rc && conn->datadgst_en && | 1048 | if (!rc && conn->datadgst_en && |
@@ -2428,19 +2426,20 @@ iscsi_pool_free(struct iscsi_queue *q, void **items) | |||
2428 | } | 2426 | } |
2429 | 2427 | ||
2430 | static struct iscsi_cls_conn * | 2428 | static struct iscsi_cls_conn * |
2431 | iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx) | 2429 | iscsi_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) |
2432 | { | 2430 | { |
2431 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
2433 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | 2432 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); |
2434 | struct iscsi_conn *conn; | 2433 | struct iscsi_conn *conn; |
2435 | struct iscsi_cls_conn *cls_conn; | 2434 | struct iscsi_cls_conn *cls_conn; |
2436 | 2435 | ||
2437 | cls_conn = iscsi_create_conn(hostdata_session(shost->hostdata), | 2436 | cls_conn = iscsi_create_conn(cls_session, conn_idx); |
2438 | conn_idx); | ||
2439 | if (!cls_conn) | 2437 | if (!cls_conn) |
2440 | return NULL; | 2438 | return NULL; |
2441 | conn = cls_conn->dd_data; | 2439 | conn = cls_conn->dd_data; |
2440 | memset(conn, 0, sizeof(*conn)); | ||
2442 | 2441 | ||
2443 | memset(conn, 0, sizeof(struct iscsi_conn)); | 2442 | conn->cls_conn = cls_conn; |
2444 | conn->c_stage = ISCSI_CONN_INITIAL_STAGE; | 2443 | conn->c_stage = ISCSI_CONN_INITIAL_STAGE; |
2445 | conn->in_progress = IN_PROGRESS_WAIT_HEADER; | 2444 | conn->in_progress = IN_PROGRESS_WAIT_HEADER; |
2446 | conn->id = conn_idx; | 2445 | conn->id = conn_idx; |
@@ -2452,8 +2451,6 @@ iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx) | |||
2452 | conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; | 2451 | conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; |
2453 | conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; | 2452 | conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; |
2454 | 2453 | ||
2455 | spin_lock_init(&conn->lock); | ||
2456 | |||
2457 | /* initialize general xmit PDU commands queue */ | 2454 | /* initialize general xmit PDU commands queue */ |
2458 | conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*), | 2455 | conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*), |
2459 | GFP_KERNEL, NULL); | 2456 | GFP_KERNEL, NULL); |
@@ -2625,11 +2622,13 @@ iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn) | |||
2625 | } | 2622 | } |
2626 | 2623 | ||
2627 | static int | 2624 | static int |
2628 | iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh, | 2625 | iscsi_conn_bind(struct iscsi_cls_session *cls_session, |
2629 | uint32_t transport_fd, int is_leading) | 2626 | struct iscsi_cls_conn *cls_conn, uint32_t transport_fd, |
2627 | int is_leading) | ||
2630 | { | 2628 | { |
2631 | struct iscsi_session *session = iscsi_ptr(sessionh); | 2629 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); |
2632 | struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = iscsi_ptr(connh); | 2630 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); |
2631 | struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data; | ||
2633 | struct sock *sk; | 2632 | struct sock *sk; |
2634 | struct socket *sock; | 2633 | struct socket *sock; |
2635 | int err; | 2634 | int err; |
@@ -2703,9 +2702,9 @@ iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh, | |||
2703 | } | 2702 | } |
2704 | 2703 | ||
2705 | static int | 2704 | static int |
2706 | iscsi_conn_start(iscsi_connh_t connh) | 2705 | iscsi_conn_start(struct iscsi_cls_conn *cls_conn) |
2707 | { | 2706 | { |
2708 | struct iscsi_conn *conn = iscsi_ptr(connh); | 2707 | struct iscsi_conn *conn = cls_conn->dd_data; |
2709 | struct iscsi_session *session = conn->session; | 2708 | struct iscsi_session *session = conn->session; |
2710 | struct sock *sk; | 2709 | struct sock *sk; |
2711 | 2710 | ||
@@ -2754,9 +2753,9 @@ iscsi_conn_start(iscsi_connh_t connh) | |||
2754 | } | 2753 | } |
2755 | 2754 | ||
2756 | static void | 2755 | static void |
2757 | iscsi_conn_stop(iscsi_connh_t connh, int flag) | 2756 | iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) |
2758 | { | 2757 | { |
2759 | struct iscsi_conn *conn = iscsi_ptr(connh); | 2758 | struct iscsi_conn *conn = cls_conn->dd_data; |
2760 | struct iscsi_session *session = conn->session; | 2759 | struct iscsi_session *session = conn->session; |
2761 | struct sock *sk; | 2760 | struct sock *sk; |
2762 | unsigned long flags; | 2761 | unsigned long flags; |
@@ -3253,9 +3252,9 @@ static struct scsi_host_template iscsi_sht = { | |||
3253 | 3252 | ||
3254 | static struct iscsi_transport iscsi_tcp_transport; | 3253 | static struct iscsi_transport iscsi_tcp_transport; |
3255 | 3254 | ||
3256 | static struct Scsi_Host * | 3255 | static struct iscsi_cls_session * |
3257 | iscsi_session_create(struct scsi_transport_template *scsit, | 3256 | iscsi_session_create(struct scsi_transport_template *scsit, |
3258 | uint32_t initial_cmdsn) | 3257 | uint32_t initial_cmdsn, uint32_t *sid) |
3259 | { | 3258 | { |
3260 | struct Scsi_Host *shost; | 3259 | struct Scsi_Host *shost; |
3261 | struct iscsi_session *session; | 3260 | struct iscsi_session *session; |
@@ -3268,13 +3267,14 @@ iscsi_session_create(struct scsi_transport_template *scsit, | |||
3268 | session = iscsi_hostdata(shost->hostdata); | 3267 | session = iscsi_hostdata(shost->hostdata); |
3269 | memset(session, 0, sizeof(struct iscsi_session)); | 3268 | memset(session, 0, sizeof(struct iscsi_session)); |
3270 | session->host = shost; | 3269 | session->host = shost; |
3271 | session->state = ISCSI_STATE_LOGGED_IN; | 3270 | session->state = ISCSI_STATE_FREE; |
3272 | session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; | 3271 | session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; |
3273 | session->cmds_max = ISCSI_XMIT_CMDS_MAX; | 3272 | session->cmds_max = ISCSI_XMIT_CMDS_MAX; |
3274 | session->cmdsn = initial_cmdsn; | 3273 | session->cmdsn = initial_cmdsn; |
3275 | session->exp_cmdsn = initial_cmdsn + 1; | 3274 | session->exp_cmdsn = initial_cmdsn + 1; |
3276 | session->max_cmdsn = initial_cmdsn + 1; | 3275 | session->max_cmdsn = initial_cmdsn + 1; |
3277 | session->max_r2t = 1; | 3276 | session->max_r2t = 1; |
3277 | *sid = shost->host_no; | ||
3278 | 3278 | ||
3279 | /* initialize SCSI PDU commands pool */ | 3279 | /* initialize SCSI PDU commands pool */ |
3280 | if (iscsi_pool_init(&session->cmdpool, session->cmds_max, | 3280 | if (iscsi_pool_init(&session->cmdpool, session->cmds_max, |
@@ -3311,22 +3311,24 @@ iscsi_session_create(struct scsi_transport_template *scsit, | |||
3311 | if (iscsi_r2tpool_alloc(session)) | 3311 | if (iscsi_r2tpool_alloc(session)) |
3312 | goto r2tpool_alloc_fail; | 3312 | goto r2tpool_alloc_fail; |
3313 | 3313 | ||
3314 | return shost; | 3314 | return hostdata_session(shost->hostdata); |
3315 | 3315 | ||
3316 | r2tpool_alloc_fail: | 3316 | r2tpool_alloc_fail: |
3317 | for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) | 3317 | for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) |
3318 | kfree(session->mgmt_cmds[cmd_i]->data); | 3318 | kfree(session->mgmt_cmds[cmd_i]->data); |
3319 | iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); | ||
3320 | immdata_alloc_fail: | 3319 | immdata_alloc_fail: |
3320 | iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); | ||
3321 | mgmtpool_alloc_fail: | 3321 | mgmtpool_alloc_fail: |
3322 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); | 3322 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); |
3323 | cmdpool_alloc_fail: | 3323 | cmdpool_alloc_fail: |
3324 | iscsi_transport_destroy_session(shost); | ||
3324 | return NULL; | 3325 | return NULL; |
3325 | } | 3326 | } |
3326 | 3327 | ||
3327 | static void | 3328 | static void |
3328 | iscsi_session_destroy(struct Scsi_Host *shost) | 3329 | iscsi_session_destroy(struct iscsi_cls_session *cls_session) |
3329 | { | 3330 | { |
3331 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
3330 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | 3332 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); |
3331 | int cmd_i; | 3333 | int cmd_i; |
3332 | struct iscsi_data_task *dtask, *n; | 3334 | struct iscsi_data_task *dtask, *n; |
@@ -3350,10 +3352,10 @@ iscsi_session_destroy(struct Scsi_Host *shost) | |||
3350 | } | 3352 | } |
3351 | 3353 | ||
3352 | static int | 3354 | static int |
3353 | iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param, | 3355 | iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, |
3354 | uint32_t value) | 3356 | uint32_t value) |
3355 | { | 3357 | { |
3356 | struct iscsi_conn *conn = iscsi_ptr(connh); | 3358 | struct iscsi_conn *conn = cls_conn->dd_data; |
3357 | struct iscsi_session *session = conn->session; | 3359 | struct iscsi_session *session = conn->session; |
3358 | 3360 | ||
3359 | spin_lock_bh(&session->lock); | 3361 | spin_lock_bh(&session->lock); |
@@ -3495,9 +3497,10 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param, | |||
3495 | } | 3497 | } |
3496 | 3498 | ||
3497 | static int | 3499 | static int |
3498 | iscsi_session_get_param(struct Scsi_Host *shost, | 3500 | iscsi_session_get_param(struct iscsi_cls_session *cls_session, |
3499 | enum iscsi_param param, uint32_t *value) | 3501 | enum iscsi_param param, uint32_t *value) |
3500 | { | 3502 | { |
3503 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
3501 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | 3504 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); |
3502 | 3505 | ||
3503 | switch(param) { | 3506 | switch(param) { |
@@ -3539,9 +3542,10 @@ iscsi_session_get_param(struct Scsi_Host *shost, | |||
3539 | } | 3542 | } |
3540 | 3543 | ||
3541 | static int | 3544 | static int |
3542 | iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value) | 3545 | iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, |
3546 | enum iscsi_param param, uint32_t *value) | ||
3543 | { | 3547 | { |
3544 | struct iscsi_conn *conn = data; | 3548 | struct iscsi_conn *conn = cls_conn->dd_data; |
3545 | 3549 | ||
3546 | switch(param) { | 3550 | switch(param) { |
3547 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | 3551 | case ISCSI_PARAM_MAX_RECV_DLENGTH: |
@@ -3564,9 +3568,9 @@ iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value) | |||
3564 | } | 3568 | } |
3565 | 3569 | ||
3566 | static void | 3570 | static void |
3567 | iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats) | 3571 | iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) |
3568 | { | 3572 | { |
3569 | struct iscsi_conn *conn = iscsi_ptr(connh); | 3573 | struct iscsi_conn *conn = cls_conn->dd_data; |
3570 | 3574 | ||
3571 | stats->txdata_octets = conn->txdata_octets; | 3575 | stats->txdata_octets = conn->txdata_octets; |
3572 | stats->rxdata_octets = conn->rxdata_octets; | 3576 | stats->rxdata_octets = conn->rxdata_octets; |
@@ -3587,10 +3591,10 @@ iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats) | |||
3587 | } | 3591 | } |
3588 | 3592 | ||
3589 | static int | 3593 | static int |
3590 | iscsi_conn_send_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, char *data, | 3594 | iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, |
3591 | uint32_t data_size) | 3595 | char *data, uint32_t data_size) |
3592 | { | 3596 | { |
3593 | struct iscsi_conn *conn = iscsi_ptr(connh); | 3597 | struct iscsi_conn *conn = cls_conn->dd_data; |
3594 | int rc; | 3598 | int rc; |
3595 | 3599 | ||
3596 | mutex_lock(&conn->xmitmutex); | 3600 | mutex_lock(&conn->xmitmutex); |
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index f95e61b76f70..ba26741ac154 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h | |||
@@ -113,7 +113,10 @@ struct iscsi_tcp_recv { | |||
113 | int datadgst; | 113 | int datadgst; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct iscsi_cls_conn; | ||
117 | |||
116 | struct iscsi_conn { | 118 | struct iscsi_conn { |
119 | struct iscsi_cls_conn *cls_conn; /* ptr to class connection */ | ||
117 | struct iscsi_hdr hdr; /* header placeholder */ | 120 | struct iscsi_hdr hdr; /* header placeholder */ |
118 | char hdrext[4*sizeof(__u16) + | 121 | char hdrext[4*sizeof(__u16) + |
119 | sizeof(__u32)]; | 122 | sizeof(__u32)]; |
@@ -143,7 +146,6 @@ struct iscsi_conn { | |||
143 | struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ | 146 | struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ |
144 | struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ | 147 | struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ |
145 | struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ | 148 | struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ |
146 | spinlock_t lock; /* FIXME: to be removed */ | ||
147 | 149 | ||
148 | /* old values for socket callbacks */ | 150 | /* old values for socket callbacks */ |
149 | void (*old_data_ready)(struct sock *, int); | 151 | void (*old_data_ready)(struct sock *, int); |
diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index 23728d1c980c..fcd304e11c26 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c | |||
@@ -65,27 +65,6 @@ static int jazz_esp_release(struct Scsi_Host *shost) | |||
65 | return 0; | 65 | return 0; |
66 | } | 66 | } |
67 | 67 | ||
68 | static struct scsi_host_template driver_template = { | ||
69 | .proc_name = "jazz_esp", | ||
70 | .proc_info = &esp_proc_info, | ||
71 | .name = "ESP 100/100a/200", | ||
72 | .detect = jazz_esp_detect, | ||
73 | .slave_alloc = esp_slave_alloc, | ||
74 | .slave_destroy = esp_slave_destroy, | ||
75 | .release = jazz_esp_release, | ||
76 | .info = esp_info, | ||
77 | .queuecommand = esp_queue, | ||
78 | .eh_abort_handler = esp_abort, | ||
79 | .eh_bus_reset_handler = esp_reset, | ||
80 | .can_queue = 7, | ||
81 | .this_id = 7, | ||
82 | .sg_tablesize = SG_ALL, | ||
83 | .cmd_per_lun = 1, | ||
84 | .use_clustering = DISABLE_CLUSTERING, | ||
85 | }; | ||
86 | |||
87 | #include "scsi_module.c" | ||
88 | |||
89 | /***************************************************************** Detection */ | 68 | /***************************************************************** Detection */ |
90 | static int jazz_esp_detect(struct scsi_host_template *tpnt) | 69 | static int jazz_esp_detect(struct scsi_host_template *tpnt) |
91 | { | 70 | { |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 46c4cdbaee86..4f91b0dc572b 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -82,6 +82,10 @@ int atapi_enabled = 0; | |||
82 | module_param(atapi_enabled, int, 0444); | 82 | module_param(atapi_enabled, int, 0444); |
83 | MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); | 83 | MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); |
84 | 84 | ||
85 | int libata_fua = 0; | ||
86 | module_param_named(fua, libata_fua, int, 0444); | ||
87 | MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); | ||
88 | |||
85 | MODULE_AUTHOR("Jeff Garzik"); | 89 | MODULE_AUTHOR("Jeff Garzik"); |
86 | MODULE_DESCRIPTION("Library module for ATA devices"); | 90 | MODULE_DESCRIPTION("Library module for ATA devices"); |
87 | MODULE_LICENSE("GPL"); | 91 | MODULE_LICENSE("GPL"); |
@@ -614,7 +618,7 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc) | |||
614 | } else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) { | 618 | } else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) { |
615 | /* Unable to use DMA due to host limitation */ | 619 | /* Unable to use DMA due to host limitation */ |
616 | tf->protocol = ATA_PROT_PIO; | 620 | tf->protocol = ATA_PROT_PIO; |
617 | index = dev->multi_count ? 0 : 4; | 621 | index = dev->multi_count ? 0 : 8; |
618 | } else { | 622 | } else { |
619 | tf->protocol = ATA_PROT_DMA; | 623 | tf->protocol = ATA_PROT_DMA; |
620 | index = 16; | 624 | index = 16; |
@@ -2514,7 +2518,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) | |||
2514 | assert(sg != NULL); | 2518 | assert(sg != NULL); |
2515 | 2519 | ||
2516 | if (qc->flags & ATA_QCFLAG_SINGLE) | 2520 | if (qc->flags & ATA_QCFLAG_SINGLE) |
2517 | assert(qc->n_elem == 1); | 2521 | assert(qc->n_elem <= 1); |
2518 | 2522 | ||
2519 | VPRINTK("unmapping %u sg elements\n", qc->n_elem); | 2523 | VPRINTK("unmapping %u sg elements\n", qc->n_elem); |
2520 | 2524 | ||
@@ -2537,7 +2541,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) | |||
2537 | kunmap_atomic(addr, KM_IRQ0); | 2541 | kunmap_atomic(addr, KM_IRQ0); |
2538 | } | 2542 | } |
2539 | } else { | 2543 | } else { |
2540 | if (sg_dma_len(&sg[0]) > 0) | 2544 | if (qc->n_elem) |
2541 | dma_unmap_single(ap->host_set->dev, | 2545 | dma_unmap_single(ap->host_set->dev, |
2542 | sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), | 2546 | sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), |
2543 | dir); | 2547 | dir); |
@@ -2570,7 +2574,7 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) | |||
2570 | unsigned int idx; | 2574 | unsigned int idx; |
2571 | 2575 | ||
2572 | assert(qc->__sg != NULL); | 2576 | assert(qc->__sg != NULL); |
2573 | assert(qc->n_elem > 0); | 2577 | assert(qc->n_elem > 0 || qc->pad_len > 0); |
2574 | 2578 | ||
2575 | idx = 0; | 2579 | idx = 0; |
2576 | ata_for_each_sg(sg, qc) { | 2580 | ata_for_each_sg(sg, qc) { |
@@ -2715,6 +2719,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
2715 | int dir = qc->dma_dir; | 2719 | int dir = qc->dma_dir; |
2716 | struct scatterlist *sg = qc->__sg; | 2720 | struct scatterlist *sg = qc->__sg; |
2717 | dma_addr_t dma_address; | 2721 | dma_addr_t dma_address; |
2722 | int trim_sg = 0; | ||
2718 | 2723 | ||
2719 | /* we must lengthen transfers to end on a 32-bit boundary */ | 2724 | /* we must lengthen transfers to end on a 32-bit boundary */ |
2720 | qc->pad_len = sg->length & 3; | 2725 | qc->pad_len = sg->length & 3; |
@@ -2734,13 +2739,15 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
2734 | sg_dma_len(psg) = ATA_DMA_PAD_SZ; | 2739 | sg_dma_len(psg) = ATA_DMA_PAD_SZ; |
2735 | /* trim sg */ | 2740 | /* trim sg */ |
2736 | sg->length -= qc->pad_len; | 2741 | sg->length -= qc->pad_len; |
2742 | if (sg->length == 0) | ||
2743 | trim_sg = 1; | ||
2737 | 2744 | ||
2738 | DPRINTK("padding done, sg->length=%u pad_len=%u\n", | 2745 | DPRINTK("padding done, sg->length=%u pad_len=%u\n", |
2739 | sg->length, qc->pad_len); | 2746 | sg->length, qc->pad_len); |
2740 | } | 2747 | } |
2741 | 2748 | ||
2742 | if (!sg->length) { | 2749 | if (trim_sg) { |
2743 | sg_dma_address(sg) = 0; | 2750 | qc->n_elem--; |
2744 | goto skip_map; | 2751 | goto skip_map; |
2745 | } | 2752 | } |
2746 | 2753 | ||
@@ -2753,9 +2760,9 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) | |||
2753 | } | 2760 | } |
2754 | 2761 | ||
2755 | sg_dma_address(sg) = dma_address; | 2762 | sg_dma_address(sg) = dma_address; |
2756 | skip_map: | ||
2757 | sg_dma_len(sg) = sg->length; | 2763 | sg_dma_len(sg) = sg->length; |
2758 | 2764 | ||
2765 | skip_map: | ||
2759 | DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), | 2766 | DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), |
2760 | qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); | 2767 | qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); |
2761 | 2768 | ||
@@ -3357,11 +3364,12 @@ static void ata_pio_error(struct ata_port *ap) | |||
3357 | { | 3364 | { |
3358 | struct ata_queued_cmd *qc; | 3365 | struct ata_queued_cmd *qc; |
3359 | 3366 | ||
3360 | printk(KERN_WARNING "ata%u: PIO error\n", ap->id); | ||
3361 | |||
3362 | qc = ata_qc_from_tag(ap, ap->active_tag); | 3367 | qc = ata_qc_from_tag(ap, ap->active_tag); |
3363 | assert(qc != NULL); | 3368 | assert(qc != NULL); |
3364 | 3369 | ||
3370 | if (qc->tf.command != ATA_CMD_PACKET) | ||
3371 | printk(KERN_WARNING "ata%u: PIO error\n", ap->id); | ||
3372 | |||
3365 | /* make sure qc->err_mask is available to | 3373 | /* make sure qc->err_mask is available to |
3366 | * know what's wrong and recover | 3374 | * know what's wrong and recover |
3367 | */ | 3375 | */ |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 07b1e7cc61df..59503c9ccac9 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -1708,6 +1708,8 @@ static int ata_dev_supports_fua(u16 *id) | |||
1708 | { | 1708 | { |
1709 | unsigned char model[41], fw[9]; | 1709 | unsigned char model[41], fw[9]; |
1710 | 1710 | ||
1711 | if (!libata_fua) | ||
1712 | return 0; | ||
1711 | if (!ata_id_has_fua(id)) | 1713 | if (!ata_id_has_fua(id)) |
1712 | return 0; | 1714 | return 0; |
1713 | 1715 | ||
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index e03ce48b7b4b..fddaf479a544 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h | |||
@@ -41,6 +41,7 @@ struct ata_scsi_args { | |||
41 | 41 | ||
42 | /* libata-core.c */ | 42 | /* libata-core.c */ |
43 | extern int atapi_enabled; | 43 | extern int atapi_enabled; |
44 | extern int libata_fua; | ||
44 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | 45 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, |
45 | struct ata_device *dev); | 46 | struct ata_device *dev); |
46 | extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); | 47 | extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); |
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 311a4122bd70..93edaa8696cf 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c | |||
@@ -537,9 +537,9 @@ static int mac53c94_remove(struct macio_dev *mdev) | |||
537 | free_irq(fp->intr, fp); | 537 | free_irq(fp->intr, fp); |
538 | 538 | ||
539 | if (fp->regs) | 539 | if (fp->regs) |
540 | iounmap((void *) fp->regs); | 540 | iounmap(fp->regs); |
541 | if (fp->dma) | 541 | if (fp->dma) |
542 | iounmap((void *) fp->dma); | 542 | iounmap(fp->dma); |
543 | kfree(fp->dma_cmd_space); | 543 | kfree(fp->dma_cmd_space); |
544 | 544 | ||
545 | scsi_host_put(host); | 545 | scsi_host_put(host); |
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index d101a8a6f4e8..7144674bc8e6 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c | |||
@@ -5049,7 +5049,7 @@ static struct pci_device_id megaraid_pci_tbl[] = { | |||
5049 | MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl); | 5049 | MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl); |
5050 | 5050 | ||
5051 | static struct pci_driver megaraid_pci_driver = { | 5051 | static struct pci_driver megaraid_pci_driver = { |
5052 | .name = "megaraid", | 5052 | .name = "megaraid_legacy", |
5053 | .id_table = megaraid_pci_tbl, | 5053 | .id_table = megaraid_pci_tbl, |
5054 | .probe = megaraid_probe_one, | 5054 | .probe = megaraid_probe_one, |
5055 | .remove = __devexit_p(megaraid_remove_one), | 5055 | .remove = __devexit_p(megaraid_remove_one), |
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 4b3e0d6e5afa..4b75fe619d9c 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <linux/mutex.h> | 5 | #include <linux/mutex.h> |
6 | 6 | ||
7 | #define MEGARAID_VERSION \ | 7 | #define MEGARAID_VERSION \ |
8 | "v2.00.3 (Release Date: Wed Feb 19 08:51:30 EST 2003)\n" | 8 | "v2.00.4 (Release Date: Thu Feb 9 08:51:30 EST 2006)\n" |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * Driver features - change the values to enable or disable features in the | 11 | * Driver features - change the values to enable or disable features in the |
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index a487f414960e..4f39dd01936d 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
11 | * | 11 | * |
12 | * FILE : megaraid_sas.c | 12 | * FILE : megaraid_sas.c |
13 | * Version : v00.00.02.02 | 13 | * Version : v00.00.02.04 |
14 | * | 14 | * |
15 | * Authors: | 15 | * Authors: |
16 | * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> | 16 | * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> |
@@ -60,6 +60,12 @@ static struct pci_device_id megasas_pci_table[] = { | |||
60 | PCI_ANY_ID, | 60 | PCI_ANY_ID, |
61 | }, | 61 | }, |
62 | { | 62 | { |
63 | PCI_VENDOR_ID_LSI_LOGIC, | ||
64 | PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP | ||
65 | PCI_ANY_ID, | ||
66 | PCI_ANY_ID, | ||
67 | }, | ||
68 | { | ||
63 | PCI_VENDOR_ID_DELL, | 69 | PCI_VENDOR_ID_DELL, |
64 | PCI_DEVICE_ID_DELL_PERC5, // xscale IOP | 70 | PCI_DEVICE_ID_DELL_PERC5, // xscale IOP |
65 | PCI_ANY_ID, | 71 | PCI_ANY_ID, |
@@ -199,6 +205,86 @@ static struct megasas_instance_template megasas_instance_template_xscale = { | |||
199 | */ | 205 | */ |
200 | 206 | ||
201 | /** | 207 | /** |
208 | * The following functions are defined for ppc (deviceid : 0x60) | ||
209 | * controllers | ||
210 | */ | ||
211 | |||
212 | /** | ||
213 | * megasas_enable_intr_ppc - Enables interrupts | ||
214 | * @regs: MFI register set | ||
215 | */ | ||
216 | static inline void | ||
217 | megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs) | ||
218 | { | ||
219 | writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); | ||
220 | |||
221 | writel(~0x80000004, &(regs)->outbound_intr_mask); | ||
222 | |||
223 | /* Dummy readl to force pci flush */ | ||
224 | readl(®s->outbound_intr_mask); | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * megasas_read_fw_status_reg_ppc - returns the current FW status value | ||
229 | * @regs: MFI register set | ||
230 | */ | ||
231 | static u32 | ||
232 | megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs) | ||
233 | { | ||
234 | return readl(&(regs)->outbound_scratch_pad); | ||
235 | } | ||
236 | |||
237 | /** | ||
238 | * megasas_clear_interrupt_ppc - Check & clear interrupt | ||
239 | * @regs: MFI register set | ||
240 | */ | ||
241 | static int | ||
242 | megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs) | ||
243 | { | ||
244 | u32 status; | ||
245 | /* | ||
246 | * Check if it is our interrupt | ||
247 | */ | ||
248 | status = readl(®s->outbound_intr_status); | ||
249 | |||
250 | if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) { | ||
251 | return 1; | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * Clear the interrupt by writing back the same value | ||
256 | */ | ||
257 | writel(status, ®s->outbound_doorbell_clear); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | /** | ||
262 | * megasas_fire_cmd_ppc - Sends command to the FW | ||
263 | * @frame_phys_addr : Physical address of cmd | ||
264 | * @frame_count : Number of frames for the command | ||
265 | * @regs : MFI register set | ||
266 | */ | ||
267 | static inline void | ||
268 | megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs) | ||
269 | { | ||
270 | writel((frame_phys_addr | (frame_count<<1))|1, | ||
271 | &(regs)->inbound_queue_port); | ||
272 | } | ||
273 | |||
274 | static struct megasas_instance_template megasas_instance_template_ppc = { | ||
275 | |||
276 | .fire_cmd = megasas_fire_cmd_ppc, | ||
277 | .enable_intr = megasas_enable_intr_ppc, | ||
278 | .clear_intr = megasas_clear_intr_ppc, | ||
279 | .read_fw_status_reg = megasas_read_fw_status_reg_ppc, | ||
280 | }; | ||
281 | |||
282 | /** | ||
283 | * This is the end of set of functions & definitions | ||
284 | * specific to ppc (deviceid : 0x60) controllers | ||
285 | */ | ||
286 | |||
287 | /** | ||
202 | * megasas_disable_intr - Disables interrupts | 288 | * megasas_disable_intr - Disables interrupts |
203 | * @regs: MFI register set | 289 | * @regs: MFI register set |
204 | */ | 290 | */ |
@@ -707,6 +793,20 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) | |||
707 | return 0; | 793 | return 0; |
708 | } | 794 | } |
709 | 795 | ||
796 | static int megasas_slave_configure(struct scsi_device *sdev) | ||
797 | { | ||
798 | /* | ||
799 | * Don't export physical disk devices to the disk driver. | ||
800 | * | ||
801 | * FIXME: Currently we don't export them to the midlayer at all. | ||
802 | * That will be fixed once LSI engineers have audited the | ||
803 | * firmware for possible issues. | ||
804 | */ | ||
805 | if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK) | ||
806 | return -ENXIO; | ||
807 | return 0; | ||
808 | } | ||
809 | |||
710 | /** | 810 | /** |
711 | * megasas_wait_for_outstanding - Wait for all outstanding cmds | 811 | * megasas_wait_for_outstanding - Wait for all outstanding cmds |
712 | * @instance: Adapter soft state | 812 | * @instance: Adapter soft state |
@@ -857,6 +957,7 @@ static struct scsi_host_template megasas_template = { | |||
857 | .module = THIS_MODULE, | 957 | .module = THIS_MODULE, |
858 | .name = "LSI Logic SAS based MegaRAID driver", | 958 | .name = "LSI Logic SAS based MegaRAID driver", |
859 | .proc_name = "megaraid_sas", | 959 | .proc_name = "megaraid_sas", |
960 | .slave_configure = megasas_slave_configure, | ||
860 | .queuecommand = megasas_queue_command, | 961 | .queuecommand = megasas_queue_command, |
861 | .eh_device_reset_handler = megasas_reset_device, | 962 | .eh_device_reset_handler = megasas_reset_device, |
862 | .eh_bus_reset_handler = megasas_reset_bus_host, | 963 | .eh_bus_reset_handler = megasas_reset_bus_host, |
@@ -985,20 +1086,6 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, | |||
985 | break; | 1086 | break; |
986 | } | 1087 | } |
987 | 1088 | ||
988 | /* | ||
989 | * Don't export physical disk devices to mid-layer. | ||
990 | */ | ||
991 | if (!MEGASAS_IS_LOGICAL(cmd->scmd) && | ||
992 | (hdr->cmd_status == MFI_STAT_OK) && | ||
993 | (cmd->scmd->cmnd[0] == INQUIRY)) { | ||
994 | |||
995 | if (((*(u8 *) cmd->scmd->request_buffer) & 0x1F) == | ||
996 | TYPE_DISK) { | ||
997 | cmd->scmd->result = DID_BAD_TARGET << 16; | ||
998 | exception = 1; | ||
999 | } | ||
1000 | } | ||
1001 | |||
1002 | case MFI_CMD_LD_READ: | 1089 | case MFI_CMD_LD_READ: |
1003 | case MFI_CMD_LD_WRITE: | 1090 | case MFI_CMD_LD_WRITE: |
1004 | 1091 | ||
@@ -1607,7 +1694,17 @@ static int megasas_init_mfi(struct megasas_instance *instance) | |||
1607 | 1694 | ||
1608 | reg_set = instance->reg_set; | 1695 | reg_set = instance->reg_set; |
1609 | 1696 | ||
1610 | instance->instancet = &megasas_instance_template_xscale; | 1697 | switch(instance->pdev->device) |
1698 | { | ||
1699 | case PCI_DEVICE_ID_LSI_SAS1078R: | ||
1700 | instance->instancet = &megasas_instance_template_ppc; | ||
1701 | break; | ||
1702 | case PCI_DEVICE_ID_LSI_SAS1064R: | ||
1703 | case PCI_DEVICE_ID_DELL_PERC5: | ||
1704 | default: | ||
1705 | instance->instancet = &megasas_instance_template_xscale; | ||
1706 | break; | ||
1707 | } | ||
1611 | 1708 | ||
1612 | /* | 1709 | /* |
1613 | * We expect the FW state to be READY | 1710 | * We expect the FW state to be READY |
@@ -1983,6 +2080,7 @@ static int megasas_io_attach(struct megasas_instance *instance) | |||
1983 | host->max_channel = MEGASAS_MAX_CHANNELS - 1; | 2080 | host->max_channel = MEGASAS_MAX_CHANNELS - 1; |
1984 | host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL; | 2081 | host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL; |
1985 | host->max_lun = MEGASAS_MAX_LUN; | 2082 | host->max_lun = MEGASAS_MAX_LUN; |
2083 | host->max_cmd_len = 16; | ||
1986 | 2084 | ||
1987 | /* | 2085 | /* |
1988 | * Notify the mid-layer about the new controller | 2086 | * Notify the mid-layer about the new controller |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index d6d166c0663f..89639f0c38ef 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -18,9 +18,9 @@ | |||
18 | /** | 18 | /** |
19 | * MegaRAID SAS Driver meta data | 19 | * MegaRAID SAS Driver meta data |
20 | */ | 20 | */ |
21 | #define MEGASAS_VERSION "00.00.02.02" | 21 | #define MEGASAS_VERSION "00.00.02.04" |
22 | #define MEGASAS_RELDATE "Jan 23, 2006" | 22 | #define MEGASAS_RELDATE "Feb 03, 2006" |
23 | #define MEGASAS_EXT_VERSION "Mon Jan 23 14:09:01 PST 2006" | 23 | #define MEGASAS_EXT_VERSION "Fri Feb 03 14:31:44 PST 2006" |
24 | /* | 24 | /* |
25 | * ===================================== | 25 | * ===================================== |
26 | * MegaRAID SAS MFI firmware definitions | 26 | * MegaRAID SAS MFI firmware definitions |
@@ -553,31 +553,46 @@ struct megasas_ctrl_info { | |||
553 | #define MFI_OB_INTR_STATUS_MASK 0x00000002 | 553 | #define MFI_OB_INTR_STATUS_MASK 0x00000002 |
554 | #define MFI_POLL_TIMEOUT_SECS 10 | 554 | #define MFI_POLL_TIMEOUT_SECS 10 |
555 | 555 | ||
556 | #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 | ||
557 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x00000060 | ||
558 | |||
556 | struct megasas_register_set { | 559 | struct megasas_register_set { |
560 | u32 reserved_0[4]; /*0000h*/ | ||
557 | 561 | ||
558 | u32 reserved_0[4]; /*0000h */ | 562 | u32 inbound_msg_0; /*0010h*/ |
563 | u32 inbound_msg_1; /*0014h*/ | ||
564 | u32 outbound_msg_0; /*0018h*/ | ||
565 | u32 outbound_msg_1; /*001Ch*/ | ||
559 | 566 | ||
560 | u32 inbound_msg_0; /*0010h */ | 567 | u32 inbound_doorbell; /*0020h*/ |
561 | u32 inbound_msg_1; /*0014h */ | 568 | u32 inbound_intr_status; /*0024h*/ |
562 | u32 outbound_msg_0; /*0018h */ | 569 | u32 inbound_intr_mask; /*0028h*/ |
563 | u32 outbound_msg_1; /*001Ch */ | ||
564 | 570 | ||
565 | u32 inbound_doorbell; /*0020h */ | 571 | u32 outbound_doorbell; /*002Ch*/ |
566 | u32 inbound_intr_status; /*0024h */ | 572 | u32 outbound_intr_status; /*0030h*/ |
567 | u32 inbound_intr_mask; /*0028h */ | 573 | u32 outbound_intr_mask; /*0034h*/ |
568 | 574 | ||
569 | u32 outbound_doorbell; /*002Ch */ | 575 | u32 reserved_1[2]; /*0038h*/ |
570 | u32 outbound_intr_status; /*0030h */ | ||
571 | u32 outbound_intr_mask; /*0034h */ | ||
572 | 576 | ||
573 | u32 reserved_1[2]; /*0038h */ | 577 | u32 inbound_queue_port; /*0040h*/ |
578 | u32 outbound_queue_port; /*0044h*/ | ||
574 | 579 | ||
575 | u32 inbound_queue_port; /*0040h */ | 580 | u32 reserved_2[22]; /*0048h*/ |
576 | u32 outbound_queue_port; /*0044h */ | ||
577 | 581 | ||
578 | u32 reserved_2; /*004Ch */ | 582 | u32 outbound_doorbell_clear; /*00A0h*/ |
579 | 583 | ||
580 | u32 index_registers[1004]; /*0050h */ | 584 | u32 reserved_3[3]; /*00A4h*/ |
585 | |||
586 | u32 outbound_scratch_pad ; /*00B0h*/ | ||
587 | |||
588 | u32 reserved_4[3]; /*00B4h*/ | ||
589 | |||
590 | u32 inbound_low_queue_port ; /*00C0h*/ | ||
591 | |||
592 | u32 inbound_high_queue_port ; /*00C4h*/ | ||
593 | |||
594 | u32 reserved_5; /*00C8h*/ | ||
595 | u32 index_registers[820]; /*00CCh*/ | ||
581 | 596 | ||
582 | } __attribute__ ((packed)); | 597 | } __attribute__ ((packed)); |
583 | 598 | ||
diff --git a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig index df52190f4d94..eac8e179cfff 100644 --- a/drivers/scsi/pcmcia/Kconfig +++ b/drivers/scsi/pcmcia/Kconfig | |||
@@ -8,6 +8,7 @@ menu "PCMCIA SCSI adapter support" | |||
8 | config PCMCIA_AHA152X | 8 | config PCMCIA_AHA152X |
9 | tristate "Adaptec AHA152X PCMCIA support" | 9 | tristate "Adaptec AHA152X PCMCIA support" |
10 | depends on m && !64BIT | 10 | depends on m && !64BIT |
11 | select SCSI_SPI_ATTRS | ||
11 | help | 12 | help |
12 | Say Y here if you intend to attach this type of PCMCIA SCSI host | 13 | Say Y here if you intend to attach this type of PCMCIA SCSI host |
13 | adapter to your computer. | 14 | adapter to your computer. |
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 0c9edb7051f4..5609847e254a 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c | |||
@@ -275,10 +275,8 @@ static int aha152x_resume(struct pcmcia_device *dev) | |||
275 | 275 | ||
276 | link->state &= ~DEV_SUSPEND; | 276 | link->state &= ~DEV_SUSPEND; |
277 | if (link->state & DEV_CONFIG) { | 277 | if (link->state & DEV_CONFIG) { |
278 | Scsi_Cmnd tmp; | ||
279 | pcmcia_request_configuration(link->handle, &link->conf); | 278 | pcmcia_request_configuration(link->handle, &link->conf); |
280 | tmp.device->host = info->host; | 279 | aha152x_host_reset_host(info->host); |
281 | aha152x_host_reset(&tmp); | ||
282 | } | 280 | } |
283 | 281 | ||
284 | return 0; | 282 | return 0; |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index b17ee62dd1a9..92b3e13e9061 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | #include <linux/vmalloc.h> | 9 | #include <linux/vmalloc.h> |
10 | #include <scsi/scsi_transport_fc.h> | ||
11 | 10 | ||
12 | /* SYSFS attributes --------------------------------------------------------- */ | 11 | /* SYSFS attributes --------------------------------------------------------- */ |
13 | 12 | ||
@@ -114,7 +113,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off, | |||
114 | struct device, kobj))); | 113 | struct device, kobj))); |
115 | unsigned long flags; | 114 | unsigned long flags; |
116 | 115 | ||
117 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size) | 116 | if (!capable(CAP_SYS_ADMIN) || off != 0) |
118 | return 0; | 117 | return 0; |
119 | 118 | ||
120 | /* Read NVRAM. */ | 119 | /* Read NVRAM. */ |
@@ -123,7 +122,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off, | |||
123 | ha->nvram_size); | 122 | ha->nvram_size); |
124 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 123 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
125 | 124 | ||
126 | return (count); | 125 | return ha->nvram_size; |
127 | } | 126 | } |
128 | 127 | ||
129 | static ssize_t | 128 | static ssize_t |
@@ -175,19 +174,150 @@ static struct bin_attribute sysfs_nvram_attr = { | |||
175 | .mode = S_IRUSR | S_IWUSR, | 174 | .mode = S_IRUSR | S_IWUSR, |
176 | .owner = THIS_MODULE, | 175 | .owner = THIS_MODULE, |
177 | }, | 176 | }, |
178 | .size = 0, | 177 | .size = 512, |
179 | .read = qla2x00_sysfs_read_nvram, | 178 | .read = qla2x00_sysfs_read_nvram, |
180 | .write = qla2x00_sysfs_write_nvram, | 179 | .write = qla2x00_sysfs_write_nvram, |
181 | }; | 180 | }; |
182 | 181 | ||
182 | static ssize_t | ||
183 | qla2x00_sysfs_read_optrom(struct kobject *kobj, char *buf, loff_t off, | ||
184 | size_t count) | ||
185 | { | ||
186 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | ||
187 | struct device, kobj))); | ||
188 | |||
189 | if (ha->optrom_state != QLA_SREADING) | ||
190 | return 0; | ||
191 | if (off > ha->optrom_size) | ||
192 | return 0; | ||
193 | if (off + count > ha->optrom_size) | ||
194 | count = ha->optrom_size - off; | ||
195 | |||
196 | memcpy(buf, &ha->optrom_buffer[off], count); | ||
197 | |||
198 | return count; | ||
199 | } | ||
200 | |||
201 | static ssize_t | ||
202 | qla2x00_sysfs_write_optrom(struct kobject *kobj, char *buf, loff_t off, | ||
203 | size_t count) | ||
204 | { | ||
205 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | ||
206 | struct device, kobj))); | ||
207 | |||
208 | if (ha->optrom_state != QLA_SWRITING) | ||
209 | return -EINVAL; | ||
210 | if (off > ha->optrom_size) | ||
211 | return -ERANGE; | ||
212 | if (off + count > ha->optrom_size) | ||
213 | count = ha->optrom_size - off; | ||
214 | |||
215 | memcpy(&ha->optrom_buffer[off], buf, count); | ||
216 | |||
217 | return count; | ||
218 | } | ||
219 | |||
220 | static struct bin_attribute sysfs_optrom_attr = { | ||
221 | .attr = { | ||
222 | .name = "optrom", | ||
223 | .mode = S_IRUSR | S_IWUSR, | ||
224 | .owner = THIS_MODULE, | ||
225 | }, | ||
226 | .size = OPTROM_SIZE_24XX, | ||
227 | .read = qla2x00_sysfs_read_optrom, | ||
228 | .write = qla2x00_sysfs_write_optrom, | ||
229 | }; | ||
230 | |||
231 | static ssize_t | ||
232 | qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, char *buf, loff_t off, | ||
233 | size_t count) | ||
234 | { | ||
235 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | ||
236 | struct device, kobj))); | ||
237 | int val; | ||
238 | |||
239 | if (off) | ||
240 | return 0; | ||
241 | |||
242 | if (sscanf(buf, "%d", &val) != 1) | ||
243 | return -EINVAL; | ||
244 | |||
245 | switch (val) { | ||
246 | case 0: | ||
247 | if (ha->optrom_state != QLA_SREADING && | ||
248 | ha->optrom_state != QLA_SWRITING) | ||
249 | break; | ||
250 | |||
251 | ha->optrom_state = QLA_SWAITING; | ||
252 | vfree(ha->optrom_buffer); | ||
253 | ha->optrom_buffer = NULL; | ||
254 | break; | ||
255 | case 1: | ||
256 | if (ha->optrom_state != QLA_SWAITING) | ||
257 | break; | ||
258 | |||
259 | ha->optrom_state = QLA_SREADING; | ||
260 | ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); | ||
261 | if (ha->optrom_buffer == NULL) { | ||
262 | qla_printk(KERN_WARNING, ha, | ||
263 | "Unable to allocate memory for optrom retrieval " | ||
264 | "(%x).\n", ha->optrom_size); | ||
265 | |||
266 | ha->optrom_state = QLA_SWAITING; | ||
267 | return count; | ||
268 | } | ||
269 | |||
270 | memset(ha->optrom_buffer, 0, ha->optrom_size); | ||
271 | ha->isp_ops.read_optrom(ha, ha->optrom_buffer, 0, | ||
272 | ha->optrom_size); | ||
273 | break; | ||
274 | case 2: | ||
275 | if (ha->optrom_state != QLA_SWAITING) | ||
276 | break; | ||
277 | |||
278 | ha->optrom_state = QLA_SWRITING; | ||
279 | ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); | ||
280 | if (ha->optrom_buffer == NULL) { | ||
281 | qla_printk(KERN_WARNING, ha, | ||
282 | "Unable to allocate memory for optrom update " | ||
283 | "(%x).\n", ha->optrom_size); | ||
284 | |||
285 | ha->optrom_state = QLA_SWAITING; | ||
286 | return count; | ||
287 | } | ||
288 | memset(ha->optrom_buffer, 0, ha->optrom_size); | ||
289 | break; | ||
290 | case 3: | ||
291 | if (ha->optrom_state != QLA_SWRITING) | ||
292 | break; | ||
293 | |||
294 | ha->isp_ops.write_optrom(ha, ha->optrom_buffer, 0, | ||
295 | ha->optrom_size); | ||
296 | break; | ||
297 | } | ||
298 | return count; | ||
299 | } | ||
300 | |||
301 | static struct bin_attribute sysfs_optrom_ctl_attr = { | ||
302 | .attr = { | ||
303 | .name = "optrom_ctl", | ||
304 | .mode = S_IWUSR, | ||
305 | .owner = THIS_MODULE, | ||
306 | }, | ||
307 | .size = 0, | ||
308 | .write = qla2x00_sysfs_write_optrom_ctl, | ||
309 | }; | ||
310 | |||
183 | void | 311 | void |
184 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | 312 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) |
185 | { | 313 | { |
186 | struct Scsi_Host *host = ha->host; | 314 | struct Scsi_Host *host = ha->host; |
187 | 315 | ||
188 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); | 316 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); |
189 | sysfs_nvram_attr.size = ha->nvram_size; | ||
190 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); | 317 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); |
318 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | ||
319 | sysfs_create_bin_file(&host->shost_gendev.kobj, | ||
320 | &sysfs_optrom_ctl_attr); | ||
191 | } | 321 | } |
192 | 322 | ||
193 | void | 323 | void |
@@ -197,6 +327,12 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) | |||
197 | 327 | ||
198 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); | 328 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); |
199 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); | 329 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); |
330 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | ||
331 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | ||
332 | &sysfs_optrom_ctl_attr); | ||
333 | |||
334 | if (ha->beacon_blink_led == 1) | ||
335 | ha->isp_ops.beacon_off(ha); | ||
200 | } | 336 | } |
201 | 337 | ||
202 | /* Scsi_Host attributes. */ | 338 | /* Scsi_Host attributes. */ |
@@ -384,6 +520,50 @@ qla2x00_zio_timer_store(struct class_device *cdev, const char *buf, | |||
384 | return strlen(buf); | 520 | return strlen(buf); |
385 | } | 521 | } |
386 | 522 | ||
523 | static ssize_t | ||
524 | qla2x00_beacon_show(struct class_device *cdev, char *buf) | ||
525 | { | ||
526 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | ||
527 | int len = 0; | ||
528 | |||
529 | if (ha->beacon_blink_led) | ||
530 | len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n"); | ||
531 | else | ||
532 | len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n"); | ||
533 | return len; | ||
534 | } | ||
535 | |||
536 | static ssize_t | ||
537 | qla2x00_beacon_store(struct class_device *cdev, const char *buf, | ||
538 | size_t count) | ||
539 | { | ||
540 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | ||
541 | int val = 0; | ||
542 | int rval; | ||
543 | |||
544 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) | ||
545 | return -EPERM; | ||
546 | |||
547 | if (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) { | ||
548 | qla_printk(KERN_WARNING, ha, | ||
549 | "Abort ISP active -- ignoring beacon request.\n"); | ||
550 | return -EBUSY; | ||
551 | } | ||
552 | |||
553 | if (sscanf(buf, "%d", &val) != 1) | ||
554 | return -EINVAL; | ||
555 | |||
556 | if (val) | ||
557 | rval = ha->isp_ops.beacon_on(ha); | ||
558 | else | ||
559 | rval = ha->isp_ops.beacon_off(ha); | ||
560 | |||
561 | if (rval != QLA_SUCCESS) | ||
562 | count = 0; | ||
563 | |||
564 | return count; | ||
565 | } | ||
566 | |||
387 | static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, | 567 | static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, |
388 | NULL); | 568 | NULL); |
389 | static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); | 569 | static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); |
@@ -398,6 +578,8 @@ static CLASS_DEVICE_ATTR(zio, S_IRUGO | S_IWUSR, qla2x00_zio_show, | |||
398 | qla2x00_zio_store); | 578 | qla2x00_zio_store); |
399 | static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show, | 579 | static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show, |
400 | qla2x00_zio_timer_store); | 580 | qla2x00_zio_timer_store); |
581 | static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show, | ||
582 | qla2x00_beacon_store); | ||
401 | 583 | ||
402 | struct class_device_attribute *qla2x00_host_attrs[] = { | 584 | struct class_device_attribute *qla2x00_host_attrs[] = { |
403 | &class_device_attr_driver_version, | 585 | &class_device_attr_driver_version, |
@@ -411,6 +593,7 @@ struct class_device_attribute *qla2x00_host_attrs[] = { | |||
411 | &class_device_attr_state, | 593 | &class_device_attr_state, |
412 | &class_device_attr_zio, | 594 | &class_device_attr_zio, |
413 | &class_device_attr_zio_timer, | 595 | &class_device_attr_zio_timer, |
596 | &class_device_attr_beacon, | ||
414 | NULL, | 597 | NULL, |
415 | }; | 598 | }; |
416 | 599 | ||
@@ -426,6 +609,49 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost) | |||
426 | } | 609 | } |
427 | 610 | ||
428 | static void | 611 | static void |
612 | qla2x00_get_host_speed(struct Scsi_Host *shost) | ||
613 | { | ||
614 | scsi_qla_host_t *ha = to_qla_host(shost); | ||
615 | uint32_t speed = 0; | ||
616 | |||
617 | switch (ha->link_data_rate) { | ||
618 | case LDR_1GB: | ||
619 | speed = 1; | ||
620 | break; | ||
621 | case LDR_2GB: | ||
622 | speed = 2; | ||
623 | break; | ||
624 | case LDR_4GB: | ||
625 | speed = 4; | ||
626 | break; | ||
627 | } | ||
628 | fc_host_speed(shost) = speed; | ||
629 | } | ||
630 | |||
631 | static void | ||
632 | qla2x00_get_host_port_type(struct Scsi_Host *shost) | ||
633 | { | ||
634 | scsi_qla_host_t *ha = to_qla_host(shost); | ||
635 | uint32_t port_type = FC_PORTTYPE_UNKNOWN; | ||
636 | |||
637 | switch (ha->current_topology) { | ||
638 | case ISP_CFG_NL: | ||
639 | port_type = FC_PORTTYPE_LPORT; | ||
640 | break; | ||
641 | case ISP_CFG_FL: | ||
642 | port_type = FC_PORTTYPE_NLPORT; | ||
643 | break; | ||
644 | case ISP_CFG_N: | ||
645 | port_type = FC_PORTTYPE_PTP; | ||
646 | break; | ||
647 | case ISP_CFG_F: | ||
648 | port_type = FC_PORTTYPE_NPORT; | ||
649 | break; | ||
650 | } | ||
651 | fc_host_port_type(shost) = port_type; | ||
652 | } | ||
653 | |||
654 | static void | ||
429 | qla2x00_get_starget_node_name(struct scsi_target *starget) | 655 | qla2x00_get_starget_node_name(struct scsi_target *starget) |
430 | { | 656 | { |
431 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); | 657 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); |
@@ -512,6 +738,41 @@ qla2x00_issue_lip(struct Scsi_Host *shost) | |||
512 | return 0; | 738 | return 0; |
513 | } | 739 | } |
514 | 740 | ||
741 | static struct fc_host_statistics * | ||
742 | qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | ||
743 | { | ||
744 | scsi_qla_host_t *ha = to_qla_host(shost); | ||
745 | int rval; | ||
746 | uint16_t mb_stat[1]; | ||
747 | link_stat_t stat_buf; | ||
748 | struct fc_host_statistics *pfc_host_stat; | ||
749 | |||
750 | pfc_host_stat = &ha->fc_host_stat; | ||
751 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); | ||
752 | |||
753 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { | ||
754 | rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, | ||
755 | sizeof(stat_buf) / 4, mb_stat); | ||
756 | } else { | ||
757 | rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf, | ||
758 | mb_stat); | ||
759 | } | ||
760 | if (rval != 0) { | ||
761 | qla_printk(KERN_WARNING, ha, | ||
762 | "Unable to retrieve host statistics (%d).\n", mb_stat[0]); | ||
763 | return pfc_host_stat; | ||
764 | } | ||
765 | |||
766 | pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt; | ||
767 | pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt; | ||
768 | pfc_host_stat->loss_of_signal_count = stat_buf.loss_sig_cnt; | ||
769 | pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt; | ||
770 | pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt; | ||
771 | pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt; | ||
772 | |||
773 | return pfc_host_stat; | ||
774 | } | ||
775 | |||
515 | struct fc_function_template qla2xxx_transport_functions = { | 776 | struct fc_function_template qla2xxx_transport_functions = { |
516 | 777 | ||
517 | .show_host_node_name = 1, | 778 | .show_host_node_name = 1, |
@@ -520,6 +781,10 @@ struct fc_function_template qla2xxx_transport_functions = { | |||
520 | 781 | ||
521 | .get_host_port_id = qla2x00_get_host_port_id, | 782 | .get_host_port_id = qla2x00_get_host_port_id, |
522 | .show_host_port_id = 1, | 783 | .show_host_port_id = 1, |
784 | .get_host_speed = qla2x00_get_host_speed, | ||
785 | .show_host_speed = 1, | ||
786 | .get_host_port_type = qla2x00_get_host_port_type, | ||
787 | .show_host_port_type = 1, | ||
523 | 788 | ||
524 | .dd_fcrport_size = sizeof(struct fc_port *), | 789 | .dd_fcrport_size = sizeof(struct fc_port *), |
525 | .show_rport_supported_classes = 1, | 790 | .show_rport_supported_classes = 1, |
@@ -536,6 +801,7 @@ struct fc_function_template qla2xxx_transport_functions = { | |||
536 | .show_rport_dev_loss_tmo = 1, | 801 | .show_rport_dev_loss_tmo = 1, |
537 | 802 | ||
538 | .issue_fc_host_lip = qla2x00_issue_lip, | 803 | .issue_fc_host_lip = qla2x00_issue_lip, |
804 | .get_fc_host_stats = qla2x00_get_fc_host_stats, | ||
539 | }; | 805 | }; |
540 | 806 | ||
541 | void | 807 | void |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index bad066e5772a..b31a03bbd14f 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <scsi/scsi_host.h> | 29 | #include <scsi/scsi_host.h> |
30 | #include <scsi/scsi_device.h> | 30 | #include <scsi/scsi_device.h> |
31 | #include <scsi/scsi_cmnd.h> | 31 | #include <scsi/scsi_cmnd.h> |
32 | #include <scsi/scsi_transport_fc.h> | ||
32 | 33 | ||
33 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) | 34 | #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) |
34 | #if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE) | 35 | #if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE) |
@@ -181,6 +182,13 @@ | |||
181 | #define WRT_REG_DWORD(addr, data) writel(data,addr) | 182 | #define WRT_REG_DWORD(addr, data) writel(data,addr) |
182 | 183 | ||
183 | /* | 184 | /* |
185 | * The ISP2312 v2 chip cannot access the FLASH/GPIO registers via MMIO in an | ||
186 | * 133Mhz slot. | ||
187 | */ | ||
188 | #define RD_REG_WORD_PIO(addr) (inw((unsigned long)addr)) | ||
189 | #define WRT_REG_WORD_PIO(addr, data) (outw(data,(unsigned long)addr)) | ||
190 | |||
191 | /* | ||
184 | * Fibre Channel device definitions. | 192 | * Fibre Channel device definitions. |
185 | */ | 193 | */ |
186 | #define WWN_SIZE 8 /* Size of WWPN, WWN & WWNN */ | 194 | #define WWN_SIZE 8 /* Size of WWPN, WWN & WWNN */ |
@@ -432,6 +440,9 @@ struct device_reg_2xxx { | |||
432 | #define GPIO_LED_GREEN_ON_AMBER_OFF 0x0040 | 440 | #define GPIO_LED_GREEN_ON_AMBER_OFF 0x0040 |
433 | #define GPIO_LED_GREEN_OFF_AMBER_ON 0x0080 | 441 | #define GPIO_LED_GREEN_OFF_AMBER_ON 0x0080 |
434 | #define GPIO_LED_GREEN_ON_AMBER_ON 0x00C0 | 442 | #define GPIO_LED_GREEN_ON_AMBER_ON 0x00C0 |
443 | #define GPIO_LED_ALL_OFF 0x0000 | ||
444 | #define GPIO_LED_RED_ON_OTHER_OFF 0x0001 /* isp2322 */ | ||
445 | #define GPIO_LED_RGA_ON 0x00C1 /* isp2322: red green amber */ | ||
435 | 446 | ||
436 | union { | 447 | union { |
437 | struct { | 448 | struct { |
@@ -2199,6 +2210,15 @@ struct isp_operations { | |||
2199 | 2210 | ||
2200 | void (*fw_dump) (struct scsi_qla_host *, int); | 2211 | void (*fw_dump) (struct scsi_qla_host *, int); |
2201 | void (*ascii_fw_dump) (struct scsi_qla_host *); | 2212 | void (*ascii_fw_dump) (struct scsi_qla_host *); |
2213 | |||
2214 | int (*beacon_on) (struct scsi_qla_host *); | ||
2215 | int (*beacon_off) (struct scsi_qla_host *); | ||
2216 | void (*beacon_blink) (struct scsi_qla_host *); | ||
2217 | |||
2218 | uint8_t * (*read_optrom) (struct scsi_qla_host *, uint8_t *, | ||
2219 | uint32_t, uint32_t); | ||
2220 | int (*write_optrom) (struct scsi_qla_host *, uint8_t *, uint32_t, | ||
2221 | uint32_t); | ||
2202 | }; | 2222 | }; |
2203 | 2223 | ||
2204 | /* | 2224 | /* |
@@ -2331,6 +2351,10 @@ typedef struct scsi_qla_host { | |||
2331 | uint16_t min_external_loopid; /* First external loop Id */ | 2351 | uint16_t min_external_loopid; /* First external loop Id */ |
2332 | 2352 | ||
2333 | uint16_t link_data_rate; /* F/W operating speed */ | 2353 | uint16_t link_data_rate; /* F/W operating speed */ |
2354 | #define LDR_1GB 0 | ||
2355 | #define LDR_2GB 1 | ||
2356 | #define LDR_4GB 3 | ||
2357 | #define LDR_UNKNOWN 0xFFFF | ||
2334 | 2358 | ||
2335 | uint8_t current_topology; | 2359 | uint8_t current_topology; |
2336 | uint8_t prev_topology; | 2360 | uint8_t prev_topology; |
@@ -2486,12 +2510,26 @@ typedef struct scsi_qla_host { | |||
2486 | uint8_t *port_name; | 2510 | uint8_t *port_name; |
2487 | uint32_t isp_abort_cnt; | 2511 | uint32_t isp_abort_cnt; |
2488 | 2512 | ||
2513 | /* Option ROM information. */ | ||
2514 | char *optrom_buffer; | ||
2515 | uint32_t optrom_size; | ||
2516 | int optrom_state; | ||
2517 | #define QLA_SWAITING 0 | ||
2518 | #define QLA_SREADING 1 | ||
2519 | #define QLA_SWRITING 2 | ||
2520 | |||
2489 | /* Needed for BEACON */ | 2521 | /* Needed for BEACON */ |
2490 | uint16_t beacon_blink_led; | 2522 | uint16_t beacon_blink_led; |
2491 | uint16_t beacon_green_on; | 2523 | uint8_t beacon_color_state; |
2524 | #define QLA_LED_GRN_ON 0x01 | ||
2525 | #define QLA_LED_YLW_ON 0x02 | ||
2526 | #define QLA_LED_ABR_ON 0x04 | ||
2527 | #define QLA_LED_ALL_ON 0x07 /* yellow, green, amber. */ | ||
2528 | /* ISP2322: red, green, amber. */ | ||
2492 | 2529 | ||
2493 | uint16_t zio_mode; | 2530 | uint16_t zio_mode; |
2494 | uint16_t zio_timer; | 2531 | uint16_t zio_timer; |
2532 | struct fc_host_statistics fc_host_stat; | ||
2495 | } scsi_qla_host_t; | 2533 | } scsi_qla_host_t; |
2496 | 2534 | ||
2497 | 2535 | ||
@@ -2557,7 +2595,9 @@ struct _qla2x00stats { | |||
2557 | /* | 2595 | /* |
2558 | * Flash support definitions | 2596 | * Flash support definitions |
2559 | */ | 2597 | */ |
2560 | #define FLASH_IMAGE_SIZE 131072 | 2598 | #define OPTROM_SIZE_2300 0x20000 |
2599 | #define OPTROM_SIZE_2322 0x100000 | ||
2600 | #define OPTROM_SIZE_24XX 0x100000 | ||
2561 | 2601 | ||
2562 | #include "qla_gbl.h" | 2602 | #include "qla_gbl.h" |
2563 | #include "qla_dbg.h" | 2603 | #include "qla_dbg.h" |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 35266bd5d538..ffdc2680f049 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -75,12 +75,12 @@ extern void qla2x00_cmd_timeout(srb_t *); | |||
75 | extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); | 75 | extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); |
76 | extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); | 76 | extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); |
77 | 77 | ||
78 | extern void qla2x00_blink_led(scsi_qla_host_t *); | ||
79 | |||
80 | extern int qla2x00_down_timeout(struct semaphore *, unsigned long); | 78 | extern int qla2x00_down_timeout(struct semaphore *, unsigned long); |
81 | 79 | ||
82 | extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); | 80 | extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); |
83 | 81 | ||
82 | extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *); | ||
83 | |||
84 | /* | 84 | /* |
85 | * Global Function Prototypes in qla_iocb.c source file. | 85 | * Global Function Prototypes in qla_iocb.c source file. |
86 | */ | 86 | */ |
@@ -185,6 +185,13 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *, | |||
185 | extern int | 185 | extern int |
186 | qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map); | 186 | qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map); |
187 | 187 | ||
188 | extern int | ||
189 | qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, link_stat_t *, | ||
190 | uint16_t *); | ||
191 | |||
192 | extern int | ||
193 | qla24xx_get_isp_stats(scsi_qla_host_t *, uint32_t *, uint32_t, uint16_t *); | ||
194 | |||
188 | extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); | 195 | extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); |
189 | extern int qla24xx_abort_target(fc_port_t *); | 196 | extern int qla24xx_abort_target(fc_port_t *); |
190 | 197 | ||
@@ -228,6 +235,22 @@ extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | |||
228 | extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | 235 | extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, |
229 | uint32_t); | 236 | uint32_t); |
230 | 237 | ||
238 | extern int qla2x00_beacon_on(struct scsi_qla_host *); | ||
239 | extern int qla2x00_beacon_off(struct scsi_qla_host *); | ||
240 | extern void qla2x00_beacon_blink(struct scsi_qla_host *); | ||
241 | extern int qla24xx_beacon_on(struct scsi_qla_host *); | ||
242 | extern int qla24xx_beacon_off(struct scsi_qla_host *); | ||
243 | extern void qla24xx_beacon_blink(struct scsi_qla_host *); | ||
244 | |||
245 | extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *, | ||
246 | uint32_t, uint32_t); | ||
247 | extern int qla2x00_write_optrom_data(struct scsi_qla_host *, uint8_t *, | ||
248 | uint32_t, uint32_t); | ||
249 | extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, | ||
250 | uint32_t, uint32_t); | ||
251 | extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, | ||
252 | uint32_t, uint32_t); | ||
253 | |||
231 | /* | 254 | /* |
232 | * Global Function Prototypes in qla_dbg.c source file. | 255 | * Global Function Prototypes in qla_dbg.c source file. |
233 | */ | 256 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e67bb0997818..634ee174bff2 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/vmalloc.h> | 10 | #include <linux/vmalloc.h> |
11 | #include <scsi/scsi_transport_fc.h> | ||
12 | 11 | ||
13 | #include "qla_devtbl.h" | 12 | #include "qla_devtbl.h" |
14 | 13 | ||
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 7ec0b8d6f07b..6544b6d0891d 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -814,6 +814,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
814 | cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; | 814 | cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; |
815 | 815 | ||
816 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); | 816 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); |
817 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); | ||
817 | 818 | ||
818 | /* Load SCSI command packet. */ | 819 | /* Load SCSI command packet. */ |
819 | memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); | 820 | memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 71a46fcee8cc..42aa7a7c1a73 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -402,9 +402,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
402 | break; | 402 | break; |
403 | 403 | ||
404 | case MBA_LOOP_UP: /* Loop Up Event */ | 404 | case MBA_LOOP_UP: /* Loop Up Event */ |
405 | ha->link_data_rate = 0; | ||
406 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 405 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
407 | link_speed = link_speeds[0]; | 406 | link_speed = link_speeds[0]; |
407 | ha->link_data_rate = LDR_1GB; | ||
408 | } else { | 408 | } else { |
409 | link_speed = link_speeds[LS_UNKNOWN]; | 409 | link_speed = link_speeds[LS_UNKNOWN]; |
410 | if (mb[1] < 5) | 410 | if (mb[1] < 5) |
@@ -436,7 +436,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
436 | } | 436 | } |
437 | 437 | ||
438 | ha->flags.management_server_logged_in = 0; | 438 | ha->flags.management_server_logged_in = 0; |
439 | ha->link_data_rate = 0; | 439 | ha->link_data_rate = LDR_UNKNOWN; |
440 | if (ql2xfdmienable) | 440 | if (ql2xfdmienable) |
441 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 441 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
442 | 442 | ||
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 3099b379de9d..363dfdd042b0 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <scsi/scsi_transport_fc.h> | ||
11 | 10 | ||
12 | static void | 11 | static void |
13 | qla2x00_mbx_sem_timeout(unsigned long data) | 12 | qla2x00_mbx_sem_timeout(unsigned long data) |
@@ -1874,7 +1873,8 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1874 | mcp->mb[3] = LSW(id_list_dma); | 1873 | mcp->mb[3] = LSW(id_list_dma); |
1875 | mcp->mb[6] = MSW(MSD(id_list_dma)); | 1874 | mcp->mb[6] = MSW(MSD(id_list_dma)); |
1876 | mcp->mb[7] = LSW(MSD(id_list_dma)); | 1875 | mcp->mb[7] = LSW(MSD(id_list_dma)); |
1877 | mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2; | 1876 | mcp->mb[8] = 0; |
1877 | mcp->out_mb |= MBX_8|MBX_7|MBX_6|MBX_3|MBX_2; | ||
1878 | } else { | 1878 | } else { |
1879 | mcp->mb[1] = MSW(id_list_dma); | 1879 | mcp->mb[1] = MSW(id_list_dma); |
1880 | mcp->mb[2] = LSW(id_list_dma); | 1880 | mcp->mb[2] = LSW(id_list_dma); |
@@ -2017,8 +2017,109 @@ qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map) | |||
2017 | 2017 | ||
2018 | return rval; | 2018 | return rval; |
2019 | } | 2019 | } |
2020 | #endif | ||
2021 | |||
2022 | /* | ||
2023 | * qla2x00_get_link_status | ||
2024 | * | ||
2025 | * Input: | ||
2026 | * ha = adapter block pointer. | ||
2027 | * loop_id = device loop ID. | ||
2028 | * ret_buf = pointer to link status return buffer. | ||
2029 | * | ||
2030 | * Returns: | ||
2031 | * 0 = success. | ||
2032 | * BIT_0 = mem alloc error. | ||
2033 | * BIT_1 = mailbox error. | ||
2034 | */ | ||
2035 | int | ||
2036 | qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | ||
2037 | link_stat_t *ret_buf, uint16_t *status) | ||
2038 | { | ||
2039 | int rval; | ||
2040 | mbx_cmd_t mc; | ||
2041 | mbx_cmd_t *mcp = &mc; | ||
2042 | link_stat_t *stat_buf; | ||
2043 | dma_addr_t stat_buf_dma; | ||
2044 | |||
2045 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | ||
2046 | |||
2047 | stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma); | ||
2048 | if (stat_buf == NULL) { | ||
2049 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", | ||
2050 | __func__, ha->host_no)); | ||
2051 | return BIT_0; | ||
2052 | } | ||
2053 | memset(stat_buf, 0, sizeof(link_stat_t)); | ||
2054 | |||
2055 | mcp->mb[0] = MBC_GET_LINK_STATUS; | ||
2056 | mcp->mb[2] = MSW(stat_buf_dma); | ||
2057 | mcp->mb[3] = LSW(stat_buf_dma); | ||
2058 | mcp->mb[6] = MSW(MSD(stat_buf_dma)); | ||
2059 | mcp->mb[7] = LSW(MSD(stat_buf_dma)); | ||
2060 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; | ||
2061 | mcp->in_mb = MBX_0; | ||
2062 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { | ||
2063 | mcp->mb[1] = loop_id; | ||
2064 | mcp->mb[4] = 0; | ||
2065 | mcp->mb[10] = 0; | ||
2066 | mcp->out_mb |= MBX_10|MBX_4|MBX_1; | ||
2067 | mcp->in_mb |= MBX_1; | ||
2068 | } else if (HAS_EXTENDED_IDS(ha)) { | ||
2069 | mcp->mb[1] = loop_id; | ||
2070 | mcp->mb[10] = 0; | ||
2071 | mcp->out_mb |= MBX_10|MBX_1; | ||
2072 | } else { | ||
2073 | mcp->mb[1] = loop_id << 8; | ||
2074 | mcp->out_mb |= MBX_1; | ||
2075 | } | ||
2076 | mcp->tov = 30; | ||
2077 | mcp->flags = IOCTL_CMD; | ||
2078 | rval = qla2x00_mailbox_command(ha, mcp); | ||
2079 | |||
2080 | if (rval == QLA_SUCCESS) { | ||
2081 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { | ||
2082 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", | ||
2083 | __func__, ha->host_no, mcp->mb[0]);) | ||
2084 | status[0] = mcp->mb[0]; | ||
2085 | rval = BIT_1; | ||
2086 | } else { | ||
2087 | /* copy over data -- firmware data is LE. */ | ||
2088 | ret_buf->link_fail_cnt = | ||
2089 | le32_to_cpu(stat_buf->link_fail_cnt); | ||
2090 | ret_buf->loss_sync_cnt = | ||
2091 | le32_to_cpu(stat_buf->loss_sync_cnt); | ||
2092 | ret_buf->loss_sig_cnt = | ||
2093 | le32_to_cpu(stat_buf->loss_sig_cnt); | ||
2094 | ret_buf->prim_seq_err_cnt = | ||
2095 | le32_to_cpu(stat_buf->prim_seq_err_cnt); | ||
2096 | ret_buf->inval_xmit_word_cnt = | ||
2097 | le32_to_cpu(stat_buf->inval_xmit_word_cnt); | ||
2098 | ret_buf->inval_crc_cnt = | ||
2099 | le32_to_cpu(stat_buf->inval_crc_cnt); | ||
2100 | |||
2101 | DEBUG11(printk("%s(%ld): stat dump: fail_cnt=%d " | ||
2102 | "loss_sync=%d loss_sig=%d seq_err=%d " | ||
2103 | "inval_xmt_word=%d inval_crc=%d.\n", __func__, | ||
2104 | ha->host_no, stat_buf->link_fail_cnt, | ||
2105 | stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt, | ||
2106 | stat_buf->prim_seq_err_cnt, | ||
2107 | stat_buf->inval_xmit_word_cnt, | ||
2108 | stat_buf->inval_crc_cnt);) | ||
2109 | } | ||
2110 | } else { | ||
2111 | /* Failed. */ | ||
2112 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | ||
2113 | ha->host_no, rval);) | ||
2114 | rval = BIT_1; | ||
2115 | } | ||
2116 | |||
2117 | dma_pool_free(ha->s_dma_pool, stat_buf, stat_buf_dma); | ||
2020 | 2118 | ||
2021 | uint8_t | 2119 | return rval; |
2120 | } | ||
2121 | |||
2122 | int | ||
2022 | qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, | 2123 | qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, |
2023 | uint16_t *status) | 2124 | uint16_t *status) |
2024 | { | 2125 | { |
@@ -2080,7 +2181,6 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, | |||
2080 | 2181 | ||
2081 | return rval; | 2182 | return rval; |
2082 | } | 2183 | } |
2083 | #endif | ||
2084 | 2184 | ||
2085 | int | 2185 | int |
2086 | qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | 2186 | qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 5866a7c706a8..9f91f1a20542 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -366,6 +366,12 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
366 | goto qc_fail_command; | 366 | goto qc_fail_command; |
367 | } | 367 | } |
368 | 368 | ||
369 | /* Close window on fcport/rport state-transitioning. */ | ||
370 | if (!*(fc_port_t **)rport->dd_data) { | ||
371 | cmd->result = DID_IMM_RETRY << 16; | ||
372 | goto qc_fail_command; | ||
373 | } | ||
374 | |||
369 | if (atomic_read(&fcport->state) != FCS_ONLINE) { | 375 | if (atomic_read(&fcport->state) != FCS_ONLINE) { |
370 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || | 376 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || |
371 | atomic_read(&ha->loop_state) == LOOP_DEAD) { | 377 | atomic_read(&ha->loop_state) == LOOP_DEAD) { |
@@ -421,6 +427,12 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
421 | goto qc24_fail_command; | 427 | goto qc24_fail_command; |
422 | } | 428 | } |
423 | 429 | ||
430 | /* Close window on fcport/rport state-transitioning. */ | ||
431 | if (!*(fc_port_t **)rport->dd_data) { | ||
432 | cmd->result = DID_IMM_RETRY << 16; | ||
433 | goto qc24_fail_command; | ||
434 | } | ||
435 | |||
424 | if (atomic_read(&fcport->state) != FCS_ONLINE) { | 436 | if (atomic_read(&fcport->state) != FCS_ONLINE) { |
425 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || | 437 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || |
426 | atomic_read(&ha->loop_state) == LOOP_DEAD) { | 438 | atomic_read(&ha->loop_state) == LOOP_DEAD) { |
@@ -513,7 +525,7 @@ qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) | |||
513 | * Success (Adapter is online) : 0 | 525 | * Success (Adapter is online) : 0 |
514 | * Failed (Adapter is offline/disabled) : 1 | 526 | * Failed (Adapter is offline/disabled) : 1 |
515 | */ | 527 | */ |
516 | static int | 528 | int |
517 | qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) | 529 | qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) |
518 | { | 530 | { |
519 | int return_status; | 531 | int return_status; |
@@ -1312,6 +1324,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
1312 | ha->ports = MAX_BUSES; | 1324 | ha->ports = MAX_BUSES; |
1313 | ha->init_cb_size = sizeof(init_cb_t); | 1325 | ha->init_cb_size = sizeof(init_cb_t); |
1314 | ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; | 1326 | ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; |
1327 | ha->link_data_rate = LDR_UNKNOWN; | ||
1328 | ha->optrom_size = OPTROM_SIZE_2300; | ||
1315 | 1329 | ||
1316 | /* Assign ISP specific operations. */ | 1330 | /* Assign ISP specific operations. */ |
1317 | ha->isp_ops.pci_config = qla2100_pci_config; | 1331 | ha->isp_ops.pci_config = qla2100_pci_config; |
@@ -1339,6 +1353,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
1339 | ha->isp_ops.write_nvram = qla2x00_write_nvram_data; | 1353 | ha->isp_ops.write_nvram = qla2x00_write_nvram_data; |
1340 | ha->isp_ops.fw_dump = qla2100_fw_dump; | 1354 | ha->isp_ops.fw_dump = qla2100_fw_dump; |
1341 | ha->isp_ops.ascii_fw_dump = qla2100_ascii_fw_dump; | 1355 | ha->isp_ops.ascii_fw_dump = qla2100_ascii_fw_dump; |
1356 | ha->isp_ops.read_optrom = qla2x00_read_optrom_data; | ||
1357 | ha->isp_ops.write_optrom = qla2x00_write_optrom_data; | ||
1342 | if (IS_QLA2100(ha)) { | 1358 | if (IS_QLA2100(ha)) { |
1343 | host->max_id = MAX_TARGETS_2100; | 1359 | host->max_id = MAX_TARGETS_2100; |
1344 | ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; | 1360 | ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; |
@@ -1364,7 +1380,12 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
1364 | ha->isp_ops.intr_handler = qla2300_intr_handler; | 1380 | ha->isp_ops.intr_handler = qla2300_intr_handler; |
1365 | ha->isp_ops.fw_dump = qla2300_fw_dump; | 1381 | ha->isp_ops.fw_dump = qla2300_fw_dump; |
1366 | ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump; | 1382 | ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump; |
1383 | ha->isp_ops.beacon_on = qla2x00_beacon_on; | ||
1384 | ha->isp_ops.beacon_off = qla2x00_beacon_off; | ||
1385 | ha->isp_ops.beacon_blink = qla2x00_beacon_blink; | ||
1367 | ha->gid_list_info_size = 6; | 1386 | ha->gid_list_info_size = 6; |
1387 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) | ||
1388 | ha->optrom_size = OPTROM_SIZE_2322; | ||
1368 | } else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { | 1389 | } else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { |
1369 | host->max_id = MAX_TARGETS_2200; | 1390 | host->max_id = MAX_TARGETS_2200; |
1370 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1391 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
@@ -1400,7 +1421,13 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
1400 | ha->isp_ops.write_nvram = qla24xx_write_nvram_data; | 1421 | ha->isp_ops.write_nvram = qla24xx_write_nvram_data; |
1401 | ha->isp_ops.fw_dump = qla24xx_fw_dump; | 1422 | ha->isp_ops.fw_dump = qla24xx_fw_dump; |
1402 | ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump; | 1423 | ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump; |
1424 | ha->isp_ops.read_optrom = qla24xx_read_optrom_data; | ||
1425 | ha->isp_ops.write_optrom = qla24xx_write_optrom_data; | ||
1426 | ha->isp_ops.beacon_on = qla24xx_beacon_on; | ||
1427 | ha->isp_ops.beacon_off = qla24xx_beacon_off; | ||
1428 | ha->isp_ops.beacon_blink = qla24xx_beacon_blink; | ||
1403 | ha->gid_list_info_size = 8; | 1429 | ha->gid_list_info_size = 8; |
1430 | ha->optrom_size = OPTROM_SIZE_24XX; | ||
1404 | } | 1431 | } |
1405 | host->can_queue = ha->request_q_length + 128; | 1432 | host->can_queue = ha->request_q_length + 128; |
1406 | 1433 | ||
@@ -1657,11 +1684,13 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, | |||
1657 | spin_lock_irqsave(&fcport->rport_lock, flags); | 1684 | spin_lock_irqsave(&fcport->rport_lock, flags); |
1658 | fcport->drport = rport; | 1685 | fcport->drport = rport; |
1659 | fcport->rport = NULL; | 1686 | fcport->rport = NULL; |
1687 | *(fc_port_t **)rport->dd_data = NULL; | ||
1660 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 1688 | spin_unlock_irqrestore(&fcport->rport_lock, flags); |
1661 | set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); | 1689 | set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); |
1662 | } else { | 1690 | } else { |
1663 | spin_lock_irqsave(&fcport->rport_lock, flags); | 1691 | spin_lock_irqsave(&fcport->rport_lock, flags); |
1664 | fcport->rport = NULL; | 1692 | fcport->rport = NULL; |
1693 | *(fc_port_t **)rport->dd_data = NULL; | ||
1665 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 1694 | spin_unlock_irqrestore(&fcport->rport_lock, flags); |
1666 | fc_remote_port_delete(rport); | 1695 | fc_remote_port_delete(rport); |
1667 | } | 1696 | } |
@@ -2066,6 +2095,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2066 | ha->fw_dumped = 0; | 2095 | ha->fw_dumped = 0; |
2067 | ha->fw_dump_reading = 0; | 2096 | ha->fw_dump_reading = 0; |
2068 | ha->fw_dump_buffer = NULL; | 2097 | ha->fw_dump_buffer = NULL; |
2098 | |||
2099 | vfree(ha->optrom_buffer); | ||
2069 | } | 2100 | } |
2070 | 2101 | ||
2071 | /* | 2102 | /* |
@@ -2314,6 +2345,9 @@ qla2x00_do_dpc(void *data) | |||
2314 | if (!ha->interrupts_on) | 2345 | if (!ha->interrupts_on) |
2315 | ha->isp_ops.enable_intrs(ha); | 2346 | ha->isp_ops.enable_intrs(ha); |
2316 | 2347 | ||
2348 | if (test_and_clear_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags)) | ||
2349 | ha->isp_ops.beacon_blink(ha); | ||
2350 | |||
2317 | ha->dpc_active = 0; | 2351 | ha->dpc_active = 0; |
2318 | } /* End of while(1) */ | 2352 | } /* End of while(1) */ |
2319 | 2353 | ||
@@ -2491,6 +2525,12 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2491 | atomic_read(&ha->loop_down_timer))); | 2525 | atomic_read(&ha->loop_down_timer))); |
2492 | } | 2526 | } |
2493 | 2527 | ||
2528 | /* Check if beacon LED needs to be blinked */ | ||
2529 | if (ha->beacon_blink_led == 1) { | ||
2530 | set_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags); | ||
2531 | start_dpc++; | ||
2532 | } | ||
2533 | |||
2494 | /* Schedule the DPC routine if needed */ | 2534 | /* Schedule the DPC routine if needed */ |
2495 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || | 2535 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || |
2496 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || | 2536 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || |
@@ -2499,6 +2539,7 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2499 | start_dpc || | 2539 | start_dpc || |
2500 | test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || | 2540 | test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || |
2501 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || | 2541 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || |
2542 | test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || | ||
2502 | test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) && | 2543 | test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) && |
2503 | ha->dpc_wait && !ha->dpc_active) { | 2544 | ha->dpc_wait && !ha->dpc_active) { |
2504 | 2545 | ||
diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c index 2c3342108dd8..b70bebe18c01 100644 --- a/drivers/scsi/qla2xxx/qla_rscn.c +++ b/drivers/scsi/qla2xxx/qla_rscn.c | |||
@@ -6,8 +6,6 @@ | |||
6 | */ | 6 | */ |
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | #include <scsi/scsi_transport_fc.h> | ||
10 | |||
11 | /** | 9 | /** |
12 | * IO descriptor handle definitions. | 10 | * IO descriptor handle definitions. |
13 | * | 11 | * |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index f4d755a643e4..3866a5760f15 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -695,3 +695,966 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
695 | 695 | ||
696 | return ret; | 696 | return ret; |
697 | } | 697 | } |
698 | |||
699 | |||
700 | static inline void | ||
701 | qla2x00_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags) | ||
702 | { | ||
703 | if (IS_QLA2322(ha)) { | ||
704 | /* Flip all colors. */ | ||
705 | if (ha->beacon_color_state == QLA_LED_ALL_ON) { | ||
706 | /* Turn off. */ | ||
707 | ha->beacon_color_state = 0; | ||
708 | *pflags = GPIO_LED_ALL_OFF; | ||
709 | } else { | ||
710 | /* Turn on. */ | ||
711 | ha->beacon_color_state = QLA_LED_ALL_ON; | ||
712 | *pflags = GPIO_LED_RGA_ON; | ||
713 | } | ||
714 | } else { | ||
715 | /* Flip green led only. */ | ||
716 | if (ha->beacon_color_state == QLA_LED_GRN_ON) { | ||
717 | /* Turn off. */ | ||
718 | ha->beacon_color_state = 0; | ||
719 | *pflags = GPIO_LED_GREEN_OFF_AMBER_OFF; | ||
720 | } else { | ||
721 | /* Turn on. */ | ||
722 | ha->beacon_color_state = QLA_LED_GRN_ON; | ||
723 | *pflags = GPIO_LED_GREEN_ON_AMBER_OFF; | ||
724 | } | ||
725 | } | ||
726 | } | ||
727 | |||
728 | void | ||
729 | qla2x00_beacon_blink(struct scsi_qla_host *ha) | ||
730 | { | ||
731 | uint16_t gpio_enable; | ||
732 | uint16_t gpio_data; | ||
733 | uint16_t led_color = 0; | ||
734 | unsigned long flags; | ||
735 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
736 | |||
737 | if (ha->pio_address) | ||
738 | reg = (struct device_reg_2xxx __iomem *)ha->pio_address; | ||
739 | |||
740 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
741 | |||
742 | /* Save the Original GPIOE. */ | ||
743 | if (ha->pio_address) { | ||
744 | gpio_enable = RD_REG_WORD_PIO(®->gpioe); | ||
745 | gpio_data = RD_REG_WORD_PIO(®->gpiod); | ||
746 | } else { | ||
747 | gpio_enable = RD_REG_WORD(®->gpioe); | ||
748 | gpio_data = RD_REG_WORD(®->gpiod); | ||
749 | } | ||
750 | |||
751 | /* Set the modified gpio_enable values */ | ||
752 | gpio_enable |= GPIO_LED_MASK; | ||
753 | |||
754 | if (ha->pio_address) { | ||
755 | WRT_REG_WORD_PIO(®->gpioe, gpio_enable); | ||
756 | } else { | ||
757 | WRT_REG_WORD(®->gpioe, gpio_enable); | ||
758 | RD_REG_WORD(®->gpioe); | ||
759 | } | ||
760 | |||
761 | qla2x00_flip_colors(ha, &led_color); | ||
762 | |||
763 | /* Clear out any previously set LED color. */ | ||
764 | gpio_data &= ~GPIO_LED_MASK; | ||
765 | |||
766 | /* Set the new input LED color to GPIOD. */ | ||
767 | gpio_data |= led_color; | ||
768 | |||
769 | /* Set the modified gpio_data values */ | ||
770 | if (ha->pio_address) { | ||
771 | WRT_REG_WORD_PIO(®->gpiod, gpio_data); | ||
772 | } else { | ||
773 | WRT_REG_WORD(®->gpiod, gpio_data); | ||
774 | RD_REG_WORD(®->gpiod); | ||
775 | } | ||
776 | |||
777 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
778 | } | ||
779 | |||
780 | int | ||
781 | qla2x00_beacon_on(struct scsi_qla_host *ha) | ||
782 | { | ||
783 | uint16_t gpio_enable; | ||
784 | uint16_t gpio_data; | ||
785 | unsigned long flags; | ||
786 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
787 | |||
788 | ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING; | ||
789 | ha->fw_options[1] |= FO1_DISABLE_GPIO6_7; | ||
790 | |||
791 | if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS) { | ||
792 | qla_printk(KERN_WARNING, ha, | ||
793 | "Unable to update fw options (beacon on).\n"); | ||
794 | return QLA_FUNCTION_FAILED; | ||
795 | } | ||
796 | |||
797 | if (ha->pio_address) | ||
798 | reg = (struct device_reg_2xxx __iomem *)ha->pio_address; | ||
799 | |||
800 | /* Turn off LEDs. */ | ||
801 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
802 | if (ha->pio_address) { | ||
803 | gpio_enable = RD_REG_WORD_PIO(®->gpioe); | ||
804 | gpio_data = RD_REG_WORD_PIO(®->gpiod); | ||
805 | } else { | ||
806 | gpio_enable = RD_REG_WORD(®->gpioe); | ||
807 | gpio_data = RD_REG_WORD(®->gpiod); | ||
808 | } | ||
809 | gpio_enable |= GPIO_LED_MASK; | ||
810 | |||
811 | /* Set the modified gpio_enable values. */ | ||
812 | if (ha->pio_address) { | ||
813 | WRT_REG_WORD_PIO(®->gpioe, gpio_enable); | ||
814 | } else { | ||
815 | WRT_REG_WORD(®->gpioe, gpio_enable); | ||
816 | RD_REG_WORD(®->gpioe); | ||
817 | } | ||
818 | |||
819 | /* Clear out previously set LED colour. */ | ||
820 | gpio_data &= ~GPIO_LED_MASK; | ||
821 | if (ha->pio_address) { | ||
822 | WRT_REG_WORD_PIO(®->gpiod, gpio_data); | ||
823 | } else { | ||
824 | WRT_REG_WORD(®->gpiod, gpio_data); | ||
825 | RD_REG_WORD(®->gpiod); | ||
826 | } | ||
827 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
828 | |||
829 | /* | ||
830 | * Let the per HBA timer kick off the blinking process based on | ||
831 | * the following flags. No need to do anything else now. | ||
832 | */ | ||
833 | ha->beacon_blink_led = 1; | ||
834 | ha->beacon_color_state = 0; | ||
835 | |||
836 | return QLA_SUCCESS; | ||
837 | } | ||
838 | |||
839 | int | ||
840 | qla2x00_beacon_off(struct scsi_qla_host *ha) | ||
841 | { | ||
842 | int rval = QLA_SUCCESS; | ||
843 | |||
844 | ha->beacon_blink_led = 0; | ||
845 | |||
846 | /* Set the on flag so when it gets flipped it will be off. */ | ||
847 | if (IS_QLA2322(ha)) | ||
848 | ha->beacon_color_state = QLA_LED_ALL_ON; | ||
849 | else | ||
850 | ha->beacon_color_state = QLA_LED_GRN_ON; | ||
851 | |||
852 | ha->isp_ops.beacon_blink(ha); /* This turns green LED off */ | ||
853 | |||
854 | ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING; | ||
855 | ha->fw_options[1] &= ~FO1_DISABLE_GPIO6_7; | ||
856 | |||
857 | rval = qla2x00_set_fw_options(ha, ha->fw_options); | ||
858 | if (rval != QLA_SUCCESS) | ||
859 | qla_printk(KERN_WARNING, ha, | ||
860 | "Unable to update fw options (beacon off).\n"); | ||
861 | return rval; | ||
862 | } | ||
863 | |||
864 | |||
865 | static inline void | ||
866 | qla24xx_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags) | ||
867 | { | ||
868 | /* Flip all colors. */ | ||
869 | if (ha->beacon_color_state == QLA_LED_ALL_ON) { | ||
870 | /* Turn off. */ | ||
871 | ha->beacon_color_state = 0; | ||
872 | *pflags = 0; | ||
873 | } else { | ||
874 | /* Turn on. */ | ||
875 | ha->beacon_color_state = QLA_LED_ALL_ON; | ||
876 | *pflags = GPDX_LED_YELLOW_ON | GPDX_LED_AMBER_ON; | ||
877 | } | ||
878 | } | ||
879 | |||
880 | void | ||
881 | qla24xx_beacon_blink(struct scsi_qla_host *ha) | ||
882 | { | ||
883 | uint16_t led_color = 0; | ||
884 | uint32_t gpio_data; | ||
885 | unsigned long flags; | ||
886 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
887 | |||
888 | /* Save the Original GPIOD. */ | ||
889 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
890 | gpio_data = RD_REG_DWORD(®->gpiod); | ||
891 | |||
892 | /* Enable the gpio_data reg for update. */ | ||
893 | gpio_data |= GPDX_LED_UPDATE_MASK; | ||
894 | |||
895 | WRT_REG_DWORD(®->gpiod, gpio_data); | ||
896 | gpio_data = RD_REG_DWORD(®->gpiod); | ||
897 | |||
898 | /* Set the color bits. */ | ||
899 | qla24xx_flip_colors(ha, &led_color); | ||
900 | |||
901 | /* Clear out any previously set LED color. */ | ||
902 | gpio_data &= ~GPDX_LED_COLOR_MASK; | ||
903 | |||
904 | /* Set the new input LED color to GPIOD. */ | ||
905 | gpio_data |= led_color; | ||
906 | |||
907 | /* Set the modified gpio_data values. */ | ||
908 | WRT_REG_DWORD(®->gpiod, gpio_data); | ||
909 | gpio_data = RD_REG_DWORD(®->gpiod); | ||
910 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
911 | } | ||
912 | |||
913 | int | ||
914 | qla24xx_beacon_on(struct scsi_qla_host *ha) | ||
915 | { | ||
916 | uint32_t gpio_data; | ||
917 | unsigned long flags; | ||
918 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
919 | |||
920 | if (ha->beacon_blink_led == 0) { | ||
921 | /* Enable firmware for update */ | ||
922 | ha->fw_options[1] |= ADD_FO1_DISABLE_GPIO_LED_CTRL; | ||
923 | |||
924 | if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS) | ||
925 | return QLA_FUNCTION_FAILED; | ||
926 | |||
927 | if (qla2x00_get_fw_options(ha, ha->fw_options) != | ||
928 | QLA_SUCCESS) { | ||
929 | qla_printk(KERN_WARNING, ha, | ||
930 | "Unable to update fw options (beacon on).\n"); | ||
931 | return QLA_FUNCTION_FAILED; | ||
932 | } | ||
933 | |||
934 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
935 | gpio_data = RD_REG_DWORD(®->gpiod); | ||
936 | |||
937 | /* Enable the gpio_data reg for update. */ | ||
938 | gpio_data |= GPDX_LED_UPDATE_MASK; | ||
939 | WRT_REG_DWORD(®->gpiod, gpio_data); | ||
940 | RD_REG_DWORD(®->gpiod); | ||
941 | |||
942 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
943 | } | ||
944 | |||
945 | /* So all colors blink together. */ | ||
946 | ha->beacon_color_state = 0; | ||
947 | |||
948 | /* Let the per HBA timer kick off the blinking process. */ | ||
949 | ha->beacon_blink_led = 1; | ||
950 | |||
951 | return QLA_SUCCESS; | ||
952 | } | ||
953 | |||
954 | int | ||
955 | qla24xx_beacon_off(struct scsi_qla_host *ha) | ||
956 | { | ||
957 | uint32_t gpio_data; | ||
958 | unsigned long flags; | ||
959 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
960 | |||
961 | ha->beacon_blink_led = 0; | ||
962 | ha->beacon_color_state = QLA_LED_ALL_ON; | ||
963 | |||
964 | ha->isp_ops.beacon_blink(ha); /* Will flip to all off. */ | ||
965 | |||
966 | /* Give control back to firmware. */ | ||
967 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
968 | gpio_data = RD_REG_DWORD(®->gpiod); | ||
969 | |||
970 | /* Disable the gpio_data reg for update. */ | ||
971 | gpio_data &= ~GPDX_LED_UPDATE_MASK; | ||
972 | WRT_REG_DWORD(®->gpiod, gpio_data); | ||
973 | RD_REG_DWORD(®->gpiod); | ||
974 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
975 | |||
976 | ha->fw_options[1] &= ~ADD_FO1_DISABLE_GPIO_LED_CTRL; | ||
977 | |||
978 | if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS) { | ||
979 | qla_printk(KERN_WARNING, ha, | ||
980 | "Unable to update fw options (beacon off).\n"); | ||
981 | return QLA_FUNCTION_FAILED; | ||
982 | } | ||
983 | |||
984 | if (qla2x00_get_fw_options(ha, ha->fw_options) != QLA_SUCCESS) { | ||
985 | qla_printk(KERN_WARNING, ha, | ||
986 | "Unable to get fw options (beacon off).\n"); | ||
987 | return QLA_FUNCTION_FAILED; | ||
988 | } | ||
989 | |||
990 | return QLA_SUCCESS; | ||
991 | } | ||
992 | |||
993 | |||
994 | /* | ||
995 | * Flash support routines | ||
996 | */ | ||
997 | |||
998 | /** | ||
999 | * qla2x00_flash_enable() - Setup flash for reading and writing. | ||
1000 | * @ha: HA context | ||
1001 | */ | ||
1002 | static void | ||
1003 | qla2x00_flash_enable(scsi_qla_host_t *ha) | ||
1004 | { | ||
1005 | uint16_t data; | ||
1006 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1007 | |||
1008 | data = RD_REG_WORD(®->ctrl_status); | ||
1009 | data |= CSR_FLASH_ENABLE; | ||
1010 | WRT_REG_WORD(®->ctrl_status, data); | ||
1011 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1012 | } | ||
1013 | |||
1014 | /** | ||
1015 | * qla2x00_flash_disable() - Disable flash and allow RISC to run. | ||
1016 | * @ha: HA context | ||
1017 | */ | ||
1018 | static void | ||
1019 | qla2x00_flash_disable(scsi_qla_host_t *ha) | ||
1020 | { | ||
1021 | uint16_t data; | ||
1022 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1023 | |||
1024 | data = RD_REG_WORD(®->ctrl_status); | ||
1025 | data &= ~(CSR_FLASH_ENABLE); | ||
1026 | WRT_REG_WORD(®->ctrl_status, data); | ||
1027 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1028 | } | ||
1029 | |||
1030 | /** | ||
1031 | * qla2x00_read_flash_byte() - Reads a byte from flash | ||
1032 | * @ha: HA context | ||
1033 | * @addr: Address in flash to read | ||
1034 | * | ||
1035 | * A word is read from the chip, but, only the lower byte is valid. | ||
1036 | * | ||
1037 | * Returns the byte read from flash @addr. | ||
1038 | */ | ||
1039 | static uint8_t | ||
1040 | qla2x00_read_flash_byte(scsi_qla_host_t *ha, uint32_t addr) | ||
1041 | { | ||
1042 | uint16_t data; | ||
1043 | uint16_t bank_select; | ||
1044 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1045 | |||
1046 | bank_select = RD_REG_WORD(®->ctrl_status); | ||
1047 | |||
1048 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) { | ||
1049 | /* Specify 64K address range: */ | ||
1050 | /* clear out Module Select and Flash Address bits [19:16]. */ | ||
1051 | bank_select &= ~0xf8; | ||
1052 | bank_select |= addr >> 12 & 0xf0; | ||
1053 | bank_select |= CSR_FLASH_64K_BANK; | ||
1054 | WRT_REG_WORD(®->ctrl_status, bank_select); | ||
1055 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1056 | |||
1057 | WRT_REG_WORD(®->flash_address, (uint16_t)addr); | ||
1058 | data = RD_REG_WORD(®->flash_data); | ||
1059 | |||
1060 | return (uint8_t)data; | ||
1061 | } | ||
1062 | |||
1063 | /* Setup bit 16 of flash address. */ | ||
1064 | if ((addr & BIT_16) && ((bank_select & CSR_FLASH_64K_BANK) == 0)) { | ||
1065 | bank_select |= CSR_FLASH_64K_BANK; | ||
1066 | WRT_REG_WORD(®->ctrl_status, bank_select); | ||
1067 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1068 | } else if (((addr & BIT_16) == 0) && | ||
1069 | (bank_select & CSR_FLASH_64K_BANK)) { | ||
1070 | bank_select &= ~(CSR_FLASH_64K_BANK); | ||
1071 | WRT_REG_WORD(®->ctrl_status, bank_select); | ||
1072 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1073 | } | ||
1074 | |||
1075 | /* Always perform IO mapped accesses to the FLASH registers. */ | ||
1076 | if (ha->pio_address) { | ||
1077 | uint16_t data2; | ||
1078 | |||
1079 | reg = (struct device_reg_2xxx __iomem *)ha->pio_address; | ||
1080 | WRT_REG_WORD_PIO(®->flash_address, (uint16_t)addr); | ||
1081 | do { | ||
1082 | data = RD_REG_WORD_PIO(®->flash_data); | ||
1083 | barrier(); | ||
1084 | cpu_relax(); | ||
1085 | data2 = RD_REG_WORD_PIO(®->flash_data); | ||
1086 | } while (data != data2); | ||
1087 | } else { | ||
1088 | WRT_REG_WORD(®->flash_address, (uint16_t)addr); | ||
1089 | data = qla2x00_debounce_register(®->flash_data); | ||
1090 | } | ||
1091 | |||
1092 | return (uint8_t)data; | ||
1093 | } | ||
1094 | |||
1095 | /** | ||
1096 | * qla2x00_write_flash_byte() - Write a byte to flash | ||
1097 | * @ha: HA context | ||
1098 | * @addr: Address in flash to write | ||
1099 | * @data: Data to write | ||
1100 | */ | ||
1101 | static void | ||
1102 | qla2x00_write_flash_byte(scsi_qla_host_t *ha, uint32_t addr, uint8_t data) | ||
1103 | { | ||
1104 | uint16_t bank_select; | ||
1105 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1106 | |||
1107 | bank_select = RD_REG_WORD(®->ctrl_status); | ||
1108 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) { | ||
1109 | /* Specify 64K address range: */ | ||
1110 | /* clear out Module Select and Flash Address bits [19:16]. */ | ||
1111 | bank_select &= ~0xf8; | ||
1112 | bank_select |= addr >> 12 & 0xf0; | ||
1113 | bank_select |= CSR_FLASH_64K_BANK; | ||
1114 | WRT_REG_WORD(®->ctrl_status, bank_select); | ||
1115 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1116 | |||
1117 | WRT_REG_WORD(®->flash_address, (uint16_t)addr); | ||
1118 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1119 | WRT_REG_WORD(®->flash_data, (uint16_t)data); | ||
1120 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1121 | |||
1122 | return; | ||
1123 | } | ||
1124 | |||
1125 | /* Setup bit 16 of flash address. */ | ||
1126 | if ((addr & BIT_16) && ((bank_select & CSR_FLASH_64K_BANK) == 0)) { | ||
1127 | bank_select |= CSR_FLASH_64K_BANK; | ||
1128 | WRT_REG_WORD(®->ctrl_status, bank_select); | ||
1129 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1130 | } else if (((addr & BIT_16) == 0) && | ||
1131 | (bank_select & CSR_FLASH_64K_BANK)) { | ||
1132 | bank_select &= ~(CSR_FLASH_64K_BANK); | ||
1133 | WRT_REG_WORD(®->ctrl_status, bank_select); | ||
1134 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1135 | } | ||
1136 | |||
1137 | /* Always perform IO mapped accesses to the FLASH registers. */ | ||
1138 | if (ha->pio_address) { | ||
1139 | reg = (struct device_reg_2xxx __iomem *)ha->pio_address; | ||
1140 | WRT_REG_WORD_PIO(®->flash_address, (uint16_t)addr); | ||
1141 | WRT_REG_WORD_PIO(®->flash_data, (uint16_t)data); | ||
1142 | } else { | ||
1143 | WRT_REG_WORD(®->flash_address, (uint16_t)addr); | ||
1144 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1145 | WRT_REG_WORD(®->flash_data, (uint16_t)data); | ||
1146 | RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | /** | ||
1151 | * qla2x00_poll_flash() - Polls flash for completion. | ||
1152 | * @ha: HA context | ||
1153 | * @addr: Address in flash to poll | ||
1154 | * @poll_data: Data to be polled | ||
1155 | * @man_id: Flash manufacturer ID | ||
1156 | * @flash_id: Flash ID | ||
1157 | * | ||
1158 | * This function polls the device until bit 7 of what is read matches data | ||
1159 | * bit 7 or until data bit 5 becomes a 1. If that hapens, the flash ROM timed | ||
1160 | * out (a fatal error). The flash book recommeds reading bit 7 again after | ||
1161 | * reading bit 5 as a 1. | ||
1162 | * | ||
1163 | * Returns 0 on success, else non-zero. | ||
1164 | */ | ||
1165 | static int | ||
1166 | qla2x00_poll_flash(scsi_qla_host_t *ha, uint32_t addr, uint8_t poll_data, | ||
1167 | uint8_t man_id, uint8_t flash_id) | ||
1168 | { | ||
1169 | int status; | ||
1170 | uint8_t flash_data; | ||
1171 | uint32_t cnt; | ||
1172 | |||
1173 | status = 1; | ||
1174 | |||
1175 | /* Wait for 30 seconds for command to finish. */ | ||
1176 | poll_data &= BIT_7; | ||
1177 | for (cnt = 3000000; cnt; cnt--) { | ||
1178 | flash_data = qla2x00_read_flash_byte(ha, addr); | ||
1179 | if ((flash_data & BIT_7) == poll_data) { | ||
1180 | status = 0; | ||
1181 | break; | ||
1182 | } | ||
1183 | |||
1184 | if (man_id != 0x40 && man_id != 0xda) { | ||
1185 | if ((flash_data & BIT_5) && cnt > 2) | ||
1186 | cnt = 2; | ||
1187 | } | ||
1188 | udelay(10); | ||
1189 | barrier(); | ||
1190 | } | ||
1191 | return status; | ||
1192 | } | ||
1193 | |||
1194 | #define IS_OEM_001(ha) \ | ||
1195 | ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322 && \ | ||
1196 | (ha)->pdev->subsystem_vendor == 0x1028 && \ | ||
1197 | (ha)->pdev->subsystem_device == 0x0170) | ||
1198 | |||
1199 | /** | ||
1200 | * qla2x00_program_flash_address() - Programs a flash address | ||
1201 | * @ha: HA context | ||
1202 | * @addr: Address in flash to program | ||
1203 | * @data: Data to be written in flash | ||
1204 | * @man_id: Flash manufacturer ID | ||
1205 | * @flash_id: Flash ID | ||
1206 | * | ||
1207 | * Returns 0 on success, else non-zero. | ||
1208 | */ | ||
1209 | static int | ||
1210 | qla2x00_program_flash_address(scsi_qla_host_t *ha, uint32_t addr, uint8_t data, | ||
1211 | uint8_t man_id, uint8_t flash_id) | ||
1212 | { | ||
1213 | /* Write Program Command Sequence. */ | ||
1214 | if (IS_OEM_001(ha)) { | ||
1215 | qla2x00_write_flash_byte(ha, 0xaaa, 0xaa); | ||
1216 | qla2x00_write_flash_byte(ha, 0x555, 0x55); | ||
1217 | qla2x00_write_flash_byte(ha, 0xaaa, 0xa0); | ||
1218 | qla2x00_write_flash_byte(ha, addr, data); | ||
1219 | } else { | ||
1220 | if (man_id == 0xda && flash_id == 0xc1) { | ||
1221 | qla2x00_write_flash_byte(ha, addr, data); | ||
1222 | if (addr & 0x7e) | ||
1223 | return 0; | ||
1224 | } else { | ||
1225 | qla2x00_write_flash_byte(ha, 0x5555, 0xaa); | ||
1226 | qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); | ||
1227 | qla2x00_write_flash_byte(ha, 0x5555, 0xa0); | ||
1228 | qla2x00_write_flash_byte(ha, addr, data); | ||
1229 | } | ||
1230 | } | ||
1231 | |||
1232 | udelay(150); | ||
1233 | |||
1234 | /* Wait for write to complete. */ | ||
1235 | return qla2x00_poll_flash(ha, addr, data, man_id, flash_id); | ||
1236 | } | ||
1237 | |||
1238 | /** | ||
1239 | * qla2x00_erase_flash() - Erase the flash. | ||
1240 | * @ha: HA context | ||
1241 | * @man_id: Flash manufacturer ID | ||
1242 | * @flash_id: Flash ID | ||
1243 | * | ||
1244 | * Returns 0 on success, else non-zero. | ||
1245 | */ | ||
1246 | static int | ||
1247 | qla2x00_erase_flash(scsi_qla_host_t *ha, uint8_t man_id, uint8_t flash_id) | ||
1248 | { | ||
1249 | /* Individual Sector Erase Command Sequence */ | ||
1250 | if (IS_OEM_001(ha)) { | ||
1251 | qla2x00_write_flash_byte(ha, 0xaaa, 0xaa); | ||
1252 | qla2x00_write_flash_byte(ha, 0x555, 0x55); | ||
1253 | qla2x00_write_flash_byte(ha, 0xaaa, 0x80); | ||
1254 | qla2x00_write_flash_byte(ha, 0xaaa, 0xaa); | ||
1255 | qla2x00_write_flash_byte(ha, 0x555, 0x55); | ||
1256 | qla2x00_write_flash_byte(ha, 0xaaa, 0x10); | ||
1257 | } else { | ||
1258 | qla2x00_write_flash_byte(ha, 0x5555, 0xaa); | ||
1259 | qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); | ||
1260 | qla2x00_write_flash_byte(ha, 0x5555, 0x80); | ||
1261 | qla2x00_write_flash_byte(ha, 0x5555, 0xaa); | ||
1262 | qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); | ||
1263 | qla2x00_write_flash_byte(ha, 0x5555, 0x10); | ||
1264 | } | ||
1265 | |||
1266 | udelay(150); | ||
1267 | |||
1268 | /* Wait for erase to complete. */ | ||
1269 | return qla2x00_poll_flash(ha, 0x00, 0x80, man_id, flash_id); | ||
1270 | } | ||
1271 | |||
1272 | /** | ||
1273 | * qla2x00_erase_flash_sector() - Erase a flash sector. | ||
1274 | * @ha: HA context | ||
1275 | * @addr: Flash sector to erase | ||
1276 | * @sec_mask: Sector address mask | ||
1277 | * @man_id: Flash manufacturer ID | ||
1278 | * @flash_id: Flash ID | ||
1279 | * | ||
1280 | * Returns 0 on success, else non-zero. | ||
1281 | */ | ||
1282 | static int | ||
1283 | qla2x00_erase_flash_sector(scsi_qla_host_t *ha, uint32_t addr, | ||
1284 | uint32_t sec_mask, uint8_t man_id, uint8_t flash_id) | ||
1285 | { | ||
1286 | /* Individual Sector Erase Command Sequence */ | ||
1287 | qla2x00_write_flash_byte(ha, 0x5555, 0xaa); | ||
1288 | qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); | ||
1289 | qla2x00_write_flash_byte(ha, 0x5555, 0x80); | ||
1290 | qla2x00_write_flash_byte(ha, 0x5555, 0xaa); | ||
1291 | qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); | ||
1292 | if (man_id == 0x1f && flash_id == 0x13) | ||
1293 | qla2x00_write_flash_byte(ha, addr & sec_mask, 0x10); | ||
1294 | else | ||
1295 | qla2x00_write_flash_byte(ha, addr & sec_mask, 0x30); | ||
1296 | |||
1297 | udelay(150); | ||
1298 | |||
1299 | /* Wait for erase to complete. */ | ||
1300 | return qla2x00_poll_flash(ha, addr, 0x80, man_id, flash_id); | ||
1301 | } | ||
1302 | |||
1303 | /** | ||
1304 | * qla2x00_get_flash_manufacturer() - Read manufacturer ID from flash chip. | ||
1305 | * @man_id: Flash manufacturer ID | ||
1306 | * @flash_id: Flash ID | ||
1307 | */ | ||
1308 | static void | ||
1309 | qla2x00_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, | ||
1310 | uint8_t *flash_id) | ||
1311 | { | ||
1312 | qla2x00_write_flash_byte(ha, 0x5555, 0xaa); | ||
1313 | qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); | ||
1314 | qla2x00_write_flash_byte(ha, 0x5555, 0x90); | ||
1315 | *man_id = qla2x00_read_flash_byte(ha, 0x0000); | ||
1316 | *flash_id = qla2x00_read_flash_byte(ha, 0x0001); | ||
1317 | qla2x00_write_flash_byte(ha, 0x5555, 0xaa); | ||
1318 | qla2x00_write_flash_byte(ha, 0x2aaa, 0x55); | ||
1319 | qla2x00_write_flash_byte(ha, 0x5555, 0xf0); | ||
1320 | } | ||
1321 | |||
1322 | |||
1323 | static inline void | ||
1324 | qla2x00_suspend_hba(struct scsi_qla_host *ha) | ||
1325 | { | ||
1326 | int cnt; | ||
1327 | unsigned long flags; | ||
1328 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1329 | |||
1330 | /* Suspend HBA. */ | ||
1331 | scsi_block_requests(ha->host); | ||
1332 | ha->isp_ops.disable_intrs(ha); | ||
1333 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | ||
1334 | |||
1335 | /* Pause RISC. */ | ||
1336 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1337 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); | ||
1338 | RD_REG_WORD(®->hccr); | ||
1339 | if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) { | ||
1340 | for (cnt = 0; cnt < 30000; cnt++) { | ||
1341 | if ((RD_REG_WORD(®->hccr) & HCCR_RISC_PAUSE) != 0) | ||
1342 | break; | ||
1343 | udelay(100); | ||
1344 | } | ||
1345 | } else { | ||
1346 | udelay(10); | ||
1347 | } | ||
1348 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1349 | } | ||
1350 | |||
1351 | static inline void | ||
1352 | qla2x00_resume_hba(struct scsi_qla_host *ha) | ||
1353 | { | ||
1354 | /* Resume HBA. */ | ||
1355 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | ||
1356 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1357 | up(ha->dpc_wait); | ||
1358 | qla2x00_wait_for_hba_online(ha); | ||
1359 | scsi_unblock_requests(ha->host); | ||
1360 | } | ||
1361 | |||
1362 | uint8_t * | ||
1363 | qla2x00_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | ||
1364 | uint32_t offset, uint32_t length) | ||
1365 | { | ||
1366 | unsigned long flags; | ||
1367 | uint32_t addr, midpoint; | ||
1368 | uint8_t *data; | ||
1369 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1370 | |||
1371 | /* Suspend HBA. */ | ||
1372 | qla2x00_suspend_hba(ha); | ||
1373 | |||
1374 | /* Go with read. */ | ||
1375 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1376 | midpoint = ha->optrom_size / 2; | ||
1377 | |||
1378 | qla2x00_flash_enable(ha); | ||
1379 | WRT_REG_WORD(®->nvram, 0); | ||
1380 | RD_REG_WORD(®->nvram); /* PCI Posting. */ | ||
1381 | for (addr = offset, data = buf; addr < length; addr++, data++) { | ||
1382 | if (addr == midpoint) { | ||
1383 | WRT_REG_WORD(®->nvram, NVR_SELECT); | ||
1384 | RD_REG_WORD(®->nvram); /* PCI Posting. */ | ||
1385 | } | ||
1386 | |||
1387 | *data = qla2x00_read_flash_byte(ha, addr); | ||
1388 | } | ||
1389 | qla2x00_flash_disable(ha); | ||
1390 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1391 | |||
1392 | /* Resume HBA. */ | ||
1393 | qla2x00_resume_hba(ha); | ||
1394 | |||
1395 | return buf; | ||
1396 | } | ||
1397 | |||
1398 | int | ||
1399 | qla2x00_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | ||
1400 | uint32_t offset, uint32_t length) | ||
1401 | { | ||
1402 | |||
1403 | int rval; | ||
1404 | unsigned long flags; | ||
1405 | uint8_t man_id, flash_id, sec_number, data; | ||
1406 | uint16_t wd; | ||
1407 | uint32_t addr, liter, sec_mask, rest_addr; | ||
1408 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1409 | |||
1410 | /* Suspend HBA. */ | ||
1411 | qla2x00_suspend_hba(ha); | ||
1412 | |||
1413 | rval = QLA_SUCCESS; | ||
1414 | sec_number = 0; | ||
1415 | |||
1416 | /* Reset ISP chip. */ | ||
1417 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1418 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | ||
1419 | pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); | ||
1420 | |||
1421 | /* Go with write. */ | ||
1422 | qla2x00_flash_enable(ha); | ||
1423 | do { /* Loop once to provide quick error exit */ | ||
1424 | /* Structure of flash memory based on manufacturer */ | ||
1425 | if (IS_OEM_001(ha)) { | ||
1426 | /* OEM variant with special flash part. */ | ||
1427 | man_id = flash_id = 0; | ||
1428 | rest_addr = 0xffff; | ||
1429 | sec_mask = 0x10000; | ||
1430 | goto update_flash; | ||
1431 | } | ||
1432 | qla2x00_get_flash_manufacturer(ha, &man_id, &flash_id); | ||
1433 | switch (man_id) { | ||
1434 | case 0x20: /* ST flash. */ | ||
1435 | if (flash_id == 0xd2 || flash_id == 0xe3) { | ||
1436 | /* | ||
1437 | * ST m29w008at part - 64kb sector size with | ||
1438 | * 32kb,8kb,8kb,16kb sectors at memory address | ||
1439 | * 0xf0000. | ||
1440 | */ | ||
1441 | rest_addr = 0xffff; | ||
1442 | sec_mask = 0x10000; | ||
1443 | break; | ||
1444 | } | ||
1445 | /* | ||
1446 | * ST m29w010b part - 16kb sector size | ||
1447 | * Default to 16kb sectors | ||
1448 | */ | ||
1449 | rest_addr = 0x3fff; | ||
1450 | sec_mask = 0x1c000; | ||
1451 | break; | ||
1452 | case 0x40: /* Mostel flash. */ | ||
1453 | /* Mostel v29c51001 part - 512 byte sector size. */ | ||
1454 | rest_addr = 0x1ff; | ||
1455 | sec_mask = 0x1fe00; | ||
1456 | break; | ||
1457 | case 0xbf: /* SST flash. */ | ||
1458 | /* SST39sf10 part - 4kb sector size. */ | ||
1459 | rest_addr = 0xfff; | ||
1460 | sec_mask = 0x1f000; | ||
1461 | break; | ||
1462 | case 0xda: /* Winbond flash. */ | ||
1463 | /* Winbond W29EE011 part - 256 byte sector size. */ | ||
1464 | rest_addr = 0x7f; | ||
1465 | sec_mask = 0x1ff80; | ||
1466 | break; | ||
1467 | case 0xc2: /* Macronix flash. */ | ||
1468 | /* 64k sector size. */ | ||
1469 | if (flash_id == 0x38 || flash_id == 0x4f) { | ||
1470 | rest_addr = 0xffff; | ||
1471 | sec_mask = 0x10000; | ||
1472 | break; | ||
1473 | } | ||
1474 | /* Fall through... */ | ||
1475 | |||
1476 | case 0x1f: /* Atmel flash. */ | ||
1477 | /* 512k sector size. */ | ||
1478 | if (flash_id == 0x13) { | ||
1479 | rest_addr = 0x7fffffff; | ||
1480 | sec_mask = 0x80000000; | ||
1481 | break; | ||
1482 | } | ||
1483 | /* Fall through... */ | ||
1484 | |||
1485 | case 0x01: /* AMD flash. */ | ||
1486 | if (flash_id == 0x38 || flash_id == 0x40 || | ||
1487 | flash_id == 0x4f) { | ||
1488 | /* Am29LV081 part - 64kb sector size. */ | ||
1489 | /* Am29LV002BT part - 64kb sector size. */ | ||
1490 | rest_addr = 0xffff; | ||
1491 | sec_mask = 0x10000; | ||
1492 | break; | ||
1493 | } else if (flash_id == 0x3e) { | ||
1494 | /* | ||
1495 | * Am29LV008b part - 64kb sector size with | ||
1496 | * 32kb,8kb,8kb,16kb sector at memory address | ||
1497 | * h0xf0000. | ||
1498 | */ | ||
1499 | rest_addr = 0xffff; | ||
1500 | sec_mask = 0x10000; | ||
1501 | break; | ||
1502 | } else if (flash_id == 0x20 || flash_id == 0x6e) { | ||
1503 | /* | ||
1504 | * Am29LV010 part or AM29f010 - 16kb sector | ||
1505 | * size. | ||
1506 | */ | ||
1507 | rest_addr = 0x3fff; | ||
1508 | sec_mask = 0x1c000; | ||
1509 | break; | ||
1510 | } else if (flash_id == 0x6d) { | ||
1511 | /* Am29LV001 part - 8kb sector size. */ | ||
1512 | rest_addr = 0x1fff; | ||
1513 | sec_mask = 0x1e000; | ||
1514 | break; | ||
1515 | } | ||
1516 | default: | ||
1517 | /* Default to 16 kb sector size. */ | ||
1518 | rest_addr = 0x3fff; | ||
1519 | sec_mask = 0x1c000; | ||
1520 | break; | ||
1521 | } | ||
1522 | |||
1523 | update_flash: | ||
1524 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) { | ||
1525 | if (qla2x00_erase_flash(ha, man_id, flash_id)) { | ||
1526 | rval = QLA_FUNCTION_FAILED; | ||
1527 | break; | ||
1528 | } | ||
1529 | } | ||
1530 | |||
1531 | for (addr = offset, liter = 0; liter < length; liter++, | ||
1532 | addr++) { | ||
1533 | data = buf[liter]; | ||
1534 | /* Are we at the beginning of a sector? */ | ||
1535 | if ((addr & rest_addr) == 0) { | ||
1536 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) { | ||
1537 | if (addr >= 0x10000UL) { | ||
1538 | if (((addr >> 12) & 0xf0) && | ||
1539 | ((man_id == 0x01 && | ||
1540 | flash_id == 0x3e) || | ||
1541 | (man_id == 0x20 && | ||
1542 | flash_id == 0xd2))) { | ||
1543 | sec_number++; | ||
1544 | if (sec_number == 1) { | ||
1545 | rest_addr = | ||
1546 | 0x7fff; | ||
1547 | sec_mask = | ||
1548 | 0x18000; | ||
1549 | } else if ( | ||
1550 | sec_number == 2 || | ||
1551 | sec_number == 3) { | ||
1552 | rest_addr = | ||
1553 | 0x1fff; | ||
1554 | sec_mask = | ||
1555 | 0x1e000; | ||
1556 | } else if ( | ||
1557 | sec_number == 4) { | ||
1558 | rest_addr = | ||
1559 | 0x3fff; | ||
1560 | sec_mask = | ||
1561 | 0x1c000; | ||
1562 | } | ||
1563 | } | ||
1564 | } | ||
1565 | } else if (addr == ha->optrom_size / 2) { | ||
1566 | WRT_REG_WORD(®->nvram, NVR_SELECT); | ||
1567 | RD_REG_WORD(®->nvram); | ||
1568 | } | ||
1569 | |||
1570 | if (flash_id == 0xda && man_id == 0xc1) { | ||
1571 | qla2x00_write_flash_byte(ha, 0x5555, | ||
1572 | 0xaa); | ||
1573 | qla2x00_write_flash_byte(ha, 0x2aaa, | ||
1574 | 0x55); | ||
1575 | qla2x00_write_flash_byte(ha, 0x5555, | ||
1576 | 0xa0); | ||
1577 | } else if (!IS_QLA2322(ha) && !IS_QLA6322(ha)) { | ||
1578 | /* Then erase it */ | ||
1579 | if (qla2x00_erase_flash_sector(ha, | ||
1580 | addr, sec_mask, man_id, | ||
1581 | flash_id)) { | ||
1582 | rval = QLA_FUNCTION_FAILED; | ||
1583 | break; | ||
1584 | } | ||
1585 | if (man_id == 0x01 && flash_id == 0x6d) | ||
1586 | sec_number++; | ||
1587 | } | ||
1588 | } | ||
1589 | |||
1590 | if (man_id == 0x01 && flash_id == 0x6d) { | ||
1591 | if (sec_number == 1 && | ||
1592 | addr == (rest_addr - 1)) { | ||
1593 | rest_addr = 0x0fff; | ||
1594 | sec_mask = 0x1f000; | ||
1595 | } else if (sec_number == 3 && (addr & 0x7ffe)) { | ||
1596 | rest_addr = 0x3fff; | ||
1597 | sec_mask = 0x1c000; | ||
1598 | } | ||
1599 | } | ||
1600 | |||
1601 | if (qla2x00_program_flash_address(ha, addr, data, | ||
1602 | man_id, flash_id)) { | ||
1603 | rval = QLA_FUNCTION_FAILED; | ||
1604 | break; | ||
1605 | } | ||
1606 | } | ||
1607 | } while (0); | ||
1608 | qla2x00_flash_disable(ha); | ||
1609 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1610 | |||
1611 | /* Resume HBA. */ | ||
1612 | qla2x00_resume_hba(ha); | ||
1613 | |||
1614 | return rval; | ||
1615 | } | ||
1616 | |||
1617 | uint8_t * | ||
1618 | qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | ||
1619 | uint32_t offset, uint32_t length) | ||
1620 | { | ||
1621 | /* Suspend HBA. */ | ||
1622 | scsi_block_requests(ha->host); | ||
1623 | ha->isp_ops.disable_intrs(ha); | ||
1624 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | ||
1625 | |||
1626 | /* Go with read. */ | ||
1627 | qla24xx_read_flash_data(ha, (uint32_t *)buf, offset >> 2, length >> 2); | ||
1628 | |||
1629 | /* Resume HBA. */ | ||
1630 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | ||
1631 | ha->isp_ops.enable_intrs(ha); | ||
1632 | scsi_unblock_requests(ha->host); | ||
1633 | |||
1634 | return buf; | ||
1635 | } | ||
1636 | |||
1637 | int | ||
1638 | qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | ||
1639 | uint32_t offset, uint32_t length) | ||
1640 | { | ||
1641 | int rval; | ||
1642 | |||
1643 | /* Suspend HBA. */ | ||
1644 | scsi_block_requests(ha->host); | ||
1645 | ha->isp_ops.disable_intrs(ha); | ||
1646 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | ||
1647 | |||
1648 | /* Go with write. */ | ||
1649 | rval = qla24xx_write_flash_data(ha, (uint32_t *)buf, offset >> 2, | ||
1650 | length >> 2); | ||
1651 | |||
1652 | /* Resume HBA -- RISC reset needed. */ | ||
1653 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | ||
1654 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1655 | up(ha->dpc_wait); | ||
1656 | qla2x00_wait_for_hba_online(ha); | ||
1657 | scsi_unblock_requests(ha->host); | ||
1658 | |||
1659 | return rval; | ||
1660 | } | ||
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index cd54244058b5..2770005324b4 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -510,6 +510,12 @@ static const struct mv_hw_ops mv6xxx_ops = { | |||
510 | }; | 510 | }; |
511 | 511 | ||
512 | /* | 512 | /* |
513 | * module options | ||
514 | */ | ||
515 | static int msi; /* Use PCI msi; either zero (off, default) or non-zero */ | ||
516 | |||
517 | |||
518 | /* | ||
513 | * Functions | 519 | * Functions |
514 | */ | 520 | */ |
515 | 521 | ||
@@ -991,6 +997,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
991 | case ATA_CMD_READ_EXT: | 997 | case ATA_CMD_READ_EXT: |
992 | case ATA_CMD_WRITE: | 998 | case ATA_CMD_WRITE: |
993 | case ATA_CMD_WRITE_EXT: | 999 | case ATA_CMD_WRITE_EXT: |
1000 | case ATA_CMD_WRITE_FUA_EXT: | ||
994 | mv_crqb_pack_cmd(cw++, tf->hob_nsect, ATA_REG_NSECT, 0); | 1001 | mv_crqb_pack_cmd(cw++, tf->hob_nsect, ATA_REG_NSECT, 0); |
995 | break; | 1002 | break; |
996 | #ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */ | 1003 | #ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */ |
@@ -2191,7 +2198,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2191 | } | 2198 | } |
2192 | 2199 | ||
2193 | /* Enable interrupts */ | 2200 | /* Enable interrupts */ |
2194 | if (pci_enable_msi(pdev) == 0) { | 2201 | if (msi && pci_enable_msi(pdev) == 0) { |
2195 | hpriv->hp_flags |= MV_HP_FLAG_MSI; | 2202 | hpriv->hp_flags |= MV_HP_FLAG_MSI; |
2196 | } else { | 2203 | } else { |
2197 | pci_intx(pdev, 1); | 2204 | pci_intx(pdev, 1); |
@@ -2246,5 +2253,8 @@ MODULE_LICENSE("GPL"); | |||
2246 | MODULE_DEVICE_TABLE(pci, mv_pci_tbl); | 2253 | MODULE_DEVICE_TABLE(pci, mv_pci_tbl); |
2247 | MODULE_VERSION(DRV_VERSION); | 2254 | MODULE_VERSION(DRV_VERSION); |
2248 | 2255 | ||
2256 | module_param(msi, int, 0444); | ||
2257 | MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)"); | ||
2258 | |||
2249 | module_init(mv_init); | 2259 | module_init(mv_init); |
2250 | module_exit(mv_exit); | 2260 | module_exit(mv_exit); |
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index de05e2883f9c..80480f0fb2b8 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
@@ -277,7 +277,7 @@ static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) | |||
277 | u8 *prd = pp->pkt + QS_CPB_BYTES; | 277 | u8 *prd = pp->pkt + QS_CPB_BYTES; |
278 | 278 | ||
279 | assert(qc->__sg != NULL); | 279 | assert(qc->__sg != NULL); |
280 | assert(qc->n_elem > 0); | 280 | assert(qc->n_elem > 0 || qc->pad_len > 0); |
281 | 281 | ||
282 | nelem = 0; | 282 | nelem = 0; |
283 | ata_for_each_sg(sg, qc) { | 283 | ata_for_each_sg(sg, qc) { |
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index b017f85e6d6a..9face3c6aa21 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -49,11 +49,13 @@ | |||
49 | #define DRV_VERSION "0.9" | 49 | #define DRV_VERSION "0.9" |
50 | 50 | ||
51 | enum { | 51 | enum { |
52 | SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), | ||
52 | SIL_FLAG_MOD15WRITE = (1 << 30), | 53 | SIL_FLAG_MOD15WRITE = (1 << 30), |
53 | 54 | ||
54 | sil_3112 = 0, | 55 | sil_3112 = 0, |
55 | sil_3112_m15w = 1, | 56 | sil_3112_m15w = 1, |
56 | sil_3114 = 2, | 57 | sil_3512 = 2, |
58 | sil_3114 = 3, | ||
57 | 59 | ||
58 | SIL_FIFO_R0 = 0x40, | 60 | SIL_FIFO_R0 = 0x40, |
59 | SIL_FIFO_W0 = 0x41, | 61 | SIL_FIFO_W0 = 0x41, |
@@ -90,7 +92,7 @@ static void sil_post_set_mode (struct ata_port *ap); | |||
90 | static const struct pci_device_id sil_pci_tbl[] = { | 92 | static const struct pci_device_id sil_pci_tbl[] = { |
91 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, | 93 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
92 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, | 94 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
93 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 95 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 }, |
94 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, | 96 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, |
95 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, | 97 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
96 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, | 98 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
@@ -185,7 +187,8 @@ static const struct ata_port_info sil_port_info[] = { | |||
185 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 187 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
186 | .udma_mask = 0x3f, /* udma0-5 */ | 188 | .udma_mask = 0x3f, /* udma0-5 */ |
187 | .port_ops = &sil_ops, | 189 | .port_ops = &sil_ops, |
188 | }, /* sil_3112_15w - keep it sync'd w/ sil_3112 */ | 190 | }, |
191 | /* sil_3112_15w - keep it sync'd w/ sil_3112 */ | ||
189 | { | 192 | { |
190 | .sht = &sil_sht, | 193 | .sht = &sil_sht, |
191 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 194 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
@@ -195,11 +198,24 @@ static const struct ata_port_info sil_port_info[] = { | |||
195 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 198 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
196 | .udma_mask = 0x3f, /* udma0-5 */ | 199 | .udma_mask = 0x3f, /* udma0-5 */ |
197 | .port_ops = &sil_ops, | 200 | .port_ops = &sil_ops, |
198 | }, /* sil_3114 */ | 201 | }, |
202 | /* sil_3512 */ | ||
199 | { | 203 | { |
200 | .sht = &sil_sht, | 204 | .sht = &sil_sht, |
201 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 205 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
202 | ATA_FLAG_SRST | ATA_FLAG_MMIO, | 206 | ATA_FLAG_SRST | ATA_FLAG_MMIO | |
207 | SIL_FLAG_RERR_ON_DMA_ACT, | ||
208 | .pio_mask = 0x1f, /* pio0-4 */ | ||
209 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
210 | .udma_mask = 0x3f, /* udma0-5 */ | ||
211 | .port_ops = &sil_ops, | ||
212 | }, | ||
213 | /* sil_3114 */ | ||
214 | { | ||
215 | .sht = &sil_sht, | ||
216 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
217 | ATA_FLAG_SRST | ATA_FLAG_MMIO | | ||
218 | SIL_FLAG_RERR_ON_DMA_ACT, | ||
203 | .pio_mask = 0x1f, /* pio0-4 */ | 219 | .pio_mask = 0x1f, /* pio0-4 */ |
204 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 220 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
205 | .udma_mask = 0x3f, /* udma0-5 */ | 221 | .udma_mask = 0x3f, /* udma0-5 */ |
@@ -216,12 +232,13 @@ static const struct { | |||
216 | unsigned long scr; /* SATA control register block */ | 232 | unsigned long scr; /* SATA control register block */ |
217 | unsigned long sien; /* SATA Interrupt Enable register */ | 233 | unsigned long sien; /* SATA Interrupt Enable register */ |
218 | unsigned long xfer_mode;/* data transfer mode register */ | 234 | unsigned long xfer_mode;/* data transfer mode register */ |
235 | unsigned long sfis_cfg; /* SATA FIS reception config register */ | ||
219 | } sil_port[] = { | 236 | } sil_port[] = { |
220 | /* port 0 ... */ | 237 | /* port 0 ... */ |
221 | { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4 }, | 238 | { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4, 0x14c }, |
222 | { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4 }, | 239 | { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4, 0x1cc }, |
223 | { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4 }, | 240 | { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4, 0x34c }, |
224 | { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4 }, | 241 | { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4, 0x3cc }, |
225 | /* ... port 3 */ | 242 | /* ... port 3 */ |
226 | }; | 243 | }; |
227 | 244 | ||
@@ -231,6 +248,10 @@ MODULE_LICENSE("GPL"); | |||
231 | MODULE_DEVICE_TABLE(pci, sil_pci_tbl); | 248 | MODULE_DEVICE_TABLE(pci, sil_pci_tbl); |
232 | MODULE_VERSION(DRV_VERSION); | 249 | MODULE_VERSION(DRV_VERSION); |
233 | 250 | ||
251 | static int slow_down = 0; | ||
252 | module_param(slow_down, int, 0444); | ||
253 | MODULE_PARM_DESC(slow_down, "Sledgehammer used to work around random problems, by limiting commands to 15 sectors (0=off, 1=on)"); | ||
254 | |||
234 | 255 | ||
235 | static unsigned char sil_get_device_cache_line(struct pci_dev *pdev) | 256 | static unsigned char sil_get_device_cache_line(struct pci_dev *pdev) |
236 | { | 257 | { |
@@ -354,8 +375,10 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) | |||
354 | } | 375 | } |
355 | 376 | ||
356 | /* limit requests to 15 sectors */ | 377 | /* limit requests to 15 sectors */ |
357 | if ((ap->flags & SIL_FLAG_MOD15WRITE) && (quirks & SIL_QUIRK_MOD15WRITE)) { | 378 | if (slow_down || |
358 | printk(KERN_INFO "ata%u(%u): applying Seagate errata fix\n", | 379 | ((ap->flags & SIL_FLAG_MOD15WRITE) && |
380 | (quirks & SIL_QUIRK_MOD15WRITE))) { | ||
381 | printk(KERN_INFO "ata%u(%u): applying Seagate errata fix (mod15write workaround)\n", | ||
359 | ap->id, dev->devno); | 382 | ap->id, dev->devno); |
360 | ap->host->max_sectors = 15; | 383 | ap->host->max_sectors = 15; |
361 | ap->host->hostt->max_sectors = 15; | 384 | ap->host->hostt->max_sectors = 15; |
@@ -465,6 +488,23 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
465 | dev_printk(KERN_WARNING, &pdev->dev, | 488 | dev_printk(KERN_WARNING, &pdev->dev, |
466 | "cache line size not set. Driver may not function\n"); | 489 | "cache line size not set. Driver may not function\n"); |
467 | 490 | ||
491 | /* Apply R_ERR on DMA activate FIS errata workaround */ | ||
492 | if (probe_ent->host_flags & SIL_FLAG_RERR_ON_DMA_ACT) { | ||
493 | int cnt; | ||
494 | |||
495 | for (i = 0, cnt = 0; i < probe_ent->n_ports; i++) { | ||
496 | tmp = readl(mmio_base + sil_port[i].sfis_cfg); | ||
497 | if ((tmp & 0x3) != 0x01) | ||
498 | continue; | ||
499 | if (!cnt) | ||
500 | dev_printk(KERN_INFO, &pdev->dev, | ||
501 | "Applying R_ERR on DMA activate " | ||
502 | "FIS errata fix\n"); | ||
503 | writel(tmp & ~0x3, mmio_base + sil_port[i].sfis_cfg); | ||
504 | cnt++; | ||
505 | } | ||
506 | } | ||
507 | |||
468 | if (ent->driver_data == sil_3114) { | 508 | if (ent->driver_data == sil_3114) { |
469 | irq_mask = SIL_MASK_4PORT; | 509 | irq_mask = SIL_MASK_4PORT; |
470 | 510 | ||
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 2e2c3b7acb0c..e484e8db6810 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
@@ -81,6 +81,19 @@ | |||
81 | /* Port stride */ | 81 | /* Port stride */ |
82 | #define VSC_SATA_PORT_OFFSET 0x200 | 82 | #define VSC_SATA_PORT_OFFSET 0x200 |
83 | 83 | ||
84 | /* Error interrupt status bit offsets */ | ||
85 | #define VSC_SATA_INT_ERROR_E_OFFSET 2 | ||
86 | #define VSC_SATA_INT_ERROR_P_OFFSET 4 | ||
87 | #define VSC_SATA_INT_ERROR_T_OFFSET 5 | ||
88 | #define VSC_SATA_INT_ERROR_M_OFFSET 1 | ||
89 | #define is_vsc_sata_int_err(port_idx, int_status) \ | ||
90 | (int_status & ((1 << (VSC_SATA_INT_ERROR_E_OFFSET + (8 * port_idx))) | \ | ||
91 | (1 << (VSC_SATA_INT_ERROR_P_OFFSET + (8 * port_idx))) | \ | ||
92 | (1 << (VSC_SATA_INT_ERROR_T_OFFSET + (8 * port_idx))) | \ | ||
93 | (1 << (VSC_SATA_INT_ERROR_M_OFFSET + (8 * port_idx))) \ | ||
94 | )\ | ||
95 | ) | ||
96 | |||
84 | 97 | ||
85 | static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | 98 | static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) |
86 | { | 99 | { |
@@ -201,13 +214,28 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, | |||
201 | struct ata_port *ap; | 214 | struct ata_port *ap; |
202 | 215 | ||
203 | ap = host_set->ports[i]; | 216 | ap = host_set->ports[i]; |
217 | |||
218 | if (is_vsc_sata_int_err(i, int_status)) { | ||
219 | u32 err_status; | ||
220 | printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); | ||
221 | err_status = ap ? vsc_sata_scr_read(ap, SCR_ERROR) : 0; | ||
222 | vsc_sata_scr_write(ap, SCR_ERROR, err_status); | ||
223 | handled++; | ||
224 | } | ||
225 | |||
204 | if (ap && !(ap->flags & | 226 | if (ap && !(ap->flags & |
205 | (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { | 227 | (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { |
206 | struct ata_queued_cmd *qc; | 228 | struct ata_queued_cmd *qc; |
207 | 229 | ||
208 | qc = ata_qc_from_tag(ap, ap->active_tag); | 230 | qc = ata_qc_from_tag(ap, ap->active_tag); |
209 | if (qc && (!(qc->tf.ctl & ATA_NIEN))) | 231 | if (qc && (!(qc->tf.ctl & ATA_NIEN))) { |
210 | handled += ata_host_intr(ap, qc); | 232 | handled += ata_host_intr(ap, qc); |
233 | } else { | ||
234 | printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__); | ||
235 | ata_chk_status(ap); | ||
236 | handled++; | ||
237 | } | ||
238 | |||
211 | } | 239 | } |
212 | } | 240 | } |
213 | } | 241 | } |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 245ca99a641e..c551bb84dbfb 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -1245,7 +1245,7 @@ static int __init init_scsi(void) | |||
1245 | if (error) | 1245 | if (error) |
1246 | goto cleanup_sysctl; | 1246 | goto cleanup_sysctl; |
1247 | 1247 | ||
1248 | for (i = 0; i < NR_CPUS; i++) | 1248 | for_each_cpu(i) |
1249 | INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); | 1249 | INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); |
1250 | 1250 | ||
1251 | devfs_mk_dir("scsi"); | 1251 | devfs_mk_dir("scsi"); |
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index f01ec0a7c506..84c3937ae8fb 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
@@ -126,6 +126,7 @@ static struct { | |||
126 | {"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN}, | 126 | {"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN}, |
127 | {"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN}, | 127 | {"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN}, |
128 | {"BELKIN", "USB 2 HS-CF", "1.95", BLIST_FORCELUN | BLIST_INQUIRY_36}, | 128 | {"BELKIN", "USB 2 HS-CF", "1.95", BLIST_FORCELUN | BLIST_INQUIRY_36}, |
129 | {"BROWNIE", "1600U3P", NULL, BLIST_NOREPORTLUN}, | ||
129 | {"CANON", "IPUBJD", NULL, BLIST_SPARSELUN}, | 130 | {"CANON", "IPUBJD", NULL, BLIST_SPARSELUN}, |
130 | {"CBOX3", "USB Storage-SMC", "300A", BLIST_FORCELUN | BLIST_INQUIRY_36}, | 131 | {"CBOX3", "USB Storage-SMC", "300A", BLIST_FORCELUN | BLIST_INQUIRY_36}, |
131 | {"CMD", "CRA-7280", NULL, BLIST_SPARSELUN}, /* CMD RAID Controller */ | 132 | {"CMD", "CRA-7280", NULL, BLIST_SPARSELUN}, /* CMD RAID Controller */ |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 5cc97b721661..ff82ccfbb106 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1308,7 +1308,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
1308 | * the request was not marked fast fail. Note that above, | 1308 | * the request was not marked fast fail. Note that above, |
1309 | * even if the request is marked fast fail, we still requeue | 1309 | * even if the request is marked fast fail, we still requeue |
1310 | * for queue congestion conditions (QUEUE_FULL or BUSY) */ | 1310 | * for queue congestion conditions (QUEUE_FULL or BUSY) */ |
1311 | if ((++scmd->retries) < scmd->allowed | 1311 | if ((++scmd->retries) <= scmd->allowed |
1312 | && !blk_noretry_request(scmd->request)) { | 1312 | && !blk_noretry_request(scmd->request)) { |
1313 | return NEEDS_RETRY; | 1313 | return NEEDS_RETRY; |
1314 | } else { | 1314 | } else { |
@@ -1433,7 +1433,7 @@ static void scsi_eh_flush_done_q(struct list_head *done_q) | |||
1433 | list_del_init(&scmd->eh_entry); | 1433 | list_del_init(&scmd->eh_entry); |
1434 | if (scsi_device_online(scmd->device) && | 1434 | if (scsi_device_online(scmd->device) && |
1435 | !blk_noretry_request(scmd->request) && | 1435 | !blk_noretry_request(scmd->request) && |
1436 | (++scmd->retries < scmd->allowed)) { | 1436 | (++scmd->retries <= scmd->allowed)) { |
1437 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush" | 1437 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush" |
1438 | " retry cmd: %p\n", | 1438 | " retry cmd: %p\n", |
1439 | current->comm, | 1439 | current->comm, |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 4a602853a98e..701a328f7beb 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/hardirq.h> | ||
19 | 20 | ||
20 | #include <scsi/scsi.h> | 21 | #include <scsi/scsi.h> |
21 | #include <scsi/scsi_dbg.h> | 22 | #include <scsi/scsi_dbg.h> |
@@ -1497,7 +1498,7 @@ static void scsi_kill_request(struct request *req, request_queue_t *q) | |||
1497 | static void scsi_softirq_done(struct request *rq) | 1498 | static void scsi_softirq_done(struct request *rq) |
1498 | { | 1499 | { |
1499 | struct scsi_cmnd *cmd = rq->completion_data; | 1500 | struct scsi_cmnd *cmd = rq->completion_data; |
1500 | unsigned long wait_for = cmd->allowed * cmd->timeout_per_command; | 1501 | unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command; |
1501 | int disposition; | 1502 | int disposition; |
1502 | 1503 | ||
1503 | INIT_LIST_HEAD(&cmd->eh_entry); | 1504 | INIT_LIST_HEAD(&cmd->eh_entry); |
@@ -2248,3 +2249,61 @@ scsi_target_unblock(struct device *dev) | |||
2248 | device_for_each_child(dev, NULL, target_unblock); | 2249 | device_for_each_child(dev, NULL, target_unblock); |
2249 | } | 2250 | } |
2250 | EXPORT_SYMBOL_GPL(scsi_target_unblock); | 2251 | EXPORT_SYMBOL_GPL(scsi_target_unblock); |
2252 | |||
2253 | |||
2254 | struct work_queue_work { | ||
2255 | struct work_struct work; | ||
2256 | void (*fn)(void *); | ||
2257 | void *data; | ||
2258 | }; | ||
2259 | |||
2260 | static void execute_in_process_context_work(void *data) | ||
2261 | { | ||
2262 | void (*fn)(void *data); | ||
2263 | struct work_queue_work *wqw = data; | ||
2264 | |||
2265 | fn = wqw->fn; | ||
2266 | data = wqw->data; | ||
2267 | |||
2268 | kfree(wqw); | ||
2269 | |||
2270 | fn(data); | ||
2271 | } | ||
2272 | |||
2273 | /** | ||
2274 | * scsi_execute_in_process_context - reliably execute the routine with user context | ||
2275 | * @fn: the function to execute | ||
2276 | * @data: data to pass to the function | ||
2277 | * | ||
2278 | * Executes the function immediately if process context is available, | ||
2279 | * otherwise schedules the function for delayed execution. | ||
2280 | * | ||
2281 | * Returns: 0 - function was executed | ||
2282 | * 1 - function was scheduled for execution | ||
2283 | * <0 - error | ||
2284 | */ | ||
2285 | int scsi_execute_in_process_context(void (*fn)(void *data), void *data) | ||
2286 | { | ||
2287 | struct work_queue_work *wqw; | ||
2288 | |||
2289 | if (!in_interrupt()) { | ||
2290 | fn(data); | ||
2291 | return 0; | ||
2292 | } | ||
2293 | |||
2294 | wqw = kmalloc(sizeof(struct work_queue_work), GFP_ATOMIC); | ||
2295 | |||
2296 | if (unlikely(!wqw)) { | ||
2297 | printk(KERN_ERR "Failed to allocate memory\n"); | ||
2298 | WARN_ON(1); | ||
2299 | return -ENOMEM; | ||
2300 | } | ||
2301 | |||
2302 | INIT_WORK(&wqw->work, execute_in_process_context_work, wqw); | ||
2303 | wqw->fn = fn; | ||
2304 | wqw->data = data; | ||
2305 | schedule_work(&wqw->work); | ||
2306 | |||
2307 | return 1; | ||
2308 | } | ||
2309 | EXPORT_SYMBOL_GPL(scsi_execute_in_process_context); | ||
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 752fb5da3de4..f9ecc3dea7df 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -387,19 +387,12 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, | |||
387 | return found_target; | 387 | return found_target; |
388 | } | 388 | } |
389 | 389 | ||
390 | struct work_queue_wrapper { | 390 | static void scsi_target_reap_usercontext(void *data) |
391 | struct work_struct work; | 391 | { |
392 | struct scsi_target *starget; | 392 | struct scsi_target *starget = data; |
393 | }; | ||
394 | |||
395 | static void scsi_target_reap_work(void *data) { | ||
396 | struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; | ||
397 | struct scsi_target *starget = wqw->starget; | ||
398 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 393 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
399 | unsigned long flags; | 394 | unsigned long flags; |
400 | 395 | ||
401 | kfree(wqw); | ||
402 | |||
403 | spin_lock_irqsave(shost->host_lock, flags); | 396 | spin_lock_irqsave(shost->host_lock, flags); |
404 | 397 | ||
405 | if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { | 398 | if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { |
@@ -428,18 +421,7 @@ static void scsi_target_reap_work(void *data) { | |||
428 | */ | 421 | */ |
429 | void scsi_target_reap(struct scsi_target *starget) | 422 | void scsi_target_reap(struct scsi_target *starget) |
430 | { | 423 | { |
431 | struct work_queue_wrapper *wqw = | 424 | scsi_execute_in_process_context(scsi_target_reap_usercontext, starget); |
432 | kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC); | ||
433 | |||
434 | if (!wqw) { | ||
435 | starget_printk(KERN_ERR, starget, | ||
436 | "Failed to allocate memory in scsi_reap_target()\n"); | ||
437 | return; | ||
438 | } | ||
439 | |||
440 | INIT_WORK(&wqw->work, scsi_target_reap_work, wqw); | ||
441 | wqw->starget = starget; | ||
442 | schedule_work(&wqw->work); | ||
443 | } | 425 | } |
444 | 426 | ||
445 | /** | 427 | /** |
@@ -770,8 +752,20 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) | |||
770 | 752 | ||
771 | transport_configure_device(&sdev->sdev_gendev); | 753 | transport_configure_device(&sdev->sdev_gendev); |
772 | 754 | ||
773 | if (sdev->host->hostt->slave_configure) | 755 | if (sdev->host->hostt->slave_configure) { |
774 | sdev->host->hostt->slave_configure(sdev); | 756 | int ret = sdev->host->hostt->slave_configure(sdev); |
757 | if (ret) { | ||
758 | /* | ||
759 | * if LLDD reports slave not present, don't clutter | ||
760 | * console with alloc failure messages | ||
761 | */ | ||
762 | if (ret != -ENXIO) { | ||
763 | sdev_printk(KERN_ERR, sdev, | ||
764 | "failed to configure device\n"); | ||
765 | } | ||
766 | return SCSI_SCAN_NO_RESPONSE; | ||
767 | } | ||
768 | } | ||
775 | 769 | ||
776 | /* | 770 | /* |
777 | * Ok, the device is now all set up, we can | 771 | * Ok, the device is now all set up, we can |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index a77b32deaf8f..902a5def8e62 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -217,8 +217,9 @@ static void scsi_device_cls_release(struct class_device *class_dev) | |||
217 | put_device(&sdev->sdev_gendev); | 217 | put_device(&sdev->sdev_gendev); |
218 | } | 218 | } |
219 | 219 | ||
220 | static void scsi_device_dev_release(struct device *dev) | 220 | static void scsi_device_dev_release_usercontext(void *data) |
221 | { | 221 | { |
222 | struct device *dev = data; | ||
222 | struct scsi_device *sdev; | 223 | struct scsi_device *sdev; |
223 | struct device *parent; | 224 | struct device *parent; |
224 | struct scsi_target *starget; | 225 | struct scsi_target *starget; |
@@ -237,6 +238,7 @@ static void scsi_device_dev_release(struct device *dev) | |||
237 | 238 | ||
238 | if (sdev->request_queue) { | 239 | if (sdev->request_queue) { |
239 | sdev->request_queue->queuedata = NULL; | 240 | sdev->request_queue->queuedata = NULL; |
241 | /* user context needed to free queue */ | ||
240 | scsi_free_queue(sdev->request_queue); | 242 | scsi_free_queue(sdev->request_queue); |
241 | /* temporary expedient, try to catch use of queue lock | 243 | /* temporary expedient, try to catch use of queue lock |
242 | * after free of sdev */ | 244 | * after free of sdev */ |
@@ -252,6 +254,11 @@ static void scsi_device_dev_release(struct device *dev) | |||
252 | put_device(parent); | 254 | put_device(parent); |
253 | } | 255 | } |
254 | 256 | ||
257 | static void scsi_device_dev_release(struct device *dev) | ||
258 | { | ||
259 | scsi_execute_in_process_context(scsi_device_dev_release_usercontext, dev); | ||
260 | } | ||
261 | |||
255 | static struct class sdev_class = { | 262 | static struct class sdev_class = { |
256 | .name = "scsi_device", | 263 | .name = "scsi_device", |
257 | .release = scsi_device_cls_release, | 264 | .release = scsi_device_cls_release, |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index f2c9acf11bd0..13ea64119b73 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -223,7 +223,7 @@ static void fc_rport_terminate(struct fc_rport *rport); | |||
223 | */ | 223 | */ |
224 | #define FC_STARGET_NUM_ATTRS 3 | 224 | #define FC_STARGET_NUM_ATTRS 3 |
225 | #define FC_RPORT_NUM_ATTRS 9 | 225 | #define FC_RPORT_NUM_ATTRS 9 |
226 | #define FC_HOST_NUM_ATTRS 16 | 226 | #define FC_HOST_NUM_ATTRS 17 |
227 | 227 | ||
228 | struct fc_internal { | 228 | struct fc_internal { |
229 | struct scsi_transport_template t; | 229 | struct scsi_transport_template t; |
@@ -1498,8 +1498,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, | |||
1498 | } | 1498 | } |
1499 | 1499 | ||
1500 | /* Search the bindings array */ | 1500 | /* Search the bindings array */ |
1501 | if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) && | 1501 | if (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE) { |
1502 | (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) { | ||
1503 | 1502 | ||
1504 | /* search for a matching consistent binding */ | 1503 | /* search for a matching consistent binding */ |
1505 | 1504 | ||
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 59a1c9d9d3bd..71e54a64adca 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -39,10 +39,6 @@ struct iscsi_internal { | |||
39 | struct iscsi_transport *iscsi_transport; | 39 | struct iscsi_transport *iscsi_transport; |
40 | struct list_head list; | 40 | struct list_head list; |
41 | /* | 41 | /* |
42 | * List of sessions for this transport | ||
43 | */ | ||
44 | struct list_head sessions; | ||
45 | /* | ||
46 | * based on transport capabilities, at register time we set these | 42 | * based on transport capabilities, at register time we set these |
47 | * bits to tell the transport class it wants attributes displayed | 43 | * bits to tell the transport class it wants attributes displayed |
48 | * in sysfs or that it can support different iSCSI Data-Path | 44 | * in sysfs or that it can support different iSCSI Data-Path |
@@ -164,9 +160,43 @@ static struct mempool_zone *z_reply; | |||
164 | #define Z_MAX_ERROR 16 | 160 | #define Z_MAX_ERROR 16 |
165 | #define Z_HIWAT_ERROR 12 | 161 | #define Z_HIWAT_ERROR 12 |
166 | 162 | ||
163 | static LIST_HEAD(sesslist); | ||
164 | static DEFINE_SPINLOCK(sesslock); | ||
167 | static LIST_HEAD(connlist); | 165 | static LIST_HEAD(connlist); |
168 | static DEFINE_SPINLOCK(connlock); | 166 | static DEFINE_SPINLOCK(connlock); |
169 | 167 | ||
168 | static struct iscsi_cls_session *iscsi_session_lookup(uint64_t handle) | ||
169 | { | ||
170 | unsigned long flags; | ||
171 | struct iscsi_cls_session *sess; | ||
172 | |||
173 | spin_lock_irqsave(&sesslock, flags); | ||
174 | list_for_each_entry(sess, &sesslist, sess_list) { | ||
175 | if (sess == iscsi_ptr(handle)) { | ||
176 | spin_unlock_irqrestore(&sesslock, flags); | ||
177 | return sess; | ||
178 | } | ||
179 | } | ||
180 | spin_unlock_irqrestore(&sesslock, flags); | ||
181 | return NULL; | ||
182 | } | ||
183 | |||
184 | static struct iscsi_cls_conn *iscsi_conn_lookup(uint64_t handle) | ||
185 | { | ||
186 | unsigned long flags; | ||
187 | struct iscsi_cls_conn *conn; | ||
188 | |||
189 | spin_lock_irqsave(&connlock, flags); | ||
190 | list_for_each_entry(conn, &connlist, conn_list) { | ||
191 | if (conn == iscsi_ptr(handle)) { | ||
192 | spin_unlock_irqrestore(&connlock, flags); | ||
193 | return conn; | ||
194 | } | ||
195 | } | ||
196 | spin_unlock_irqrestore(&connlock, flags); | ||
197 | return NULL; | ||
198 | } | ||
199 | |||
170 | /* | 200 | /* |
171 | * The following functions can be used by LLDs that allocate | 201 | * The following functions can be used by LLDs that allocate |
172 | * their own scsi_hosts or by software iscsi LLDs | 202 | * their own scsi_hosts or by software iscsi LLDs |
@@ -365,6 +395,7 @@ iscsi_transport_create_session(struct scsi_transport_template *scsit, | |||
365 | { | 395 | { |
366 | struct iscsi_cls_session *session; | 396 | struct iscsi_cls_session *session; |
367 | struct Scsi_Host *shost; | 397 | struct Scsi_Host *shost; |
398 | unsigned long flags; | ||
368 | 399 | ||
369 | shost = scsi_host_alloc(transport->host_template, | 400 | shost = scsi_host_alloc(transport->host_template, |
370 | hostdata_privsize(transport)); | 401 | hostdata_privsize(transport)); |
@@ -389,6 +420,9 @@ iscsi_transport_create_session(struct scsi_transport_template *scsit, | |||
389 | goto remove_host; | 420 | goto remove_host; |
390 | 421 | ||
391 | *(unsigned long*)shost->hostdata = (unsigned long)session; | 422 | *(unsigned long*)shost->hostdata = (unsigned long)session; |
423 | spin_lock_irqsave(&sesslock, flags); | ||
424 | list_add(&session->sess_list, &sesslist); | ||
425 | spin_unlock_irqrestore(&sesslock, flags); | ||
392 | return shost; | 426 | return shost; |
393 | 427 | ||
394 | remove_host: | 428 | remove_host: |
@@ -410,9 +444,13 @@ EXPORT_SYMBOL_GPL(iscsi_transport_create_session); | |||
410 | int iscsi_transport_destroy_session(struct Scsi_Host *shost) | 444 | int iscsi_transport_destroy_session(struct Scsi_Host *shost) |
411 | { | 445 | { |
412 | struct iscsi_cls_session *session; | 446 | struct iscsi_cls_session *session; |
447 | unsigned long flags; | ||
413 | 448 | ||
414 | scsi_remove_host(shost); | 449 | scsi_remove_host(shost); |
415 | session = hostdata_session(shost->hostdata); | 450 | session = hostdata_session(shost->hostdata); |
451 | spin_lock_irqsave(&sesslock, flags); | ||
452 | list_del(&session->sess_list); | ||
453 | spin_unlock_irqrestore(&sesslock, flags); | ||
416 | iscsi_destroy_session(session); | 454 | iscsi_destroy_session(session); |
417 | /* ref from host alloc */ | 455 | /* ref from host alloc */ |
418 | scsi_host_put(shost); | 456 | scsi_host_put(shost); |
@@ -424,22 +462,6 @@ EXPORT_SYMBOL_GPL(iscsi_transport_destroy_session); | |||
424 | /* | 462 | /* |
425 | * iscsi interface functions | 463 | * iscsi interface functions |
426 | */ | 464 | */ |
427 | static struct iscsi_cls_conn* | ||
428 | iscsi_if_find_conn(uint64_t key) | ||
429 | { | ||
430 | unsigned long flags; | ||
431 | struct iscsi_cls_conn *conn; | ||
432 | |||
433 | spin_lock_irqsave(&connlock, flags); | ||
434 | list_for_each_entry(conn, &connlist, conn_list) | ||
435 | if (conn->connh == key) { | ||
436 | spin_unlock_irqrestore(&connlock, flags); | ||
437 | return conn; | ||
438 | } | ||
439 | spin_unlock_irqrestore(&connlock, flags); | ||
440 | return NULL; | ||
441 | } | ||
442 | |||
443 | static struct iscsi_internal * | 465 | static struct iscsi_internal * |
444 | iscsi_if_transport_lookup(struct iscsi_transport *tt) | 466 | iscsi_if_transport_lookup(struct iscsi_transport *tt) |
445 | { | 467 | { |
@@ -463,7 +485,7 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb) | |||
463 | } | 485 | } |
464 | 486 | ||
465 | static void* | 487 | static void* |
466 | mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data) | 488 | mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) |
467 | { | 489 | { |
468 | struct mempool_zone *zone = pool_data; | 490 | struct mempool_zone *zone = pool_data; |
469 | 491 | ||
@@ -504,6 +526,12 @@ mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) | |||
504 | if (!zp) | 526 | if (!zp) |
505 | return NULL; | 527 | return NULL; |
506 | 528 | ||
529 | zp->size = size; | ||
530 | zp->hiwat = hiwat; | ||
531 | INIT_LIST_HEAD(&zp->freequeue); | ||
532 | spin_lock_init(&zp->freelock); | ||
533 | atomic_set(&zp->allocated, 0); | ||
534 | |||
507 | zp->pool = mempool_create(max, mempool_zone_alloc_skb, | 535 | zp->pool = mempool_create(max, mempool_zone_alloc_skb, |
508 | mempool_zone_free_skb, zp); | 536 | mempool_zone_free_skb, zp); |
509 | if (!zp->pool) { | 537 | if (!zp->pool) { |
@@ -511,13 +539,6 @@ mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) | |||
511 | return NULL; | 539 | return NULL; |
512 | } | 540 | } |
513 | 541 | ||
514 | zp->size = size; | ||
515 | zp->hiwat = hiwat; | ||
516 | |||
517 | INIT_LIST_HEAD(&zp->freequeue); | ||
518 | spin_lock_init(&zp->freelock); | ||
519 | atomic_set(&zp->allocated, 0); | ||
520 | |||
521 | return zp; | 542 | return zp; |
522 | } | 543 | } |
523 | 544 | ||
@@ -559,25 +580,21 @@ iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb) | |||
559 | return 0; | 580 | return 0; |
560 | } | 581 | } |
561 | 582 | ||
562 | int iscsi_recv_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, | 583 | int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, |
563 | char *data, uint32_t data_size) | 584 | char *data, uint32_t data_size) |
564 | { | 585 | { |
565 | struct nlmsghdr *nlh; | 586 | struct nlmsghdr *nlh; |
566 | struct sk_buff *skb; | 587 | struct sk_buff *skb; |
567 | struct iscsi_uevent *ev; | 588 | struct iscsi_uevent *ev; |
568 | struct iscsi_cls_conn *conn; | ||
569 | char *pdu; | 589 | char *pdu; |
570 | int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) + | 590 | int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) + |
571 | data_size); | 591 | data_size); |
572 | 592 | ||
573 | conn = iscsi_if_find_conn(connh); | ||
574 | BUG_ON(!conn); | ||
575 | |||
576 | mempool_zone_complete(conn->z_pdu); | 593 | mempool_zone_complete(conn->z_pdu); |
577 | 594 | ||
578 | skb = mempool_zone_get_skb(conn->z_pdu); | 595 | skb = mempool_zone_get_skb(conn->z_pdu); |
579 | if (!skb) { | 596 | if (!skb) { |
580 | iscsi_conn_error(connh, ISCSI_ERR_CONN_FAILED); | 597 | iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED); |
581 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver " | 598 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver " |
582 | "control PDU: OOM\n"); | 599 | "control PDU: OOM\n"); |
583 | return -ENOMEM; | 600 | return -ENOMEM; |
@@ -590,7 +607,7 @@ int iscsi_recv_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, | |||
590 | ev->type = ISCSI_KEVENT_RECV_PDU; | 607 | ev->type = ISCSI_KEVENT_RECV_PDU; |
591 | if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) | 608 | if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) |
592 | ev->iferror = -ENOMEM; | 609 | ev->iferror = -ENOMEM; |
593 | ev->r.recv_req.conn_handle = connh; | 610 | ev->r.recv_req.conn_handle = iscsi_handle(conn); |
594 | pdu = (char*)ev + sizeof(*ev); | 611 | pdu = (char*)ev + sizeof(*ev); |
595 | memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); | 612 | memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); |
596 | memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); | 613 | memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); |
@@ -599,17 +616,13 @@ int iscsi_recv_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, | |||
599 | } | 616 | } |
600 | EXPORT_SYMBOL_GPL(iscsi_recv_pdu); | 617 | EXPORT_SYMBOL_GPL(iscsi_recv_pdu); |
601 | 618 | ||
602 | void iscsi_conn_error(iscsi_connh_t connh, enum iscsi_err error) | 619 | void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) |
603 | { | 620 | { |
604 | struct nlmsghdr *nlh; | 621 | struct nlmsghdr *nlh; |
605 | struct sk_buff *skb; | 622 | struct sk_buff *skb; |
606 | struct iscsi_uevent *ev; | 623 | struct iscsi_uevent *ev; |
607 | struct iscsi_cls_conn *conn; | ||
608 | int len = NLMSG_SPACE(sizeof(*ev)); | 624 | int len = NLMSG_SPACE(sizeof(*ev)); |
609 | 625 | ||
610 | conn = iscsi_if_find_conn(connh); | ||
611 | BUG_ON(!conn); | ||
612 | |||
613 | mempool_zone_complete(conn->z_error); | 626 | mempool_zone_complete(conn->z_error); |
614 | 627 | ||
615 | skb = mempool_zone_get_skb(conn->z_error); | 628 | skb = mempool_zone_get_skb(conn->z_error); |
@@ -626,7 +639,7 @@ void iscsi_conn_error(iscsi_connh_t connh, enum iscsi_err error) | |||
626 | if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat) | 639 | if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat) |
627 | ev->iferror = -ENOMEM; | 640 | ev->iferror = -ENOMEM; |
628 | ev->r.connerror.error = error; | 641 | ev->r.connerror.error = error; |
629 | ev->r.connerror.conn_handle = connh; | 642 | ev->r.connerror.conn_handle = iscsi_handle(conn); |
630 | 643 | ||
631 | iscsi_unicast_skb(conn->z_error, skb); | 644 | iscsi_unicast_skb(conn->z_error, skb); |
632 | 645 | ||
@@ -662,8 +675,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, | |||
662 | } | 675 | } |
663 | 676 | ||
664 | static int | 677 | static int |
665 | iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb, | 678 | iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) |
666 | struct nlmsghdr *nlh) | ||
667 | { | 679 | { |
668 | struct iscsi_uevent *ev = NLMSG_DATA(nlh); | 680 | struct iscsi_uevent *ev = NLMSG_DATA(nlh); |
669 | struct iscsi_stats *stats; | 681 | struct iscsi_stats *stats; |
@@ -677,7 +689,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb, | |||
677 | ISCSI_STATS_CUSTOM_MAX); | 689 | ISCSI_STATS_CUSTOM_MAX); |
678 | int err = 0; | 690 | int err = 0; |
679 | 691 | ||
680 | conn = iscsi_if_find_conn(ev->u.get_stats.conn_handle); | 692 | conn = iscsi_conn_lookup(ev->u.get_stats.conn_handle); |
681 | if (!conn) | 693 | if (!conn) |
682 | return -EEXIST; | 694 | return -EEXIST; |
683 | 695 | ||
@@ -707,14 +719,14 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb, | |||
707 | ((char*)evstat + sizeof(*evstat)); | 719 | ((char*)evstat + sizeof(*evstat)); |
708 | memset(stats, 0, sizeof(*stats)); | 720 | memset(stats, 0, sizeof(*stats)); |
709 | 721 | ||
710 | transport->get_stats(ev->u.get_stats.conn_handle, stats); | 722 | transport->get_stats(conn, stats); |
711 | actual_size = NLMSG_SPACE(sizeof(struct iscsi_uevent) + | 723 | actual_size = NLMSG_SPACE(sizeof(struct iscsi_uevent) + |
712 | sizeof(struct iscsi_stats) + | 724 | sizeof(struct iscsi_stats) + |
713 | sizeof(struct iscsi_stats_custom) * | 725 | sizeof(struct iscsi_stats_custom) * |
714 | stats->custom_length); | 726 | stats->custom_length); |
715 | actual_size -= sizeof(*nlhstat); | 727 | actual_size -= sizeof(*nlhstat); |
716 | actual_size = NLMSG_LENGTH(actual_size); | 728 | actual_size = NLMSG_LENGTH(actual_size); |
717 | skb_trim(skb, NLMSG_ALIGN(actual_size)); | 729 | skb_trim(skbstat, NLMSG_ALIGN(actual_size)); |
718 | nlhstat->nlmsg_len = actual_size; | 730 | nlhstat->nlmsg_len = actual_size; |
719 | 731 | ||
720 | err = iscsi_unicast_skb(conn->z_pdu, skbstat); | 732 | err = iscsi_unicast_skb(conn->z_pdu, skbstat); |
@@ -727,58 +739,34 @@ static int | |||
727 | iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) | 739 | iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) |
728 | { | 740 | { |
729 | struct iscsi_transport *transport = priv->iscsi_transport; | 741 | struct iscsi_transport *transport = priv->iscsi_transport; |
730 | struct Scsi_Host *shost; | 742 | struct iscsi_cls_session *session; |
731 | 743 | uint32_t sid; | |
732 | if (!transport->create_session) | ||
733 | return -EINVAL; | ||
734 | 744 | ||
735 | shost = transport->create_session(&priv->t, | 745 | session = transport->create_session(&priv->t, |
736 | ev->u.c_session.initial_cmdsn); | 746 | ev->u.c_session.initial_cmdsn, |
737 | if (!shost) | 747 | &sid); |
748 | if (!session) | ||
738 | return -ENOMEM; | 749 | return -ENOMEM; |
739 | 750 | ||
740 | ev->r.c_session_ret.session_handle = iscsi_handle(iscsi_hostdata(shost->hostdata)); | 751 | ev->r.c_session_ret.session_handle = iscsi_handle(session); |
741 | ev->r.c_session_ret.sid = shost->host_no; | 752 | ev->r.c_session_ret.sid = sid; |
742 | return 0; | 753 | return 0; |
743 | } | 754 | } |
744 | 755 | ||
745 | static int | 756 | static int |
746 | iscsi_if_destroy_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) | 757 | iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) |
747 | { | 758 | { |
748 | struct iscsi_transport *transport = priv->iscsi_transport; | ||
749 | |||
750 | struct Scsi_Host *shost; | ||
751 | |||
752 | if (!transport->destroy_session) | ||
753 | return -EINVAL; | ||
754 | |||
755 | shost = scsi_host_lookup(ev->u.d_session.sid); | ||
756 | if (shost == ERR_PTR(-ENXIO)) | ||
757 | return -EEXIST; | ||
758 | |||
759 | if (transport->destroy_session) | ||
760 | transport->destroy_session(shost); | ||
761 | /* ref from host lookup */ | ||
762 | scsi_host_put(shost); | ||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | static int | ||
767 | iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev){ | ||
768 | struct Scsi_Host *shost; | ||
769 | struct iscsi_cls_conn *conn; | 759 | struct iscsi_cls_conn *conn; |
760 | struct iscsi_cls_session *session; | ||
770 | unsigned long flags; | 761 | unsigned long flags; |
771 | 762 | ||
772 | if (!transport->create_conn) | 763 | session = iscsi_session_lookup(ev->u.c_conn.session_handle); |
764 | if (!session) | ||
773 | return -EINVAL; | 765 | return -EINVAL; |
774 | 766 | ||
775 | shost = scsi_host_lookup(ev->u.c_conn.sid); | 767 | conn = transport->create_conn(session, ev->u.c_conn.cid); |
776 | if (shost == ERR_PTR(-ENXIO)) | ||
777 | return -EEXIST; | ||
778 | |||
779 | conn = transport->create_conn(shost, ev->u.c_conn.cid); | ||
780 | if (!conn) | 768 | if (!conn) |
781 | goto release_ref; | 769 | return -ENOMEM; |
782 | 770 | ||
783 | conn->z_pdu = mempool_zone_init(Z_MAX_PDU, | 771 | conn->z_pdu = mempool_zone_init(Z_MAX_PDU, |
784 | NLMSG_SPACE(sizeof(struct iscsi_uevent) + | 772 | NLMSG_SPACE(sizeof(struct iscsi_uevent) + |
@@ -800,14 +788,13 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
800 | goto free_pdu_pool; | 788 | goto free_pdu_pool; |
801 | } | 789 | } |
802 | 790 | ||
803 | ev->r.handle = conn->connh = iscsi_handle(conn->dd_data); | 791 | ev->r.handle = iscsi_handle(conn); |
804 | 792 | ||
805 | spin_lock_irqsave(&connlock, flags); | 793 | spin_lock_irqsave(&connlock, flags); |
806 | list_add(&conn->conn_list, &connlist); | 794 | list_add(&conn->conn_list, &connlist); |
807 | conn->active = 1; | 795 | conn->active = 1; |
808 | spin_unlock_irqrestore(&connlock, flags); | 796 | spin_unlock_irqrestore(&connlock, flags); |
809 | 797 | ||
810 | scsi_host_put(shost); | ||
811 | return 0; | 798 | return 0; |
812 | 799 | ||
813 | free_pdu_pool: | 800 | free_pdu_pool: |
@@ -815,8 +802,6 @@ free_pdu_pool: | |||
815 | destroy_conn: | 802 | destroy_conn: |
816 | if (transport->destroy_conn) | 803 | if (transport->destroy_conn) |
817 | transport->destroy_conn(conn->dd_data); | 804 | transport->destroy_conn(conn->dd_data); |
818 | release_ref: | ||
819 | scsi_host_put(shost); | ||
820 | return -ENOMEM; | 805 | return -ENOMEM; |
821 | } | 806 | } |
822 | 807 | ||
@@ -827,13 +812,9 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev | |||
827 | struct iscsi_cls_conn *conn; | 812 | struct iscsi_cls_conn *conn; |
828 | struct mempool_zone *z_error, *z_pdu; | 813 | struct mempool_zone *z_error, *z_pdu; |
829 | 814 | ||
830 | conn = iscsi_if_find_conn(ev->u.d_conn.conn_handle); | 815 | conn = iscsi_conn_lookup(ev->u.d_conn.conn_handle); |
831 | if (!conn) | 816 | if (!conn) |
832 | return -EEXIST; | ||
833 | |||
834 | if (!transport->destroy_conn) | ||
835 | return -EINVAL; | 817 | return -EINVAL; |
836 | |||
837 | spin_lock_irqsave(&connlock, flags); | 818 | spin_lock_irqsave(&connlock, flags); |
838 | conn->active = 0; | 819 | conn->active = 0; |
839 | list_del(&conn->conn_list); | 820 | list_del(&conn->conn_list); |
@@ -858,23 +839,27 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
858 | struct iscsi_uevent *ev = NLMSG_DATA(nlh); | 839 | struct iscsi_uevent *ev = NLMSG_DATA(nlh); |
859 | struct iscsi_transport *transport = NULL; | 840 | struct iscsi_transport *transport = NULL; |
860 | struct iscsi_internal *priv; | 841 | struct iscsi_internal *priv; |
861 | 842 | struct iscsi_cls_session *session; | |
862 | if (NETLINK_CREDS(skb)->uid) | 843 | struct iscsi_cls_conn *conn; |
863 | return -EPERM; | ||
864 | 844 | ||
865 | priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); | 845 | priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); |
866 | if (!priv) | 846 | if (!priv) |
867 | return -EINVAL; | 847 | return -EINVAL; |
868 | transport = priv->iscsi_transport; | 848 | transport = priv->iscsi_transport; |
869 | 849 | ||
870 | daemon_pid = NETLINK_CREDS(skb)->pid; | 850 | if (!try_module_get(transport->owner)) |
851 | return -EINVAL; | ||
871 | 852 | ||
872 | switch (nlh->nlmsg_type) { | 853 | switch (nlh->nlmsg_type) { |
873 | case ISCSI_UEVENT_CREATE_SESSION: | 854 | case ISCSI_UEVENT_CREATE_SESSION: |
874 | err = iscsi_if_create_session(priv, ev); | 855 | err = iscsi_if_create_session(priv, ev); |
875 | break; | 856 | break; |
876 | case ISCSI_UEVENT_DESTROY_SESSION: | 857 | case ISCSI_UEVENT_DESTROY_SESSION: |
877 | err = iscsi_if_destroy_session(priv, ev); | 858 | session = iscsi_session_lookup(ev->u.d_session.session_handle); |
859 | if (session) | ||
860 | transport->destroy_session(session); | ||
861 | else | ||
862 | err = -EINVAL; | ||
878 | break; | 863 | break; |
879 | case ISCSI_UEVENT_CREATE_CONN: | 864 | case ISCSI_UEVENT_CREATE_CONN: |
880 | err = iscsi_if_create_conn(transport, ev); | 865 | err = iscsi_if_create_conn(transport, ev); |
@@ -883,56 +868,64 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
883 | err = iscsi_if_destroy_conn(transport, ev); | 868 | err = iscsi_if_destroy_conn(transport, ev); |
884 | break; | 869 | break; |
885 | case ISCSI_UEVENT_BIND_CONN: | 870 | case ISCSI_UEVENT_BIND_CONN: |
886 | if (!iscsi_if_find_conn(ev->u.b_conn.conn_handle)) | 871 | session = iscsi_session_lookup(ev->u.b_conn.session_handle); |
887 | return -EEXIST; | 872 | conn = iscsi_conn_lookup(ev->u.b_conn.conn_handle); |
888 | ev->r.retcode = transport->bind_conn( | 873 | |
889 | ev->u.b_conn.session_handle, | 874 | if (session && conn) |
890 | ev->u.b_conn.conn_handle, | 875 | ev->r.retcode = transport->bind_conn(session, conn, |
891 | ev->u.b_conn.transport_fd, | 876 | ev->u.b_conn.transport_fd, |
892 | ev->u.b_conn.is_leading); | 877 | ev->u.b_conn.is_leading); |
878 | else | ||
879 | err = -EINVAL; | ||
893 | break; | 880 | break; |
894 | case ISCSI_UEVENT_SET_PARAM: | 881 | case ISCSI_UEVENT_SET_PARAM: |
895 | if (!iscsi_if_find_conn(ev->u.set_param.conn_handle)) | 882 | conn = iscsi_conn_lookup(ev->u.set_param.conn_handle); |
896 | return -EEXIST; | 883 | if (conn) |
897 | ev->r.retcode = transport->set_param( | 884 | ev->r.retcode = transport->set_param(conn, |
898 | ev->u.set_param.conn_handle, | 885 | ev->u.set_param.param, ev->u.set_param.value); |
899 | ev->u.set_param.param, ev->u.set_param.value); | 886 | else |
887 | err = -EINVAL; | ||
900 | break; | 888 | break; |
901 | case ISCSI_UEVENT_START_CONN: | 889 | case ISCSI_UEVENT_START_CONN: |
902 | if (!iscsi_if_find_conn(ev->u.start_conn.conn_handle)) | 890 | conn = iscsi_conn_lookup(ev->u.start_conn.conn_handle); |
903 | return -EEXIST; | 891 | if (conn) |
904 | ev->r.retcode = transport->start_conn( | 892 | ev->r.retcode = transport->start_conn(conn); |
905 | ev->u.start_conn.conn_handle); | 893 | else |
894 | err = -EINVAL; | ||
895 | |||
906 | break; | 896 | break; |
907 | case ISCSI_UEVENT_STOP_CONN: | 897 | case ISCSI_UEVENT_STOP_CONN: |
908 | if (!iscsi_if_find_conn(ev->u.stop_conn.conn_handle)) | 898 | conn = iscsi_conn_lookup(ev->u.stop_conn.conn_handle); |
909 | return -EEXIST; | 899 | if (conn) |
910 | transport->stop_conn(ev->u.stop_conn.conn_handle, | 900 | transport->stop_conn(conn, ev->u.stop_conn.flag); |
911 | ev->u.stop_conn.flag); | 901 | else |
902 | err = -EINVAL; | ||
912 | break; | 903 | break; |
913 | case ISCSI_UEVENT_SEND_PDU: | 904 | case ISCSI_UEVENT_SEND_PDU: |
914 | if (!iscsi_if_find_conn(ev->u.send_pdu.conn_handle)) | 905 | conn = iscsi_conn_lookup(ev->u.send_pdu.conn_handle); |
915 | return -EEXIST; | 906 | if (conn) |
916 | ev->r.retcode = transport->send_pdu( | 907 | ev->r.retcode = transport->send_pdu(conn, |
917 | ev->u.send_pdu.conn_handle, | 908 | (struct iscsi_hdr*)((char*)ev + sizeof(*ev)), |
918 | (struct iscsi_hdr*)((char*)ev + sizeof(*ev)), | 909 | (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size, |
919 | (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size, | 910 | ev->u.send_pdu.data_size); |
920 | ev->u.send_pdu.data_size); | 911 | else |
912 | err = -EINVAL; | ||
921 | break; | 913 | break; |
922 | case ISCSI_UEVENT_GET_STATS: | 914 | case ISCSI_UEVENT_GET_STATS: |
923 | err = iscsi_if_get_stats(transport, skb, nlh); | 915 | err = iscsi_if_get_stats(transport, nlh); |
924 | break; | 916 | break; |
925 | default: | 917 | default: |
926 | err = -EINVAL; | 918 | err = -EINVAL; |
927 | break; | 919 | break; |
928 | } | 920 | } |
929 | 921 | ||
922 | module_put(transport->owner); | ||
930 | return err; | 923 | return err; |
931 | } | 924 | } |
932 | 925 | ||
933 | /* Get message from skb (based on rtnetlink_rcv_skb). Each message is | 926 | /* Get message from skb (based on rtnetlink_rcv_skb). Each message is |
934 | * processed by iscsi_if_recv_msg. Malformed skbs with wrong length are | 927 | * processed by iscsi_if_recv_msg. Malformed skbs with wrong length are |
935 | * discarded silently. */ | 928 | * or invalid creds discarded silently. */ |
936 | static void | 929 | static void |
937 | iscsi_if_rx(struct sock *sk, int len) | 930 | iscsi_if_rx(struct sock *sk, int len) |
938 | { | 931 | { |
@@ -940,6 +933,12 @@ iscsi_if_rx(struct sock *sk, int len) | |||
940 | 933 | ||
941 | mutex_lock(&rx_queue_mutex); | 934 | mutex_lock(&rx_queue_mutex); |
942 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 935 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { |
936 | if (NETLINK_CREDS(skb)->uid) { | ||
937 | skb_pull(skb, skb->len); | ||
938 | goto free_skb; | ||
939 | } | ||
940 | daemon_pid = NETLINK_CREDS(skb)->pid; | ||
941 | |||
943 | while (skb->len >= NLMSG_SPACE(0)) { | 942 | while (skb->len >= NLMSG_SPACE(0)) { |
944 | int err; | 943 | int err; |
945 | uint32_t rlen; | 944 | uint32_t rlen; |
@@ -951,10 +950,12 @@ iscsi_if_rx(struct sock *sk, int len) | |||
951 | skb->len < nlh->nlmsg_len) { | 950 | skb->len < nlh->nlmsg_len) { |
952 | break; | 951 | break; |
953 | } | 952 | } |
953 | |||
954 | ev = NLMSG_DATA(nlh); | 954 | ev = NLMSG_DATA(nlh); |
955 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | 955 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); |
956 | if (rlen > skb->len) | 956 | if (rlen > skb->len) |
957 | rlen = skb->len; | 957 | rlen = skb->len; |
958 | |||
958 | err = iscsi_if_recv_msg(skb, nlh); | 959 | err = iscsi_if_recv_msg(skb, nlh); |
959 | if (err) { | 960 | if (err) { |
960 | ev->type = ISCSI_KEVENT_IF_ERROR; | 961 | ev->type = ISCSI_KEVENT_IF_ERROR; |
@@ -978,6 +979,7 @@ iscsi_if_rx(struct sock *sk, int len) | |||
978 | } while (err < 0 && err != -ECONNREFUSED); | 979 | } while (err < 0 && err != -ECONNREFUSED); |
979 | skb_pull(skb, rlen); | 980 | skb_pull(skb, rlen); |
980 | } | 981 | } |
982 | free_skb: | ||
981 | kfree_skb(skb); | 983 | kfree_skb(skb); |
982 | } | 984 | } |
983 | mutex_unlock(&rx_queue_mutex); | 985 | mutex_unlock(&rx_queue_mutex); |
@@ -997,7 +999,7 @@ show_conn_int_param_##param(struct class_device *cdev, char *buf) \ | |||
997 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | 999 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ |
998 | struct iscsi_transport *t = conn->transport; \ | 1000 | struct iscsi_transport *t = conn->transport; \ |
999 | \ | 1001 | \ |
1000 | t->get_conn_param(conn->dd_data, param, &value); \ | 1002 | t->get_conn_param(conn, param, &value); \ |
1001 | return snprintf(buf, 20, format"\n", value); \ | 1003 | return snprintf(buf, 20, format"\n", value); \ |
1002 | } | 1004 | } |
1003 | 1005 | ||
@@ -1024,10 +1026,9 @@ show_session_int_param_##param(struct class_device *cdev, char *buf) \ | |||
1024 | { \ | 1026 | { \ |
1025 | uint32_t value = 0; \ | 1027 | uint32_t value = 0; \ |
1026 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | 1028 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ |
1027 | struct Scsi_Host *shost = iscsi_session_to_shost(session); \ | ||
1028 | struct iscsi_transport *t = session->transport; \ | 1029 | struct iscsi_transport *t = session->transport; \ |
1029 | \ | 1030 | \ |
1030 | t->get_session_param(shost, param, &value); \ | 1031 | t->get_session_param(session, param, &value); \ |
1031 | return snprintf(buf, 20, format"\n", value); \ | 1032 | return snprintf(buf, 20, format"\n", value); \ |
1032 | } | 1033 | } |
1033 | 1034 | ||
@@ -1121,7 +1122,6 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
1121 | return NULL; | 1122 | return NULL; |
1122 | memset(priv, 0, sizeof(*priv)); | 1123 | memset(priv, 0, sizeof(*priv)); |
1123 | INIT_LIST_HEAD(&priv->list); | 1124 | INIT_LIST_HEAD(&priv->list); |
1124 | INIT_LIST_HEAD(&priv->sessions); | ||
1125 | priv->iscsi_transport = tt; | 1125 | priv->iscsi_transport = tt; |
1126 | 1126 | ||
1127 | priv->cdev.class = &iscsi_transport_class; | 1127 | priv->cdev.class = &iscsi_transport_class; |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 930db398d107..9d9872347f56 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -89,6 +89,11 @@ | |||
89 | #define SD_MAX_RETRIES 5 | 89 | #define SD_MAX_RETRIES 5 |
90 | #define SD_PASSTHROUGH_RETRIES 1 | 90 | #define SD_PASSTHROUGH_RETRIES 1 |
91 | 91 | ||
92 | /* | ||
93 | * Size of the initial data buffer for mode and read capacity data | ||
94 | */ | ||
95 | #define SD_BUF_SIZE 512 | ||
96 | |||
92 | static void scsi_disk_release(struct kref *kref); | 97 | static void scsi_disk_release(struct kref *kref); |
93 | 98 | ||
94 | struct scsi_disk { | 99 | struct scsi_disk { |
@@ -1239,7 +1244,7 @@ sd_do_mode_sense(struct scsi_device *sdp, int dbd, int modepage, | |||
1239 | 1244 | ||
1240 | /* | 1245 | /* |
1241 | * read write protect setting, if possible - called only in sd_revalidate_disk() | 1246 | * read write protect setting, if possible - called only in sd_revalidate_disk() |
1242 | * called with buffer of length 512 | 1247 | * called with buffer of length SD_BUF_SIZE |
1243 | */ | 1248 | */ |
1244 | static void | 1249 | static void |
1245 | sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, | 1250 | sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, |
@@ -1297,7 +1302,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, | |||
1297 | 1302 | ||
1298 | /* | 1303 | /* |
1299 | * sd_read_cache_type - called only from sd_revalidate_disk() | 1304 | * sd_read_cache_type - called only from sd_revalidate_disk() |
1300 | * called with buffer of length 512 | 1305 | * called with buffer of length SD_BUF_SIZE |
1301 | */ | 1306 | */ |
1302 | static void | 1307 | static void |
1303 | sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, | 1308 | sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, |
@@ -1342,6 +1347,8 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, | |||
1342 | 1347 | ||
1343 | /* Take headers and block descriptors into account */ | 1348 | /* Take headers and block descriptors into account */ |
1344 | len += data.header_length + data.block_descriptor_length; | 1349 | len += data.header_length + data.block_descriptor_length; |
1350 | if (len > SD_BUF_SIZE) | ||
1351 | goto bad_sense; | ||
1345 | 1352 | ||
1346 | /* Get the data */ | 1353 | /* Get the data */ |
1347 | res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); | 1354 | res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); |
@@ -1354,6 +1361,12 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, | |||
1354 | int ct = 0; | 1361 | int ct = 0; |
1355 | int offset = data.header_length + data.block_descriptor_length; | 1362 | int offset = data.header_length + data.block_descriptor_length; |
1356 | 1363 | ||
1364 | if (offset >= SD_BUF_SIZE - 2) { | ||
1365 | printk(KERN_ERR "%s: malformed MODE SENSE response", | ||
1366 | diskname); | ||
1367 | goto defaults; | ||
1368 | } | ||
1369 | |||
1357 | if ((buffer[offset] & 0x3f) != modepage) { | 1370 | if ((buffer[offset] & 0x3f) != modepage) { |
1358 | printk(KERN_ERR "%s: got wrong page\n", diskname); | 1371 | printk(KERN_ERR "%s: got wrong page\n", diskname); |
1359 | goto defaults; | 1372 | goto defaults; |
@@ -1398,6 +1411,7 @@ defaults: | |||
1398 | diskname); | 1411 | diskname); |
1399 | sdkp->WCE = 0; | 1412 | sdkp->WCE = 0; |
1400 | sdkp->RCD = 0; | 1413 | sdkp->RCD = 0; |
1414 | sdkp->DPOFUA = 0; | ||
1401 | } | 1415 | } |
1402 | 1416 | ||
1403 | /** | 1417 | /** |
@@ -1421,7 +1435,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
1421 | if (!scsi_device_online(sdp)) | 1435 | if (!scsi_device_online(sdp)) |
1422 | goto out; | 1436 | goto out; |
1423 | 1437 | ||
1424 | buffer = kmalloc(512, GFP_KERNEL | __GFP_DMA); | 1438 | buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL | __GFP_DMA); |
1425 | if (!buffer) { | 1439 | if (!buffer) { |
1426 | printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation " | 1440 | printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation " |
1427 | "failure.\n"); | 1441 | "failure.\n"); |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 7d0700091f3d..5a0a19322d01 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1679,7 +1679,7 @@ static int | |||
1679 | sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize) | 1679 | sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize) |
1680 | { | 1680 | { |
1681 | int sg_bufflen = tablesize * sizeof(struct scatterlist); | 1681 | int sg_bufflen = tablesize * sizeof(struct scatterlist); |
1682 | unsigned int gfp_flags = GFP_ATOMIC | __GFP_NOWARN; | 1682 | gfp_t gfp_flags = GFP_ATOMIC | __GFP_NOWARN; |
1683 | 1683 | ||
1684 | /* | 1684 | /* |
1685 | * TODO: test without low_dma, we should not need it since | 1685 | * TODO: test without low_dma, we should not need it since |
@@ -2162,7 +2162,7 @@ sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size) | |||
2162 | 2162 | ||
2163 | srp->res_used = 1; | 2163 | srp->res_used = 1; |
2164 | SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size)); | 2164 | SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size)); |
2165 | rem = size = (size + 1) & (~1); /* round to even for aha1542 */ | 2165 | rem = size; |
2166 | 2166 | ||
2167 | for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) { | 2167 | for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) { |
2168 | num = sg->length; | 2168 | num = sg->length; |
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 5d02ff4db6cc..b65462f76484 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c | |||
@@ -192,7 +192,7 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) | |||
192 | SDev = cd->device; | 192 | SDev = cd->device; |
193 | 193 | ||
194 | if (!sense) { | 194 | if (!sense) { |
195 | sense = kmalloc(sizeof(*sense), GFP_KERNEL); | 195 | sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); |
196 | if (!sense) { | 196 | if (!sense) { |
197 | err = -ENOMEM; | 197 | err = -ENOMEM; |
198 | goto out; | 198 | goto out; |
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index 8260f040d39c..2627000ca653 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c | |||
@@ -919,6 +919,8 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru | |||
919 | 919 | ||
920 | tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED); | 920 | tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED); |
921 | tp->usrtags = SYM_SETUP_MAX_TAG; | 921 | tp->usrtags = SYM_SETUP_MAX_TAG; |
922 | tp->usr_width = np->maxwide; | ||
923 | tp->usr_period = 9; | ||
922 | 924 | ||
923 | sym_nvram_setup_target(tp, i, nvram); | 925 | sym_nvram_setup_target(tp, i, nvram); |
924 | 926 | ||
@@ -3588,7 +3590,7 @@ static int sym_evaluate_dp(struct sym_hcb *np, struct sym_ccb *cp, u32 scr, int | |||
3588 | 3590 | ||
3589 | if (pm) { | 3591 | if (pm) { |
3590 | dp_scr = scr_to_cpu(pm->ret); | 3592 | dp_scr = scr_to_cpu(pm->ret); |
3591 | dp_ofs -= scr_to_cpu(pm->sg.size); | 3593 | dp_ofs -= scr_to_cpu(pm->sg.size) & 0x00ffffff; |
3592 | } | 3594 | } |
3593 | 3595 | ||
3594 | /* | 3596 | /* |
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 7aef7518b0d1..8c5c276c5577 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -362,7 +362,7 @@ static struct uart_ops serial21285_ops = { | |||
362 | 362 | ||
363 | static struct uart_port serial21285_port = { | 363 | static struct uart_port serial21285_port = { |
364 | .mapbase = 0x42000160, | 364 | .mapbase = 0x42000160, |
365 | .iotype = SERIAL_IO_MEM, | 365 | .iotype = UPIO_MEM, |
366 | .irq = NO_IRQ, | 366 | .irq = NO_IRQ, |
367 | .fifosize = 16, | 367 | .fifosize = 16, |
368 | .ops = &serial21285_ops, | 368 | .ops = &serial21285_ops, |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 8cbf0fc5a225..7f0f35a05dca 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -332,7 +332,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg | |||
332 | * Make sure that we do not overflow the buffer | 332 | * Make sure that we do not overflow the buffer |
333 | */ | 333 | */ |
334 | if (tty_request_buffer_room(tty, 1) == 0) { | 334 | if (tty_request_buffer_room(tty, 1) == 0) { |
335 | schedule_work(&tty->flip.work); | 335 | tty_schedule_flip(tty); |
336 | return; | 336 | return; |
337 | } | 337 | } |
338 | 338 | ||
@@ -353,7 +353,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg | |||
353 | } while((rx = uart->urx.w) & URX_DATA_READY); | 353 | } while((rx = uart->urx.w) & URX_DATA_READY); |
354 | #endif | 354 | #endif |
355 | 355 | ||
356 | schedule_work(&tty->flip.work); | 356 | tty_schedule_flip(tty); |
357 | 357 | ||
358 | clear_and_exit: | 358 | clear_and_exit: |
359 | return; | 359 | return; |
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 60f5a5dc17f1..9843ae3d420e 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
@@ -509,7 +509,7 @@ static _INLINE_ void receive_chars(ser_info_t *info) | |||
509 | 509 | ||
510 | info->rx_cur = (QUICC_BD *)bdp; | 510 | info->rx_cur = (QUICC_BD *)bdp; |
511 | 511 | ||
512 | schedule_work(&tty->flip.work); | 512 | tty_schedule_flip(tty); |
513 | } | 513 | } |
514 | 514 | ||
515 | static _INLINE_ void receive_break(ser_info_t *info) | 515 | static _INLINE_ void receive_break(ser_info_t *info) |
@@ -521,7 +521,7 @@ static _INLINE_ void receive_break(ser_info_t *info) | |||
521 | * the break. If not, we exit now, losing the break. FIXME | 521 | * the break. If not, we exit now, losing the break. FIXME |
522 | */ | 522 | */ |
523 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 523 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
524 | schedule_work(&tty->flip.work); | 524 | tty_schedule_flip(tty); |
525 | } | 525 | } |
526 | 526 | ||
527 | static _INLINE_ void transmit_chars(ser_info_t *info) | 527 | static _INLINE_ void transmit_chars(ser_info_t *info) |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 179c1f065e60..7aca22c9976d 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -2198,7 +2198,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2198 | touch_nmi_watchdog(); | 2198 | touch_nmi_watchdog(); |
2199 | 2199 | ||
2200 | /* | 2200 | /* |
2201 | * First save the UER then disable the interrupts | 2201 | * First save the IER then disable the interrupts |
2202 | */ | 2202 | */ |
2203 | ier = serial_in(up, UART_IER); | 2203 | ier = serial_in(up, UART_IER); |
2204 | 2204 | ||
@@ -2229,6 +2229,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2229 | * and restore the IER | 2229 | * and restore the IER |
2230 | */ | 2230 | */ |
2231 | wait_for_xmitr(up, BOTH_EMPTY); | 2231 | wait_for_xmitr(up, BOTH_EMPTY); |
2232 | up->ier |= UART_IER_THRI; | ||
2232 | serial_out(up, UART_IER, ier | UART_IER_THRI); | 2233 | serial_out(up, UART_IER, ier | UART_IER_THRI); |
2233 | } | 2234 | } |
2234 | 2235 | ||
@@ -2325,6 +2326,12 @@ static struct uart_driver serial8250_reg = { | |||
2325 | .cons = SERIAL8250_CONSOLE, | 2326 | .cons = SERIAL8250_CONSOLE, |
2326 | }; | 2327 | }; |
2327 | 2328 | ||
2329 | /* | ||
2330 | * early_serial_setup - early registration for 8250 ports | ||
2331 | * | ||
2332 | * Setup an 8250 port structure prior to console initialisation. Use | ||
2333 | * after console initialisation will cause undefined behaviour. | ||
2334 | */ | ||
2328 | int __init early_serial_setup(struct uart_port *port) | 2335 | int __init early_serial_setup(struct uart_port *port) |
2329 | { | 2336 | { |
2330 | if (port->line >= ARRAY_SIZE(serial8250_ports)) | 2337 | if (port->line >= ARRAY_SIZE(serial8250_ports)) |
diff --git a/drivers/serial/8250_au1x00.c b/drivers/serial/8250_au1x00.c index 06ae8fbcc947..8d8d7a70d03e 100644 --- a/drivers/serial/8250_au1x00.c +++ b/drivers/serial/8250_au1x00.c | |||
@@ -56,7 +56,6 @@ static struct plat_serial8250_port au1x00_data[] = { | |||
56 | #elif defined(CONFIG_SOC_AU1550) | 56 | #elif defined(CONFIG_SOC_AU1550) |
57 | PORT(UART0_ADDR, AU1550_UART0_INT), | 57 | PORT(UART0_ADDR, AU1550_UART0_INT), |
58 | PORT(UART1_ADDR, AU1550_UART1_INT), | 58 | PORT(UART1_ADDR, AU1550_UART1_INT), |
59 | PORT(UART2_ADDR, AU1550_UART2_INT), | ||
60 | PORT(UART3_ADDR, AU1550_UART3_INT), | 59 | PORT(UART3_ADDR, AU1550_UART3_INT), |
61 | #elif defined(CONFIG_SOC_AU1200) | 60 | #elif defined(CONFIG_SOC_AU1200) |
62 | PORT(UART0_ADDR, AU1200_UART0_INT), | 61 | PORT(UART0_ADDR, AU1200_UART0_INT), |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 2a912153321e..94886c000d2a 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -439,6 +439,20 @@ static int pci_siig_init(struct pci_dev *dev) | |||
439 | return -ENODEV; | 439 | return -ENODEV; |
440 | } | 440 | } |
441 | 441 | ||
442 | static int pci_siig_setup(struct serial_private *priv, | ||
443 | struct pciserial_board *board, | ||
444 | struct uart_port *port, int idx) | ||
445 | { | ||
446 | unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0; | ||
447 | |||
448 | if (idx > 3) { | ||
449 | bar = 4; | ||
450 | offset = (idx - 4) * 8; | ||
451 | } | ||
452 | |||
453 | return setup_port(priv, port, bar, offset, 0); | ||
454 | } | ||
455 | |||
442 | /* | 456 | /* |
443 | * Timedia has an explosion of boards, and to avoid the PCI table from | 457 | * Timedia has an explosion of boards, and to avoid the PCI table from |
444 | * growing *huge*, we use this function to collapse some 70 entries | 458 | * growing *huge*, we use this function to collapse some 70 entries |
@@ -748,7 +762,7 @@ static struct pci_serial_quirk pci_serial_quirks[] = { | |||
748 | .subvendor = PCI_ANY_ID, | 762 | .subvendor = PCI_ANY_ID, |
749 | .subdevice = PCI_ANY_ID, | 763 | .subdevice = PCI_ANY_ID, |
750 | .init = pci_siig_init, | 764 | .init = pci_siig_init, |
751 | .setup = pci_default_setup, | 765 | .setup = pci_siig_setup, |
752 | }, | 766 | }, |
753 | /* | 767 | /* |
754 | * Titan cards | 768 | * Titan cards |
@@ -1868,6 +1882,10 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
1868 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 1882 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
1869 | PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0, | 1883 | PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0, |
1870 | pbn_b0_4_1843200 }, | 1884 | pbn_b0_4_1843200 }, |
1885 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, | ||
1886 | PCI_VENDOR_ID_AFAVLAB, | ||
1887 | PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0, | ||
1888 | pbn_b0_4_1152000 }, | ||
1871 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | 1889 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, |
1872 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 1890 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
1873 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, | 1891 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, |
@@ -2141,6 +2159,15 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
2141 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850, | 2159 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850, |
2142 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 2160 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
2143 | pbn_b0_bt_4_921600 }, | 2161 | pbn_b0_bt_4_921600 }, |
2162 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_550, | ||
2163 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
2164 | pbn_b0_bt_8_921600 }, | ||
2165 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_650, | ||
2166 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
2167 | pbn_b0_bt_8_921600 }, | ||
2168 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_850, | ||
2169 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
2170 | pbn_b0_bt_8_921600 }, | ||
2144 | 2171 | ||
2145 | /* | 2172 | /* |
2146 | * Computone devices submitted by Doug McNash dmcnash@computone.com | 2173 | * Computone devices submitted by Doug McNash dmcnash@computone.com |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ee4265d7a8c9..b3c561abe3f6 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -98,6 +98,7 @@ config SERIAL_8250_NR_UARTS | |||
98 | config SERIAL_8250_RUNTIME_UARTS | 98 | config SERIAL_8250_RUNTIME_UARTS |
99 | int "Number of 8250/16550 serial ports to register at runtime" | 99 | int "Number of 8250/16550 serial ports to register at runtime" |
100 | depends on SERIAL_8250 | 100 | depends on SERIAL_8250 |
101 | range 0 SERIAL_8250_NR_UARTS | ||
101 | default "4" | 102 | default "4" |
102 | help | 103 | help |
103 | Set this to the maximum number of serial ports you want | 104 | Set this to the maximum number of serial ports you want |
@@ -901,8 +902,8 @@ config SERIAL_JSM | |||
901 | something like this to connect more than two modems to your Linux | 902 | something like this to connect more than two modems to your Linux |
902 | box, for instance in order to become a dial-in server. This driver | 903 | box, for instance in order to become a dial-in server. This driver |
903 | supports PCI boards only. | 904 | supports PCI boards only. |
904 | If you have a card like this, say Y here and read the file | 905 | |
905 | <file:Documentation/jsm.txt>. | 906 | If you have a card like this, say Y here, otherwise say N. |
906 | 907 | ||
907 | To compile this driver as a module, choose M here: the | 908 | To compile this driver as a module, choose M here: the |
908 | module will be called jsm. | 909 | module will be called jsm. |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 429de2723a1c..321a3b3a5728 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -561,7 +561,7 @@ static struct uart_amba_port amba_ports[UART_NR] = { | |||
561 | .port = { | 561 | .port = { |
562 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), | 562 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), |
563 | .mapbase = INTEGRATOR_UART0_BASE, | 563 | .mapbase = INTEGRATOR_UART0_BASE, |
564 | .iotype = SERIAL_IO_MEM, | 564 | .iotype = UPIO_MEM, |
565 | .irq = IRQ_UARTINT0, | 565 | .irq = IRQ_UARTINT0, |
566 | .uartclk = 14745600, | 566 | .uartclk = 14745600, |
567 | .fifosize = 16, | 567 | .fifosize = 16, |
@@ -576,7 +576,7 @@ static struct uart_amba_port amba_ports[UART_NR] = { | |||
576 | .port = { | 576 | .port = { |
577 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), | 577 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), |
578 | .mapbase = INTEGRATOR_UART1_BASE, | 578 | .mapbase = INTEGRATOR_UART1_BASE, |
579 | .iotype = SERIAL_IO_MEM, | 579 | .iotype = UPIO_MEM, |
580 | .irq = IRQ_UARTINT1, | 580 | .irq = IRQ_UARTINT1, |
581 | .uartclk = 14745600, | 581 | .uartclk = 14745600, |
582 | .fifosize = 16, | 582 | .fifosize = 16, |
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index ceb5d7f37bbd..344022fe53ef 100644 --- a/drivers/serial/au1x00_uart.c +++ b/drivers/serial/au1x00_uart.c | |||
@@ -892,7 +892,7 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res | |||
892 | int ret = 0; | 892 | int ret = 0; |
893 | 893 | ||
894 | switch (up->port.iotype) { | 894 | switch (up->port.iotype) { |
895 | case SERIAL_IO_MEM: | 895 | case UPIO_MEM: |
896 | if (up->port.mapbase) { | 896 | if (up->port.mapbase) { |
897 | *res = request_mem_region(up->port.mapbase, size, "serial"); | 897 | *res = request_mem_region(up->port.mapbase, size, "serial"); |
898 | if (!*res) | 898 | if (!*res) |
@@ -900,8 +900,8 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res | |||
900 | } | 900 | } |
901 | break; | 901 | break; |
902 | 902 | ||
903 | case SERIAL_IO_HUB6: | 903 | case UPIO_HUB6: |
904 | case SERIAL_IO_PORT: | 904 | case UPIO_PORT: |
905 | *res = request_region(up->port.iobase, size, "serial"); | 905 | *res = request_region(up->port.iobase, size, "serial"); |
906 | if (!*res) | 906 | if (!*res) |
907 | ret = -EBUSY; | 907 | ret = -EBUSY; |
@@ -919,7 +919,7 @@ static void serial8250_release_port(struct uart_port *port) | |||
919 | size <<= up->port.regshift; | 919 | size <<= up->port.regshift; |
920 | 920 | ||
921 | switch (up->port.iotype) { | 921 | switch (up->port.iotype) { |
922 | case SERIAL_IO_MEM: | 922 | case UPIO_MEM: |
923 | if (up->port.mapbase) { | 923 | if (up->port.mapbase) { |
924 | /* | 924 | /* |
925 | * Unmap the area. | 925 | * Unmap the area. |
@@ -935,8 +935,8 @@ static void serial8250_release_port(struct uart_port *port) | |||
935 | } | 935 | } |
936 | break; | 936 | break; |
937 | 937 | ||
938 | case SERIAL_IO_HUB6: | 938 | case UPIO_HUB6: |
939 | case SERIAL_IO_PORT: | 939 | case UPIO_PORT: |
940 | start = up->port.iobase; | 940 | start = up->port.iobase; |
941 | 941 | ||
942 | if (size) | 942 | if (size) |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 16af5626c243..b7bf4c698a47 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -252,12 +252,9 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
252 | /* If we have not enough room in tty flip buffer, then we try | 252 | /* If we have not enough room in tty flip buffer, then we try |
253 | * later, which will be the next rx-interrupt or a timeout | 253 | * later, which will be the next rx-interrupt or a timeout |
254 | */ | 254 | */ |
255 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { | 255 | if(tty_buffer_request_room(tty, i) < i) { |
256 | tty->flip.work.func((void *)tty); | 256 | printk(KERN_WARNING "No room in flip buffer\n"); |
257 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { | 257 | return; |
258 | printk(KERN_WARNING "TTY_DONT_FLIP set\n"); | ||
259 | return; | ||
260 | } | ||
261 | } | 258 | } |
262 | 259 | ||
263 | /* get pointer */ | 260 | /* get pointer */ |
@@ -276,9 +273,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
276 | continue; | 273 | continue; |
277 | 274 | ||
278 | error_return: | 275 | error_return: |
279 | *tty->flip.char_buf_ptr++ = ch; | 276 | tty_insert_flip_char(tty, ch, flg); |
280 | *tty->flip.flag_buf_ptr++ = flg; | ||
281 | tty->flip.count++; | ||
282 | 277 | ||
283 | } /* End while (i--) */ | 278 | } /* End while (i--) */ |
284 | 279 | ||
@@ -908,7 +903,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
908 | .port = { | 903 | .port = { |
909 | .irq = SMC1_IRQ, | 904 | .irq = SMC1_IRQ, |
910 | .ops = &cpm_uart_pops, | 905 | .ops = &cpm_uart_pops, |
911 | .iotype = SERIAL_IO_MEM, | 906 | .iotype = UPIO_MEM, |
912 | .lock = SPIN_LOCK_UNLOCKED, | 907 | .lock = SPIN_LOCK_UNLOCKED, |
913 | }, | 908 | }, |
914 | .flags = FLAG_SMC, | 909 | .flags = FLAG_SMC, |
@@ -922,7 +917,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
922 | .port = { | 917 | .port = { |
923 | .irq = SMC2_IRQ, | 918 | .irq = SMC2_IRQ, |
924 | .ops = &cpm_uart_pops, | 919 | .ops = &cpm_uart_pops, |
925 | .iotype = SERIAL_IO_MEM, | 920 | .iotype = UPIO_MEM, |
926 | .lock = SPIN_LOCK_UNLOCKED, | 921 | .lock = SPIN_LOCK_UNLOCKED, |
927 | }, | 922 | }, |
928 | .flags = FLAG_SMC, | 923 | .flags = FLAG_SMC, |
@@ -939,7 +934,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
939 | .port = { | 934 | .port = { |
940 | .irq = SCC1_IRQ, | 935 | .irq = SCC1_IRQ, |
941 | .ops = &cpm_uart_pops, | 936 | .ops = &cpm_uart_pops, |
942 | .iotype = SERIAL_IO_MEM, | 937 | .iotype = UPIO_MEM, |
943 | .lock = SPIN_LOCK_UNLOCKED, | 938 | .lock = SPIN_LOCK_UNLOCKED, |
944 | }, | 939 | }, |
945 | .tx_nrfifos = TX_NUM_FIFO, | 940 | .tx_nrfifos = TX_NUM_FIFO, |
@@ -953,7 +948,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
953 | .port = { | 948 | .port = { |
954 | .irq = SCC2_IRQ, | 949 | .irq = SCC2_IRQ, |
955 | .ops = &cpm_uart_pops, | 950 | .ops = &cpm_uart_pops, |
956 | .iotype = SERIAL_IO_MEM, | 951 | .iotype = UPIO_MEM, |
957 | .lock = SPIN_LOCK_UNLOCKED, | 952 | .lock = SPIN_LOCK_UNLOCKED, |
958 | }, | 953 | }, |
959 | .tx_nrfifos = TX_NUM_FIFO, | 954 | .tx_nrfifos = TX_NUM_FIFO, |
@@ -967,7 +962,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
967 | .port = { | 962 | .port = { |
968 | .irq = SCC3_IRQ, | 963 | .irq = SCC3_IRQ, |
969 | .ops = &cpm_uart_pops, | 964 | .ops = &cpm_uart_pops, |
970 | .iotype = SERIAL_IO_MEM, | 965 | .iotype = UPIO_MEM, |
971 | .lock = SPIN_LOCK_UNLOCKED, | 966 | .lock = SPIN_LOCK_UNLOCKED, |
972 | }, | 967 | }, |
973 | .tx_nrfifos = TX_NUM_FIFO, | 968 | .tx_nrfifos = TX_NUM_FIFO, |
@@ -981,7 +976,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
981 | .port = { | 976 | .port = { |
982 | .irq = SCC4_IRQ, | 977 | .irq = SCC4_IRQ, |
983 | .ops = &cpm_uart_pops, | 978 | .ops = &cpm_uart_pops, |
984 | .iotype = SERIAL_IO_MEM, | 979 | .iotype = UPIO_MEM, |
985 | .lock = SPIN_LOCK_UNLOCKED, | 980 | .lock = SPIN_LOCK_UNLOCKED, |
986 | }, | 981 | }, |
987 | .tx_nrfifos = TX_NUM_FIFO, | 982 | .tx_nrfifos = TX_NUM_FIFO, |
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index a64ba26a94e8..ba5541de673b 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
@@ -262,6 +262,7 @@ static inline void dz_receive_chars(struct dz_port *dport) | |||
262 | } | 262 | } |
263 | tty_insert_flip_char(tty, ch, flag); | 263 | tty_insert_flip_char(tty, ch, flag); |
264 | ignore_char: | 264 | ignore_char: |
265 | ; | ||
265 | } while (status & DZ_DVAL); | 266 | } while (status & DZ_DVAL); |
266 | 267 | ||
267 | if (tty) | 268 | if (tty) |
@@ -650,7 +651,7 @@ static void __init dz_init_ports(void) | |||
650 | for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { | 651 | for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { |
651 | spin_lock_init(&dport->port.lock); | 652 | spin_lock_init(&dport->port.lock); |
652 | dport->port.membase = (char *) base; | 653 | dport->port.membase = (char *) base; |
653 | dport->port.iotype = SERIAL_IO_PORT; | 654 | dport->port.iotype = UPIO_PORT; |
654 | dport->port.irq = dec_interrupt[DEC_IRQ_DZ11]; | 655 | dport->port.irq = dec_interrupt[DEC_IRQ_DZ11]; |
655 | dport->port.line = i; | 656 | dport->port.line = i; |
656 | dport->port.fifosize = 1; | 657 | dport->port.fifosize = 1; |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 858048efe1ed..4d53fb5ca87b 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -668,7 +668,7 @@ static struct imx_port imx_ports[] = { | |||
668 | .rtsirq = UART1_MINT_RTS, | 668 | .rtsirq = UART1_MINT_RTS, |
669 | .port = { | 669 | .port = { |
670 | .type = PORT_IMX, | 670 | .type = PORT_IMX, |
671 | .iotype = SERIAL_IO_MEM, | 671 | .iotype = UPIO_MEM, |
672 | .membase = (void *)IMX_UART1_BASE, | 672 | .membase = (void *)IMX_UART1_BASE, |
673 | .mapbase = IMX_UART1_BASE, /* FIXME */ | 673 | .mapbase = IMX_UART1_BASE, /* FIXME */ |
674 | .irq = UART1_MINT_RX, | 674 | .irq = UART1_MINT_RX, |
@@ -684,7 +684,7 @@ static struct imx_port imx_ports[] = { | |||
684 | .rtsirq = UART2_MINT_RTS, | 684 | .rtsirq = UART2_MINT_RTS, |
685 | .port = { | 685 | .port = { |
686 | .type = PORT_IMX, | 686 | .type = PORT_IMX, |
687 | .iotype = SERIAL_IO_MEM, | 687 | .iotype = UPIO_MEM, |
688 | .membase = (void *)IMX_UART2_BASE, | 688 | .membase = (void *)IMX_UART2_BASE, |
689 | .mapbase = IMX_UART2_BASE, /* FIXME */ | 689 | .mapbase = IMX_UART2_BASE, /* FIXME */ |
690 | .irq = UART2_MINT_RX, | 690 | .irq = UART2_MINT_RX, |
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index 1d85533d46d2..a37579ce6d76 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c | |||
@@ -1717,11 +1717,9 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1717 | } | 1717 | } |
1718 | 1718 | ||
1719 | if (cflag & CRTSCTS) { | 1719 | if (cflag & CRTSCTS) { |
1720 | info->flags |= ASYNC_CTS_FLOW; | ||
1721 | port->ip_sscr |= IOC4_SSCR_HFC_EN; | 1720 | port->ip_sscr |= IOC4_SSCR_HFC_EN; |
1722 | } | 1721 | } |
1723 | else { | 1722 | else { |
1724 | info->flags &= ~ASYNC_CTS_FLOW; | ||
1725 | port->ip_sscr &= ~IOC4_SSCR_HFC_EN; | 1723 | port->ip_sscr &= ~IOC4_SSCR_HFC_EN; |
1726 | } | 1724 | } |
1727 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); | 1725 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); |
@@ -1760,18 +1758,6 @@ static inline int ic4_startup_local(struct uart_port *the_port) | |||
1760 | 1758 | ||
1761 | info = the_port->info; | 1759 | info = the_port->info; |
1762 | 1760 | ||
1763 | if (info->tty) { | ||
1764 | set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
1765 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | ||
1766 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | ||
1767 | info->tty->alt_speed = 57600; | ||
1768 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | ||
1769 | info->tty->alt_speed = 115200; | ||
1770 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | ||
1771 | info->tty->alt_speed = 230400; | ||
1772 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | ||
1773 | info->tty->alt_speed = 460800; | ||
1774 | } | ||
1775 | local_open(port); | 1761 | local_open(port); |
1776 | 1762 | ||
1777 | /* set the speed of the serial port */ | 1763 | /* set the speed of the serial port */ |
@@ -2315,7 +2301,6 @@ static void receive_chars(struct uart_port *the_port) | |||
2315 | int read_count, request_count = IOC4_MAX_CHARS; | 2301 | int read_count, request_count = IOC4_MAX_CHARS; |
2316 | struct uart_icount *icount; | 2302 | struct uart_icount *icount; |
2317 | struct uart_info *info = the_port->info; | 2303 | struct uart_info *info = the_port->info; |
2318 | int flip = 0; | ||
2319 | unsigned long pflags; | 2304 | unsigned long pflags; |
2320 | 2305 | ||
2321 | /* Make sure all the pointers are "good" ones */ | 2306 | /* Make sure all the pointers are "good" ones */ |
@@ -2327,7 +2312,7 @@ static void receive_chars(struct uart_port *the_port) | |||
2327 | spin_lock_irqsave(&the_port->lock, pflags); | 2312 | spin_lock_irqsave(&the_port->lock, pflags); |
2328 | tty = info->tty; | 2313 | tty = info->tty; |
2329 | 2314 | ||
2330 | request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS - 2); | 2315 | request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS); |
2331 | 2316 | ||
2332 | if (request_count > 0) { | 2317 | if (request_count > 0) { |
2333 | icount = &the_port->icount; | 2318 | icount = &the_port->icount; |
@@ -2340,8 +2325,7 @@ static void receive_chars(struct uart_port *the_port) | |||
2340 | 2325 | ||
2341 | spin_unlock_irqrestore(&the_port->lock, pflags); | 2326 | spin_unlock_irqrestore(&the_port->lock, pflags); |
2342 | 2327 | ||
2343 | if (flip) | 2328 | tty_flip_buffer_push(tty); |
2344 | tty_flip_buffer_push(tty); | ||
2345 | } | 2329 | } |
2346 | 2330 | ||
2347 | /** | 2331 | /** |
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 66f117d15065..193722d680cf 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c | |||
@@ -215,7 +215,7 @@ static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs) | |||
215 | /* Lower and upper byte of baud rate generator divisor. */ | 215 | /* Lower and upper byte of baud rate generator divisor. */ |
216 | write_zsreg(channel, R12, regs[R12]); | 216 | write_zsreg(channel, R12, regs[R12]); |
217 | write_zsreg(channel, R13, regs[R13]); | 217 | write_zsreg(channel, R13, regs[R13]); |
218 | 218 | ||
219 | /* Now rewrite R14, with BRENAB (if set). */ | 219 | /* Now rewrite R14, with BRENAB (if set). */ |
220 | write_zsreg(channel, R14, regs[R14]); | 220 | write_zsreg(channel, R14, regs[R14]); |
221 | 221 | ||
@@ -420,10 +420,8 @@ static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up, | |||
420 | if (up->port.info == NULL) | 420 | if (up->port.info == NULL) |
421 | goto ack_tx_int; | 421 | goto ack_tx_int; |
422 | xmit = &up->port.info->xmit; | 422 | xmit = &up->port.info->xmit; |
423 | if (uart_circ_empty(xmit)) { | 423 | if (uart_circ_empty(xmit)) |
424 | uart_write_wakeup(&up->port); | ||
425 | goto ack_tx_int; | 424 | goto ack_tx_int; |
426 | } | ||
427 | if (uart_tx_stopped(&up->port)) | 425 | if (uart_tx_stopped(&up->port)) |
428 | goto ack_tx_int; | 426 | goto ack_tx_int; |
429 | 427 | ||
@@ -571,7 +569,7 @@ static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
571 | else | 569 | else |
572 | clear_bits |= DTR; | 570 | clear_bits |= DTR; |
573 | 571 | ||
574 | /* NOTE: Not subject to 'transmitter active' rule. */ | 572 | /* NOTE: Not subject to 'transmitter active' rule. */ |
575 | up->curregs[R5] |= set_bits; | 573 | up->curregs[R5] |= set_bits; |
576 | up->curregs[R5] &= ~clear_bits; | 574 | up->curregs[R5] &= ~clear_bits; |
577 | write_zsreg(channel, R5, up->curregs[R5]); | 575 | write_zsreg(channel, R5, up->curregs[R5]); |
@@ -654,7 +652,7 @@ static void ip22zilog_enable_ms(struct uart_port *port) | |||
654 | if (new_reg != up->curregs[R15]) { | 652 | if (new_reg != up->curregs[R15]) { |
655 | up->curregs[R15] = new_reg; | 653 | up->curregs[R15] = new_reg; |
656 | 654 | ||
657 | /* NOTE: Not subject to 'transmitter active' rule. */ | 655 | /* NOTE: Not subject to 'transmitter active' rule. */ |
658 | write_zsreg(channel, R15, up->curregs[R15]); | 656 | write_zsreg(channel, R15, up->curregs[R15]); |
659 | } | 657 | } |
660 | } | 658 | } |
@@ -680,7 +678,7 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state) | |||
680 | if (new_reg != up->curregs[R5]) { | 678 | if (new_reg != up->curregs[R5]) { |
681 | up->curregs[R5] = new_reg; | 679 | up->curregs[R5] = new_reg; |
682 | 680 | ||
683 | /* NOTE: Not subject to 'transmitter active' rule. */ | 681 | /* NOTE: Not subject to 'transmitter active' rule. */ |
684 | write_zsreg(channel, R5, up->curregs[R5]); | 682 | write_zsreg(channel, R5, up->curregs[R5]); |
685 | } | 683 | } |
686 | 684 | ||
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index b48066a64a7d..242a04104393 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -80,7 +80,7 @@ | |||
80 | #include <asm/serial.h> | 80 | #include <asm/serial.h> |
81 | 81 | ||
82 | /* Standard COM flags */ | 82 | /* Standard COM flags */ |
83 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | 83 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * SERIAL_PORT_DFNS tells us about built-in ports that have no | 86 | * SERIAL_PORT_DFNS tells us about built-in ports that have no |
diff --git a/drivers/serial/m32r_sio.h b/drivers/serial/m32r_sio.h index 07d0dd80aa3d..7c3ec24f7e50 100644 --- a/drivers/serial/m32r_sio.h +++ b/drivers/serial/m32r_sio.h | |||
@@ -37,7 +37,7 @@ struct old_serial_port { | |||
37 | unsigned int irq; | 37 | unsigned int irq; |
38 | unsigned int flags; | 38 | unsigned int flags; |
39 | unsigned char io_type; | 39 | unsigned char io_type; |
40 | unsigned char *iomem_base; | 40 | unsigned char __iomem *iomem_base; |
41 | unsigned short iomem_reg_shift; | 41 | unsigned short iomem_reg_shift; |
42 | }; | 42 | }; |
43 | 43 | ||
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index 0ef648fa4b2d..8cbbb954df2c 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c | |||
@@ -57,20 +57,16 @@ struct timer_list mcfrs_timer_struct; | |||
57 | * keep going. Perhaps one day the cflag settings for the | 57 | * keep going. Perhaps one day the cflag settings for the |
58 | * console can be used instead. | 58 | * console can be used instead. |
59 | */ | 59 | */ |
60 | #if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ | ||
61 | defined(CONFIG_senTec) || defined(CONFIG_SNEHA) | ||
62 | #define CONSOLE_BAUD_RATE 19200 | ||
63 | #define DEFAULT_CBAUD B19200 | ||
64 | #endif | ||
65 | |||
66 | #if defined(CONFIG_HW_FEITH) | 60 | #if defined(CONFIG_HW_FEITH) |
67 | #define CONSOLE_BAUD_RATE 38400 | 61 | #define CONSOLE_BAUD_RATE 38400 |
68 | #define DEFAULT_CBAUD B38400 | 62 | #define DEFAULT_CBAUD B38400 |
69 | #endif | 63 | #elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) |
70 | |||
71 | #if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) | ||
72 | #define CONSOLE_BAUD_RATE 115200 | 64 | #define CONSOLE_BAUD_RATE 115200 |
73 | #define DEFAULT_CBAUD B115200 | 65 | #define DEFAULT_CBAUD B115200 |
66 | #elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ | ||
67 | defined(CONFIG_senTec) || defined(CONFIG_SNEHA) | ||
68 | #define CONSOLE_BAUD_RATE 19200 | ||
69 | #define DEFAULT_CBAUD B19200 | ||
74 | #endif | 70 | #endif |
75 | 71 | ||
76 | #ifndef CONSOLE_BAUD_RATE | 72 | #ifndef CONSOLE_BAUD_RATE |
@@ -350,7 +346,7 @@ static inline void receive_chars(struct mcf_serial *info) | |||
350 | } | 346 | } |
351 | tty_insert_flip_char(tty, ch, flag); | 347 | tty_insert_flip_char(tty, ch, flag); |
352 | } | 348 | } |
353 | tty_flip_buffer_push(tty); | 349 | tty_schedule_flip(tty); |
354 | return; | 350 | return; |
355 | } | 351 | } |
356 | 352 | ||
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 4e49168c3176..868eaf4a1a68 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c | |||
@@ -462,7 +462,7 @@ static int __init mux_probe(struct parisc_device *dev) | |||
462 | port->mapbase = dev->hpa.start + MUX_OFFSET + | 462 | port->mapbase = dev->hpa.start + MUX_OFFSET + |
463 | (i * MUX_LINE_OFFSET); | 463 | (i * MUX_LINE_OFFSET); |
464 | port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); | 464 | port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); |
465 | port->iotype = SERIAL_IO_MEM; | 465 | port->iotype = UPIO_MEM; |
466 | port->type = PORT_MUX; | 466 | port->type = PORT_MUX; |
467 | port->irq = NO_IRQ; | 467 | port->irq = NO_IRQ; |
468 | port->uartclk = 0; | 468 | port->uartclk = 0; |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 4e03a87f3fb4..9b7ed58cb53b 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -1492,7 +1492,7 @@ no_dma: | |||
1492 | /* | 1492 | /* |
1493 | * Init remaining bits of "port" structure | 1493 | * Init remaining bits of "port" structure |
1494 | */ | 1494 | */ |
1495 | uap->port.iotype = SERIAL_IO_MEM; | 1495 | uap->port.iotype = UPIO_MEM; |
1496 | uap->port.irq = np->intrs[0].line; | 1496 | uap->port.irq = np->intrs[0].line; |
1497 | uap->port.uartclk = ZS_CLOCK; | 1497 | uap->port.uartclk = ZS_CLOCK; |
1498 | uap->port.fifosize = 1; | 1498 | uap->port.fifosize = 1; |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 0a2dd6c5b95f..7410e093a6b9 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -161,7 +161,11 @@ s3c24xx_serial_dbg(const char *fmt, ...) | |||
161 | 161 | ||
162 | /* we can support 3 uarts, but not always use them */ | 162 | /* we can support 3 uarts, but not always use them */ |
163 | 163 | ||
164 | #ifdef CONFIG_CPU_S3C2400 | ||
165 | #define NR_PORTS (2) | ||
166 | #else | ||
164 | #define NR_PORTS (3) | 167 | #define NR_PORTS (3) |
168 | #endif | ||
165 | 169 | ||
166 | /* port irq numbers */ | 170 | /* port irq numbers */ |
167 | 171 | ||
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index ff7b60b4de37..2c00b8625852 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -628,7 +628,7 @@ static void __init sa1100_init_ports(void) | |||
628 | sa1100_ports[i].port.ops = &sa1100_pops; | 628 | sa1100_ports[i].port.ops = &sa1100_pops; |
629 | sa1100_ports[i].port.fifosize = 8; | 629 | sa1100_ports[i].port.fifosize = 8; |
630 | sa1100_ports[i].port.line = i; | 630 | sa1100_ports[i].port.line = i; |
631 | sa1100_ports[i].port.iotype = SERIAL_IO_MEM; | 631 | sa1100_ports[i].port.iotype = UPIO_MEM; |
632 | init_timer(&sa1100_ports[i].timer); | 632 | init_timer(&sa1100_ports[i].timer); |
633 | sa1100_ports[i].timer.function = sa1100_timeout; | 633 | sa1100_ports[i].timer.function = sa1100_timeout; |
634 | sa1100_ports[i].timer.data = (unsigned long)&sa1100_ports[i]; | 634 | sa1100_ports[i].timer.data = (unsigned long)&sa1100_ports[i]; |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 0717abfdae06..cc1faa31d124 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -71,6 +71,11 @@ static void uart_change_pm(struct uart_state *state, int pm_state); | |||
71 | void uart_write_wakeup(struct uart_port *port) | 71 | void uart_write_wakeup(struct uart_port *port) |
72 | { | 72 | { |
73 | struct uart_info *info = port->info; | 73 | struct uart_info *info = port->info; |
74 | /* | ||
75 | * This means you called this function _after_ the port was | ||
76 | * closed. No cookie for you. | ||
77 | */ | ||
78 | BUG_ON(!info); | ||
74 | tasklet_schedule(&info->tlet); | 79 | tasklet_schedule(&info->tlet); |
75 | } | 80 | } |
76 | 81 | ||
@@ -471,14 +476,26 @@ static void uart_flush_chars(struct tty_struct *tty) | |||
471 | } | 476 | } |
472 | 477 | ||
473 | static int | 478 | static int |
474 | uart_write(struct tty_struct *tty, const unsigned char * buf, int count) | 479 | uart_write(struct tty_struct *tty, const unsigned char *buf, int count) |
475 | { | 480 | { |
476 | struct uart_state *state = tty->driver_data; | 481 | struct uart_state *state = tty->driver_data; |
477 | struct uart_port *port = state->port; | 482 | struct uart_port *port; |
478 | struct circ_buf *circ = &state->info->xmit; | 483 | struct circ_buf *circ; |
479 | unsigned long flags; | 484 | unsigned long flags; |
480 | int c, ret = 0; | 485 | int c, ret = 0; |
481 | 486 | ||
487 | /* | ||
488 | * This means you called this function _after_ the port was | ||
489 | * closed. No cookie for you. | ||
490 | */ | ||
491 | if (!state || !state->info) { | ||
492 | WARN_ON(1); | ||
493 | return -EL3HLT; | ||
494 | } | ||
495 | |||
496 | port = state->port; | ||
497 | circ = &state->info->xmit; | ||
498 | |||
482 | if (!circ->buf) | 499 | if (!circ->buf) |
483 | return 0; | 500 | return 0; |
484 | 501 | ||
@@ -521,6 +538,15 @@ static void uart_flush_buffer(struct tty_struct *tty) | |||
521 | struct uart_port *port = state->port; | 538 | struct uart_port *port = state->port; |
522 | unsigned long flags; | 539 | unsigned long flags; |
523 | 540 | ||
541 | /* | ||
542 | * This means you called this function _after_ the port was | ||
543 | * closed. No cookie for you. | ||
544 | */ | ||
545 | if (!state || !state->info) { | ||
546 | WARN_ON(1); | ||
547 | return; | ||
548 | } | ||
549 | |||
524 | DPRINTK("uart_flush_buffer(%d) called\n", tty->index); | 550 | DPRINTK("uart_flush_buffer(%d) called\n", tty->index); |
525 | 551 | ||
526 | spin_lock_irqsave(&port->lock, flags); | 552 | spin_lock_irqsave(&port->lock, flags); |
@@ -2237,7 +2263,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) | |||
2237 | * If this port is a console, then the spinlock is already | 2263 | * If this port is a console, then the spinlock is already |
2238 | * initialised. | 2264 | * initialised. |
2239 | */ | 2265 | */ |
2240 | if (!uart_console(port)) | 2266 | if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) |
2241 | spin_lock_init(&port->lock); | 2267 | spin_lock_init(&port->lock); |
2242 | 2268 | ||
2243 | uart_configure_port(drv, state, port); | 2269 | uart_configure_port(drv, state, port); |
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index d0490f67f597..04186eaae227 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c | |||
@@ -501,7 +501,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { | |||
501 | .port = { | 501 | .port = { |
502 | .membase = (void*) io_p2v (UART1_PHYS), | 502 | .membase = (void*) io_p2v (UART1_PHYS), |
503 | .mapbase = UART1_PHYS, | 503 | .mapbase = UART1_PHYS, |
504 | .iotype = SERIAL_IO_MEM, | 504 | .iotype = UPIO_MEM, |
505 | .irq = IRQ_UART1INTR, | 505 | .irq = IRQ_UART1INTR, |
506 | .uartclk = 14745600/2, | 506 | .uartclk = 14745600/2, |
507 | .fifosize = 16, | 507 | .fifosize = 16, |
@@ -514,7 +514,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { | |||
514 | .port = { | 514 | .port = { |
515 | .membase = (void*) io_p2v (UART2_PHYS), | 515 | .membase = (void*) io_p2v (UART2_PHYS), |
516 | .mapbase = UART2_PHYS, | 516 | .mapbase = UART2_PHYS, |
517 | .iotype = SERIAL_IO_MEM, | 517 | .iotype = UPIO_MEM, |
518 | .irq = IRQ_UART2INTR, | 518 | .irq = IRQ_UART2INTR, |
519 | .uartclk = 14745600/2, | 519 | .uartclk = 14745600/2, |
520 | .fifosize = 16, | 520 | .fifosize = 16, |
@@ -527,7 +527,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { | |||
527 | .port = { | 527 | .port = { |
528 | .membase = (void*) io_p2v (UART3_PHYS), | 528 | .membase = (void*) io_p2v (UART3_PHYS), |
529 | .mapbase = UART3_PHYS, | 529 | .mapbase = UART3_PHYS, |
530 | .iotype = SERIAL_IO_MEM, | 530 | .iotype = UPIO_MEM, |
531 | .irq = IRQ_UART3INTR, | 531 | .irq = IRQ_UART3INTR, |
532 | .uartclk = 14745600/2, | 532 | .uartclk = 14745600/2, |
533 | .fifosize = 16, | 533 | .fifosize = 16, |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 80737c131ce7..44f6bf79bbe1 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -1468,10 +1468,10 @@ static struct sci_port sci_ports[] = { | |||
1468 | .port = { | 1468 | .port = { |
1469 | .membase = (void *)0xff923000, | 1469 | .membase = (void *)0xff923000, |
1470 | .mapbase = 0xff923000, | 1470 | .mapbase = 0xff923000, |
1471 | .iotype = SERIAL_IO_MEM, | 1471 | .iotype = UPIO_MEM, |
1472 | .irq = 61, | 1472 | .irq = 61, |
1473 | .ops = &sci_uart_ops, | 1473 | .ops = &sci_uart_ops, |
1474 | .flags = ASYNC_BOOT_AUTOCONF, | 1474 | .flags = UPF_BOOT_AUTOCONF, |
1475 | .line = 0, | 1475 | .line = 0, |
1476 | }, | 1476 | }, |
1477 | .type = PORT_SCIF, | 1477 | .type = PORT_SCIF, |
@@ -1482,10 +1482,10 @@ static struct sci_port sci_ports[] = { | |||
1482 | .port = { | 1482 | .port = { |
1483 | .membase = (void *)0xff924000, | 1483 | .membase = (void *)0xff924000, |
1484 | .mapbase = 0xff924000, | 1484 | .mapbase = 0xff924000, |
1485 | .iotype = SERIAL_IO_MEM, | 1485 | .iotype = UPIO_MEM, |
1486 | .irq = 62, | 1486 | .irq = 62, |
1487 | .ops = &sci_uart_ops, | 1487 | .ops = &sci_uart_ops, |
1488 | .flags = ASYNC_BOOT_AUTOCONF, | 1488 | .flags = UPF_BOOT_AUTOCONF, |
1489 | .line = 1, | 1489 | .line = 1, |
1490 | }, | 1490 | }, |
1491 | .type = PORT_SCIF, | 1491 | .type = PORT_SCIF, |
@@ -1496,10 +1496,10 @@ static struct sci_port sci_ports[] = { | |||
1496 | .port = { | 1496 | .port = { |
1497 | .membase = (void *)0xff925000, | 1497 | .membase = (void *)0xff925000, |
1498 | .mapbase = 0xff925000, | 1498 | .mapbase = 0xff925000, |
1499 | .iotype = SERIAL_IO_MEM, | 1499 | .iotype = UPIO_MEM, |
1500 | .irq = 63, | 1500 | .irq = 63, |
1501 | .ops = &sci_uart_ops, | 1501 | .ops = &sci_uart_ops, |
1502 | .flags = ASYNC_BOOT_AUTOCONF, | 1502 | .flags = UPF_BOOT_AUTOCONF, |
1503 | .line = 2, | 1503 | .line = 2, |
1504 | }, | 1504 | }, |
1505 | .type = PORT_SCIF, | 1505 | .type = PORT_SCIF, |
@@ -1511,10 +1511,10 @@ static struct sci_port sci_ports[] = { | |||
1511 | .port = { | 1511 | .port = { |
1512 | .membase = (void *)0xffe00000, | 1512 | .membase = (void *)0xffe00000, |
1513 | .mapbase = 0xffe00000, | 1513 | .mapbase = 0xffe00000, |
1514 | .iotype = SERIAL_IO_MEM, | 1514 | .iotype = UPIO_MEM, |
1515 | .irq = 43, | 1515 | .irq = 43, |
1516 | .ops = &sci_uart_ops, | 1516 | .ops = &sci_uart_ops, |
1517 | .flags = ASYNC_BOOT_AUTOCONF, | 1517 | .flags = UPF_BOOT_AUTOCONF, |
1518 | .line = 0, | 1518 | .line = 0, |
1519 | }, | 1519 | }, |
1520 | .type = PORT_SCIF, | 1520 | .type = PORT_SCIF, |
@@ -1525,10 +1525,10 @@ static struct sci_port sci_ports[] = { | |||
1525 | .port = { | 1525 | .port = { |
1526 | .membase = (void *)0xffe10000, | 1526 | .membase = (void *)0xffe10000, |
1527 | .mapbase = 0xffe10000, | 1527 | .mapbase = 0xffe10000, |
1528 | .iotype = SERIAL_IO_MEM, | 1528 | .iotype = UPIO_MEM, |
1529 | .irq = 79, | 1529 | .irq = 79, |
1530 | .ops = &sci_uart_ops, | 1530 | .ops = &sci_uart_ops, |
1531 | .flags = ASYNC_BOOT_AUTOCONF, | 1531 | .flags = UPF_BOOT_AUTOCONF, |
1532 | .line = 1, | 1532 | .line = 1, |
1533 | }, | 1533 | }, |
1534 | .type = PORT_SCIF, | 1534 | .type = PORT_SCIF, |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index 43e67d6c29d4..60ea4a3f0713 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -820,7 +820,7 @@ static int __init sn_sal_module_init(void) | |||
820 | int retval; | 820 | int retval; |
821 | 821 | ||
822 | if (!ia64_platform_is("sn2")) | 822 | if (!ia64_platform_is("sn2")) |
823 | return -ENODEV; | 823 | return 0; |
824 | 824 | ||
825 | printk(KERN_INFO "sn_console: Console driver init\n"); | 825 | printk(KERN_INFO "sn_console: Console driver init\n"); |
826 | 826 | ||
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 8bcaebcc0ad7..85664228a0b6 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -1036,7 +1036,7 @@ static void __init sab_attach_callback(struct linux_ebus_device *edev, void *arg | |||
1036 | up->port.irq = edev->irqs[0]; | 1036 | up->port.irq = edev->irqs[0]; |
1037 | up->port.fifosize = SAB82532_XMIT_FIFO_SIZE; | 1037 | up->port.fifosize = SAB82532_XMIT_FIFO_SIZE; |
1038 | up->port.mapbase = (unsigned long)up->regs; | 1038 | up->port.mapbase = (unsigned long)up->regs; |
1039 | up->port.iotype = SERIAL_IO_MEM; | 1039 | up->port.iotype = UPIO_MEM; |
1040 | 1040 | ||
1041 | writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc); | 1041 | writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc); |
1042 | 1042 | ||
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index bc67442c6b4c..4e453fa966ae 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -109,11 +109,11 @@ static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset) | |||
109 | offset <<= up->port.regshift; | 109 | offset <<= up->port.regshift; |
110 | 110 | ||
111 | switch (up->port.iotype) { | 111 | switch (up->port.iotype) { |
112 | case SERIAL_IO_HUB6: | 112 | case UPIO_HUB6: |
113 | outb(up->port.hub6 - 1 + offset, up->port.iobase); | 113 | outb(up->port.hub6 - 1 + offset, up->port.iobase); |
114 | return inb(up->port.iobase + 1); | 114 | return inb(up->port.iobase + 1); |
115 | 115 | ||
116 | case SERIAL_IO_MEM: | 116 | case UPIO_MEM: |
117 | return readb(up->port.membase + offset); | 117 | return readb(up->port.membase + offset); |
118 | 118 | ||
119 | default: | 119 | default: |
@@ -139,12 +139,12 @@ serial_out(struct uart_sunsu_port *up, int offset, int value) | |||
139 | offset <<= up->port.regshift; | 139 | offset <<= up->port.regshift; |
140 | 140 | ||
141 | switch (up->port.iotype) { | 141 | switch (up->port.iotype) { |
142 | case SERIAL_IO_HUB6: | 142 | case UPIO_HUB6: |
143 | outb(up->port.hub6 - 1 + offset, up->port.iobase); | 143 | outb(up->port.hub6 - 1 + offset, up->port.iobase); |
144 | outb(value, up->port.iobase + 1); | 144 | outb(value, up->port.iobase + 1); |
145 | break; | 145 | break; |
146 | 146 | ||
147 | case SERIAL_IO_MEM: | 147 | case UPIO_MEM: |
148 | writeb(value, up->port.membase + offset); | 148 | writeb(value, up->port.membase + offset); |
149 | break; | 149 | break; |
150 | 150 | ||
@@ -299,13 +299,10 @@ static void sunsu_start_tx(struct uart_port *port) | |||
299 | static void sunsu_stop_rx(struct uart_port *port) | 299 | static void sunsu_stop_rx(struct uart_port *port) |
300 | { | 300 | { |
301 | struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | 301 | struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; |
302 | unsigned long flags; | ||
303 | 302 | ||
304 | spin_lock_irqsave(&up->port.lock, flags); | ||
305 | up->ier &= ~UART_IER_RLSI; | 303 | up->ier &= ~UART_IER_RLSI; |
306 | up->port.read_status_mask &= ~UART_LSR_DR; | 304 | up->port.read_status_mask &= ~UART_LSR_DR; |
307 | serial_out(up, UART_IER, up->ier); | 305 | serial_out(up, UART_IER, up->ier); |
308 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
309 | } | 306 | } |
310 | 307 | ||
311 | static void sunsu_enable_ms(struct uart_port *port) | 308 | static void sunsu_enable_ms(struct uart_port *port) |
@@ -1052,7 +1049,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) | |||
1052 | return; | 1049 | return; |
1053 | 1050 | ||
1054 | up->type_probed = PORT_UNKNOWN; | 1051 | up->type_probed = PORT_UNKNOWN; |
1055 | up->port.iotype = SERIAL_IO_MEM; | 1052 | up->port.iotype = UPIO_MEM; |
1056 | 1053 | ||
1057 | /* | 1054 | /* |
1058 | * First we look for Ebus-bases su's | 1055 | * First we look for Ebus-bases su's |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 3c72484adea7..5cc4d4c2935c 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -1487,7 +1487,7 @@ static void __init sunzilog_prepare(void) | |||
1487 | up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB; | 1487 | up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB; |
1488 | 1488 | ||
1489 | /* Channel A */ | 1489 | /* Channel A */ |
1490 | up[(chip * 2) + 0].port.iotype = SERIAL_IO_MEM; | 1490 | up[(chip * 2) + 0].port.iotype = UPIO_MEM; |
1491 | up[(chip * 2) + 0].port.irq = zilog_irq; | 1491 | up[(chip * 2) + 0].port.irq = zilog_irq; |
1492 | up[(chip * 2) + 0].port.uartclk = ZS_CLOCK; | 1492 | up[(chip * 2) + 0].port.uartclk = ZS_CLOCK; |
1493 | up[(chip * 2) + 0].port.fifosize = 1; | 1493 | up[(chip * 2) + 0].port.fifosize = 1; |
@@ -1498,7 +1498,7 @@ static void __init sunzilog_prepare(void) | |||
1498 | up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; | 1498 | up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; |
1499 | 1499 | ||
1500 | /* Channel B */ | 1500 | /* Channel B */ |
1501 | up[(chip * 2) + 1].port.iotype = SERIAL_IO_MEM; | 1501 | up[(chip * 2) + 1].port.iotype = UPIO_MEM; |
1502 | up[(chip * 2) + 1].port.irq = zilog_irq; | 1502 | up[(chip * 2) + 1].port.irq = zilog_irq; |
1503 | up[(chip * 2) + 1].port.uartclk = ZS_CLOCK; | 1503 | up[(chip * 2) + 1].port.uartclk = ZS_CLOCK; |
1504 | up[(chip * 2) + 1].port.fifosize = 1; | 1504 | up[(chip * 2) + 1].port.fifosize = 1; |
diff --git a/drivers/serial/v850e_uart.c b/drivers/serial/v850e_uart.c index 9378895a8d56..df705fda4243 100644 --- a/drivers/serial/v850e_uart.c +++ b/drivers/serial/v850e_uart.c | |||
@@ -496,7 +496,7 @@ static int __init v850e_uart_init (void) | |||
496 | 496 | ||
497 | port->ops = &v850e_uart_ops; | 497 | port->ops = &v850e_uart_ops; |
498 | port->line = chan; | 498 | port->line = chan; |
499 | port->iotype = SERIAL_IO_MEM; | 499 | port->iotype = UPIO_MEM; |
500 | port->flags = UPF_BOOT_AUTOCONF; | 500 | port->flags = UPF_BOOT_AUTOCONF; |
501 | 501 | ||
502 | /* We actually use multiple IRQs, but the serial | 502 | /* We actually use multiple IRQs, but the serial |
diff --git a/drivers/sn/Kconfig b/drivers/sn/Kconfig index d95265b187a3..a34731625877 100644 --- a/drivers/sn/Kconfig +++ b/drivers/sn/Kconfig | |||
@@ -3,10 +3,11 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | menu "SN Devices" | 5 | menu "SN Devices" |
6 | depends on SGI_SN | ||
6 | 7 | ||
7 | config SGI_IOC4 | 8 | config SGI_IOC4 |
8 | tristate "SGI IOC4 Base IO support" | 9 | tristate "SGI IOC4 Base IO support" |
9 | depends on (IA64_GENERIC || IA64_SGI_SN2) && MMTIMER | 10 | depends on MMTIMER |
10 | default m | 11 | default m |
11 | ---help--- | 12 | ---help--- |
12 | This option enables basic support for the SGI IOC4-based Base IO | 13 | This option enables basic support for the SGI IOC4-based Base IO |
@@ -19,7 +20,6 @@ config SGI_IOC4 | |||
19 | 20 | ||
20 | config SGI_IOC3 | 21 | config SGI_IOC3 |
21 | tristate "SGI IOC3 Base IO support" | 22 | tristate "SGI IOC3 Base IO support" |
22 | depends on (IA64_GENERIC || IA64_SGI_SN2) | ||
23 | default m | 23 | default m |
24 | ---help--- | 24 | ---help--- |
25 | This option enables basic support for the SGI IOC3-based Base IO | 25 | This option enables basic support for the SGI IOC3-based Base IO |
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index c70ae81b5d98..93449a1a0065 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c | |||
@@ -38,10 +38,10 @@ static inline unsigned mcr_pack(unsigned pulse, unsigned sample) | |||
38 | 38 | ||
39 | static int nic_wait(struct ioc3_driver_data *idd) | 39 | static int nic_wait(struct ioc3_driver_data *idd) |
40 | { | 40 | { |
41 | volatile unsigned mcr; | 41 | unsigned mcr; |
42 | 42 | ||
43 | do { | 43 | do { |
44 | mcr = (volatile unsigned)idd->vma->mcr; | 44 | mcr = readl(&idd->vma->mcr); |
45 | } while (!(mcr & 2)); | 45 | } while (!(mcr & 2)); |
46 | 46 | ||
47 | return mcr & 1; | 47 | return mcr & 1; |
@@ -53,7 +53,7 @@ static int nic_reset(struct ioc3_driver_data *idd) | |||
53 | unsigned long flags; | 53 | unsigned long flags; |
54 | 54 | ||
55 | local_irq_save(flags); | 55 | local_irq_save(flags); |
56 | idd->vma->mcr = mcr_pack(500, 65); | 56 | writel(mcr_pack(500, 65), &idd->vma->mcr); |
57 | presence = nic_wait(idd); | 57 | presence = nic_wait(idd); |
58 | local_irq_restore(flags); | 58 | local_irq_restore(flags); |
59 | 59 | ||
@@ -62,13 +62,13 @@ static int nic_reset(struct ioc3_driver_data *idd) | |||
62 | return presence; | 62 | return presence; |
63 | } | 63 | } |
64 | 64 | ||
65 | static inline int nic_read_bit(struct ioc3_driver_data *idd) | 65 | static int nic_read_bit(struct ioc3_driver_data *idd) |
66 | { | 66 | { |
67 | int result; | 67 | int result; |
68 | unsigned long flags; | 68 | unsigned long flags; |
69 | 69 | ||
70 | local_irq_save(flags); | 70 | local_irq_save(flags); |
71 | idd->vma->mcr = mcr_pack(6, 13); | 71 | writel(mcr_pack(6, 13), &idd->vma->mcr); |
72 | result = nic_wait(idd); | 72 | result = nic_wait(idd); |
73 | local_irq_restore(flags); | 73 | local_irq_restore(flags); |
74 | 74 | ||
@@ -77,12 +77,12 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd) | |||
77 | return result; | 77 | return result; |
78 | } | 78 | } |
79 | 79 | ||
80 | static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit) | 80 | static void nic_write_bit(struct ioc3_driver_data *idd, int bit) |
81 | { | 81 | { |
82 | if (bit) | 82 | if (bit) |
83 | idd->vma->mcr = mcr_pack(6, 110); | 83 | writel(mcr_pack(6, 110), &idd->vma->mcr); |
84 | else | 84 | else |
85 | idd->vma->mcr = mcr_pack(80, 30); | 85 | writel(mcr_pack(80, 30), &idd->vma->mcr); |
86 | 86 | ||
87 | nic_wait(idd); | 87 | nic_wait(idd); |
88 | } | 88 | } |
@@ -337,7 +337,7 @@ static void probe_nic(struct ioc3_driver_data *idd) | |||
337 | int save = 0, loops = 3; | 337 | int save = 0, loops = 3; |
338 | unsigned long first, addr; | 338 | unsigned long first, addr; |
339 | 339 | ||
340 | idd->vma->gpcr_s = GPCR_MLAN_EN; | 340 | writel(GPCR_MLAN_EN, &idd->vma->gpcr_s); |
341 | 341 | ||
342 | while(loops>0) { | 342 | while(loops>0) { |
343 | idd->nic_part[0] = 0; | 343 | idd->nic_part[0] = 0; |
@@ -371,8 +371,7 @@ static void probe_nic(struct ioc3_driver_data *idd) | |||
371 | 371 | ||
372 | /* Interrupts */ | 372 | /* Interrupts */ |
373 | 373 | ||
374 | static inline void | 374 | static void write_ireg(struct ioc3_driver_data *idd, uint32_t val, int which) |
375 | write_ireg(struct ioc3_driver_data *idd, uint32_t val, int which) | ||
376 | { | 375 | { |
377 | unsigned long flags; | 376 | unsigned long flags; |
378 | 377 | ||
@@ -408,7 +407,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs) | |||
408 | 407 | ||
409 | read_lock_irqsave(&ioc3_submodules_lock, flags); | 408 | read_lock_irqsave(&ioc3_submodules_lock, flags); |
410 | 409 | ||
411 | if(idd->dual_irq && idd->vma->eisr) { | 410 | if(idd->dual_irq && readb(&idd->vma->eisr)) { |
412 | /* send Ethernet IRQ to the driver */ | 411 | /* send Ethernet IRQ to the driver */ |
413 | if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && | 412 | if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && |
414 | ioc3_ethernet->intr) { | 413 | ioc3_ethernet->intr) { |
@@ -682,7 +681,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
682 | idd->id = ioc3_counter++; | 681 | idd->id = ioc3_counter++; |
683 | up_write(&ioc3_devices_rwsem); | 682 | up_write(&ioc3_devices_rwsem); |
684 | 683 | ||
685 | idd->gpdr_shadow = idd->vma->gpdr; | 684 | idd->gpdr_shadow = readl(&idd->vma->gpdr); |
686 | 685 | ||
687 | /* Read IOC3 NIC contents */ | 686 | /* Read IOC3 NIC contents */ |
688 | probe_nic(idd); | 687 | probe_nic(idd); |
@@ -735,14 +734,12 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
735 | } | 734 | } |
736 | 735 | ||
737 | /* Add this IOC3 to all submodules */ | 736 | /* Add this IOC3 to all submodules */ |
738 | read_lock(&ioc3_submodules_lock); | ||
739 | for(id=0;id<IOC3_MAX_SUBMODULES;id++) | 737 | for(id=0;id<IOC3_MAX_SUBMODULES;id++) |
740 | if(ioc3_submodules[id] && ioc3_submodules[id]->probe) { | 738 | if(ioc3_submodules[id] && ioc3_submodules[id]->probe) { |
741 | idd->active[id] = 1; | 739 | idd->active[id] = 1; |
742 | idd->active[id] = !ioc3_submodules[id]->probe | 740 | idd->active[id] = !ioc3_submodules[id]->probe |
743 | (ioc3_submodules[id], idd); | 741 | (ioc3_submodules[id], idd); |
744 | } | 742 | } |
745 | read_unlock(&ioc3_submodules_lock); | ||
746 | 743 | ||
747 | printk(KERN_INFO "IOC3 Master Driver loaded for %s\n", pci_name(pdev)); | 744 | printk(KERN_INFO "IOC3 Master Driver loaded for %s\n", pci_name(pdev)); |
748 | 745 | ||
@@ -767,7 +764,6 @@ static void ioc3_remove(struct pci_dev *pdev) | |||
767 | idd = pci_get_drvdata(pdev); | 764 | idd = pci_get_drvdata(pdev); |
768 | 765 | ||
769 | /* Remove this IOC3 from all submodules */ | 766 | /* Remove this IOC3 from all submodules */ |
770 | read_lock(&ioc3_submodules_lock); | ||
771 | for(id=0;id<IOC3_MAX_SUBMODULES;id++) | 767 | for(id=0;id<IOC3_MAX_SUBMODULES;id++) |
772 | if(idd->active[id]) { | 768 | if(idd->active[id]) { |
773 | if(ioc3_submodules[id] && ioc3_submodules[id]->remove) | 769 | if(ioc3_submodules[id] && ioc3_submodules[id]->remove) |
@@ -781,7 +777,6 @@ static void ioc3_remove(struct pci_dev *pdev) | |||
781 | pci_name(pdev)); | 777 | pci_name(pdev)); |
782 | idd->active[id] = 0; | 778 | idd->active[id] = 0; |
783 | } | 779 | } |
784 | read_unlock(&ioc3_submodules_lock); | ||
785 | 780 | ||
786 | /* Clear and disable all IRQs */ | 781 | /* Clear and disable all IRQs */ |
787 | write_ireg(idd, ~0, IOC3_W_IEC); | 782 | write_ireg(idd, ~0, IOC3_W_IEC); |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index b77dbd63e596..7a75faeb0526 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -75,16 +75,6 @@ config SPI_BUTTERFLY | |||
75 | inexpensive battery powered microcontroller evaluation board. | 75 | inexpensive battery powered microcontroller evaluation board. |
76 | This same cable can be used to flash new firmware. | 76 | This same cable can be used to flash new firmware. |
77 | 77 | ||
78 | config SPI_BUTTERFLY | ||
79 | tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" | ||
80 | depends on SPI_MASTER && PARPORT && EXPERIMENTAL | ||
81 | select SPI_BITBANG | ||
82 | help | ||
83 | This uses a custom parallel port cable to connect to an AVR | ||
84 | Butterfly <http://www.atmel.com/products/avr/butterfly>, an | ||
85 | inexpensive battery powered microcontroller evaluation board. | ||
86 | This same cable can be used to flash new firmware. | ||
87 | |||
88 | # | 78 | # |
89 | # Add new SPI master controllers in alphabetical order above this line | 79 | # Add new SPI master controllers in alphabetical order above this line |
90 | # | 80 | # |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 791c4dc550ae..94f5e8ed83a7 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -90,7 +90,7 @@ static int spi_suspend(struct device *dev, pm_message_t message) | |||
90 | int value; | 90 | int value; |
91 | struct spi_driver *drv = to_spi_driver(dev->driver); | 91 | struct spi_driver *drv = to_spi_driver(dev->driver); |
92 | 92 | ||
93 | if (!drv->suspend) | 93 | if (!drv || !drv->suspend) |
94 | return 0; | 94 | return 0; |
95 | 95 | ||
96 | /* suspend will stop irqs and dma; no more i/o */ | 96 | /* suspend will stop irqs and dma; no more i/o */ |
@@ -105,7 +105,7 @@ static int spi_resume(struct device *dev) | |||
105 | int value; | 105 | int value; |
106 | struct spi_driver *drv = to_spi_driver(dev->driver); | 106 | struct spi_driver *drv = to_spi_driver(dev->driver); |
107 | 107 | ||
108 | if (!drv->resume) | 108 | if (!drv || !drv->resume) |
109 | return 0; | 109 | return 0; |
110 | 110 | ||
111 | /* resume may restart the i/o queue */ | 111 | /* resume may restart the i/o queue */ |
@@ -449,7 +449,6 @@ void spi_unregister_master(struct spi_master *master) | |||
449 | { | 449 | { |
450 | (void) device_for_each_child(master->cdev.dev, NULL, __unregister); | 450 | (void) device_for_each_child(master->cdev.dev, NULL, __unregister); |
451 | class_device_unregister(&master->cdev); | 451 | class_device_unregister(&master->cdev); |
452 | master->cdev.dev = NULL; | ||
453 | } | 452 | } |
454 | EXPORT_SYMBOL_GPL(spi_unregister_master); | 453 | EXPORT_SYMBOL_GPL(spi_unregister_master); |
455 | 454 | ||
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c index 79a3c59615ab..ff9e5faa4dc9 100644 --- a/drivers/spi/spi_butterfly.c +++ b/drivers/spi/spi_butterfly.c | |||
@@ -163,21 +163,20 @@ static void butterfly_chipselect(struct spi_device *spi, int value) | |||
163 | struct butterfly *pp = spidev_to_pp(spi); | 163 | struct butterfly *pp = spidev_to_pp(spi); |
164 | 164 | ||
165 | /* set default clock polarity */ | 165 | /* set default clock polarity */ |
166 | if (value) | 166 | if (value != BITBANG_CS_INACTIVE) |
167 | setsck(spi, spi->mode & SPI_CPOL); | 167 | setsck(spi, spi->mode & SPI_CPOL); |
168 | 168 | ||
169 | /* no chipselect on this USI link config */ | 169 | /* no chipselect on this USI link config */ |
170 | if (is_usidev(spi)) | 170 | if (is_usidev(spi)) |
171 | return; | 171 | return; |
172 | 172 | ||
173 | /* here, value == "activate or not" */ | 173 | /* here, value == "activate or not"; |
174 | 174 | * most PARPORT_CONTROL_* bits are negated, so we must | |
175 | /* most PARPORT_CONTROL_* bits are negated */ | 175 | * morph it to value == "bit value to write in control register" |
176 | */ | ||
176 | if (spi_cs_bit == PARPORT_CONTROL_INIT) | 177 | if (spi_cs_bit == PARPORT_CONTROL_INIT) |
177 | value = !value; | 178 | value = !value; |
178 | 179 | ||
179 | /* here, value == "bit value to write in control register" */ | ||
180 | |||
181 | parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); | 180 | parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); |
182 | } | 181 | } |
183 | 182 | ||
@@ -202,7 +201,9 @@ butterfly_txrx_word_mode0(struct spi_device *spi, | |||
202 | 201 | ||
203 | /* override default partitioning with cmdlinepart */ | 202 | /* override default partitioning with cmdlinepart */ |
204 | static struct mtd_partition partitions[] = { { | 203 | static struct mtd_partition partitions[] = { { |
205 | /* JFFS2 wants partitions of 4*N blocks for this device ... */ | 204 | /* JFFS2 wants partitions of 4*N blocks for this device, |
205 | * so sectors 0 and 1 can't be partitions by themselves. | ||
206 | */ | ||
206 | 207 | ||
207 | /* sector 0 = 8 pages * 264 bytes/page (1 block) | 208 | /* sector 0 = 8 pages * 264 bytes/page (1 block) |
208 | * sector 1 = 248 pages * 264 bytes/page | 209 | * sector 1 = 248 pages * 264 bytes/page |
@@ -316,8 +317,9 @@ static void butterfly_attach(struct parport *p) | |||
316 | if (status < 0) | 317 | if (status < 0) |
317 | goto clean2; | 318 | goto clean2; |
318 | 319 | ||
319 | /* Bus 1 lets us talk to at45db041b (firmware disables AVR) | 320 | /* Bus 1 lets us talk to at45db041b (firmware disables AVR SPI), AVR |
320 | * or AVR (firmware resets at45, acts as spi slave) | 321 | * (firmware resets at45, acts as spi slave) or neither (we ignore |
322 | * both, AVR uses AT45). Here we expect firmware for the first option. | ||
321 | */ | 323 | */ |
322 | pp->info[0].max_speed_hz = 15 * 1000 * 1000; | 324 | pp->info[0].max_speed_hz = 15 * 1000 * 1000; |
323 | strcpy(pp->info[0].modalias, "mtd_dataflash"); | 325 | strcpy(pp->info[0].modalias, "mtd_dataflash"); |
@@ -330,7 +332,9 @@ static void butterfly_attach(struct parport *p) | |||
330 | pp->dataflash->dev.bus_id); | 332 | pp->dataflash->dev.bus_id); |
331 | 333 | ||
332 | #ifdef HAVE_USI | 334 | #ifdef HAVE_USI |
333 | /* even more custom AVR firmware */ | 335 | /* Bus 2 is only for talking to the AVR, and it can work no |
336 | * matter who masters bus 1; needs appropriate AVR firmware. | ||
337 | */ | ||
334 | pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; | 338 | pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; |
335 | strcpy(pp->info[1].modalias, "butterfly"); | 339 | strcpy(pp->info[1].modalias, "butterfly"); |
336 | // pp->info[1].platform_data = ... TBD ... ; | 340 | // pp->info[1].platform_data = ... TBD ... ; |
@@ -378,13 +382,8 @@ static void butterfly_detach(struct parport *p) | |||
378 | pp = butterfly; | 382 | pp = butterfly; |
379 | butterfly = NULL; | 383 | butterfly = NULL; |
380 | 384 | ||
381 | #ifdef HAVE_USI | 385 | /* stop() unregisters child devices too */ |
382 | spi_unregister_device(pp->butterfly); | 386 | pdev = to_platform_device(pp->bitbang.master->cdev.dev); |
383 | pp->butterfly = NULL; | ||
384 | #endif | ||
385 | spi_unregister_device(pp->dataflash); | ||
386 | pp->dataflash = NULL; | ||
387 | |||
388 | status = spi_bitbang_stop(&pp->bitbang); | 387 | status = spi_bitbang_stop(&pp->bitbang); |
389 | 388 | ||
390 | /* turn off VCC */ | 389 | /* turn off VCC */ |
@@ -394,8 +393,6 @@ static void butterfly_detach(struct parport *p) | |||
394 | parport_release(pp->pd); | 393 | parport_release(pp->pd); |
395 | parport_unregister_device(pp->pd); | 394 | parport_unregister_device(pp->pd); |
396 | 395 | ||
397 | pdev = to_platform_device(pp->bitbang.master->cdev.dev); | ||
398 | |||
399 | (void) spi_master_put(pp->bitbang.master); | 396 | (void) spi_master_put(pp->bitbang.master); |
400 | 397 | ||
401 | platform_device_unregister(pdev); | 398 | platform_device_unregister(pdev); |
@@ -420,4 +417,5 @@ static void __exit butterfly_exit(void) | |||
420 | } | 417 | } |
421 | module_exit(butterfly_exit); | 418 | module_exit(butterfly_exit); |
422 | 419 | ||
420 | MODULE_DESCRIPTION("Parport Adapter driver for AVR Butterfly"); | ||
423 | MODULE_LICENSE("GPL"); | 421 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c index a0e5af638e0e..4a51e56f85b6 100644 --- a/drivers/tc/tc.c +++ b/drivers/tc/tc.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | 18 | ||
19 | #include <asm/addrspace.h> | 19 | #include <asm/addrspace.h> |
20 | #include <asm/bug.h> | ||
21 | #include <asm/errno.h> | 20 | #include <asm/errno.h> |
22 | #include <asm/io.h> | 21 | #include <asm/io.h> |
23 | #include <asm/paccess.h> | 22 | #include <asm/paccess.h> |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 076462c8ba2a..dce9d987f0fc 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -378,7 +378,7 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface, | |||
378 | 378 | ||
379 | return NULL; | 379 | return NULL; |
380 | } | 380 | } |
381 | EXPORT_SYMBOL_GPL(usb_match_id); | 381 | EXPORT_SYMBOL(usb_match_id); |
382 | 382 | ||
383 | int usb_device_match(struct device *dev, struct device_driver *drv) | 383 | int usb_device_match(struct device *dev, struct device_driver *drv) |
384 | { | 384 | { |
@@ -446,7 +446,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner) | |||
446 | 446 | ||
447 | return retval; | 447 | return retval; |
448 | } | 448 | } |
449 | EXPORT_SYMBOL_GPL(usb_register_driver); | 449 | EXPORT_SYMBOL(usb_register_driver); |
450 | 450 | ||
451 | /** | 451 | /** |
452 | * usb_deregister - unregister a USB driver | 452 | * usb_deregister - unregister a USB driver |
@@ -469,4 +469,4 @@ void usb_deregister(struct usb_driver *driver) | |||
469 | 469 | ||
470 | usbfs_update_special(); | 470 | usbfs_update_special(); |
471 | } | 471 | } |
472 | EXPORT_SYMBOL_GPL(usb_deregister); | 472 | EXPORT_SYMBOL(usb_deregister); |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index e02fea5a5433..1a362c5e7f3d 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -1062,11 +1062,11 @@ static int lh7a40x_ep_enable(struct usb_ep *_ep, | |||
1062 | ep->pio_irqs = 0; | 1062 | ep->pio_irqs = 0; |
1063 | ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); | 1063 | ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); |
1064 | 1064 | ||
1065 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
1066 | |||
1065 | /* Reset halt state (does flush) */ | 1067 | /* Reset halt state (does flush) */ |
1066 | lh7a40x_set_halt(_ep, 0); | 1068 | lh7a40x_set_halt(_ep, 0); |
1067 | 1069 | ||
1068 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
1069 | |||
1070 | DEBUG("%s: enabled %s\n", __FUNCTION__, _ep->name); | 1070 | DEBUG("%s: enabled %s\n", __FUNCTION__, _ep->name); |
1071 | return 0; | 1071 | return 0; |
1072 | } | 1072 | } |
@@ -1775,6 +1775,7 @@ static void lh7a40x_ep0_setup(struct lh7a40x_udc *dev, u32 csr) | |||
1775 | break; | 1775 | break; |
1776 | 1776 | ||
1777 | qep = &dev->ep[ep_num]; | 1777 | qep = &dev->ep[ep_num]; |
1778 | spin_unlock(&dev->lock); | ||
1778 | if (ctrl.bRequest == USB_REQ_SET_FEATURE) { | 1779 | if (ctrl.bRequest == USB_REQ_SET_FEATURE) { |
1779 | DEBUG_SETUP("SET_FEATURE (%d)\n", | 1780 | DEBUG_SETUP("SET_FEATURE (%d)\n", |
1780 | ep_num); | 1781 | ep_num); |
@@ -1784,6 +1785,7 @@ static void lh7a40x_ep0_setup(struct lh7a40x_udc *dev, u32 csr) | |||
1784 | ep_num); | 1785 | ep_num); |
1785 | lh7a40x_set_halt(&qep->ep, 0); | 1786 | lh7a40x_set_halt(&qep->ep, 0); |
1786 | } | 1787 | } |
1788 | spin_lock(&dev->lock); | ||
1787 | usb_set_index(0); | 1789 | usb_set_index(0); |
1788 | 1790 | ||
1789 | /* Reply with a ZLP on next IN token */ | 1791 | /* Reply with a ZLP on next IN token */ |
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 9689efeb364c..6d6eaad73968 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -853,11 +853,14 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) | |||
853 | // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID)); | 853 | // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID)); |
854 | if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; | 854 | if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; |
855 | 855 | ||
856 | /* | 856 | /* |
857 | * we need more memory: | 857 | * we need more memory: |
858 | * oid_supported_list is the largest answer | 858 | * gen_ndis_query_resp expects enough space for |
859 | * rndis_query_cmplt_type followed by data. | ||
860 | * oid_supported_list is the largest data reply | ||
859 | */ | 861 | */ |
860 | r = rndis_add_response (configNr, sizeof (oid_supported_list)); | 862 | r = rndis_add_response (configNr, |
863 | sizeof (oid_supported_list) + sizeof(rndis_query_cmplt_type)); | ||
861 | if (!r) | 864 | if (!r) |
862 | return -ENOMEM; | 865 | return -ENOMEM; |
863 | resp = (rndis_query_cmplt_type *) r->buf; | 866 | resp = (rndis_query_cmplt_type *) r->buf; |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index e9e5bc178cef..9e81c26313f9 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -191,8 +191,9 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
191 | } | 191 | } |
192 | if (wait_time <= 0) | 192 | if (wait_time <= 0) |
193 | printk(KERN_WARNING "%s %s: BIOS handoff " | 193 | printk(KERN_WARNING "%s %s: BIOS handoff " |
194 | "failed (BIOS bug ?)\n", | 194 | "failed (BIOS bug ?) %08x\n", |
195 | pdev->dev.bus_id, "OHCI"); | 195 | pdev->dev.bus_id, "OHCI", |
196 | readl(base + OHCI_CONTROL)); | ||
196 | 197 | ||
197 | /* reset controller, preserving RWC */ | 198 | /* reset controller, preserving RWC */ |
198 | writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); | 199 | writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); |
@@ -243,6 +244,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
243 | pr_debug("%s %s: BIOS handoff\n", | 244 | pr_debug("%s %s: BIOS handoff\n", |
244 | pdev->dev.bus_id, "EHCI"); | 245 | pdev->dev.bus_id, "EHCI"); |
245 | 246 | ||
247 | #if 0 | ||
248 | /* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on, | ||
249 | * but that seems dubious in general (the BIOS left it off intentionally) | ||
250 | * and is known to prevent some systems from booting. so we won't do this | ||
251 | * unless maybe we can determine when we're on a system that needs SMI forced. | ||
252 | */ | ||
246 | /* BIOS workaround (?): be sure the | 253 | /* BIOS workaround (?): be sure the |
247 | * pre-Linux code receives the SMI | 254 | * pre-Linux code receives the SMI |
248 | */ | 255 | */ |
@@ -252,12 +259,14 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
252 | pci_write_config_dword(pdev, | 259 | pci_write_config_dword(pdev, |
253 | offset + EHCI_USBLEGCTLSTS, | 260 | offset + EHCI_USBLEGCTLSTS, |
254 | val | EHCI_USBLEGCTLSTS_SOOE); | 261 | val | EHCI_USBLEGCTLSTS_SOOE); |
255 | } | 262 | #endif |
256 | 263 | ||
257 | /* always say Linux will own the hardware | 264 | /* some systems get upset if this semaphore is |
258 | * by setting EHCI_USBLEGSUP_OS. | 265 | * set for any other reason than forcing a BIOS |
259 | */ | 266 | * handoff.. |
260 | pci_write_config_byte(pdev, offset + 3, 1); | 267 | */ |
268 | pci_write_config_byte(pdev, offset + 3, 1); | ||
269 | } | ||
261 | 270 | ||
262 | /* if boot firmware now owns EHCI, spin till | 271 | /* if boot firmware now owns EHCI, spin till |
263 | * it hands it over. | 272 | * it hands it over. |
@@ -274,8 +283,8 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
274 | * it down, and hope nothing goes too wrong | 283 | * it down, and hope nothing goes too wrong |
275 | */ | 284 | */ |
276 | printk(KERN_WARNING "%s %s: BIOS handoff " | 285 | printk(KERN_WARNING "%s %s: BIOS handoff " |
277 | "failed (BIOS bug ?)\n", | 286 | "failed (BIOS bug ?) %08x\n", |
278 | pdev->dev.bus_id, "EHCI"); | 287 | pdev->dev.bus_id, "EHCI", cap); |
279 | pci_write_config_byte(pdev, offset + 2, 0); | 288 | pci_write_config_byte(pdev, offset + 2, 0); |
280 | } | 289 | } |
281 | 290 | ||
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 466384d7c79f..134d2000128a 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -101,7 +101,7 @@ static struct resource resources[] = { | |||
101 | }, | 101 | }, |
102 | }; | 102 | }; |
103 | 103 | ||
104 | extern struct device_driver sl811h_driver; | 104 | extern struct platform_driver sl811h_driver; |
105 | 105 | ||
106 | static struct platform_device platform_dev = { | 106 | static struct platform_device platform_dev = { |
107 | .id = -1, | 107 | .id = -1, |
@@ -132,7 +132,7 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) | |||
132 | * initialized already because of the link order dependency created | 132 | * initialized already because of the link order dependency created |
133 | * by referencing "sl811h_driver". | 133 | * by referencing "sl811h_driver". |
134 | */ | 134 | */ |
135 | platform_dev.name = sl811h_driver.name; | 135 | platform_dev.name = sl811h_driver.driver.name; |
136 | return platform_device_register(&platform_dev); | 136 | return platform_device_register(&platform_dev); |
137 | } | 137 | } |
138 | 138 | ||
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 6f7a684c3e07..07a012f88772 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -1407,6 +1407,7 @@ void hid_init_reports(struct hid_device *hid) | |||
1407 | #define USB_VENDOR_ID_WISEGROUP 0x0925 | 1407 | #define USB_VENDOR_ID_WISEGROUP 0x0925 |
1408 | #define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 | 1408 | #define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 |
1409 | #define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 | 1409 | #define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 |
1410 | #define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866 | ||
1410 | 1411 | ||
1411 | #define USB_VENDOR_ID_CODEMERCS 0x07c0 | 1412 | #define USB_VENDOR_ID_CODEMERCS 0x07c0 |
1412 | #define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 | 1413 | #define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 |
@@ -1435,17 +1436,20 @@ void hid_init_reports(struct hid_device *hid) | |||
1435 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | 1436 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 |
1436 | 1437 | ||
1437 | #define USB_VENDOR_ID_LD 0x0f11 | 1438 | #define USB_VENDOR_ID_LD 0x0f11 |
1438 | #define USB_DEVICE_ID_CASSY 0x1000 | 1439 | #define USB_DEVICE_ID_LD_CASSY 0x1000 |
1439 | #define USB_DEVICE_ID_POCKETCASSY 0x1010 | 1440 | #define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 |
1440 | #define USB_DEVICE_ID_MOBILECASSY 0x1020 | 1441 | #define USB_DEVICE_ID_LD_MOBILECASSY 0x1020 |
1441 | #define USB_DEVICE_ID_JWM 0x1080 | 1442 | #define USB_DEVICE_ID_LD_JWM 0x1080 |
1442 | #define USB_DEVICE_ID_DMMP 0x1081 | 1443 | #define USB_DEVICE_ID_LD_DMMP 0x1081 |
1443 | #define USB_DEVICE_ID_UMIP 0x1090 | 1444 | #define USB_DEVICE_ID_LD_UMIP 0x1090 |
1444 | #define USB_DEVICE_ID_VIDEOCOM 0x1200 | 1445 | #define USB_DEVICE_ID_LD_XRAY1 0x1100 |
1445 | #define USB_DEVICE_ID_COM3LAB 0x2000 | 1446 | #define USB_DEVICE_ID_LD_XRAY2 0x1101 |
1446 | #define USB_DEVICE_ID_TELEPORT 0x2010 | 1447 | #define USB_DEVICE_ID_LD_VIDEOCOM 0x1200 |
1447 | #define USB_DEVICE_ID_NETWORKANALYSER 0x2020 | 1448 | #define USB_DEVICE_ID_LD_COM3LAB 0x2000 |
1448 | #define USB_DEVICE_ID_POWERCONTROL 0x2030 | 1449 | #define USB_DEVICE_ID_LD_TELEPORT 0x2010 |
1450 | #define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020 | ||
1451 | #define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 | ||
1452 | #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 | ||
1449 | 1453 | ||
1450 | #define USB_VENDOR_ID_APPLE 0x05ac | 1454 | #define USB_VENDOR_ID_APPLE 0x05ac |
1451 | #define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 | 1455 | #define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 |
@@ -1491,17 +1495,20 @@ static const struct hid_blacklist { | |||
1491 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, | 1495 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, |
1492 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, | 1496 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, |
1493 | { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, | 1497 | { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, |
1494 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY, HID_QUIRK_IGNORE }, | 1498 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, |
1495 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY, HID_QUIRK_IGNORE }, | 1499 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY, HID_QUIRK_IGNORE }, |
1496 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY, HID_QUIRK_IGNORE }, | 1500 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY, HID_QUIRK_IGNORE }, |
1497 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM, HID_QUIRK_IGNORE }, | 1501 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM, HID_QUIRK_IGNORE }, |
1498 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP, HID_QUIRK_IGNORE }, | 1502 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP, HID_QUIRK_IGNORE }, |
1499 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP, HID_QUIRK_IGNORE }, | 1503 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP, HID_QUIRK_IGNORE }, |
1500 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM, HID_QUIRK_IGNORE }, | 1504 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1, HID_QUIRK_IGNORE }, |
1501 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB, HID_QUIRK_IGNORE }, | 1505 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2, HID_QUIRK_IGNORE }, |
1502 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT, HID_QUIRK_IGNORE }, | 1506 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM, HID_QUIRK_IGNORE }, |
1503 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER, HID_QUIRK_IGNORE }, | 1507 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB, HID_QUIRK_IGNORE }, |
1504 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL, HID_QUIRK_IGNORE }, | 1508 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT, HID_QUIRK_IGNORE }, |
1509 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER, HID_QUIRK_IGNORE }, | ||
1510 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL, HID_QUIRK_IGNORE }, | ||
1511 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST, HID_QUIRK_IGNORE }, | ||
1505 | { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE }, | 1512 | { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE }, |
1506 | { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE }, | 1513 | { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE }, |
1507 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, | 1514 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, |
@@ -1571,6 +1578,7 @@ static const struct hid_blacklist { | |||
1571 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, | 1578 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, |
1572 | { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, | 1579 | { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET }, |
1573 | { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, | 1580 | { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, |
1581 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | ||
1574 | 1582 | ||
1575 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, | 1583 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, |
1576 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, | 1584 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 6649531fa824..8ba6a701e9c1 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -141,7 +141,7 @@ source "drivers/usb/misc/sisusbvga/Kconfig" | |||
141 | 141 | ||
142 | config USB_LD | 142 | config USB_LD |
143 | tristate "USB LD driver" | 143 | tristate "USB LD driver" |
144 | depends on USB && EXPERIMENTAL | 144 | depends on USB |
145 | help | 145 | help |
146 | This driver is for generic USB devices that use interrupt transfers, | 146 | This driver is for generic USB devices that use interrupt transfers, |
147 | like LD Didactic's USB devices. | 147 | like LD Didactic's USB devices. |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 331d4ae949ed..e2d1198623eb 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -24,6 +24,7 @@ | |||
24 | * V0.1 (mh) Initial version | 24 | * V0.1 (mh) Initial version |
25 | * V0.11 (mh) Added raw support for HID 1.0 devices (no interrupt out endpoint) | 25 | * V0.11 (mh) Added raw support for HID 1.0 devices (no interrupt out endpoint) |
26 | * V0.12 (mh) Added kmalloc check for string buffer | 26 | * V0.12 (mh) Added kmalloc check for string buffer |
27 | * V0.13 (mh) Added support for LD X-Ray and Machine Test System | ||
27 | */ | 28 | */ |
28 | 29 | ||
29 | #include <linux/config.h> | 30 | #include <linux/config.h> |
@@ -40,17 +41,20 @@ | |||
40 | 41 | ||
41 | /* Define these values to match your devices */ | 42 | /* Define these values to match your devices */ |
42 | #define USB_VENDOR_ID_LD 0x0f11 /* USB Vendor ID of LD Didactic GmbH */ | 43 | #define USB_VENDOR_ID_LD 0x0f11 /* USB Vendor ID of LD Didactic GmbH */ |
43 | #define USB_DEVICE_ID_CASSY 0x1000 /* USB Product ID for all CASSY-S modules */ | 44 | #define USB_DEVICE_ID_LD_CASSY 0x1000 /* USB Product ID of CASSY-S */ |
44 | #define USB_DEVICE_ID_POCKETCASSY 0x1010 /* USB Product ID for Pocket-CASSY */ | 45 | #define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 /* USB Product ID of Pocket-CASSY */ |
45 | #define USB_DEVICE_ID_MOBILECASSY 0x1020 /* USB Product ID for Mobile-CASSY */ | 46 | #define USB_DEVICE_ID_LD_MOBILECASSY 0x1020 /* USB Product ID of Mobile-CASSY */ |
46 | #define USB_DEVICE_ID_JWM 0x1080 /* USB Product ID for Joule and Wattmeter */ | 47 | #define USB_DEVICE_ID_LD_JWM 0x1080 /* USB Product ID of Joule and Wattmeter */ |
47 | #define USB_DEVICE_ID_DMMP 0x1081 /* USB Product ID for Digital Multimeter P (reserved) */ | 48 | #define USB_DEVICE_ID_LD_DMMP 0x1081 /* USB Product ID of Digital Multimeter P (reserved) */ |
48 | #define USB_DEVICE_ID_UMIP 0x1090 /* USB Product ID for UMI P */ | 49 | #define USB_DEVICE_ID_LD_UMIP 0x1090 /* USB Product ID of UMI P */ |
49 | #define USB_DEVICE_ID_VIDEOCOM 0x1200 /* USB Product ID for VideoCom */ | 50 | #define USB_DEVICE_ID_LD_XRAY1 0x1100 /* USB Product ID of X-Ray Apparatus */ |
50 | #define USB_DEVICE_ID_COM3LAB 0x2000 /* USB Product ID for COM3LAB */ | 51 | #define USB_DEVICE_ID_LD_XRAY2 0x1101 /* USB Product ID of X-Ray Apparatus */ |
51 | #define USB_DEVICE_ID_TELEPORT 0x2010 /* USB Product ID for Terminal Adapter */ | 52 | #define USB_DEVICE_ID_LD_VIDEOCOM 0x1200 /* USB Product ID of VideoCom */ |
52 | #define USB_DEVICE_ID_NETWORKANALYSER 0x2020 /* USB Product ID for Network Analyser */ | 53 | #define USB_DEVICE_ID_LD_COM3LAB 0x2000 /* USB Product ID of COM3LAB */ |
53 | #define USB_DEVICE_ID_POWERCONTROL 0x2030 /* USB Product ID for Controlling device for Power Electronics */ | 54 | #define USB_DEVICE_ID_LD_TELEPORT 0x2010 /* USB Product ID of Terminal Adapter */ |
55 | #define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020 /* USB Product ID of Network Analyser */ | ||
56 | #define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 /* USB Product ID of Converter Control Unit */ | ||
57 | #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 /* USB Product ID of Machine Test System */ | ||
54 | 58 | ||
55 | #define USB_VENDOR_ID_VERNIER 0x08f7 | 59 | #define USB_VENDOR_ID_VERNIER 0x08f7 |
56 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | 60 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 |
@@ -67,17 +71,20 @@ | |||
67 | 71 | ||
68 | /* table of devices that work with this driver */ | 72 | /* table of devices that work with this driver */ |
69 | static struct usb_device_id ld_usb_table [] = { | 73 | static struct usb_device_id ld_usb_table [] = { |
70 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY) }, | 74 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, |
71 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY) }, | 75 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, |
72 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY) }, | 76 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) }, |
73 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM) }, | 77 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, |
74 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP) }, | 78 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, |
75 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP) }, | 79 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, |
76 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM) }, | 80 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1) }, |
77 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB) }, | 81 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2) }, |
78 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT) }, | 82 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM) }, |
79 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER) }, | 83 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB) }, |
80 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL) }, | 84 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT) }, |
85 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) }, | ||
86 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) }, | ||
87 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) }, | ||
81 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, | 88 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, |
82 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, | 89 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, |
83 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, | 90 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, |
@@ -85,7 +92,7 @@ static struct usb_device_id ld_usb_table [] = { | |||
85 | { } /* Terminating entry */ | 92 | { } /* Terminating entry */ |
86 | }; | 93 | }; |
87 | MODULE_DEVICE_TABLE(usb, ld_usb_table); | 94 | MODULE_DEVICE_TABLE(usb, ld_usb_table); |
88 | MODULE_VERSION("V0.12"); | 95 | MODULE_VERSION("V0.13"); |
89 | MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>"); | 96 | MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>"); |
90 | MODULE_DESCRIPTION("LD USB Driver"); | 97 | MODULE_DESCRIPTION("LD USB Driver"); |
91 | MODULE_LICENSE("GPL"); | 98 | MODULE_LICENSE("GPL"); |
@@ -632,8 +639,8 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * | |||
632 | 639 | ||
633 | /* workaround for early firmware versions on fast computers */ | 640 | /* workaround for early firmware versions on fast computers */ |
634 | if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) && | 641 | if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) && |
635 | ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_CASSY) || | 642 | ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_CASSY) || |
636 | (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_COM3LAB)) && | 643 | (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_COM3LAB)) && |
637 | (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { | 644 | (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { |
638 | buffer = kmalloc(256, GFP_KERNEL); | 645 | buffer = kmalloc(256, GFP_KERNEL); |
639 | if (buffer == NULL) { | 646 | if (buffer == NULL) { |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f2b4ca8692d8..c145e1ed8429 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -469,8 +469,14 @@ static struct usb_device_id id_table_combined [] = { | |||
469 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, | 469 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, |
470 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, | 470 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, |
471 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, | 471 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, |
472 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) }, | ||
473 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_YS_PID) }, | ||
472 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, | 474 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, |
473 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, | 475 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, |
476 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_IC_PID) }, | ||
477 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_DB9_PID) }, | ||
478 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_RS232_PID) }, | ||
479 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y9_PID) }, | ||
474 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, | 480 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, |
475 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, | 481 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, |
476 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | 482 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index ca40f16370f1..bdef3b8c731f 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -333,10 +333,18 @@ | |||
333 | 333 | ||
334 | /* | 334 | /* |
335 | * microHAM product IDs (http://www.microham.com). | 335 | * microHAM product IDs (http://www.microham.com). |
336 | * Submitted by Justin Burket (KL1RL) <zorton@jtan.com>. | 336 | * Submitted by Justin Burket (KL1RL) <zorton@jtan.com> |
337 | * and Mike Studer (K6EEP) <k6eep@hamsoftware.org>. | ||
338 | * Ian Abbott <abbotti@mev.co.uk> added a few more from the driver INF file. | ||
337 | */ | 339 | */ |
340 | #define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ | ||
341 | #define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ | ||
338 | #define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ | 342 | #define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ |
339 | #define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ | 343 | #define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ |
344 | #define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ | ||
345 | #define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ | ||
346 | #define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ | ||
347 | #define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ | ||
340 | 348 | ||
341 | /* | 349 | /* |
342 | * Active Robots product ids. | 350 | * Active Robots product ids. |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index e8e575e037c1..37c81c08faad 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -73,9 +73,10 @@ static struct usb_device_id id_table [] = { | |||
73 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, | 73 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, |
74 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, | 74 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, |
75 | { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, | 75 | { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, |
76 | { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) }, | 76 | { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) }, |
77 | { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID ) }, | 77 | { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) }, |
78 | { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) }, | 78 | { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) }, |
79 | { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) }, | ||
79 | { } /* Terminating entry */ | 80 | { } /* Terminating entry */ |
80 | }; | 81 | }; |
81 | 82 | ||
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 1807087a76e3..9bc4755162ad 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -71,3 +71,7 @@ | |||
71 | 71 | ||
72 | #define SAGEM_VENDOR_ID 0x079b | 72 | #define SAGEM_VENDOR_ID 0x079b |
73 | #define SAGEM_PRODUCT_ID 0x0027 | 73 | #define SAGEM_PRODUCT_ID 0x0027 |
74 | |||
75 | /* Leadtek GPS 9531 (ID 0413:2101) */ | ||
76 | #define LEADTEK_VENDOR_ID 0x0413 | ||
77 | #define LEADTEK_9531_PRODUCT_ID 0x2101 | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4dd6865d32b0..b5c96e74a903 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -242,8 +242,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
242 | 242 | ||
243 | down(&port->sem); | 243 | down(&port->sem); |
244 | 244 | ||
245 | if (port->open_count == 0) | 245 | if (port->open_count == 0) { |
246 | goto out; | 246 | up(&port->sem); |
247 | return; | ||
248 | } | ||
247 | 249 | ||
248 | --port->open_count; | 250 | --port->open_count; |
249 | if (port->open_count == 0) { | 251 | if (port->open_count == 0) { |
@@ -260,10 +262,8 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
260 | module_put(port->serial->type->driver.owner); | 262 | module_put(port->serial->type->driver.owner); |
261 | } | 263 | } |
262 | 264 | ||
263 | kref_put(&port->serial->kref, destroy_serial); | ||
264 | |||
265 | out: | ||
266 | up(&port->sem); | 265 | up(&port->sem); |
266 | kref_put(&port->serial->kref, destroy_serial); | ||
267 | } | 267 | } |
268 | 268 | ||
269 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) | 269 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index bce3d55affd8..11a48d874752 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -69,6 +69,8 @@ static struct usb_device_id id_table [] = { | |||
69 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 69 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
70 | { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID), | 70 | { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID), |
71 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 71 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
72 | { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID), | ||
73 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | ||
72 | { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID), | 74 | { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID), |
73 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 75 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
74 | { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID), | 76 | { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID), |
@@ -139,6 +141,7 @@ static struct usb_device_id id_table_combined [] = { | |||
139 | { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, | 141 | { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, |
140 | { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) }, | 142 | { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) }, |
141 | { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID) }, | 143 | { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID) }, |
144 | { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID) }, | ||
142 | { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) }, | 145 | { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) }, |
143 | { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) }, | 146 | { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) }, |
144 | { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) }, | 147 | { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) }, |
diff --git a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h index b84d1cb4c693..765118d83fb6 100644 --- a/drivers/usb/serial/visor.h +++ b/drivers/usb/serial/visor.h | |||
@@ -36,6 +36,9 @@ | |||
36 | #define PALM_ZIRE_ID 0x0070 | 36 | #define PALM_ZIRE_ID 0x0070 |
37 | #define PALM_M100_ID 0x0080 | 37 | #define PALM_M100_ID 0x0080 |
38 | 38 | ||
39 | #define GSPDA_VENDOR_ID 0x115e | ||
40 | #define GSPDA_XPLORE_M68_ID 0xf100 | ||
41 | |||
39 | #define SONY_VENDOR_ID 0x054C | 42 | #define SONY_VENDOR_ID 0x054C |
40 | #define SONY_CLIE_3_5_ID 0x0038 | 43 | #define SONY_CLIE_3_5_ID 0x0038 |
41 | #define SONY_CLIE_4_0_ID 0x0066 | 44 | #define SONY_CLIE_4_0_ID 0x0066 |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index ee958f986eb8..31ca92056c27 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -106,6 +106,13 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113, | |||
106 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 106 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
107 | US_FL_FIX_INQUIRY ), | 107 | US_FL_FIX_INQUIRY ), |
108 | 108 | ||
109 | /* Reported by Christian Leber <christian@leber.de> */ | ||
110 | UNUSUAL_DEV( 0x0419, 0xaaf5, 0x0100, 0x0100, | ||
111 | "TrekStor", | ||
112 | "i.Beat 115 2.0", | ||
113 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
114 | US_FL_IGNORE_RESIDUE | US_FL_NOT_LOCKABLE ), | ||
115 | |||
109 | /* Reported by Stefan Werner <dustbln@gmx.de> */ | 116 | /* Reported by Stefan Werner <dustbln@gmx.de> */ |
110 | UNUSUAL_DEV( 0x0419, 0xaaf6, 0x0100, 0x0100, | 117 | UNUSUAL_DEV( 0x0419, 0xaaf6, 0x0100, 0x0100, |
111 | "TrekStor", | 118 | "TrekStor", |
@@ -127,6 +134,14 @@ UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, | |||
127 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), | 134 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), |
128 | #endif | 135 | #endif |
129 | 136 | ||
137 | /* Patch submitted by Daniel Drake <dsd@gentoo.org> | ||
138 | * Device reports nonsense bInterfaceProtocol 6 when connected over USB2 */ | ||
139 | UNUSUAL_DEV( 0x0451, 0x5416, 0x0100, 0x0100, | ||
140 | "Neuros Audio", | ||
141 | "USB 2.0 HD 2.5", | ||
142 | US_SC_DEVICE, US_PR_BULK, NULL, | ||
143 | US_FL_NEED_OVERRIDE ), | ||
144 | |||
130 | /* | 145 | /* |
131 | * Pete Zaitcev <zaitcev@yahoo.com>, from Patrick C. F. Ernzer, bz#162559. | 146 | * Pete Zaitcev <zaitcev@yahoo.com>, from Patrick C. F. Ernzer, bz#162559. |
132 | * The key does not actually break, but it returns zero sense which | 147 | * The key does not actually break, but it returns zero sense which |
@@ -137,13 +152,16 @@ UNUSUAL_DEV( 0x0457, 0x0150, 0x0100, 0x0100, | |||
137 | "USB Mass Storage Device", | 152 | "USB Mass Storage Device", |
138 | US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), | 153 | US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), |
139 | 154 | ||
140 | /* Patch submitted by Daniel Drake <dsd@gentoo.org> | 155 | /* |
141 | * Device reports nonsense bInterfaceProtocol 6 when connected over USB2 */ | 156 | * Bohdan Linda <bohdan.linda@gmail.com> |
142 | UNUSUAL_DEV( 0x0451, 0x5416, 0x0100, 0x0100, | 157 | * 1GB USB sticks MyFlash High Speed. I have restricted |
143 | "Neuros Audio", | 158 | * the revision to my model only |
144 | "USB 2.0 HD 2.5", | 159 | */ |
145 | US_SC_DEVICE, US_PR_BULK, NULL, | 160 | UNUSUAL_DEV( 0x0457, 0x0151, 0x0100, 0x0100, |
146 | US_FL_NEED_OVERRIDE ), | 161 | "USB 2.0", |
162 | "Flash Disk", | ||
163 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
164 | US_FL_NOT_LOCKABLE ), | ||
147 | 165 | ||
148 | UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, | 166 | UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, |
149 | "Rio", | 167 | "Rio", |
@@ -735,6 +753,13 @@ UNUSUAL_DEV( 0x0693, 0x0005, 0x0100, 0x0100, | |||
735 | "Flashgate", | 753 | "Flashgate", |
736 | US_SC_SCSI, US_PR_BULK, NULL, 0 ), | 754 | US_SC_SCSI, US_PR_BULK, NULL, 0 ), |
737 | 755 | ||
756 | /* Reported by David Hamilton <niftimusmaximus@lycos.com> */ | ||
757 | UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001, | ||
758 | "Thomson Multimedia Inc.", | ||
759 | "RCA RD1080 MP3 Player", | ||
760 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
761 | US_FL_FIX_CAPACITY ), | ||
762 | |||
738 | UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200, | 763 | UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200, |
739 | "Sandisk", | 764 | "Sandisk", |
740 | "ImageMate SDDR-05a", | 765 | "ImageMate SDDR-05a", |
@@ -946,6 +971,12 @@ UNUSUAL_DEV( 0x084d, 0x0011, 0x0110, 0x0110, | |||
946 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 971 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
947 | US_FL_BULK32), | 972 | US_FL_BULK32), |
948 | 973 | ||
974 | /* Submitted by Jan De Luyck <lkml@kcore.org> */ | ||
975 | UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000, | ||
976 | "CITIZEN", | ||
977 | "X1DE-USB", | ||
978 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
979 | US_FL_SINGLE_LUN), | ||
949 | 980 | ||
950 | /* Entry needed for flags. Moreover, all devices with this ID use | 981 | /* Entry needed for flags. Moreover, all devices with this ID use |
951 | * bulk-only transport, but _some_ falsely report Control/Bulk instead. | 982 | * bulk-only transport, but _some_ falsely report Control/Bulk instead. |
@@ -1085,6 +1116,13 @@ UNUSUAL_DEV( 0x0dda, 0x0301, 0x0012, 0x0012, | |||
1085 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1116 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1086 | US_FL_IGNORE_RESIDUE ), | 1117 | US_FL_IGNORE_RESIDUE ), |
1087 | 1118 | ||
1119 | /* Reported by Jim McCloskey <mcclosk@ucsc.edu> */ | ||
1120 | UNUSUAL_DEV( 0x0e21, 0x0520, 0x0100, 0x0100, | ||
1121 | "Cowon Systems", | ||
1122 | "iAUDIO M5", | ||
1123 | US_SC_DEVICE, US_PR_BULK, NULL, | ||
1124 | 0 ), | ||
1125 | |||
1088 | /* Submitted by Antoine Mairesse <antoine.mairesse@free.fr> */ | 1126 | /* Submitted by Antoine Mairesse <antoine.mairesse@free.fr> */ |
1089 | UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300, | 1127 | UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300, |
1090 | "USB", | 1128 | "USB", |
@@ -1162,6 +1200,13 @@ UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, | |||
1162 | US_FL_SINGLE_LUN), | 1200 | US_FL_SINGLE_LUN), |
1163 | #endif | 1201 | #endif |
1164 | 1202 | ||
1203 | /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ | ||
1204 | UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, | ||
1205 | "DataStor", | ||
1206 | "USB4500 FW1.04", | ||
1207 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1208 | US_FL_FIX_CAPACITY), | ||
1209 | |||
1165 | /* Control/Bulk transport for all SubClass values */ | 1210 | /* Control/Bulk transport for all SubClass values */ |
1166 | USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), | 1211 | USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), |
1167 | USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), | 1212 | USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 3e153d313bb0..f5079c78ba4e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -520,16 +520,11 @@ config FB_GBE | |||
520 | config FB_GBE_MEM | 520 | config FB_GBE_MEM |
521 | int "Video memory size in MB" | 521 | int "Video memory size in MB" |
522 | depends on FB_GBE | 522 | depends on FB_GBE |
523 | default 8 | 523 | default 4 |
524 | help | 524 | help |
525 | This is the amount of memory reserved for the framebuffer, | 525 | This is the amount of memory reserved for the framebuffer, |
526 | which can be any value between 1MB and 8MB. | 526 | which can be any value between 1MB and 8MB. |
527 | 527 | ||
528 | config BUS_I2C | ||
529 | bool | ||
530 | depends on (FB = y) && VISWS | ||
531 | default y | ||
532 | |||
533 | config FB_SUN3 | 528 | config FB_SUN3 |
534 | bool "Sun3 framebuffer support" | 529 | bool "Sun3 framebuffer support" |
535 | depends on (FB = y) && (SUN3 || SUN3X) && BROKEN | 530 | depends on (FB = y) && (SUN3 || SUN3X) && BROKEN |
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index df8e5667b348..466042808daf 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c | |||
@@ -253,7 +253,7 @@ static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper, | |||
253 | { | 253 | { |
254 | unsigned char *src; | 254 | unsigned char *src; |
255 | unsigned int xindex, yindex, chipindex, linesize; | 255 | unsigned int xindex, yindex, chipindex, linesize; |
256 | int i, count; | 256 | int i; |
257 | unsigned char val; | 257 | unsigned char val; |
258 | unsigned char bitmask, rightshift; | 258 | unsigned char bitmask, rightshift; |
259 | 259 | ||
@@ -282,7 +282,6 @@ static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper, | |||
282 | } | 282 | } |
283 | ks108_writeb_data(par, chipindex, val); | 283 | ks108_writeb_data(par, chipindex, val); |
284 | left++; | 284 | left++; |
285 | count++; | ||
286 | if (bitmask == 0x80) { | 285 | if (bitmask == 0x80) { |
287 | bitmask = 1; | 286 | bitmask = 1; |
288 | src++; | 287 | src++; |
@@ -460,11 +459,11 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou | |||
460 | inode = file->f_dentry->d_inode; | 459 | inode = file->f_dentry->d_inode; |
461 | fbidx = iminor(inode); | 460 | fbidx = iminor(inode); |
462 | info = registered_fb[fbidx]; | 461 | info = registered_fb[fbidx]; |
463 | par = info->par; | ||
464 | 462 | ||
465 | if (!info || !info->screen_base) | 463 | if (!info || !info->screen_base) |
466 | return -ENODEV; | 464 | return -ENODEV; |
467 | 465 | ||
466 | par = info->par; | ||
468 | xres = info->var.xres; | 467 | xres = info->var.xres; |
469 | fbmemlength = (xres * info->var.yres)/8; | 468 | fbmemlength = (xres * info->var.yres)/8; |
470 | 469 | ||
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c index 69f75547865d..c924d81f7978 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/asiliantfb.c | |||
@@ -322,32 +322,29 @@ static int asiliantfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
322 | writeb(green, mmio_base + 0x791); | 322 | writeb(green, mmio_base + 0x791); |
323 | writeb(blue, mmio_base + 0x791); | 323 | writeb(blue, mmio_base + 0x791); |
324 | 324 | ||
325 | switch(p->var.bits_per_pixel) { | 325 | if (regno < 16) { |
326 | case 15: | 326 | switch(p->var.red.offset) { |
327 | if (regno < 16) { | 327 | case 10: /* RGB 555 */ |
328 | ((u32 *)(p->pseudo_palette))[regno] = | 328 | ((u32 *)(p->pseudo_palette))[regno] = |
329 | ((red & 0xf8) << 7) | | 329 | ((red & 0xf8) << 7) | |
330 | ((green & 0xf8) << 2) | | 330 | ((green & 0xf8) << 2) | |
331 | ((blue & 0xf8) >> 3); | 331 | ((blue & 0xf8) >> 3); |
332 | } | 332 | break; |
333 | break; | 333 | case 11: /* RGB 565 */ |
334 | case 16: | ||
335 | if (regno < 16) { | ||
336 | ((u32 *)(p->pseudo_palette))[regno] = | 334 | ((u32 *)(p->pseudo_palette))[regno] = |
337 | ((red & 0xf8) << 8) | | 335 | ((red & 0xf8) << 8) | |
338 | ((green & 0xfc) << 3) | | 336 | ((green & 0xfc) << 3) | |
339 | ((blue & 0xf8) >> 3); | 337 | ((blue & 0xf8) >> 3); |
340 | } | 338 | break; |
341 | break; | 339 | case 16: /* RGB 888 */ |
342 | case 24: | ||
343 | if (regno < 24) { | ||
344 | ((u32 *)(p->pseudo_palette))[regno] = | 340 | ((u32 *)(p->pseudo_palette))[regno] = |
345 | (red << 16) | | 341 | (red << 16) | |
346 | (green << 8) | | 342 | (green << 8) | |
347 | (blue); | 343 | (blue); |
344 | break; | ||
348 | } | 345 | } |
349 | break; | ||
350 | } | 346 | } |
347 | |||
351 | return 0; | 348 | return 0; |
352 | } | 349 | } |
353 | 350 | ||
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index bfc8a93b2c73..620c9a934e0e 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -1326,7 +1326,7 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll, | |||
1326 | unsigned char post_dividers[] = {1,2,4,8,3,6,12}; | 1326 | unsigned char post_dividers[] = {1,2,4,8,3,6,12}; |
1327 | u32 output_freq; | 1327 | u32 output_freq; |
1328 | u32 vclk; /* in .01 MHz */ | 1328 | u32 vclk; /* in .01 MHz */ |
1329 | int i; | 1329 | int i = 0; |
1330 | u32 n, d; | 1330 | u32 n, d; |
1331 | 1331 | ||
1332 | vclk = 100000000 / period_in_ps; /* convert units to 10 kHz */ | 1332 | vclk = 100000000 / period_in_ps; /* convert units to 10 kHz */ |
@@ -1340,15 +1340,16 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll, | |||
1340 | /* now, find an acceptable divider */ | 1340 | /* now, find an acceptable divider */ |
1341 | for (i = 0; i < sizeof(post_dividers); i++) { | 1341 | for (i = 0; i < sizeof(post_dividers); i++) { |
1342 | output_freq = post_dividers[i] * vclk; | 1342 | output_freq = post_dividers[i] * vclk; |
1343 | if (output_freq >= c.ppll_min && output_freq <= c.ppll_max) | 1343 | if (output_freq >= c.ppll_min && output_freq <= c.ppll_max) { |
1344 | pll->post_divider = post_dividers[i]; | ||
1344 | break; | 1345 | break; |
1346 | } | ||
1345 | } | 1347 | } |
1346 | 1348 | ||
1347 | /* calculate feedback divider */ | 1349 | /* calculate feedback divider */ |
1348 | n = c.ref_divider * output_freq; | 1350 | n = c.ref_divider * output_freq; |
1349 | d = c.ref_clk; | 1351 | d = c.ref_clk; |
1350 | 1352 | ||
1351 | pll->post_divider = post_dividers[i]; | ||
1352 | pll->feedback_divider = round_div(n, d); | 1353 | pll->feedback_divider = round_div(n, d); |
1353 | pll->vclk = vclk; | 1354 | pll->vclk = vclk; |
1354 | 1355 | ||
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c index 7f9838dceab5..98c05bc0de44 100644 --- a/drivers/video/aty/radeon_monitor.c +++ b/drivers/video/aty/radeon_monitor.c | |||
@@ -396,6 +396,10 @@ static int __devinit radeon_parse_monitor_layout(struct radeonfb_info *rinfo, | |||
396 | s1[i] = *s; | 396 | s1[i] = *s; |
397 | i++; | 397 | i++; |
398 | } | 398 | } |
399 | |||
400 | if (i > 4) | ||
401 | i = 4; | ||
402 | |||
399 | } while (*s++); | 403 | } while (*s++); |
400 | if (second) | 404 | if (second) |
401 | s2[i] = 0; | 405 | s2[i] = 0; |
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 556895e99645..1f8d805c61e5 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c | |||
@@ -1321,8 +1321,6 @@ static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo) | |||
1321 | mdelay( 15); | 1321 | mdelay( 15); |
1322 | } | 1322 | } |
1323 | 1323 | ||
1324 | #ifdef CONFIG_PPC_OF | ||
1325 | |||
1326 | static void radeon_pm_reset_pad_ctlr_strength(struct radeonfb_info *rinfo) | 1324 | static void radeon_pm_reset_pad_ctlr_strength(struct radeonfb_info *rinfo) |
1327 | { | 1325 | { |
1328 | u32 tmp, tmp2; | 1326 | u32 tmp, tmp2; |
@@ -1836,6 +1834,8 @@ static void radeon_reinitialize_M10(struct radeonfb_info *rinfo) | |||
1836 | radeon_pm_m10_enable_lvds_spread_spectrum(rinfo); | 1834 | radeon_pm_m10_enable_lvds_spread_spectrum(rinfo); |
1837 | } | 1835 | } |
1838 | 1836 | ||
1837 | #ifdef CONFIG_PPC_OF | ||
1838 | |||
1839 | static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo) | 1839 | static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo) |
1840 | { | 1840 | { |
1841 | OUTREG(MC_CNTL, rinfo->save_regs[46]); | 1841 | OUTREG(MC_CNTL, rinfo->save_regs[46]); |
@@ -2728,13 +2728,23 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) | |||
2728 | printk("radeonfb: Dynamic Clock Power Management disabled\n"); | 2728 | printk("radeonfb: Dynamic Clock Power Management disabled\n"); |
2729 | } | 2729 | } |
2730 | 2730 | ||
2731 | #if defined(CONFIG_PM) | ||
2731 | /* Check if we can power manage on suspend/resume. We can do | 2732 | /* Check if we can power manage on suspend/resume. We can do |
2732 | * D2 on M6, M7 and M9, and we can resume from D3 cold a few other | 2733 | * D2 on M6, M7 and M9, and we can resume from D3 cold a few other |
2733 | * "Mac" cards, but that's all. We need more infos about what the | 2734 | * "Mac" cards, but that's all. We need more infos about what the |
2734 | * BIOS does tho. Right now, all this PM stuff is pmac-only for that | 2735 | * BIOS does tho. Right now, all this PM stuff is pmac-only for that |
2735 | * reason. --BenH | 2736 | * reason. --BenH |
2736 | */ | 2737 | */ |
2737 | #if defined(CONFIG_PM) && defined(CONFIG_PPC_PMAC) | 2738 | /* Special case for Samsung P35 laptops |
2739 | */ | ||
2740 | if ((rinfo->pdev->vendor == PCI_VENDOR_ID_ATI) && | ||
2741 | (rinfo->pdev->device == PCI_CHIP_RV350_NP) && | ||
2742 | (rinfo->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG) && | ||
2743 | (rinfo->pdev->subsystem_device == 0xc00c)) { | ||
2744 | rinfo->reinit_func = radeon_reinitialize_M10; | ||
2745 | rinfo->pm_mode |= radeon_pm_off; | ||
2746 | } | ||
2747 | #if defined(CONFIG_PPC_PMAC) | ||
2738 | if (_machine == _MACH_Pmac && rinfo->of_node) { | 2748 | if (_machine == _MACH_Pmac && rinfo->of_node) { |
2739 | if (rinfo->is_mobility && rinfo->pm_reg && | 2749 | if (rinfo->is_mobility && rinfo->pm_reg && |
2740 | rinfo->family <= CHIP_FAMILY_RV250) | 2750 | rinfo->family <= CHIP_FAMILY_RV250) |
@@ -2778,7 +2788,8 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) | |||
2778 | OUTREG(TV_DAC_CNTL, INREG(TV_DAC_CNTL) | 0x07000000); | 2788 | OUTREG(TV_DAC_CNTL, INREG(TV_DAC_CNTL) | 0x07000000); |
2779 | #endif | 2789 | #endif |
2780 | } | 2790 | } |
2781 | #endif /* defined(CONFIG_PM) && defined(CONFIG_PPC_PMAC) */ | 2791 | #endif /* defined(CONFIG_PPC_PMAC) */ |
2792 | #endif /* defined(CONFIG_PM) */ | ||
2782 | } | 2793 | } |
2783 | 2794 | ||
2784 | void radeonfb_pm_exit(struct radeonfb_info *rinfo) | 2795 | void radeonfb_pm_exit(struct radeonfb_info *rinfo) |
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 2406899f1207..3d04b2def0f1 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/interrupt.h> | 49 | #include <linux/interrupt.h> |
50 | #include <linux/ctype.h> | 50 | #include <linux/ctype.h> |
51 | #include <linux/dma-mapping.h> | 51 | #include <linux/dma-mapping.h> |
52 | #include <linux/platform_device.h> | ||
52 | 53 | ||
53 | #include <asm/mach-au1x00/au1000.h> | 54 | #include <asm/mach-au1x00/au1000.h> |
54 | 55 | ||
@@ -406,7 +407,7 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) | |||
406 | 407 | ||
407 | vma->vm_flags |= VM_IO; | 408 | vma->vm_flags |= VM_IO; |
408 | 409 | ||
409 | if (io_remap_page_range(vma, vma->vm_start, off, | 410 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, |
410 | vma->vm_end - vma->vm_start, | 411 | vma->vm_end - vma->vm_start, |
411 | vma->vm_page_prot)) { | 412 | vma->vm_page_prot)) { |
412 | return -EAGAIN; | 413 | return -EAGAIN; |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 9d5015e99372..151fda8dded0 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/ctype.h> | 13 | #include <linux/ctype.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
16 | #include <asm/bug.h> | ||
17 | 16 | ||
18 | static ssize_t backlight_show_power(struct class_device *cdev, char *buf) | 17 | static ssize_t backlight_show_power(struct class_device *cdev, char *buf) |
19 | { | 18 | { |
@@ -173,7 +172,7 @@ struct backlight_device *backlight_device_register(const char *name, void *devda | |||
173 | 172 | ||
174 | new_bd = kmalloc(sizeof(struct backlight_device), GFP_KERNEL); | 173 | new_bd = kmalloc(sizeof(struct backlight_device), GFP_KERNEL); |
175 | if (unlikely(!new_bd)) | 174 | if (unlikely(!new_bd)) |
176 | return ERR_PTR(ENOMEM); | 175 | return ERR_PTR(-ENOMEM); |
177 | 176 | ||
178 | init_MUTEX(&new_bd->sem); | 177 | init_MUTEX(&new_bd->sem); |
179 | new_bd->props = bp; | 178 | new_bd->props = bp; |
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 68c690605aa7..86908a60c630 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/ctype.h> | 13 | #include <linux/ctype.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
16 | #include <asm/bug.h> | ||
17 | 16 | ||
18 | static ssize_t lcd_show_power(struct class_device *cdev, char *buf) | 17 | static ssize_t lcd_show_power(struct class_device *cdev, char *buf) |
19 | { | 18 | { |
@@ -172,7 +171,7 @@ struct lcd_device *lcd_device_register(const char *name, void *devdata, | |||
172 | 171 | ||
173 | new_ld = kmalloc(sizeof(struct lcd_device), GFP_KERNEL); | 172 | new_ld = kmalloc(sizeof(struct lcd_device), GFP_KERNEL); |
174 | if (unlikely(!new_ld)) | 173 | if (unlikely(!new_ld)) |
175 | return ERR_PTR(ENOMEM); | 174 | return ERR_PTR(-ENOMEM); |
176 | 175 | ||
177 | init_MUTEX(&new_ld->sem); | 176 | init_MUTEX(&new_ld->sem); |
178 | new_ld->props = lp; | 177 | new_ld->props = lp; |
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index a7bcd17112c0..0339f5640a78 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c | |||
@@ -30,10 +30,11 @@ | |||
30 | 30 | ||
31 | #define STI_DRIVERVERSION "Version 0.9a" | 31 | #define STI_DRIVERVERSION "Version 0.9a" |
32 | 32 | ||
33 | struct sti_struct *default_sti; | 33 | struct sti_struct *default_sti __read_mostly; |
34 | 34 | ||
35 | static int num_sti_roms; /* # of STI ROMS found */ | 35 | /* number of STI ROMS found and their ptrs to each struct */ |
36 | static struct sti_struct *sti_roms[MAX_STI_ROMS]; /* ptr to each sti_struct */ | 36 | static int num_sti_roms __read_mostly; |
37 | static struct sti_struct *sti_roms[MAX_STI_ROMS] __read_mostly; | ||
37 | 38 | ||
38 | 39 | ||
39 | /* The colour indices used by STI are | 40 | /* The colour indices used by STI are |
@@ -266,7 +267,7 @@ sti_rom_copy(unsigned long base, unsigned long count, void *dest) | |||
266 | 267 | ||
267 | 268 | ||
268 | 269 | ||
269 | static char default_sti_path[21]; | 270 | static char default_sti_path[21] __read_mostly; |
270 | 271 | ||
271 | #ifndef MODULE | 272 | #ifndef MODULE |
272 | static int __init sti_setup(char *str) | 273 | static int __init sti_setup(char *str) |
@@ -414,10 +415,10 @@ sti_init_glob_cfg(struct sti_struct *sti, | |||
414 | if (!sti->sti_mem_request) | 415 | if (!sti->sti_mem_request) |
415 | sti->sti_mem_request = 256; /* STI default */ | 416 | sti->sti_mem_request = 256; /* STI default */ |
416 | 417 | ||
417 | glob_cfg = kmalloc(sizeof(*sti->glob_cfg), GFP_KERNEL); | 418 | glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL); |
418 | glob_cfg_ext = kmalloc(sizeof(*glob_cfg_ext), GFP_KERNEL); | 419 | glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL); |
419 | save_addr = kmalloc(save_addr_size, GFP_KERNEL); | 420 | save_addr = kzalloc(save_addr_size, GFP_KERNEL); |
420 | sti_mem_addr = kmalloc(sti->sti_mem_request, GFP_KERNEL); | 421 | sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL); |
421 | 422 | ||
422 | if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) { | 423 | if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) { |
423 | kfree(glob_cfg); | 424 | kfree(glob_cfg); |
@@ -427,11 +428,6 @@ sti_init_glob_cfg(struct sti_struct *sti, | |||
427 | return -ENOMEM; | 428 | return -ENOMEM; |
428 | } | 429 | } |
429 | 430 | ||
430 | memset(glob_cfg, 0, sizeof(*glob_cfg)); | ||
431 | memset(glob_cfg_ext, 0, sizeof(*glob_cfg_ext)); | ||
432 | memset(save_addr, 0, save_addr_size); | ||
433 | memset(sti_mem_addr, 0, sti->sti_mem_request); | ||
434 | |||
435 | glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext); | 431 | glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext); |
436 | glob_cfg->save_addr = STI_PTR(save_addr); | 432 | glob_cfg->save_addr = STI_PTR(save_addr); |
437 | for (i=0; i<8; i++) { | 433 | for (i=0; i<8; i++) { |
@@ -502,9 +498,9 @@ sti_init_glob_cfg(struct sti_struct *sti, | |||
502 | 498 | ||
503 | #ifdef CONFIG_FB | 499 | #ifdef CONFIG_FB |
504 | struct sti_cooked_font * __init | 500 | struct sti_cooked_font * __init |
505 | sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) | 501 | sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) |
506 | { | 502 | { |
507 | struct font_desc *fbfont; | 503 | const struct font_desc *fbfont; |
508 | unsigned int size, bpc; | 504 | unsigned int size, bpc; |
509 | void *dest; | 505 | void *dest; |
510 | struct sti_rom_font *nf; | 506 | struct sti_rom_font *nf; |
@@ -525,10 +521,9 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) | |||
525 | size = bpc * 256; | 521 | size = bpc * 256; |
526 | size += sizeof(struct sti_rom_font); | 522 | size += sizeof(struct sti_rom_font); |
527 | 523 | ||
528 | nf = kmalloc(size, GFP_KERNEL); | 524 | nf = kzalloc(size, GFP_KERNEL); |
529 | if (!nf) | 525 | if (!nf) |
530 | return NULL; | 526 | return NULL; |
531 | memset(nf, 0, size); | ||
532 | 527 | ||
533 | nf->first_char = 0; | 528 | nf->first_char = 0; |
534 | nf->last_char = 255; | 529 | nf->last_char = 255; |
@@ -544,7 +539,7 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) | |||
544 | dest += sizeof(struct sti_rom_font); | 539 | dest += sizeof(struct sti_rom_font); |
545 | memcpy(dest, fbfont->data, bpc*256); | 540 | memcpy(dest, fbfont->data, bpc*256); |
546 | 541 | ||
547 | cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL); | 542 | cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); |
548 | if (!cooked_font) { | 543 | if (!cooked_font) { |
549 | kfree(nf); | 544 | kfree(nf); |
550 | return NULL; | 545 | return NULL; |
@@ -559,7 +554,7 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) | |||
559 | } | 554 | } |
560 | #else | 555 | #else |
561 | struct sti_cooked_font * __init | 556 | struct sti_cooked_font * __init |
562 | sti_select_fbfont(struct sti_cooked_rom *cooked_rom, char *fbfont_name) | 557 | sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) |
563 | { | 558 | { |
564 | return NULL; | 559 | return NULL; |
565 | } | 560 | } |
@@ -617,7 +612,7 @@ sti_cook_fonts(struct sti_cooked_rom *cooked_rom, | |||
617 | struct sti_rom_font *raw_font, *font_start; | 612 | struct sti_rom_font *raw_font, *font_start; |
618 | struct sti_cooked_font *cooked_font; | 613 | struct sti_cooked_font *cooked_font; |
619 | 614 | ||
620 | cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL); | 615 | cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); |
621 | if (!cooked_font) | 616 | if (!cooked_font) |
622 | return 0; | 617 | return 0; |
623 | 618 | ||
@@ -631,7 +626,7 @@ sti_cook_fonts(struct sti_cooked_rom *cooked_rom, | |||
631 | while (raw_font->next_font) { | 626 | while (raw_font->next_font) { |
632 | raw_font = ((void *)font_start) + (raw_font->next_font); | 627 | raw_font = ((void *)font_start) + (raw_font->next_font); |
633 | 628 | ||
634 | cooked_font->next_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL); | 629 | cooked_font->next_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); |
635 | if (!cooked_font->next_font) | 630 | if (!cooked_font->next_font) |
636 | return 1; | 631 | return 1; |
637 | 632 | ||
@@ -668,10 +663,9 @@ sti_bmode_font_raw(struct sti_cooked_font *f) | |||
668 | unsigned char *n, *p, *q; | 663 | unsigned char *n, *p, *q; |
669 | int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); | 664 | int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); |
670 | 665 | ||
671 | n = kmalloc (4*size, GFP_KERNEL); | 666 | n = kzalloc (4*size, GFP_KERNEL); |
672 | if (!n) | 667 | if (!n) |
673 | return NULL; | 668 | return NULL; |
674 | memset (n, 0, 4*size); | ||
675 | p = n + 3; | 669 | p = n + 3; |
676 | q = (unsigned char *)f->raw; | 670 | q = (unsigned char *)f->raw; |
677 | while (size--) { | 671 | while (size--) { |
@@ -816,13 +810,12 @@ sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd | |||
816 | return NULL; | 810 | return NULL; |
817 | } | 811 | } |
818 | 812 | ||
819 | sti = kmalloc(sizeof(*sti), GFP_KERNEL); | 813 | sti = kzalloc(sizeof(*sti), GFP_KERNEL); |
820 | if (!sti) { | 814 | if (!sti) { |
821 | printk(KERN_ERR "Not enough memory !\n"); | 815 | printk(KERN_ERR "Not enough memory !\n"); |
822 | return NULL; | 816 | return NULL; |
823 | } | 817 | } |
824 | 818 | ||
825 | memset(sti, 0, sizeof(*sti)); | ||
826 | spin_lock_init(&sti->lock); | 819 | spin_lock_init(&sti->lock); |
827 | 820 | ||
828 | test_rom: | 821 | test_rom: |
@@ -1035,7 +1028,7 @@ static struct parisc_driver pa_sti_driver = { | |||
1035 | * sti_init_roms() - detects all STI ROMs and stores them in sti_roms[] | 1028 | * sti_init_roms() - detects all STI ROMs and stores them in sti_roms[] |
1036 | */ | 1029 | */ |
1037 | 1030 | ||
1038 | static int sticore_initialized; | 1031 | static int sticore_initialized __read_mostly; |
1039 | 1032 | ||
1040 | static void __init sti_init_roms(void) | 1033 | static void __init sti_init_roms(void) |
1041 | { | 1034 | { |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 12d9329d1408..5a86978537d2 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -509,57 +509,60 @@ static int vgacon_doresize(struct vc_data *c, | |||
509 | { | 509 | { |
510 | unsigned long flags; | 510 | unsigned long flags; |
511 | unsigned int scanlines = height * c->vc_font.height; | 511 | unsigned int scanlines = height * c->vc_font.height; |
512 | u8 scanlines_lo, r7, vsync_end, mode, max_scan; | 512 | u8 scanlines_lo = 0, r7 = 0, vsync_end = 0, mode, max_scan; |
513 | 513 | ||
514 | spin_lock_irqsave(&vga_lock, flags); | 514 | spin_lock_irqsave(&vga_lock, flags); |
515 | 515 | ||
516 | outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg); | ||
517 | max_scan = inb_p(vga_video_port_val); | ||
518 | |||
519 | if (max_scan & 0x80) | ||
520 | scanlines <<= 1; | ||
521 | |||
522 | vgacon_xres = width * VGA_FONTWIDTH; | 516 | vgacon_xres = width * VGA_FONTWIDTH; |
523 | vgacon_yres = height * c->vc_font.height; | 517 | vgacon_yres = height * c->vc_font.height; |
524 | outb_p(VGA_CRTC_MODE, vga_video_port_reg); | 518 | if (vga_video_type >= VIDEO_TYPE_VGAC) { |
525 | mode = inb_p(vga_video_port_val); | 519 | outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg); |
520 | max_scan = inb_p(vga_video_port_val); | ||
526 | 521 | ||
527 | if (mode & 0x04) | 522 | if (max_scan & 0x80) |
528 | scanlines >>= 1; | 523 | scanlines <<= 1; |
529 | 524 | ||
530 | scanlines -= 1; | 525 | outb_p(VGA_CRTC_MODE, vga_video_port_reg); |
531 | scanlines_lo = scanlines & 0xff; | 526 | mode = inb_p(vga_video_port_val); |
532 | 527 | ||
533 | outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg); | 528 | if (mode & 0x04) |
534 | r7 = inb_p(vga_video_port_val) & ~0x42; | 529 | scanlines >>= 1; |
535 | 530 | ||
536 | if (scanlines & 0x100) | 531 | scanlines -= 1; |
537 | r7 |= 0x02; | 532 | scanlines_lo = scanlines & 0xff; |
538 | if (scanlines & 0x200) | ||
539 | r7 |= 0x40; | ||
540 | 533 | ||
541 | /* deprotect registers */ | 534 | outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg); |
542 | outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg); | 535 | r7 = inb_p(vga_video_port_val) & ~0x42; |
543 | vsync_end = inb_p(vga_video_port_val); | 536 | |
544 | outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg); | 537 | if (scanlines & 0x100) |
545 | outb_p(vsync_end & ~0x80, vga_video_port_val); | 538 | r7 |= 0x02; |
539 | if (scanlines & 0x200) | ||
540 | r7 |= 0x40; | ||
541 | |||
542 | /* deprotect registers */ | ||
543 | outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg); | ||
544 | vsync_end = inb_p(vga_video_port_val); | ||
545 | outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg); | ||
546 | outb_p(vsync_end & ~0x80, vga_video_port_val); | ||
547 | } | ||
546 | 548 | ||
547 | outb_p(VGA_CRTC_H_DISP, vga_video_port_reg); | 549 | outb_p(VGA_CRTC_H_DISP, vga_video_port_reg); |
548 | outb_p(width - 1, vga_video_port_val); | 550 | outb_p(width - 1, vga_video_port_val); |
549 | outb_p(VGA_CRTC_OFFSET, vga_video_port_reg); | 551 | outb_p(VGA_CRTC_OFFSET, vga_video_port_reg); |
550 | outb_p(width >> 1, vga_video_port_val); | 552 | outb_p(width >> 1, vga_video_port_val); |
551 | 553 | ||
552 | outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg); | 554 | if (vga_video_type >= VIDEO_TYPE_VGAC) { |
553 | outb_p(scanlines_lo, vga_video_port_val); | 555 | outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg); |
554 | outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg); | 556 | outb_p(scanlines_lo, vga_video_port_val); |
555 | outb_p(r7,vga_video_port_val); | 557 | outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg); |
558 | outb_p(r7,vga_video_port_val); | ||
556 | 559 | ||
557 | /* reprotect registers */ | 560 | /* reprotect registers */ |
558 | outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg); | 561 | outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg); |
559 | outb_p(vsync_end, vga_video_port_val); | 562 | outb_p(vsync_end, vga_video_port_val); |
563 | } | ||
560 | 564 | ||
561 | spin_unlock_irqrestore(&vga_lock, flags); | 565 | spin_unlock_irqrestore(&vga_lock, flags); |
562 | |||
563 | return 0; | 566 | return 0; |
564 | } | 567 | } |
565 | 568 | ||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index d2dede6ed3e5..996c7b58564e 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1550,6 +1550,7 @@ int fb_get_options(char *name, char **option) | |||
1550 | return retval; | 1550 | return retval; |
1551 | } | 1551 | } |
1552 | 1552 | ||
1553 | #ifndef MODULE | ||
1553 | /** | 1554 | /** |
1554 | * video_setup - process command line options | 1555 | * video_setup - process command line options |
1555 | * @options: string of options | 1556 | * @options: string of options |
@@ -1593,6 +1594,7 @@ static int __init video_setup(char *options) | |||
1593 | return 0; | 1594 | return 0; |
1594 | } | 1595 | } |
1595 | __setup("video=", video_setup); | 1596 | __setup("video=", video_setup); |
1597 | #endif | ||
1596 | 1598 | ||
1597 | /* | 1599 | /* |
1598 | * Visible symbols for modules | 1600 | * Visible symbols for modules |
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index 38d22729b129..5e25b9860196 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c | |||
@@ -656,12 +656,15 @@ static int gbefb_set_par(struct fb_info *info) | |||
656 | switch (bytesPerPixel) { | 656 | switch (bytesPerPixel) { |
657 | case 1: | 657 | case 1: |
658 | SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_I8); | 658 | SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_I8); |
659 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
659 | break; | 660 | break; |
660 | case 2: | 661 | case 2: |
661 | SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_ARGB5); | 662 | SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_ARGB5); |
663 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
662 | break; | 664 | break; |
663 | case 4: | 665 | case 4: |
664 | SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_RGB8); | 666 | SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_RGB8); |
667 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
665 | break; | 668 | break; |
666 | } | 669 | } |
667 | SET_GBE_FIELD(WID, BUF, val, GBE_BMODE_BOTH); | 670 | SET_GBE_FIELD(WID, BUF, val, GBE_BMODE_BOTH); |
@@ -1243,7 +1246,7 @@ static int __devexit gbefb_remove(struct platform_device* p_dev) | |||
1243 | (void *)gbe_tiles.cpu, gbe_tiles.dma); | 1246 | (void *)gbe_tiles.cpu, gbe_tiles.dma); |
1244 | release_mem_region(GBE_BASE, sizeof(struct sgi_gbe)); | 1247 | release_mem_region(GBE_BASE, sizeof(struct sgi_gbe)); |
1245 | iounmap(gbe); | 1248 | iounmap(gbe); |
1246 | gbefb_remove_sysfs(dev); | 1249 | gbefb_remove_sysfs(&p_dev->dev); |
1247 | framebuffer_release(info); | 1250 | framebuffer_release(info); |
1248 | 1251 | ||
1249 | return 0; | 1252 | return 0; |
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index ad416ae47596..7db42542eb19 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c | |||
@@ -1510,6 +1510,8 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1510 | default: | 1510 | default: |
1511 | printk(KERN_INFO "imsttfb: Device 0x%x unknown, " | 1511 | printk(KERN_INFO "imsttfb: Device 0x%x unknown, " |
1512 | "contact maintainer.\n", pdev->device); | 1512 | "contact maintainer.\n", pdev->device); |
1513 | release_mem_region(addr, size); | ||
1514 | framebuffer_release(info); | ||
1513 | return -ENODEV; | 1515 | return -ENODEV; |
1514 | } | 1516 | } |
1515 | 1517 | ||
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 6b8bd3cdf9c0..995b47c165a7 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
@@ -1333,33 +1333,35 @@ intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
1333 | if (regno > 255) | 1333 | if (regno > 255) |
1334 | return 1; | 1334 | return 1; |
1335 | 1335 | ||
1336 | switch (dinfo->depth) { | 1336 | if (dinfo->depth == 8) { |
1337 | case 8: | 1337 | red >>= 8; |
1338 | { | 1338 | green >>= 8; |
1339 | red >>= 8; | 1339 | blue >>= 8; |
1340 | green >>= 8; | 1340 | |
1341 | blue >>= 8; | 1341 | intelfbhw_setcolreg(dinfo, regno, red, green, blue, |
1342 | transp); | ||
1343 | } | ||
1342 | 1344 | ||
1343 | intelfbhw_setcolreg(dinfo, regno, red, green, blue, | 1345 | if (regno < 16) { |
1344 | transp); | 1346 | switch (dinfo->depth) { |
1347 | case 15: | ||
1348 | dinfo->pseudo_palette[regno] = ((red & 0xf800) >> 1) | | ||
1349 | ((green & 0xf800) >> 6) | | ||
1350 | ((blue & 0xf800) >> 11); | ||
1351 | break; | ||
1352 | case 16: | ||
1353 | dinfo->pseudo_palette[regno] = (red & 0xf800) | | ||
1354 | ((green & 0xfc00) >> 5) | | ||
1355 | ((blue & 0xf800) >> 11); | ||
1356 | break; | ||
1357 | case 24: | ||
1358 | dinfo->pseudo_palette[regno] = ((red & 0xff00) << 8) | | ||
1359 | (green & 0xff00) | | ||
1360 | ((blue & 0xff00) >> 8); | ||
1361 | break; | ||
1345 | } | 1362 | } |
1346 | break; | ||
1347 | case 15: | ||
1348 | dinfo->pseudo_palette[regno] = ((red & 0xf800) >> 1) | | ||
1349 | ((green & 0xf800) >> 6) | | ||
1350 | ((blue & 0xf800) >> 11); | ||
1351 | break; | ||
1352 | case 16: | ||
1353 | dinfo->pseudo_palette[regno] = (red & 0xf800) | | ||
1354 | ((green & 0xfc00) >> 5) | | ||
1355 | ((blue & 0xf800) >> 11); | ||
1356 | break; | ||
1357 | case 24: | ||
1358 | dinfo->pseudo_palette[regno] = ((red & 0xff00) << 8) | | ||
1359 | (green & 0xff00) | | ||
1360 | ((blue & 0xff00) >> 8); | ||
1361 | break; | ||
1362 | } | 1363 | } |
1364 | |||
1363 | return 0; | 1365 | return 0; |
1364 | } | 1366 | } |
1365 | 1367 | ||
diff --git a/drivers/video/kyro/STG4000VTG.c b/drivers/video/kyro/STG4000VTG.c index 3690b04190af..bd389709d234 100644 --- a/drivers/video/kyro/STG4000VTG.c +++ b/drivers/video/kyro/STG4000VTG.c | |||
@@ -17,7 +17,7 @@ | |||
17 | void DisableVGA(volatile STG4000REG __iomem *pSTGReg) | 17 | void DisableVGA(volatile STG4000REG __iomem *pSTGReg) |
18 | { | 18 | { |
19 | u32 tmp; | 19 | u32 tmp; |
20 | volatile u32 count, i; | 20 | volatile u32 count = 0, i; |
21 | 21 | ||
22 | /* Reset the VGA registers */ | 22 | /* Reset the VGA registers */ |
23 | tmp = STG_READ_REG(SoftwareReset); | 23 | tmp = STG_READ_REG(SoftwareReset); |
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 747602aa5615..b961d5601bd9 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c | |||
@@ -486,10 +486,8 @@ static void vgaHWRestore(const struct fb_info *info, | |||
486 | static inline int neo2200_sync(struct fb_info *info) | 486 | static inline int neo2200_sync(struct fb_info *info) |
487 | { | 487 | { |
488 | struct neofb_par *par = info->par; | 488 | struct neofb_par *par = info->par; |
489 | int waitcycles; | ||
490 | 489 | ||
491 | while (readl(&par->neo2200->bltStat) & 1) | 490 | while (readl(&par->neo2200->bltStat) & 1); |
492 | waitcycles++; | ||
493 | return 0; | 491 | return 0; |
494 | } | 492 | } |
495 | 493 | ||
@@ -843,6 +841,9 @@ static int neofb_set_par(struct fb_info *info) | |||
843 | 841 | ||
844 | par->SysIfaceCntl2 = 0xc0; /* VESA Bios sets this to 0x80! */ | 842 | par->SysIfaceCntl2 = 0xc0; /* VESA Bios sets this to 0x80! */ |
845 | 843 | ||
844 | /* Initialize: by default, we want display config register to be read */ | ||
845 | par->PanelDispCntlRegRead = 1; | ||
846 | |||
846 | /* Enable any user specified display devices. */ | 847 | /* Enable any user specified display devices. */ |
847 | par->PanelDispCntlReg1 = 0x00; | 848 | par->PanelDispCntlReg1 = 0x00; |
848 | if (par->internal_display) | 849 | if (par->internal_display) |
@@ -1334,6 +1335,18 @@ static int neofb_blank(int blank_mode, struct fb_info *info) | |||
1334 | struct neofb_par *par = info->par; | 1335 | struct neofb_par *par = info->par; |
1335 | int seqflags, lcdflags, dpmsflags, reg; | 1336 | int seqflags, lcdflags, dpmsflags, reg; |
1336 | 1337 | ||
1338 | |||
1339 | /* | ||
1340 | * Reload the value stored in the register, if sensible. It might have | ||
1341 | * been changed via FN keystroke. | ||
1342 | */ | ||
1343 | if (par->PanelDispCntlRegRead) { | ||
1344 | neoUnlock(); | ||
1345 | par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03; | ||
1346 | neoLock(&par->state); | ||
1347 | } | ||
1348 | par->PanelDispCntlRegRead = !blank_mode; | ||
1349 | |||
1337 | switch (blank_mode) { | 1350 | switch (blank_mode) { |
1338 | case FB_BLANK_POWERDOWN: /* powerdown - both sync lines down */ | 1351 | case FB_BLANK_POWERDOWN: /* powerdown - both sync lines down */ |
1339 | seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ | 1352 | seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ |
@@ -1366,7 +1379,7 @@ static int neofb_blank(int blank_mode, struct fb_info *info) | |||
1366 | case FB_BLANK_NORMAL: /* just blank screen (backlight stays on) */ | 1379 | case FB_BLANK_NORMAL: /* just blank screen (backlight stays on) */ |
1367 | seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ | 1380 | seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ |
1368 | lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ | 1381 | lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ |
1369 | dpmsflags = 0; /* no hsync/vsync suppression */ | 1382 | dpmsflags = 0x00; /* no hsync/vsync suppression */ |
1370 | break; | 1383 | break; |
1371 | case FB_BLANK_UNBLANK: /* unblank */ | 1384 | case FB_BLANK_UNBLANK: /* unblank */ |
1372 | seqflags = 0; /* Enable sequencer */ | 1385 | seqflags = 0; /* Enable sequencer */ |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index dbcb8962e57d..a7c4e5e8ead6 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -138,6 +138,8 @@ static struct pci_device_id nvidiafb_pci_tbl[] = { | |||
138 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 138 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
139 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X, | 139 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X, |
140 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 140 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
141 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_4000, | ||
142 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
141 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_448_GO, | 143 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_448_GO, |
142 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 144 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
143 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_488_GO, | 145 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_488_GO, |
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c index f3927b6cda9d..f5361cd8ccce 100644 --- a/drivers/video/pmag-ba-fb.c +++ b/drivers/video/pmag-ba-fb.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | 32 | ||
33 | #include <asm/bug.h> | ||
34 | #include <asm/io.h> | 33 | #include <asm/io.h> |
35 | #include <asm/system.h> | 34 | #include <asm/system.h> |
36 | 35 | ||
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c index 25148de5fe67..eeeac924b500 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/pmagb-b-fb.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | 29 | ||
30 | #include <asm/bug.h> | ||
31 | #include <asm/io.h> | 30 | #include <asm/io.h> |
32 | #include <asm/system.h> | 31 | #include <asm/system.h> |
33 | 32 | ||
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index e5d0f92eeae3..feec47bdd479 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c | |||
@@ -588,6 +588,7 @@ s1d13xxxfb_probe(struct platform_device *pdev) | |||
588 | goto bail; | 588 | goto bail; |
589 | } | 589 | } |
590 | 590 | ||
591 | platform_set_drvdata(pdev, info); | ||
591 | default_par = info->par; | 592 | default_par = info->par; |
592 | default_par->regs = ioremap_nocache(pdev->resource[1].start, | 593 | default_par->regs = ioremap_nocache(pdev->resource[1].start, |
593 | pdev->resource[1].end - pdev->resource[1].start +1); | 594 | pdev->resource[1].end - pdev->resource[1].start +1); |
@@ -638,8 +639,6 @@ s1d13xxxfb_probe(struct platform_device *pdev) | |||
638 | goto bail; | 639 | goto bail; |
639 | } | 640 | } |
640 | 641 | ||
641 | platform_set_drvdata(pdev, info); | ||
642 | |||
643 | printk(KERN_INFO "fb%d: %s frame buffer device\n", | 642 | printk(KERN_INFO "fb%d: %s frame buffer device\n", |
644 | info->node, info->fix.id); | 643 | info->node, info->fix.id); |
645 | 644 | ||
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index d574dd3c9c8a..9451932fbaf2 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c | |||
@@ -82,7 +82,6 @@ | |||
82 | #include <linux/fb.h> | 82 | #include <linux/fb.h> |
83 | #include <linux/init.h> | 83 | #include <linux/init.h> |
84 | #include <linux/dma-mapping.h> | 84 | #include <linux/dma-mapping.h> |
85 | #include <linux/string.h> | ||
86 | #include <linux/interrupt.h> | 85 | #include <linux/interrupt.h> |
87 | #include <linux/workqueue.h> | 86 | #include <linux/workqueue.h> |
88 | #include <linux/wait.h> | 87 | #include <linux/wait.h> |
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index ab727eaa7f43..10e6b3aab9ea 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c | |||
@@ -2021,8 +2021,8 @@ static int __devinit savagefb_probe (struct pci_dev* dev, | |||
2021 | #if defined(CONFIG_FB_SAVAGE_I2C) | 2021 | #if defined(CONFIG_FB_SAVAGE_I2C) |
2022 | savagefb_create_i2c_busses(info); | 2022 | savagefb_create_i2c_busses(info); |
2023 | savagefb_probe_i2c_connector(info, &par->edid); | 2023 | savagefb_probe_i2c_connector(info, &par->edid); |
2024 | kfree(par->edid); | ||
2025 | fb_edid_to_monspecs(par->edid, &info->monspecs); | 2024 | fb_edid_to_monspecs(par->edid, &info->monspecs); |
2025 | kfree(par->edid); | ||
2026 | fb_videomode_to_modelist(info->monspecs.modedb, | 2026 | fb_videomode_to_modelist(info->monspecs.modedb, |
2027 | info->monspecs.modedb_len, | 2027 | info->monspecs.modedb_len, |
2028 | &info->modelist); | 2028 | &info->modelist); |
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 3e7baf4c9fa8..5e5328d682db 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c | |||
@@ -786,28 +786,32 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
786 | if (regno >= info->cmap.len || regno > 255) return 1; | 786 | if (regno >= info->cmap.len || regno > 255) return 1; |
787 | 787 | ||
788 | switch (info->fix.visual) { | 788 | switch (info->fix.visual) { |
789 | case FB_VISUAL_PSEUDOCOLOR: | 789 | case FB_VISUAL_PSEUDOCOLOR: |
790 | rgbcol =(((u32)red & 0xff00) << 8) | | 790 | rgbcol =(((u32)red & 0xff00) << 8) | |
791 | (((u32)green & 0xff00) << 0) | | 791 | (((u32)green & 0xff00) << 0) | |
792 | (((u32)blue & 0xff00) >> 8); | 792 | (((u32)blue & 0xff00) >> 8); |
793 | do_setpalentry(par, regno, rgbcol); | 793 | do_setpalentry(par, regno, rgbcol); |
794 | break; | 794 | break; |
795 | /* Truecolor has no hardware color palettes. */ | 795 | /* Truecolor has no hardware color palettes. */ |
796 | case FB_VISUAL_TRUECOLOR: | 796 | case FB_VISUAL_TRUECOLOR: |
797 | if (regno < 16) { | ||
797 | rgbcol = (CNVT_TOHW( red, info->var.red.length) << | 798 | rgbcol = (CNVT_TOHW( red, info->var.red.length) << |
798 | info->var.red.offset) | | 799 | info->var.red.offset) | |
799 | (CNVT_TOHW( green, info->var.green.length) << | 800 | (CNVT_TOHW( green, info->var.green.length) << |
800 | info->var.green.offset) | | 801 | info->var.green.offset) | |
801 | (CNVT_TOHW( blue, info->var.blue.length) << | 802 | (CNVT_TOHW( blue, info->var.blue.length) << |
802 | info->var.blue.offset) | | 803 | info->var.blue.offset) | |
803 | (CNVT_TOHW( transp, info->var.transp.length) << | 804 | (CNVT_TOHW( transp, info->var.transp.length) << |
804 | info->var.transp.offset); | 805 | info->var.transp.offset); |
805 | par->palette[regno] = rgbcol; | 806 | par->palette[regno] = rgbcol; |
806 | break; | 807 | } |
807 | default: | 808 | |
808 | DPRINTK("bad depth %u\n", info->var.bits_per_pixel); | 809 | break; |
809 | break; | 810 | default: |
811 | DPRINTK("bad depth %u\n", info->var.bits_per_pixel); | ||
812 | break; | ||
810 | } | 813 | } |
814 | |||
811 | return 0; | 815 | return 0; |
812 | } | 816 | } |
813 | 817 | ||