diff options
85 files changed, 1105 insertions, 1553 deletions
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c index 8bf4153d0840..3bf6304158f6 100644 --- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c +++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/ata_platform.h> | 14 | #include <linux/ata_platform.h> |
15 | #include <linux/mv643xx_eth.h> | 15 | #include <linux/mv643xx_eth.h> |
16 | #include <linux/gpio.h> | ||
16 | #include <linux/spi/flash.h> | 17 | #include <linux/spi/flash.h> |
17 | #include <linux/spi/spi.h> | 18 | #include <linux/spi/spi.h> |
18 | #include <linux/spi/orion_spi.h> | 19 | #include <linux/spi/orion_spi.h> |
@@ -53,6 +54,11 @@ static void __init rd88f6192_init(void) | |||
53 | */ | 54 | */ |
54 | kirkwood_init(); | 55 | kirkwood_init(); |
55 | 56 | ||
57 | orion_gpio_set_valid(RD88F6192_GPIO_USB_VBUS, 1); | ||
58 | if (gpio_request(RD88F6192_GPIO_USB_VBUS, "USB VBUS") != 0 || | ||
59 | gpio_direction_output(RD88F6192_GPIO_USB_VBUS, 1) != 0) | ||
60 | pr_err("RD-88F6192-NAS: failed to setup USB VBUS GPIO\n"); | ||
61 | |||
56 | kirkwood_ehci_init(); | 62 | kirkwood_ehci_init(); |
57 | kirkwood_ge00_init(&rd88f6192_ge00_data); | 63 | kirkwood_ge00_init(&rd88f6192_ge00_data); |
58 | kirkwood_sata_init(&rd88f6192_sata_data); | 64 | kirkwood_sata_init(&rd88f6192_sata_data); |
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index b31ca4cef365..8f159db4d08a 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/delay.h> | ||
15 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
16 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
17 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
@@ -32,6 +33,7 @@ | |||
32 | 33 | ||
33 | #define DNS323_GPIO_LED_RIGHT_AMBER 1 | 34 | #define DNS323_GPIO_LED_RIGHT_AMBER 1 |
34 | #define DNS323_GPIO_LED_LEFT_AMBER 2 | 35 | #define DNS323_GPIO_LED_LEFT_AMBER 2 |
36 | #define DNS323_GPIO_SYSTEM_UP 3 | ||
35 | #define DNS323_GPIO_LED_POWER 5 | 37 | #define DNS323_GPIO_LED_POWER 5 |
36 | #define DNS323_GPIO_OVERTEMP 6 | 38 | #define DNS323_GPIO_OVERTEMP 6 |
37 | #define DNS323_GPIO_RTC 7 | 39 | #define DNS323_GPIO_RTC 7 |
@@ -239,7 +241,7 @@ static struct gpio_led dns323_leds[] = { | |||
239 | { | 241 | { |
240 | .name = "power:blue", | 242 | .name = "power:blue", |
241 | .gpio = DNS323_GPIO_LED_POWER, | 243 | .gpio = DNS323_GPIO_LED_POWER, |
242 | .active_low = 1, | 244 | .default_state = LEDS_GPIO_DEFSTATE_ON, |
243 | }, { | 245 | }, { |
244 | .name = "right:amber", | 246 | .name = "right:amber", |
245 | .gpio = DNS323_GPIO_LED_RIGHT_AMBER, | 247 | .gpio = DNS323_GPIO_LED_RIGHT_AMBER, |
@@ -334,7 +336,7 @@ static struct orion5x_mpp_mode dns323_mv88f5182_mpp_modes[] __initdata = { | |||
334 | { 0, MPP_UNUSED }, | 336 | { 0, MPP_UNUSED }, |
335 | { 1, MPP_GPIO }, /* right amber LED (sata ch0) */ | 337 | { 1, MPP_GPIO }, /* right amber LED (sata ch0) */ |
336 | { 2, MPP_GPIO }, /* left amber LED (sata ch1) */ | 338 | { 2, MPP_GPIO }, /* left amber LED (sata ch1) */ |
337 | { 3, MPP_UNUSED }, | 339 | { 3, MPP_GPIO }, /* system up flag */ |
338 | { 4, MPP_GPIO }, /* power button LED */ | 340 | { 4, MPP_GPIO }, /* power button LED */ |
339 | { 5, MPP_GPIO }, /* power button LED */ | 341 | { 5, MPP_GPIO }, /* power button LED */ |
340 | { 6, MPP_GPIO }, /* GMT G751-2f overtemp */ | 342 | { 6, MPP_GPIO }, /* GMT G751-2f overtemp */ |
@@ -372,13 +374,23 @@ static struct i2c_board_info __initdata dns323_i2c_devices[] = { | |||
372 | }, | 374 | }, |
373 | }; | 375 | }; |
374 | 376 | ||
375 | /* DNS-323 specific power off method */ | 377 | /* DNS-323 rev. A specific power off method */ |
376 | static void dns323_power_off(void) | 378 | static void dns323a_power_off(void) |
377 | { | 379 | { |
378 | pr_info("%s: triggering power-off...\n", __func__); | 380 | pr_info("%s: triggering power-off...\n", __func__); |
379 | gpio_set_value(DNS323_GPIO_POWER_OFF, 1); | 381 | gpio_set_value(DNS323_GPIO_POWER_OFF, 1); |
380 | } | 382 | } |
381 | 383 | ||
384 | /* DNS-323 rev B specific power off method */ | ||
385 | static void dns323b_power_off(void) | ||
386 | { | ||
387 | pr_info("%s: triggering power-off...\n", __func__); | ||
388 | /* Pin has to be changed to 1 and back to 0 to do actual power off. */ | ||
389 | gpio_set_value(DNS323_GPIO_POWER_OFF, 1); | ||
390 | mdelay(100); | ||
391 | gpio_set_value(DNS323_GPIO_POWER_OFF, 0); | ||
392 | } | ||
393 | |||
382 | static void __init dns323_init(void) | 394 | static void __init dns323_init(void) |
383 | { | 395 | { |
384 | /* Setup basic Orion functions. Need to be called early. */ | 396 | /* Setup basic Orion functions. Need to be called early. */ |
@@ -424,11 +436,20 @@ static void __init dns323_init(void) | |||
424 | if (dns323_dev_id() == MV88F5182_DEV_ID) | 436 | if (dns323_dev_id() == MV88F5182_DEV_ID) |
425 | orion5x_sata_init(&dns323_sata_data); | 437 | orion5x_sata_init(&dns323_sata_data); |
426 | 438 | ||
427 | /* register dns323 specific power-off method */ | 439 | /* The 5182 has flag to indicate the system is up. Without this flag |
440 | * set, power LED will flash and cannot be controlled via leds-gpio. | ||
441 | */ | ||
442 | if (dns323_dev_id() == MV88F5182_DEV_ID) | ||
443 | gpio_set_value(DNS323_GPIO_SYSTEM_UP, 1); | ||
444 | |||
445 | /* Register dns323 specific power-off method */ | ||
428 | if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 || | 446 | if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 || |
429 | gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0) | 447 | gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0) |
430 | pr_err("DNS323: failed to setup power-off GPIO\n"); | 448 | pr_err("DNS323: failed to setup power-off GPIO\n"); |
431 | pm_power_off = dns323_power_off; | 449 | if (dns323_dev_id() == MV88F5182_DEV_ID) |
450 | pm_power_off = dns323b_power_off; | ||
451 | else | ||
452 | pm_power_off = dns323a_power_off; | ||
432 | } | 453 | } |
433 | 454 | ||
434 | /* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */ | 455 | /* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */ |
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c index 1b4ad9d5e2eb..cb0feca193d4 100644 --- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c +++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c | |||
@@ -15,6 +15,9 @@ | |||
15 | #include <linux/mtd/physmap.h> | 15 | #include <linux/mtd/physmap.h> |
16 | #include <linux/mv643xx_eth.h> | 16 | #include <linux/mv643xx_eth.h> |
17 | #include <linux/ethtool.h> | 17 | #include <linux/ethtool.h> |
18 | #include <linux/leds.h> | ||
19 | #include <linux/gpio_keys.h> | ||
20 | #include <linux/input.h> | ||
18 | #include <net/dsa.h> | 21 | #include <net/dsa.h> |
19 | #include <asm/mach-types.h> | 22 | #include <asm/mach-types.h> |
20 | #include <asm/gpio.h> | 23 | #include <asm/gpio.h> |
@@ -24,6 +27,80 @@ | |||
24 | #include "common.h" | 27 | #include "common.h" |
25 | #include "mpp.h" | 28 | #include "mpp.h" |
26 | 29 | ||
30 | /* | ||
31 | * LEDs attached to GPIO | ||
32 | */ | ||
33 | static struct gpio_led wrt350n_v2_led_pins[] = { | ||
34 | { | ||
35 | .name = "wrt350nv2:green:power", | ||
36 | .gpio = 0, | ||
37 | .active_low = 1, | ||
38 | }, { | ||
39 | .name = "wrt350nv2:green:security", | ||
40 | .gpio = 1, | ||
41 | .active_low = 1, | ||
42 | }, { | ||
43 | .name = "wrt350nv2:orange:power", | ||
44 | .gpio = 5, | ||
45 | .active_low = 1, | ||
46 | }, { | ||
47 | .name = "wrt350nv2:green:usb", | ||
48 | .gpio = 6, | ||
49 | .active_low = 1, | ||
50 | }, { | ||
51 | .name = "wrt350nv2:green:wireless", | ||
52 | .gpio = 7, | ||
53 | .active_low = 1, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | static struct gpio_led_platform_data wrt350n_v2_led_data = { | ||
58 | .leds = wrt350n_v2_led_pins, | ||
59 | .num_leds = ARRAY_SIZE(wrt350n_v2_led_pins), | ||
60 | }; | ||
61 | |||
62 | static struct platform_device wrt350n_v2_leds = { | ||
63 | .name = "leds-gpio", | ||
64 | .id = -1, | ||
65 | .dev = { | ||
66 | .platform_data = &wrt350n_v2_led_data, | ||
67 | }, | ||
68 | }; | ||
69 | |||
70 | /* | ||
71 | * Buttons attached to GPIO | ||
72 | */ | ||
73 | static struct gpio_keys_button wrt350n_v2_buttons[] = { | ||
74 | { | ||
75 | .code = KEY_RESTART, | ||
76 | .gpio = 3, | ||
77 | .desc = "Reset Button", | ||
78 | .active_low = 1, | ||
79 | }, { | ||
80 | .code = KEY_WLAN, | ||
81 | .gpio = 2, | ||
82 | .desc = "WPS Button", | ||
83 | .active_low = 1, | ||
84 | }, | ||
85 | }; | ||
86 | |||
87 | static struct gpio_keys_platform_data wrt350n_v2_button_data = { | ||
88 | .buttons = wrt350n_v2_buttons, | ||
89 | .nbuttons = ARRAY_SIZE(wrt350n_v2_buttons), | ||
90 | }; | ||
91 | |||
92 | static struct platform_device wrt350n_v2_button_device = { | ||
93 | .name = "gpio-keys", | ||
94 | .id = -1, | ||
95 | .num_resources = 0, | ||
96 | .dev = { | ||
97 | .platform_data = &wrt350n_v2_button_data, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | /* | ||
102 | * General setup | ||
103 | */ | ||
27 | static struct orion5x_mpp_mode wrt350n_v2_mpp_modes[] __initdata = { | 104 | static struct orion5x_mpp_mode wrt350n_v2_mpp_modes[] __initdata = { |
28 | { 0, MPP_GPIO }, /* Power LED green (0=on) */ | 105 | { 0, MPP_GPIO }, /* Power LED green (0=on) */ |
29 | { 1, MPP_GPIO }, /* Security LED (0=on) */ | 106 | { 1, MPP_GPIO }, /* Security LED (0=on) */ |
@@ -140,6 +217,8 @@ static void __init wrt350n_v2_init(void) | |||
140 | orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE, | 217 | orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE, |
141 | WRT350N_V2_NOR_BOOT_SIZE); | 218 | WRT350N_V2_NOR_BOOT_SIZE); |
142 | platform_device_register(&wrt350n_v2_nor_flash); | 219 | platform_device_register(&wrt350n_v2_nor_flash); |
220 | platform_device_register(&wrt350n_v2_leds); | ||
221 | platform_device_register(&wrt350n_v2_button_device); | ||
143 | } | 222 | } |
144 | 223 | ||
145 | static int __init wrt350n_v2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | 224 | static int __init wrt350n_v2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) |
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 74446cf8ae69..da3156d8690b 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c | |||
@@ -457,6 +457,7 @@ static struct pxaficp_platform_data corgi_ficp_platform_data = { | |||
457 | * USB Device Controller | 457 | * USB Device Controller |
458 | */ | 458 | */ |
459 | static struct pxa2xx_udc_mach_info udc_info __initdata = { | 459 | static struct pxa2xx_udc_mach_info udc_info __initdata = { |
460 | .gpio_vbus = -1, | ||
460 | /* no connect GPIO; corgi can't tell connection status */ | 461 | /* no connect GPIO; corgi can't tell connection status */ |
461 | .gpio_pullup = CORGI_GPIO_USB_PULLUP, | 462 | .gpio_pullup = CORGI_GPIO_USB_PULLUP, |
462 | }; | 463 | }; |
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h index b13dc0269a6d..9c787855cf24 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h | |||
@@ -169,7 +169,6 @@ | |||
169 | #define GPIO86_nSDCS2 MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH) | 169 | #define GPIO86_nSDCS2 MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH) |
170 | #define GPIO87_nSDCS3 MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH) | 170 | #define GPIO87_nSDCS3 MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH) |
171 | #define GPIO88_RDnWR MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH) | 171 | #define GPIO88_RDnWR MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH) |
172 | #define GPIO89_nACRESET MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH) | ||
173 | 172 | ||
174 | /* USB */ | 173 | /* USB */ |
175 | #define GPIO9_USB_RCV MFP_CFG_IN(GPIO9, AF1) | 174 | #define GPIO9_USB_RCV MFP_CFG_IN(GPIO9, AF1) |
@@ -186,6 +185,9 @@ | |||
186 | #define GPIO30_ASSP_TXD MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW) | 185 | #define GPIO30_ASSP_TXD MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW) |
187 | #define GPIO31_ASSP_SFRM_IN MFP_CFG_IN(GPIO31, AF1) | 186 | #define GPIO31_ASSP_SFRM_IN MFP_CFG_IN(GPIO31, AF1) |
188 | #define GPIO31_ASSP_SFRM_OUT MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW) | 187 | #define GPIO31_ASSP_SFRM_OUT MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW) |
189 | #endif | 188 | |
189 | /* AC97 */ | ||
190 | #define GPIO89_AC97_nRESET MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH) | ||
191 | #endif /* CONFIG_CPU_PXA26x */ | ||
190 | 192 | ||
191 | #endif /* __ASM_ARCH_MFP_PXA25X_H */ | 193 | #endif /* __ASM_ARCH_MFP_PXA25X_H */ |
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 6112af431fa4..1beb40f692fc 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c | |||
@@ -164,8 +164,11 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) | |||
164 | saved_icmr[i] = _ICMR(irq); | 164 | saved_icmr[i] = _ICMR(irq); |
165 | _ICMR(irq) = 0; | 165 | _ICMR(irq) = 0; |
166 | } | 166 | } |
167 | for (i = 0; i < pxa_internal_irq_nr; i++) | 167 | |
168 | saved_ipr[i] = IPR(i); | 168 | if (cpu_is_pxa27x() || cpu_is_pxa3xx()) { |
169 | for (i = 0; i < pxa_internal_irq_nr; i++) | ||
170 | saved_ipr[i] = IPR(i); | ||
171 | } | ||
169 | 172 | ||
170 | return 0; | 173 | return 0; |
171 | } | 174 | } |
@@ -174,12 +177,15 @@ static int pxa_irq_resume(struct sys_device *dev) | |||
174 | { | 177 | { |
175 | int i, irq = PXA_IRQ(0); | 178 | int i, irq = PXA_IRQ(0); |
176 | 179 | ||
180 | if (cpu_is_pxa27x() || cpu_is_pxa3xx()) { | ||
181 | for (i = 0; i < pxa_internal_irq_nr; i++) | ||
182 | IPR(i) = saved_ipr[i]; | ||
183 | } | ||
184 | |||
177 | for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) { | 185 | for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) { |
178 | _ICMR(irq) = saved_icmr[i]; | 186 | _ICMR(irq) = saved_icmr[i]; |
179 | _ICLR(irq) = 0; | 187 | _ICLR(irq) = 0; |
180 | } | 188 | } |
181 | for (i = 0; i < pxa_internal_irq_nr; i++) | ||
182 | IPR(i) = saved_ipr[i]; | ||
183 | 189 | ||
184 | ICCR = 1; | 190 | ICCR = 1; |
185 | return 0; | 191 | return 0; |
diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c index d41d41d78ad9..54c84a492a0f 100644 --- a/arch/arm/plat-orion/pcie.c +++ b/arch/arm/plat-orion/pcie.c | |||
@@ -133,6 +133,12 @@ static void __init orion_pcie_setup_wins(void __iomem *base, | |||
133 | } | 133 | } |
134 | 134 | ||
135 | /* | 135 | /* |
136 | * Round up 'size' to the nearest power of two. | ||
137 | */ | ||
138 | if ((size & (size - 1)) != 0) | ||
139 | size = 1 << fls(size); | ||
140 | |||
141 | /* | ||
136 | * Setup BAR[1] to all DRAM banks. | 142 | * Setup BAR[1] to all DRAM banks. |
137 | */ | 143 | */ |
138 | writel(dram->cs[0].base, base + PCIE_BAR_LO_OFF(1)); | 144 | writel(dram->cs[0].base, base + PCIE_BAR_LO_OFF(1)); |
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index c3a74ce24ef6..5a79fc6ee818 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types | |||
@@ -12,7 +12,7 @@ | |||
12 | # | 12 | # |
13 | # http://www.arm.linux.org.uk/developer/machines/?action=new | 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new |
14 | # | 14 | # |
15 | # Last update: Wed Dec 16 20:06:34 2009 | 15 | # Last update: Thu Jan 28 22:15:54 2010 |
16 | # | 16 | # |
17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number | 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number |
18 | # | 18 | # |
@@ -2536,6 +2536,7 @@ davinci_dm6467tevm MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM 2548 | |||
2536 | c3ax03 MACH_C3AX03 C3AX03 2549 | 2536 | c3ax03 MACH_C3AX03 C3AX03 2549 |
2537 | mxt_td60 MACH_MXT_TD60 MXT_TD60 2550 | 2537 | mxt_td60 MACH_MXT_TD60 MXT_TD60 2550 |
2538 | esyx MACH_ESYX ESYX 2551 | 2538 | esyx MACH_ESYX ESYX 2551 |
2539 | dove_db2 MACH_DOVE_DB2 DOVE_DB2 2552 | ||
2539 | bulldog MACH_BULLDOG BULLDOG 2553 | 2540 | bulldog MACH_BULLDOG BULLDOG 2553 |
2540 | derell_me2000 MACH_DERELL_ME2000 DERELL_ME2000 2554 | 2541 | derell_me2000 MACH_DERELL_ME2000 DERELL_ME2000 2554 |
2541 | bcmring_base MACH_BCMRING_BASE BCMRING_BASE 2555 | 2542 | bcmring_base MACH_BCMRING_BASE BCMRING_BASE 2555 |
@@ -2555,6 +2556,7 @@ iseo MACH_ISEO ISEO 2568 | |||
2555 | cezanne MACH_CEZANNE CEZANNE 2569 | 2556 | cezanne MACH_CEZANNE CEZANNE 2569 |
2556 | lucca MACH_LUCCA LUCCA 2570 | 2557 | lucca MACH_LUCCA LUCCA 2570 |
2557 | supersmart MACH_SUPERSMART SUPERSMART 2571 | 2558 | supersmart MACH_SUPERSMART SUPERSMART 2571 |
2559 | arm11_board MACH_CS_MISANO CS_MISANO 2572 | ||
2558 | magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 2573 | 2560 | magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 2573 |
2559 | emxx MACH_EMXX EMXX 2574 | 2561 | emxx MACH_EMXX EMXX 2574 |
2560 | outlaw MACH_OUTLAW OUTLAW 2575 | 2562 | outlaw MACH_OUTLAW OUTLAW 2575 |
@@ -2578,3 +2580,59 @@ glacier MACH_GLACIER GLACIER 2592 | |||
2578 | phrazer_bulldog MACH_PHRAZER_BULLDOG PHRAZER_BULLDOG 2593 | 2580 | phrazer_bulldog MACH_PHRAZER_BULLDOG PHRAZER_BULLDOG 2593 |
2579 | omap3_bulldog MACH_OMAP3_BULLDOG OMAP3_BULLDOG 2594 | 2581 | omap3_bulldog MACH_OMAP3_BULLDOG OMAP3_BULLDOG 2594 |
2580 | pca101 MACH_PCA101 PCA101 2595 | 2582 | pca101 MACH_PCA101 PCA101 2595 |
2583 | buzzc MACH_BUZZC BUZZC 2596 | ||
2584 | sasie2 MACH_SASIE2 SASIE2 2597 | ||
2585 | davinci_cio MACH_DAVINCI_CIO DAVINCI_CIO 2598 | ||
2586 | smartmeter_dl MACH_SMARTMETER_DL SMARTMETER_DL 2599 | ||
2587 | wzl6410 MACH_WZL6410 WZL6410 2600 | ||
2588 | wzl6410m MACH_WZL6410M WZL6410M 2601 | ||
2589 | wzl6410f MACH_WZL6410F WZL6410F 2602 | ||
2590 | wzl6410i MACH_WZL6410I WZL6410I 2603 | ||
2591 | spacecom1 MACH_SPACECOM1 SPACECOM1 2604 | ||
2592 | pingu920 MACH_PINGU920 PINGU920 2605 | ||
2593 | bravoc MACH_BRAVOC BRAVOC 2606 | ||
2594 | cybo2440 MACH_CYBO2440 CYBO2440 2607 | ||
2595 | vdssw MACH_VDSSW VDSSW 2608 | ||
2596 | romulus MACH_ROMULUS ROMULUS 2609 | ||
2597 | omap_magic MACH_OMAP_MAGIC OMAP_MAGIC 2610 | ||
2598 | eltd100 MACH_ELTD100 ELTD100 2611 | ||
2599 | capc7117 MACH_CAPC7117 CAPC7117 2612 | ||
2600 | swan MACH_SWAN SWAN 2613 | ||
2601 | veu MACH_VEU VEU 2614 | ||
2602 | rm2 MACH_RM2 RM2 2615 | ||
2603 | tt2100 MACH_TT2100 TT2100 2616 | ||
2604 | venice MACH_VENICE VENICE 2617 | ||
2605 | pc7323 MACH_PC7323 PC7323 2618 | ||
2606 | masp MACH_MASP MASP 2619 | ||
2607 | fujitsu_tvstbsoc0 MACH_FUJITSU_TVSTBSOC FUJITSU_TVSTBSOC 2620 | ||
2608 | fujitsu_tvstbsoc1 MACH_FUJITSU_TVSTBSOC1 FUJITSU_TVSTBSOC1 2621 | ||
2609 | lexikon MACH_LEXIKON LEXIKON 2622 | ||
2610 | mini2440v2 MACH_MINI2440V2 MINI2440V2 2623 | ||
2611 | icontrol MACH_ICONTROL ICONTROL 2624 | ||
2612 | sheevad MACH_SHEEVAD SHEEVAD 2625 | ||
2613 | qsd8x50a_st1_1 MACH_QSD8X50A_ST1_1 QSD8X50A_ST1_1 2626 | ||
2614 | qsd8x50a_st1_5 MACH_QSD8X50A_ST1_5 QSD8X50A_ST1_5 2627 | ||
2615 | bee MACH_BEE BEE 2628 | ||
2616 | mx23evk MACH_MX23EVK MX23EVK 2629 | ||
2617 | ap4evb MACH_AP4EVB AP4EVB 2630 | ||
2618 | stockholm MACH_STOCKHOLM STOCKHOLM 2631 | ||
2619 | lpc_h3131 MACH_LPC_H3131 LPC_H3131 2632 | ||
2620 | stingray MACH_STINGRAY STINGRAY 2633 | ||
2621 | kraken MACH_KRAKEN KRAKEN 2634 | ||
2622 | gw2388 MACH_GW2388 GW2388 2635 | ||
2623 | jadecpu MACH_JADECPU JADECPU 2636 | ||
2624 | carlisle MACH_CARLISLE CARLISLE 2637 | ||
2625 | lux_sf9 MACH_LUX_SFT9 LUX_SFT9 2638 | ||
2626 | nemid_tb MACH_NEMID_TB NEMID_TB 2639 | ||
2627 | terrier MACH_TERRIER TERRIER 2640 | ||
2628 | turbot MACH_TURBOT TURBOT 2641 | ||
2629 | sanddab MACH_SANDDAB SANDDAB 2642 | ||
2630 | mx35_cicada MACH_MX35_CICADA MX35_CICADA 2643 | ||
2631 | ghi2703d MACH_GHI2703D GHI2703D 2644 | ||
2632 | lux_sfx9 MACH_LUX_SFX9 LUX_SFX9 2645 | ||
2633 | lux_sf9g MACH_LUX_SF9G LUX_SF9G 2646 | ||
2634 | lux_edk9 MACH_LUX_EDK9 LUX_EDK9 2647 | ||
2635 | hw90240 MACH_HW90240 HW90240 2648 | ||
2636 | dm365_leopard MACH_DM365_LEOPARD DM365_LEOPARD 2649 | ||
2637 | mityomapl138 MACH_MITYOMAPL138 MITYOMAPL138 2650 | ||
2638 | scat110 MACH_SCAT110 SCAT110 2651 | ||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9541171f1220..8b5d174685f0 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1311,6 +1311,7 @@ config SYS_SUPPORTS_ZBOOT | |||
1311 | select HAVE_KERNEL_GZIP | 1311 | select HAVE_KERNEL_GZIP |
1312 | select HAVE_KERNEL_BZIP2 | 1312 | select HAVE_KERNEL_BZIP2 |
1313 | select HAVE_KERNEL_LZMA | 1313 | select HAVE_KERNEL_LZMA |
1314 | select HAVE_KERNEL_LZO | ||
1314 | 1315 | ||
1315 | config SYS_SUPPORTS_ZBOOT_UART16550 | 1316 | config SYS_SUPPORTS_ZBOOT_UART16550 |
1316 | bool | 1317 | bool |
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 671d3448fad4..9df903d714d7 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile | |||
@@ -14,8 +14,11 @@ | |||
14 | 14 | ||
15 | # compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE | 15 | # compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE |
16 | VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1) | 16 | VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1) |
17 | VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536)))) | 17 | VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo -n $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536)))) |
18 | VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" ] && printf %x $$(($(VMLINUX_LOAD_ADDRESS) + $(VMLINUX_SIZE)))) | 18 | # VMLINUZ_LOAD_ADDRESS = concat "high32 of VMLINUX_LOAD_ADDRESS" and "(low32 of VMLINUX_LOAD_ADDRESS) + VMLINUX_SIZE" |
19 | HIGH32 := $(shell A=$(VMLINUX_LOAD_ADDRESS); [ $${\#A} -gt 10 ] && expr substr "$(VMLINUX_LOAD_ADDRESS)" 3 $$(($${\#A} - 10))) | ||
20 | LOW32 := $(shell [ -n "$(HIGH32)" ] && A=11 || A=3; expr substr "$(VMLINUX_LOAD_ADDRESS)" $${A} 8) | ||
21 | VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" -a -n "$(LOW32)" ] && printf "$(HIGH32)%08x" $$(($(VMLINUX_SIZE) + 0x$(LOW32)))) | ||
19 | 22 | ||
20 | # set the default size of the mallocing area for decompressing | 23 | # set the default size of the mallocing area for decompressing |
21 | BOOT_HEAP_SIZE := 0x400000 | 24 | BOOT_HEAP_SIZE := 0x400000 |
@@ -41,9 +44,11 @@ $(obj)/vmlinux.bin: $(KBUILD_IMAGE) | |||
41 | suffix_$(CONFIG_KERNEL_GZIP) = gz | 44 | suffix_$(CONFIG_KERNEL_GZIP) = gz |
42 | suffix_$(CONFIG_KERNEL_BZIP2) = bz2 | 45 | suffix_$(CONFIG_KERNEL_BZIP2) = bz2 |
43 | suffix_$(CONFIG_KERNEL_LZMA) = lzma | 46 | suffix_$(CONFIG_KERNEL_LZMA) = lzma |
47 | suffix_$(CONFIG_KERNEL_LZO) = lzo | ||
44 | tool_$(CONFIG_KERNEL_GZIP) = gzip | 48 | tool_$(CONFIG_KERNEL_GZIP) = gzip |
45 | tool_$(CONFIG_KERNEL_BZIP2) = bzip2 | 49 | tool_$(CONFIG_KERNEL_BZIP2) = bzip2 |
46 | tool_$(CONFIG_KERNEL_LZMA) = lzma | 50 | tool_$(CONFIG_KERNEL_LZMA) = lzma |
51 | tool_$(CONFIG_KERNEL_LZO) = lzo | ||
47 | $(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin | 52 | $(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin |
48 | $(call if_changed,$(tool_y)) | 53 | $(call if_changed,$(tool_y)) |
49 | 54 | ||
diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c index e48fd72898a8..55d02b3a6712 100644 --- a/arch/mips/boot/compressed/decompress.c +++ b/arch/mips/boot/compressed/decompress.c | |||
@@ -77,6 +77,10 @@ void *memset(void *s, int c, size_t n) | |||
77 | #include "../../../../lib/decompress_unlzma.c" | 77 | #include "../../../../lib/decompress_unlzma.c" |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | #ifdef CONFIG_KERNEL_LZO | ||
81 | #include "../../../../lib/decompress_unlzo.c" | ||
82 | #endif | ||
83 | |||
80 | void decompress_kernel(unsigned long boot_heap_start) | 84 | void decompress_kernel(unsigned long boot_heap_start) |
81 | { | 85 | { |
82 | int zimage_size; | 86 | int zimage_size; |
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 06960364c96b..dea4aed6478f 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h | |||
@@ -135,6 +135,7 @@ extern void free_irqno(unsigned int irq); | |||
135 | #define CP0_LEGACY_COMPARE_IRQ 7 | 135 | #define CP0_LEGACY_COMPARE_IRQ 7 |
136 | 136 | ||
137 | extern int cp0_compare_irq; | 137 | extern int cp0_compare_irq; |
138 | extern int cp0_compare_irq_shift; | ||
138 | extern int cp0_perfcount_irq; | 139 | extern int cp0_perfcount_irq; |
139 | 140 | ||
140 | #endif /* _ASM_IRQ_H */ | 141 | #endif /* _ASM_IRQ_H */ |
diff --git a/arch/mips/include/asm/mach-powertv/asic_reg_map.h b/arch/mips/include/asm/mach-powertv/asic_reg_map.h new file mode 100644 index 000000000000..6f26cb09828e --- /dev/null +++ b/arch/mips/include/asm/mach-powertv/asic_reg_map.h | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * asic_reg_map.h | ||
3 | * | ||
4 | * A macro-enclosed list of the elements for the register_map structure for | ||
5 | * use in defining and manipulating the structure. | ||
6 | * | ||
7 | * Copyright (C) 2009 Cisco Systems, Inc. | ||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
22 | */ | ||
23 | |||
24 | REGISTER_MAP_ELEMENT(eic_slow0_strt_add) | ||
25 | REGISTER_MAP_ELEMENT(eic_cfg_bits) | ||
26 | REGISTER_MAP_ELEMENT(eic_ready_status) | ||
27 | REGISTER_MAP_ELEMENT(chipver3) | ||
28 | REGISTER_MAP_ELEMENT(chipver2) | ||
29 | REGISTER_MAP_ELEMENT(chipver1) | ||
30 | REGISTER_MAP_ELEMENT(chipver0) | ||
31 | REGISTER_MAP_ELEMENT(uart1_intstat) | ||
32 | REGISTER_MAP_ELEMENT(uart1_inten) | ||
33 | REGISTER_MAP_ELEMENT(uart1_config1) | ||
34 | REGISTER_MAP_ELEMENT(uart1_config2) | ||
35 | REGISTER_MAP_ELEMENT(uart1_divisorhi) | ||
36 | REGISTER_MAP_ELEMENT(uart1_divisorlo) | ||
37 | REGISTER_MAP_ELEMENT(uart1_data) | ||
38 | REGISTER_MAP_ELEMENT(uart1_status) | ||
39 | REGISTER_MAP_ELEMENT(int_stat_3) | ||
40 | REGISTER_MAP_ELEMENT(int_stat_2) | ||
41 | REGISTER_MAP_ELEMENT(int_stat_1) | ||
42 | REGISTER_MAP_ELEMENT(int_stat_0) | ||
43 | REGISTER_MAP_ELEMENT(int_config) | ||
44 | REGISTER_MAP_ELEMENT(int_int_scan) | ||
45 | REGISTER_MAP_ELEMENT(ien_int_3) | ||
46 | REGISTER_MAP_ELEMENT(ien_int_2) | ||
47 | REGISTER_MAP_ELEMENT(ien_int_1) | ||
48 | REGISTER_MAP_ELEMENT(ien_int_0) | ||
49 | REGISTER_MAP_ELEMENT(int_level_3_3) | ||
50 | REGISTER_MAP_ELEMENT(int_level_3_2) | ||
51 | REGISTER_MAP_ELEMENT(int_level_3_1) | ||
52 | REGISTER_MAP_ELEMENT(int_level_3_0) | ||
53 | REGISTER_MAP_ELEMENT(int_level_2_3) | ||
54 | REGISTER_MAP_ELEMENT(int_level_2_2) | ||
55 | REGISTER_MAP_ELEMENT(int_level_2_1) | ||
56 | REGISTER_MAP_ELEMENT(int_level_2_0) | ||
57 | REGISTER_MAP_ELEMENT(int_level_1_3) | ||
58 | REGISTER_MAP_ELEMENT(int_level_1_2) | ||
59 | REGISTER_MAP_ELEMENT(int_level_1_1) | ||
60 | REGISTER_MAP_ELEMENT(int_level_1_0) | ||
61 | REGISTER_MAP_ELEMENT(int_level_0_3) | ||
62 | REGISTER_MAP_ELEMENT(int_level_0_2) | ||
63 | REGISTER_MAP_ELEMENT(int_level_0_1) | ||
64 | REGISTER_MAP_ELEMENT(int_level_0_0) | ||
65 | REGISTER_MAP_ELEMENT(int_docsis_en) | ||
66 | REGISTER_MAP_ELEMENT(mips_pll_setup) | ||
67 | REGISTER_MAP_ELEMENT(usb_fs) | ||
68 | REGISTER_MAP_ELEMENT(test_bus) | ||
69 | REGISTER_MAP_ELEMENT(crt_spare) | ||
70 | REGISTER_MAP_ELEMENT(usb2_ohci_int_mask) | ||
71 | REGISTER_MAP_ELEMENT(usb2_strap) | ||
72 | REGISTER_MAP_ELEMENT(ehci_hcapbase) | ||
73 | REGISTER_MAP_ELEMENT(ohci_hc_revision) | ||
74 | REGISTER_MAP_ELEMENT(bcm1_bs_lmi_steer) | ||
75 | REGISTER_MAP_ELEMENT(usb2_control) | ||
76 | REGISTER_MAP_ELEMENT(usb2_stbus_obc) | ||
77 | REGISTER_MAP_ELEMENT(usb2_stbus_mess_size) | ||
78 | REGISTER_MAP_ELEMENT(usb2_stbus_chunk_size) | ||
79 | REGISTER_MAP_ELEMENT(pcie_regs) | ||
80 | REGISTER_MAP_ELEMENT(tim_ch) | ||
81 | REGISTER_MAP_ELEMENT(tim_cl) | ||
82 | REGISTER_MAP_ELEMENT(gpio_dout) | ||
83 | REGISTER_MAP_ELEMENT(gpio_din) | ||
84 | REGISTER_MAP_ELEMENT(gpio_dir) | ||
85 | REGISTER_MAP_ELEMENT(watchdog) | ||
86 | REGISTER_MAP_ELEMENT(front_panel) | ||
87 | REGISTER_MAP_ELEMENT(misc_clk_ctl1) | ||
88 | REGISTER_MAP_ELEMENT(misc_clk_ctl2) | ||
89 | REGISTER_MAP_ELEMENT(crt_ext_ctl) | ||
90 | REGISTER_MAP_ELEMENT(register_maps) | ||
diff --git a/arch/mips/include/asm/mach-powertv/asic_regs.h b/arch/mips/include/asm/mach-powertv/asic_regs.h index 9a65c93782f9..1e11236c6dbc 100644 --- a/arch/mips/include/asm/mach-powertv/asic_regs.h +++ b/arch/mips/include/asm/mach-powertv/asic_regs.h | |||
@@ -35,11 +35,12 @@ enum asic_type { | |||
35 | #define CRONUS_11 0x0B4C1C21 | 35 | #define CRONUS_11 0x0B4C1C21 |
36 | #define CRONUSLITE_10 0x0B4C1C40 | 36 | #define CRONUSLITE_10 0x0B4C1C40 |
37 | 37 | ||
38 | #define NAND_FLASH_BASE 0x03000000 | 38 | #define NAND_FLASH_BASE 0x03000000 |
39 | #define ZEUS_IO_BASE 0x09000000 | ||
40 | #define CALLIOPE_IO_BASE 0x08000000 | 39 | #define CALLIOPE_IO_BASE 0x08000000 |
41 | #define CRONUS_IO_BASE 0x09000000 | 40 | #define CRONUS_IO_BASE 0x09000000 |
42 | #define ASIC_IO_SIZE 0x01000000 | 41 | #define ZEUS_IO_BASE 0x09000000 |
42 | |||
43 | #define ASIC_IO_SIZE 0x01000000 | ||
43 | 44 | ||
44 | /* Definitions for backward compatibility */ | 45 | /* Definitions for backward compatibility */ |
45 | #define UART1_INTSTAT uart1_intstat | 46 | #define UART1_INTSTAT uart1_intstat |
@@ -52,96 +53,62 @@ enum asic_type { | |||
52 | #define UART1_STATUS uart1_status | 53 | #define UART1_STATUS uart1_status |
53 | 54 | ||
54 | /* ASIC register enumeration */ | 55 | /* ASIC register enumeration */ |
56 | union register_map_entry { | ||
57 | unsigned long phys; | ||
58 | u32 *virt; | ||
59 | }; | ||
60 | |||
61 | #define REGISTER_MAP_ELEMENT(x) union register_map_entry x; | ||
55 | struct register_map { | 62 | struct register_map { |
56 | u32 eic_slow0_strt_add; | 63 | #include <asm/mach-powertv/asic_reg_map.h> |
57 | u32 eic_cfg_bits; | ||
58 | u32 eic_ready_status; | ||
59 | |||
60 | u32 chipver3; | ||
61 | u32 chipver2; | ||
62 | u32 chipver1; | ||
63 | u32 chipver0; | ||
64 | |||
65 | u32 uart1_intstat; | ||
66 | u32 uart1_inten; | ||
67 | u32 uart1_config1; | ||
68 | u32 uart1_config2; | ||
69 | u32 uart1_divisorhi; | ||
70 | u32 uart1_divisorlo; | ||
71 | u32 uart1_data; | ||
72 | u32 uart1_status; | ||
73 | |||
74 | u32 int_stat_3; | ||
75 | u32 int_stat_2; | ||
76 | u32 int_stat_1; | ||
77 | u32 int_stat_0; | ||
78 | u32 int_config; | ||
79 | u32 int_int_scan; | ||
80 | u32 ien_int_3; | ||
81 | u32 ien_int_2; | ||
82 | u32 ien_int_1; | ||
83 | u32 ien_int_0; | ||
84 | u32 int_level_3_3; | ||
85 | u32 int_level_3_2; | ||
86 | u32 int_level_3_1; | ||
87 | u32 int_level_3_0; | ||
88 | u32 int_level_2_3; | ||
89 | u32 int_level_2_2; | ||
90 | u32 int_level_2_1; | ||
91 | u32 int_level_2_0; | ||
92 | u32 int_level_1_3; | ||
93 | u32 int_level_1_2; | ||
94 | u32 int_level_1_1; | ||
95 | u32 int_level_1_0; | ||
96 | u32 int_level_0_3; | ||
97 | u32 int_level_0_2; | ||
98 | u32 int_level_0_1; | ||
99 | u32 int_level_0_0; | ||
100 | u32 int_docsis_en; | ||
101 | |||
102 | u32 mips_pll_setup; | ||
103 | u32 usb_fs; | ||
104 | u32 test_bus; | ||
105 | u32 crt_spare; | ||
106 | u32 usb2_ohci_int_mask; | ||
107 | u32 usb2_strap; | ||
108 | u32 ehci_hcapbase; | ||
109 | u32 ohci_hc_revision; | ||
110 | u32 bcm1_bs_lmi_steer; | ||
111 | u32 usb2_control; | ||
112 | u32 usb2_stbus_obc; | ||
113 | u32 usb2_stbus_mess_size; | ||
114 | u32 usb2_stbus_chunk_size; | ||
115 | |||
116 | u32 pcie_regs; | ||
117 | u32 tim_ch; | ||
118 | u32 tim_cl; | ||
119 | u32 gpio_dout; | ||
120 | u32 gpio_din; | ||
121 | u32 gpio_dir; | ||
122 | u32 watchdog; | ||
123 | u32 front_panel; | ||
124 | |||
125 | u32 register_maps; | ||
126 | }; | 64 | }; |
65 | #undef REGISTER_MAP_ELEMENT | ||
66 | |||
67 | /** | ||
68 | * register_map_offset_phys - add an offset to the physical address | ||
69 | * @map: Pointer to the &struct register_map | ||
70 | * @offset: Value to add | ||
71 | * | ||
72 | * Only adds the base to non-zero physical addresses | ||
73 | */ | ||
74 | static inline void register_map_offset_phys(struct register_map *map, | ||
75 | unsigned long offset) | ||
76 | { | ||
77 | #define REGISTER_MAP_ELEMENT(x) do { \ | ||
78 | if (map->x.phys != 0) \ | ||
79 | map->x.phys += offset; \ | ||
80 | } while (false); | ||
81 | |||
82 | #include <asm/mach-powertv/asic_reg_map.h> | ||
83 | #undef REGISTER_MAP_ELEMENT | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * register_map_virtualize - Convert ®ister_map to virtual addresses | ||
88 | * @map: Pointer to ®ister_map to virtualize | ||
89 | */ | ||
90 | static inline void register_map_virtualize(struct register_map *map) | ||
91 | { | ||
92 | #define REGISTER_MAP_ELEMENT(x) do { \ | ||
93 | map->x.virt = (!map->x.phys) ? NULL : \ | ||
94 | UNCAC_ADDR(phys_to_virt(map->x.phys)); \ | ||
95 | } while (false); | ||
96 | |||
97 | #include <asm/mach-powertv/asic_reg_map.h> | ||
98 | #undef REGISTER_MAP_ELEMENT | ||
99 | } | ||
127 | 100 | ||
128 | extern enum asic_type asic; | 101 | extern struct register_map _asic_register_map; |
129 | extern const struct register_map *register_map; | ||
130 | extern unsigned long asic_phy_base; /* Physical address of ASIC */ | ||
131 | extern unsigned long asic_base; /* Virtual address of ASIC */ | ||
132 | 102 | ||
133 | /* | 103 | /* |
134 | * Macros to interface to registers through their ioremapped address | 104 | * Macros to interface to registers through their ioremapped address |
135 | * asic_reg_offset Returns the offset of a given register from the start | ||
136 | * of the ASIC address space | ||
137 | * asic_reg_phys_addr Returns the physical address of the given register | 105 | * asic_reg_phys_addr Returns the physical address of the given register |
138 | * asic_reg_addr Returns the iomapped virtual address of the given | 106 | * asic_reg_addr Returns the iomapped virtual address of the given |
139 | * register. | 107 | * register. |
140 | */ | 108 | */ |
141 | #define asic_reg_offset(x) (register_map->x) | 109 | #define asic_reg_addr(x) (_asic_register_map.x.virt) |
142 | #define asic_reg_phys_addr(x) (asic_phy_base + asic_reg_offset(x)) | 110 | #define asic_reg_phys_addr(x) (virt_to_phys((void *) CAC_ADDR( \ |
143 | #define asic_reg_addr(x) \ | 111 | (unsigned long) asic_reg_addr(x)))) |
144 | ((unsigned int *) (asic_base + asic_reg_offset(x))) | ||
145 | 112 | ||
146 | /* | 113 | /* |
147 | * The asic_reg macro is gone. It should be replaced by either asic_read or | 114 | * The asic_reg macro is gone. It should be replaced by either asic_read or |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index a581d60cbcc2..f4ab3139d737 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -406,6 +406,16 @@ | |||
406 | #define ST0_XX 0x80000000 /* MIPS IV naming */ | 406 | #define ST0_XX 0x80000000 /* MIPS IV naming */ |
407 | 407 | ||
408 | /* | 408 | /* |
409 | * Bitfields and bit numbers in the coprocessor 0 IntCtl register. (MIPSR2) | ||
410 | * | ||
411 | * Refer to your MIPS R4xx0 manual, chapter 5 for explanation. | ||
412 | */ | ||
413 | #define INTCTLB_IPPCI 26 | ||
414 | #define INTCTLF_IPPCI (_ULCAST_(7) << INTCTLB_IPPCI) | ||
415 | #define INTCTLB_IPTI 29 | ||
416 | #define INTCTLF_IPTI (_ULCAST_(7) << INTCTLB_IPTI) | ||
417 | |||
418 | /* | ||
409 | * Bitfields and bit numbers in the coprocessor 0 cause register. | 419 | * Bitfields and bit numbers in the coprocessor 0 cause register. |
410 | * | 420 | * |
411 | * Refer to your MIPS R4xx0 manual, chapter 5 for explanation. | 421 | * Refer to your MIPS R4xx0 manual, chapter 5 for explanation. |
@@ -434,6 +444,8 @@ | |||
434 | #define CAUSEF_IV (_ULCAST_(1) << 23) | 444 | #define CAUSEF_IV (_ULCAST_(1) << 23) |
435 | #define CAUSEB_CE 28 | 445 | #define CAUSEB_CE 28 |
436 | #define CAUSEF_CE (_ULCAST_(3) << 28) | 446 | #define CAUSEF_CE (_ULCAST_(3) << 28) |
447 | #define CAUSEB_TI 30 | ||
448 | #define CAUSEF_TI (_ULCAST_(1) << 30) | ||
437 | #define CAUSEB_BD 31 | 449 | #define CAUSEB_BD 31 |
438 | #define CAUSEF_BD (_ULCAST_(1) << 31) | 450 | #define CAUSEF_BD (_ULCAST_(1) << 31) |
439 | 451 | ||
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index b469ad05d520..0b2450ceb13f 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
@@ -97,7 +97,7 @@ void mips_event_handler(struct clock_event_device *dev) | |||
97 | */ | 97 | */ |
98 | static int c0_compare_int_pending(void) | 98 | static int c0_compare_int_pending(void) |
99 | { | 99 | { |
100 | return (read_c0_cause() >> cp0_compare_irq) & 0x100; | 100 | return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP); |
101 | } | 101 | } |
102 | 102 | ||
103 | /* | 103 | /* |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 308e43460864..338dfe8ed002 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -1403,6 +1403,7 @@ extern void flush_tlb_handlers(void); | |||
1403 | * Timer interrupt | 1403 | * Timer interrupt |
1404 | */ | 1404 | */ |
1405 | int cp0_compare_irq; | 1405 | int cp0_compare_irq; |
1406 | int cp0_compare_irq_shift; | ||
1406 | 1407 | ||
1407 | /* | 1408 | /* |
1408 | * Performance counter IRQ or -1 if shared with timer | 1409 | * Performance counter IRQ or -1 if shared with timer |
@@ -1493,8 +1494,9 @@ void __cpuinit per_cpu_trap_init(void) | |||
1493 | * o read IntCtl.IPPCI to determine the performance counter interrupt | 1494 | * o read IntCtl.IPPCI to determine the performance counter interrupt |
1494 | */ | 1495 | */ |
1495 | if (cpu_has_mips_r2) { | 1496 | if (cpu_has_mips_r2) { |
1496 | cp0_compare_irq = (read_c0_intctl() >> 29) & 7; | 1497 | cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; |
1497 | cp0_perfcount_irq = (read_c0_intctl() >> 26) & 7; | 1498 | cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; |
1499 | cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7; | ||
1498 | if (cp0_perfcount_irq == cp0_compare_irq) | 1500 | if (cp0_perfcount_irq == cp0_compare_irq) |
1499 | cp0_perfcount_irq = -1; | 1501 | cp0_perfcount_irq = -1; |
1500 | } else { | 1502 | } else { |
diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c index 03d3884c6270..1ae6623444b2 100644 --- a/arch/mips/powertv/asic/asic-calliope.c +++ b/arch/mips/powertv/asic/asic-calliope.c | |||
@@ -23,76 +23,79 @@ | |||
23 | * Description: Defines the platform resources for the SA settop. | 23 | * Description: Defines the platform resources for the SA settop. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/init.h> | ||
26 | #include <asm/mach-powertv/asic.h> | 27 | #include <asm/mach-powertv/asic.h> |
27 | 28 | ||
28 | const struct register_map calliope_register_map = { | 29 | #define CALLIOPE_ADDR(x) (CALLIOPE_IO_BASE + (x)) |
29 | .eic_slow0_strt_add = 0x800000, | ||
30 | .eic_cfg_bits = 0x800038, | ||
31 | .eic_ready_status = 0x80004c, | ||
32 | 30 | ||
33 | .chipver3 = 0xA00800, | 31 | const struct register_map calliope_register_map __initdata = { |
34 | .chipver2 = 0xA00804, | 32 | .eic_slow0_strt_add = {.phys = CALLIOPE_ADDR(0x800000)}, |
35 | .chipver1 = 0xA00808, | 33 | .eic_cfg_bits = {.phys = CALLIOPE_ADDR(0x800038)}, |
36 | .chipver0 = 0xA0080c, | 34 | .eic_ready_status = {.phys = CALLIOPE_ADDR(0x80004c)}, |
35 | |||
36 | .chipver3 = {.phys = CALLIOPE_ADDR(0xA00800)}, | ||
37 | .chipver2 = {.phys = CALLIOPE_ADDR(0xA00804)}, | ||
38 | .chipver1 = {.phys = CALLIOPE_ADDR(0xA00808)}, | ||
39 | .chipver0 = {.phys = CALLIOPE_ADDR(0xA0080c)}, | ||
37 | 40 | ||
38 | /* The registers of IRBlaster */ | 41 | /* The registers of IRBlaster */ |
39 | .uart1_intstat = 0xA01800, | 42 | .uart1_intstat = {.phys = CALLIOPE_ADDR(0xA01800)}, |
40 | .uart1_inten = 0xA01804, | 43 | .uart1_inten = {.phys = CALLIOPE_ADDR(0xA01804)}, |
41 | .uart1_config1 = 0xA01808, | 44 | .uart1_config1 = {.phys = CALLIOPE_ADDR(0xA01808)}, |
42 | .uart1_config2 = 0xA0180C, | 45 | .uart1_config2 = {.phys = CALLIOPE_ADDR(0xA0180C)}, |
43 | .uart1_divisorhi = 0xA01810, | 46 | .uart1_divisorhi = {.phys = CALLIOPE_ADDR(0xA01810)}, |
44 | .uart1_divisorlo = 0xA01814, | 47 | .uart1_divisorlo = {.phys = CALLIOPE_ADDR(0xA01814)}, |
45 | .uart1_data = 0xA01818, | 48 | .uart1_data = {.phys = CALLIOPE_ADDR(0xA01818)}, |
46 | .uart1_status = 0xA0181C, | 49 | .uart1_status = {.phys = CALLIOPE_ADDR(0xA0181C)}, |
47 | 50 | ||
48 | .int_stat_3 = 0xA02800, | 51 | .int_stat_3 = {.phys = CALLIOPE_ADDR(0xA02800)}, |
49 | .int_stat_2 = 0xA02804, | 52 | .int_stat_2 = {.phys = CALLIOPE_ADDR(0xA02804)}, |
50 | .int_stat_1 = 0xA02808, | 53 | .int_stat_1 = {.phys = CALLIOPE_ADDR(0xA02808)}, |
51 | .int_stat_0 = 0xA0280c, | 54 | .int_stat_0 = {.phys = CALLIOPE_ADDR(0xA0280c)}, |
52 | .int_config = 0xA02810, | 55 | .int_config = {.phys = CALLIOPE_ADDR(0xA02810)}, |
53 | .int_int_scan = 0xA02818, | 56 | .int_int_scan = {.phys = CALLIOPE_ADDR(0xA02818)}, |
54 | .ien_int_3 = 0xA02830, | 57 | .ien_int_3 = {.phys = CALLIOPE_ADDR(0xA02830)}, |
55 | .ien_int_2 = 0xA02834, | 58 | .ien_int_2 = {.phys = CALLIOPE_ADDR(0xA02834)}, |
56 | .ien_int_1 = 0xA02838, | 59 | .ien_int_1 = {.phys = CALLIOPE_ADDR(0xA02838)}, |
57 | .ien_int_0 = 0xA0283c, | 60 | .ien_int_0 = {.phys = CALLIOPE_ADDR(0xA0283c)}, |
58 | .int_level_3_3 = 0xA02880, | 61 | .int_level_3_3 = {.phys = CALLIOPE_ADDR(0xA02880)}, |
59 | .int_level_3_2 = 0xA02884, | 62 | .int_level_3_2 = {.phys = CALLIOPE_ADDR(0xA02884)}, |
60 | .int_level_3_1 = 0xA02888, | 63 | .int_level_3_1 = {.phys = CALLIOPE_ADDR(0xA02888)}, |
61 | .int_level_3_0 = 0xA0288c, | 64 | .int_level_3_0 = {.phys = CALLIOPE_ADDR(0xA0288c)}, |
62 | .int_level_2_3 = 0xA02890, | 65 | .int_level_2_3 = {.phys = CALLIOPE_ADDR(0xA02890)}, |
63 | .int_level_2_2 = 0xA02894, | 66 | .int_level_2_2 = {.phys = CALLIOPE_ADDR(0xA02894)}, |
64 | .int_level_2_1 = 0xA02898, | 67 | .int_level_2_1 = {.phys = CALLIOPE_ADDR(0xA02898)}, |
65 | .int_level_2_0 = 0xA0289c, | 68 | .int_level_2_0 = {.phys = CALLIOPE_ADDR(0xA0289c)}, |
66 | .int_level_1_3 = 0xA028a0, | 69 | .int_level_1_3 = {.phys = CALLIOPE_ADDR(0xA028a0)}, |
67 | .int_level_1_2 = 0xA028a4, | 70 | .int_level_1_2 = {.phys = CALLIOPE_ADDR(0xA028a4)}, |
68 | .int_level_1_1 = 0xA028a8, | 71 | .int_level_1_1 = {.phys = CALLIOPE_ADDR(0xA028a8)}, |
69 | .int_level_1_0 = 0xA028ac, | 72 | .int_level_1_0 = {.phys = CALLIOPE_ADDR(0xA028ac)}, |
70 | .int_level_0_3 = 0xA028b0, | 73 | .int_level_0_3 = {.phys = CALLIOPE_ADDR(0xA028b0)}, |
71 | .int_level_0_2 = 0xA028b4, | 74 | .int_level_0_2 = {.phys = CALLIOPE_ADDR(0xA028b4)}, |
72 | .int_level_0_1 = 0xA028b8, | 75 | .int_level_0_1 = {.phys = CALLIOPE_ADDR(0xA028b8)}, |
73 | .int_level_0_0 = 0xA028bc, | 76 | .int_level_0_0 = {.phys = CALLIOPE_ADDR(0xA028bc)}, |
74 | .int_docsis_en = 0xA028F4, | 77 | .int_docsis_en = {.phys = CALLIOPE_ADDR(0xA028F4)}, |
75 | 78 | ||
76 | .mips_pll_setup = 0x980000, | 79 | .mips_pll_setup = {.phys = CALLIOPE_ADDR(0x980000)}, |
77 | .usb_fs = 0x980030, /* -default 72800028- */ | 80 | .usb_fs = {.phys = CALLIOPE_ADDR(0x980030)}, |
78 | .test_bus = 0x9800CC, | 81 | .test_bus = {.phys = CALLIOPE_ADDR(0x9800CC)}, |
79 | .crt_spare = 0x9800d4, | 82 | .crt_spare = {.phys = CALLIOPE_ADDR(0x9800d4)}, |
80 | .usb2_ohci_int_mask = 0x9A000c, | 83 | .usb2_ohci_int_mask = {.phys = CALLIOPE_ADDR(0x9A000c)}, |
81 | .usb2_strap = 0x9A0014, | 84 | .usb2_strap = {.phys = CALLIOPE_ADDR(0x9A0014)}, |
82 | .ehci_hcapbase = 0x9BFE00, | 85 | .ehci_hcapbase = {.phys = CALLIOPE_ADDR(0x9BFE00)}, |
83 | .ohci_hc_revision = 0x9BFC00, | 86 | .ohci_hc_revision = {.phys = CALLIOPE_ADDR(0x9BFC00)}, |
84 | .bcm1_bs_lmi_steer = 0x9E0004, | 87 | .bcm1_bs_lmi_steer = {.phys = CALLIOPE_ADDR(0x9E0004)}, |
85 | .usb2_control = 0x9E0054, | 88 | .usb2_control = {.phys = CALLIOPE_ADDR(0x9E0054)}, |
86 | .usb2_stbus_obc = 0x9BFF00, | 89 | .usb2_stbus_obc = {.phys = CALLIOPE_ADDR(0x9BFF00)}, |
87 | .usb2_stbus_mess_size = 0x9BFF04, | 90 | .usb2_stbus_mess_size = {.phys = CALLIOPE_ADDR(0x9BFF04)}, |
88 | .usb2_stbus_chunk_size = 0x9BFF08, | 91 | .usb2_stbus_chunk_size = {.phys = CALLIOPE_ADDR(0x9BFF08)}, |
89 | 92 | ||
90 | .pcie_regs = 0x000000, /* -doesn't exist- */ | 93 | .pcie_regs = {.phys = 0x000000}, /* -doesn't exist- */ |
91 | .tim_ch = 0xA02C10, | 94 | .tim_ch = {.phys = CALLIOPE_ADDR(0xA02C10)}, |
92 | .tim_cl = 0xA02C14, | 95 | .tim_cl = {.phys = CALLIOPE_ADDR(0xA02C14)}, |
93 | .gpio_dout = 0xA02c20, | 96 | .gpio_dout = {.phys = CALLIOPE_ADDR(0xA02c20)}, |
94 | .gpio_din = 0xA02c24, | 97 | .gpio_din = {.phys = CALLIOPE_ADDR(0xA02c24)}, |
95 | .gpio_dir = 0xA02c2C, | 98 | .gpio_dir = {.phys = CALLIOPE_ADDR(0xA02c2C)}, |
96 | .watchdog = 0xA02c30, | 99 | .watchdog = {.phys = CALLIOPE_ADDR(0xA02c30)}, |
97 | .front_panel = 0x000000, /* -not used- */ | 100 | .front_panel = {.phys = 0x000000}, /* -not used- */ |
98 | }; | 101 | }; |
diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c index 5f4589c9f83d..5bb64bfb508b 100644 --- a/arch/mips/powertv/asic/asic-cronus.c +++ b/arch/mips/powertv/asic/asic-cronus.c | |||
@@ -23,76 +23,79 @@ | |||
23 | * Description: Defines the platform resources for the SA settop. | 23 | * Description: Defines the platform resources for the SA settop. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/init.h> | ||
26 | #include <asm/mach-powertv/asic.h> | 27 | #include <asm/mach-powertv/asic.h> |
27 | 28 | ||
28 | const struct register_map cronus_register_map = { | 29 | #define CRONUS_ADDR(x) (CRONUS_IO_BASE + (x)) |
29 | .eic_slow0_strt_add = 0x000000, | ||
30 | .eic_cfg_bits = 0x000038, | ||
31 | .eic_ready_status = 0x00004C, | ||
32 | 30 | ||
33 | .chipver3 = 0x2A0800, | 31 | const struct register_map cronus_register_map __initdata = { |
34 | .chipver2 = 0x2A0804, | 32 | .eic_slow0_strt_add = {.phys = CRONUS_ADDR(0x000000)}, |
35 | .chipver1 = 0x2A0808, | 33 | .eic_cfg_bits = {.phys = CRONUS_ADDR(0x000038)}, |
36 | .chipver0 = 0x2A080C, | 34 | .eic_ready_status = {.phys = CRONUS_ADDR(0x00004C)}, |
35 | |||
36 | .chipver3 = {.phys = CRONUS_ADDR(0x2A0800)}, | ||
37 | .chipver2 = {.phys = CRONUS_ADDR(0x2A0804)}, | ||
38 | .chipver1 = {.phys = CRONUS_ADDR(0x2A0808)}, | ||
39 | .chipver0 = {.phys = CRONUS_ADDR(0x2A080C)}, | ||
37 | 40 | ||
38 | /* The registers of IRBlaster */ | 41 | /* The registers of IRBlaster */ |
39 | .uart1_intstat = 0x2A1800, | 42 | .uart1_intstat = {.phys = CRONUS_ADDR(0x2A1800)}, |
40 | .uart1_inten = 0x2A1804, | 43 | .uart1_inten = {.phys = CRONUS_ADDR(0x2A1804)}, |
41 | .uart1_config1 = 0x2A1808, | 44 | .uart1_config1 = {.phys = CRONUS_ADDR(0x2A1808)}, |
42 | .uart1_config2 = 0x2A180C, | 45 | .uart1_config2 = {.phys = CRONUS_ADDR(0x2A180C)}, |
43 | .uart1_divisorhi = 0x2A1810, | 46 | .uart1_divisorhi = {.phys = CRONUS_ADDR(0x2A1810)}, |
44 | .uart1_divisorlo = 0x2A1814, | 47 | .uart1_divisorlo = {.phys = CRONUS_ADDR(0x2A1814)}, |
45 | .uart1_data = 0x2A1818, | 48 | .uart1_data = {.phys = CRONUS_ADDR(0x2A1818)}, |
46 | .uart1_status = 0x2A181C, | 49 | .uart1_status = {.phys = CRONUS_ADDR(0x2A181C)}, |
47 | 50 | ||
48 | .int_stat_3 = 0x2A2800, | 51 | .int_stat_3 = {.phys = CRONUS_ADDR(0x2A2800)}, |
49 | .int_stat_2 = 0x2A2804, | 52 | .int_stat_2 = {.phys = CRONUS_ADDR(0x2A2804)}, |
50 | .int_stat_1 = 0x2A2808, | 53 | .int_stat_1 = {.phys = CRONUS_ADDR(0x2A2808)}, |
51 | .int_stat_0 = 0x2A280C, | 54 | .int_stat_0 = {.phys = CRONUS_ADDR(0x2A280C)}, |
52 | .int_config = 0x2A2810, | 55 | .int_config = {.phys = CRONUS_ADDR(0x2A2810)}, |
53 | .int_int_scan = 0x2A2818, | 56 | .int_int_scan = {.phys = CRONUS_ADDR(0x2A2818)}, |
54 | .ien_int_3 = 0x2A2830, | 57 | .ien_int_3 = {.phys = CRONUS_ADDR(0x2A2830)}, |
55 | .ien_int_2 = 0x2A2834, | 58 | .ien_int_2 = {.phys = CRONUS_ADDR(0x2A2834)}, |
56 | .ien_int_1 = 0x2A2838, | 59 | .ien_int_1 = {.phys = CRONUS_ADDR(0x2A2838)}, |
57 | .ien_int_0 = 0x2A283C, | 60 | .ien_int_0 = {.phys = CRONUS_ADDR(0x2A283C)}, |
58 | .int_level_3_3 = 0x2A2880, | 61 | .int_level_3_3 = {.phys = CRONUS_ADDR(0x2A2880)}, |
59 | .int_level_3_2 = 0x2A2884, | 62 | .int_level_3_2 = {.phys = CRONUS_ADDR(0x2A2884)}, |
60 | .int_level_3_1 = 0x2A2888, | 63 | .int_level_3_1 = {.phys = CRONUS_ADDR(0x2A2888)}, |
61 | .int_level_3_0 = 0x2A288C, | 64 | .int_level_3_0 = {.phys = CRONUS_ADDR(0x2A288C)}, |
62 | .int_level_2_3 = 0x2A2890, | 65 | .int_level_2_3 = {.phys = CRONUS_ADDR(0x2A2890)}, |
63 | .int_level_2_2 = 0x2A2894, | 66 | .int_level_2_2 = {.phys = CRONUS_ADDR(0x2A2894)}, |
64 | .int_level_2_1 = 0x2A2898, | 67 | .int_level_2_1 = {.phys = CRONUS_ADDR(0x2A2898)}, |
65 | .int_level_2_0 = 0x2A289C, | 68 | .int_level_2_0 = {.phys = CRONUS_ADDR(0x2A289C)}, |
66 | .int_level_1_3 = 0x2A28A0, | 69 | .int_level_1_3 = {.phys = CRONUS_ADDR(0x2A28A0)}, |
67 | .int_level_1_2 = 0x2A28A4, | 70 | .int_level_1_2 = {.phys = CRONUS_ADDR(0x2A28A4)}, |
68 | .int_level_1_1 = 0x2A28A8, | 71 | .int_level_1_1 = {.phys = CRONUS_ADDR(0x2A28A8)}, |
69 | .int_level_1_0 = 0x2A28AC, | 72 | .int_level_1_0 = {.phys = CRONUS_ADDR(0x2A28AC)}, |
70 | .int_level_0_3 = 0x2A28B0, | 73 | .int_level_0_3 = {.phys = CRONUS_ADDR(0x2A28B0)}, |
71 | .int_level_0_2 = 0x2A28B4, | 74 | .int_level_0_2 = {.phys = CRONUS_ADDR(0x2A28B4)}, |
72 | .int_level_0_1 = 0x2A28B8, | 75 | .int_level_0_1 = {.phys = CRONUS_ADDR(0x2A28B8)}, |
73 | .int_level_0_0 = 0x2A28BC, | 76 | .int_level_0_0 = {.phys = CRONUS_ADDR(0x2A28BC)}, |
74 | .int_docsis_en = 0x2A28F4, | 77 | .int_docsis_en = {.phys = CRONUS_ADDR(0x2A28F4)}, |
75 | 78 | ||
76 | .mips_pll_setup = 0x1C0000, | 79 | .mips_pll_setup = {.phys = CRONUS_ADDR(0x1C0000)}, |
77 | .usb_fs = 0x1C0018, | 80 | .usb_fs = {.phys = CRONUS_ADDR(0x1C0018)}, |
78 | .test_bus = 0x1C00CC, | 81 | .test_bus = {.phys = CRONUS_ADDR(0x1C00CC)}, |
79 | .crt_spare = 0x1c00d4, | 82 | .crt_spare = {.phys = CRONUS_ADDR(0x1c00d4)}, |
80 | .usb2_ohci_int_mask = 0x20000C, | 83 | .usb2_ohci_int_mask = {.phys = CRONUS_ADDR(0x20000C)}, |
81 | .usb2_strap = 0x200014, | 84 | .usb2_strap = {.phys = CRONUS_ADDR(0x200014)}, |
82 | .ehci_hcapbase = 0x21FE00, | 85 | .ehci_hcapbase = {.phys = CRONUS_ADDR(0x21FE00)}, |
83 | .ohci_hc_revision = 0x1E0000, | 86 | .ohci_hc_revision = {.phys = CRONUS_ADDR(0x1E0000)}, |
84 | .bcm1_bs_lmi_steer = 0x2E0008, | 87 | .bcm1_bs_lmi_steer = {.phys = CRONUS_ADDR(0x2E0008)}, |
85 | .usb2_control = 0x2E004C, | 88 | .usb2_control = {.phys = CRONUS_ADDR(0x2E004C)}, |
86 | .usb2_stbus_obc = 0x21FF00, | 89 | .usb2_stbus_obc = {.phys = CRONUS_ADDR(0x21FF00)}, |
87 | .usb2_stbus_mess_size = 0x21FF04, | 90 | .usb2_stbus_mess_size = {.phys = CRONUS_ADDR(0x21FF04)}, |
88 | .usb2_stbus_chunk_size = 0x21FF08, | 91 | .usb2_stbus_chunk_size = {.phys = CRONUS_ADDR(0x21FF08)}, |
89 | 92 | ||
90 | .pcie_regs = 0x220000, | 93 | .pcie_regs = {.phys = CRONUS_ADDR(0x220000)}, |
91 | .tim_ch = 0x2A2C10, | 94 | .tim_ch = {.phys = CRONUS_ADDR(0x2A2C10)}, |
92 | .tim_cl = 0x2A2C14, | 95 | .tim_cl = {.phys = CRONUS_ADDR(0x2A2C14)}, |
93 | .gpio_dout = 0x2A2C20, | 96 | .gpio_dout = {.phys = CRONUS_ADDR(0x2A2C20)}, |
94 | .gpio_din = 0x2A2C24, | 97 | .gpio_din = {.phys = CRONUS_ADDR(0x2A2C24)}, |
95 | .gpio_dir = 0x2A2C2C, | 98 | .gpio_dir = {.phys = CRONUS_ADDR(0x2A2C2C)}, |
96 | .watchdog = 0x2A2C30, | 99 | .watchdog = {.phys = CRONUS_ADDR(0x2A2C30)}, |
97 | .front_panel = 0x2A3800, | 100 | .front_panel = {.phys = CRONUS_ADDR(0x2A3800)}, |
98 | }; | 101 | }; |
diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c index 1469daab920e..095cbe10ebb9 100644 --- a/arch/mips/powertv/asic/asic-zeus.c +++ b/arch/mips/powertv/asic/asic-zeus.c | |||
@@ -23,76 +23,79 @@ | |||
23 | * Description: Defines the platform resources for the SA settop. | 23 | * Description: Defines the platform resources for the SA settop. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/init.h> | ||
26 | #include <asm/mach-powertv/asic.h> | 27 | #include <asm/mach-powertv/asic.h> |
27 | 28 | ||
28 | const struct register_map zeus_register_map = { | 29 | #define ZEUS_ADDR(x) (ZEUS_IO_BASE + (x)) |
29 | .eic_slow0_strt_add = 0x000000, | ||
30 | .eic_cfg_bits = 0x000038, | ||
31 | .eic_ready_status = 0x00004c, | ||
32 | 30 | ||
33 | .chipver3 = 0x280800, | 31 | const struct register_map zeus_register_map __initdata = { |
34 | .chipver2 = 0x280804, | 32 | .eic_slow0_strt_add = {.phys = ZEUS_ADDR(0x000000)}, |
35 | .chipver1 = 0x280808, | 33 | .eic_cfg_bits = {.phys = ZEUS_ADDR(0x000038)}, |
36 | .chipver0 = 0x28080c, | 34 | .eic_ready_status = {.phys = ZEUS_ADDR(0x00004c)}, |
35 | |||
36 | .chipver3 = {.phys = ZEUS_ADDR(0x280800)}, | ||
37 | .chipver2 = {.phys = ZEUS_ADDR(0x280804)}, | ||
38 | .chipver1 = {.phys = ZEUS_ADDR(0x280808)}, | ||
39 | .chipver0 = {.phys = ZEUS_ADDR(0x28080c)}, | ||
37 | 40 | ||
38 | /* The registers of IRBlaster */ | 41 | /* The registers of IRBlaster */ |
39 | .uart1_intstat = 0x281800, | 42 | .uart1_intstat = {.phys = ZEUS_ADDR(0x281800)}, |
40 | .uart1_inten = 0x281804, | 43 | .uart1_inten = {.phys = ZEUS_ADDR(0x281804)}, |
41 | .uart1_config1 = 0x281808, | 44 | .uart1_config1 = {.phys = ZEUS_ADDR(0x281808)}, |
42 | .uart1_config2 = 0x28180C, | 45 | .uart1_config2 = {.phys = ZEUS_ADDR(0x28180C)}, |
43 | .uart1_divisorhi = 0x281810, | 46 | .uart1_divisorhi = {.phys = ZEUS_ADDR(0x281810)}, |
44 | .uart1_divisorlo = 0x281814, | 47 | .uart1_divisorlo = {.phys = ZEUS_ADDR(0x281814)}, |
45 | .uart1_data = 0x281818, | 48 | .uart1_data = {.phys = ZEUS_ADDR(0x281818)}, |
46 | .uart1_status = 0x28181C, | 49 | .uart1_status = {.phys = ZEUS_ADDR(0x28181C)}, |
47 | 50 | ||
48 | .int_stat_3 = 0x282800, | 51 | .int_stat_3 = {.phys = ZEUS_ADDR(0x282800)}, |
49 | .int_stat_2 = 0x282804, | 52 | .int_stat_2 = {.phys = ZEUS_ADDR(0x282804)}, |
50 | .int_stat_1 = 0x282808, | 53 | .int_stat_1 = {.phys = ZEUS_ADDR(0x282808)}, |
51 | .int_stat_0 = 0x28280c, | 54 | .int_stat_0 = {.phys = ZEUS_ADDR(0x28280c)}, |
52 | .int_config = 0x282810, | 55 | .int_config = {.phys = ZEUS_ADDR(0x282810)}, |
53 | .int_int_scan = 0x282818, | 56 | .int_int_scan = {.phys = ZEUS_ADDR(0x282818)}, |
54 | .ien_int_3 = 0x282830, | 57 | .ien_int_3 = {.phys = ZEUS_ADDR(0x282830)}, |
55 | .ien_int_2 = 0x282834, | 58 | .ien_int_2 = {.phys = ZEUS_ADDR(0x282834)}, |
56 | .ien_int_1 = 0x282838, | 59 | .ien_int_1 = {.phys = ZEUS_ADDR(0x282838)}, |
57 | .ien_int_0 = 0x28283c, | 60 | .ien_int_0 = {.phys = ZEUS_ADDR(0x28283c)}, |
58 | .int_level_3_3 = 0x282880, | 61 | .int_level_3_3 = {.phys = ZEUS_ADDR(0x282880)}, |
59 | .int_level_3_2 = 0x282884, | 62 | .int_level_3_2 = {.phys = ZEUS_ADDR(0x282884)}, |
60 | .int_level_3_1 = 0x282888, | 63 | .int_level_3_1 = {.phys = ZEUS_ADDR(0x282888)}, |
61 | .int_level_3_0 = 0x28288c, | 64 | .int_level_3_0 = {.phys = ZEUS_ADDR(0x28288c)}, |
62 | .int_level_2_3 = 0x282890, | 65 | .int_level_2_3 = {.phys = ZEUS_ADDR(0x282890)}, |
63 | .int_level_2_2 = 0x282894, | 66 | .int_level_2_2 = {.phys = ZEUS_ADDR(0x282894)}, |
64 | .int_level_2_1 = 0x282898, | 67 | .int_level_2_1 = {.phys = ZEUS_ADDR(0x282898)}, |
65 | .int_level_2_0 = 0x28289c, | 68 | .int_level_2_0 = {.phys = ZEUS_ADDR(0x28289c)}, |
66 | .int_level_1_3 = 0x2828a0, | 69 | .int_level_1_3 = {.phys = ZEUS_ADDR(0x2828a0)}, |
67 | .int_level_1_2 = 0x2828a4, | 70 | .int_level_1_2 = {.phys = ZEUS_ADDR(0x2828a4)}, |
68 | .int_level_1_1 = 0x2828a8, | 71 | .int_level_1_1 = {.phys = ZEUS_ADDR(0x2828a8)}, |
69 | .int_level_1_0 = 0x2828ac, | 72 | .int_level_1_0 = {.phys = ZEUS_ADDR(0x2828ac)}, |
70 | .int_level_0_3 = 0x2828b0, | 73 | .int_level_0_3 = {.phys = ZEUS_ADDR(0x2828b0)}, |
71 | .int_level_0_2 = 0x2828b4, | 74 | .int_level_0_2 = {.phys = ZEUS_ADDR(0x2828b4)}, |
72 | .int_level_0_1 = 0x2828b8, | 75 | .int_level_0_1 = {.phys = ZEUS_ADDR(0x2828b8)}, |
73 | .int_level_0_0 = 0x2828bc, | 76 | .int_level_0_0 = {.phys = ZEUS_ADDR(0x2828bc)}, |
74 | .int_docsis_en = 0x2828F4, | 77 | .int_docsis_en = {.phys = ZEUS_ADDR(0x2828F4)}, |
75 | 78 | ||
76 | .mips_pll_setup = 0x1a0000, | 79 | .mips_pll_setup = {.phys = ZEUS_ADDR(0x1a0000)}, |
77 | .usb_fs = 0x1a0018, | 80 | .usb_fs = {.phys = ZEUS_ADDR(0x1a0018)}, |
78 | .test_bus = 0x1a0238, | 81 | .test_bus = {.phys = ZEUS_ADDR(0x1a0238)}, |
79 | .crt_spare = 0x1a0090, | 82 | .crt_spare = {.phys = ZEUS_ADDR(0x1a0090)}, |
80 | .usb2_ohci_int_mask = 0x1e000c, | 83 | .usb2_ohci_int_mask = {.phys = ZEUS_ADDR(0x1e000c)}, |
81 | .usb2_strap = 0x1e0014, | 84 | .usb2_strap = {.phys = ZEUS_ADDR(0x1e0014)}, |
82 | .ehci_hcapbase = 0x1FFE00, | 85 | .ehci_hcapbase = {.phys = ZEUS_ADDR(0x1FFE00)}, |
83 | .ohci_hc_revision = 0x1FFC00, | 86 | .ohci_hc_revision = {.phys = ZEUS_ADDR(0x1FFC00)}, |
84 | .bcm1_bs_lmi_steer = 0x2C0008, | 87 | .bcm1_bs_lmi_steer = {.phys = ZEUS_ADDR(0x2C0008)}, |
85 | .usb2_control = 0x2c01a0, | 88 | .usb2_control = {.phys = ZEUS_ADDR(0x2c01a0)}, |
86 | .usb2_stbus_obc = 0x1FFF00, | 89 | .usb2_stbus_obc = {.phys = ZEUS_ADDR(0x1FFF00)}, |
87 | .usb2_stbus_mess_size = 0x1FFF04, | 90 | .usb2_stbus_mess_size = {.phys = ZEUS_ADDR(0x1FFF04)}, |
88 | .usb2_stbus_chunk_size = 0x1FFF08, | 91 | .usb2_stbus_chunk_size = {.phys = ZEUS_ADDR(0x1FFF08)}, |
89 | 92 | ||
90 | .pcie_regs = 0x200000, | 93 | .pcie_regs = {.phys = ZEUS_ADDR(0x200000)}, |
91 | .tim_ch = 0x282C10, | 94 | .tim_ch = {.phys = ZEUS_ADDR(0x282C10)}, |
92 | .tim_cl = 0x282C14, | 95 | .tim_cl = {.phys = ZEUS_ADDR(0x282C14)}, |
93 | .gpio_dout = 0x282c20, | 96 | .gpio_dout = {.phys = ZEUS_ADDR(0x282c20)}, |
94 | .gpio_din = 0x282c24, | 97 | .gpio_din = {.phys = ZEUS_ADDR(0x282c24)}, |
95 | .gpio_dir = 0x282c2C, | 98 | .gpio_dir = {.phys = ZEUS_ADDR(0x282c2C)}, |
96 | .watchdog = 0x282c30, | 99 | .watchdog = {.phys = ZEUS_ADDR(0x282c30)}, |
97 | .front_panel = 0x283800, | 100 | .front_panel = {.phys = ZEUS_ADDR(0x283800)}, |
98 | }; | 101 | }; |
diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c index bae82880b6b5..6a882194e063 100644 --- a/arch/mips/powertv/asic/asic_devices.c +++ b/arch/mips/powertv/asic/asic_devices.c | |||
@@ -67,8 +67,8 @@ enum asic_type asic; | |||
67 | 67 | ||
68 | unsigned int platform_features; | 68 | unsigned int platform_features; |
69 | unsigned int platform_family; | 69 | unsigned int platform_family; |
70 | const struct register_map *register_map; | 70 | struct register_map _asic_register_map; |
71 | EXPORT_SYMBOL(register_map); /* Exported for testing */ | 71 | EXPORT_SYMBOL(_asic_register_map); /* Exported for testing */ |
72 | unsigned long asic_phy_base; | 72 | unsigned long asic_phy_base; |
73 | unsigned long asic_base; | 73 | unsigned long asic_base; |
74 | EXPORT_SYMBOL(asic_base); /* Exported for testing */ | 74 | EXPORT_SYMBOL(asic_base); /* Exported for testing */ |
@@ -418,6 +418,15 @@ void platform_unconfigure_usb_ohci() | |||
418 | { | 418 | { |
419 | } | 419 | } |
420 | 420 | ||
421 | static void __init set_register_map(unsigned long phys_base, | ||
422 | const struct register_map *map) | ||
423 | { | ||
424 | asic_phy_base = phys_base; | ||
425 | _asic_register_map = *map; | ||
426 | register_map_virtualize(&_asic_register_map); | ||
427 | asic_base = (unsigned long)ioremap_nocache(phys_base, ASIC_IO_SIZE); | ||
428 | } | ||
429 | |||
421 | /** | 430 | /** |
422 | * configure_platform - configuration based on platform type. | 431 | * configure_platform - configuration based on platform type. |
423 | */ | 432 | */ |
@@ -431,10 +440,7 @@ void __init configure_platform(void) | |||
431 | case FAMILY_1500VZF: | 440 | case FAMILY_1500VZF: |
432 | platform_features = FFS_CAPABLE; | 441 | platform_features = FFS_CAPABLE; |
433 | asic = ASIC_CALLIOPE; | 442 | asic = ASIC_CALLIOPE; |
434 | asic_phy_base = CALLIOPE_IO_BASE; | 443 | set_register_map(CALLIOPE_IO_BASE, &calliope_register_map); |
435 | register_map = &calliope_register_map; | ||
436 | asic_base = (unsigned long)ioremap_nocache(asic_phy_base, | ||
437 | ASIC_IO_SIZE); | ||
438 | 444 | ||
439 | if (platform_family == FAMILY_1500VZE) { | 445 | if (platform_family == FAMILY_1500VZE) { |
440 | gp_resources = non_dvr_vze_calliope_resources; | 446 | gp_resources = non_dvr_vze_calliope_resources; |
@@ -455,10 +461,7 @@ void __init configure_platform(void) | |||
455 | platform_features = FFS_CAPABLE | PCIE_CAPABLE | | 461 | platform_features = FFS_CAPABLE | PCIE_CAPABLE | |
456 | DISPLAY_CAPABLE; | 462 | DISPLAY_CAPABLE; |
457 | asic = ASIC_ZEUS; | 463 | asic = ASIC_ZEUS; |
458 | asic_phy_base = ZEUS_IO_BASE; | 464 | set_register_map(ZEUS_IO_BASE, &zeus_register_map); |
459 | register_map = &zeus_register_map; | ||
460 | asic_base = (unsigned long)ioremap_nocache(asic_phy_base, | ||
461 | ASIC_IO_SIZE); | ||
462 | gp_resources = non_dvr_zeus_resources; | 465 | gp_resources = non_dvr_zeus_resources; |
463 | 466 | ||
464 | pr_info("Platform: 4500 - ZEUS, NON_DVR_CAPABLE\n"); | 467 | pr_info("Platform: 4500 - ZEUS, NON_DVR_CAPABLE\n"); |
@@ -471,11 +474,6 @@ void __init configure_platform(void) | |||
471 | /* The settop has PCIE but it isn't used, so don't advertise | 474 | /* The settop has PCIE but it isn't used, so don't advertise |
472 | * it*/ | 475 | * it*/ |
473 | platform_features = FFS_CAPABLE | DISPLAY_CAPABLE; | 476 | platform_features = FFS_CAPABLE | DISPLAY_CAPABLE; |
474 | asic_phy_base = CRONUS_IO_BASE; /* same as Cronus */ | ||
475 | register_map = &cronus_register_map; /* same as Cronus */ | ||
476 | asic_base = (unsigned long)ioremap_nocache(asic_phy_base, | ||
477 | ASIC_IO_SIZE); | ||
478 | gp_resources = non_dvr_cronuslite_resources; | ||
479 | 477 | ||
480 | /* ASIC version will determine if this is a real CronusLite or | 478 | /* ASIC version will determine if this is a real CronusLite or |
481 | * Castrati(Cronus) */ | 479 | * Castrati(Cronus) */ |
@@ -489,6 +487,9 @@ void __init configure_platform(void) | |||
489 | else | 487 | else |
490 | asic = ASIC_CRONUSLITE; | 488 | asic = ASIC_CRONUSLITE; |
491 | 489 | ||
490 | /* Cronus and Cronus Lite have the same register map */ | ||
491 | set_register_map(CRONUS_IO_BASE, &cronus_register_map); | ||
492 | gp_resources = non_dvr_cronuslite_resources; | ||
492 | pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, " | 493 | pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, " |
493 | "chipversion=0x%08X\n", | 494 | "chipversion=0x%08X\n", |
494 | (asic == ASIC_CRONUS) ? "CRONUS" : "CRONUS LITE", | 495 | (asic == ASIC_CRONUS) ? "CRONUS" : "CRONUS LITE", |
@@ -498,10 +499,7 @@ void __init configure_platform(void) | |||
498 | case FAMILY_4600VZA: | 499 | case FAMILY_4600VZA: |
499 | platform_features = FFS_CAPABLE | DISPLAY_CAPABLE; | 500 | platform_features = FFS_CAPABLE | DISPLAY_CAPABLE; |
500 | asic = ASIC_CRONUS; | 501 | asic = ASIC_CRONUS; |
501 | asic_phy_base = CRONUS_IO_BASE; | 502 | set_register_map(CRONUS_IO_BASE, &cronus_register_map); |
502 | register_map = &cronus_register_map; | ||
503 | asic_base = (unsigned long)ioremap_nocache(asic_phy_base, | ||
504 | ASIC_IO_SIZE); | ||
505 | gp_resources = non_dvr_cronus_resources; | 503 | gp_resources = non_dvr_cronus_resources; |
506 | 504 | ||
507 | pr_info("Platform: Vz Class A - CRONUS, NON_DVR_CAPABLE\n"); | 505 | pr_info("Platform: Vz Class A - CRONUS, NON_DVR_CAPABLE\n"); |
@@ -512,10 +510,7 @@ void __init configure_platform(void) | |||
512 | platform_features = DVR_CAPABLE | PCIE_CAPABLE | | 510 | platform_features = DVR_CAPABLE | PCIE_CAPABLE | |
513 | DISPLAY_CAPABLE; | 511 | DISPLAY_CAPABLE; |
514 | asic = ASIC_ZEUS; | 512 | asic = ASIC_ZEUS; |
515 | asic_phy_base = ZEUS_IO_BASE; | 513 | set_register_map(ZEUS_IO_BASE, &zeus_register_map); |
516 | register_map = &zeus_register_map; | ||
517 | asic_base = (unsigned long)ioremap_nocache(asic_phy_base, | ||
518 | ASIC_IO_SIZE); | ||
519 | gp_resources = dvr_zeus_resources; | 514 | gp_resources = dvr_zeus_resources; |
520 | 515 | ||
521 | pr_info("Platform: 8500/RNG200 - ZEUS, DVR_CAPABLE\n"); | 516 | pr_info("Platform: 8500/RNG200 - ZEUS, DVR_CAPABLE\n"); |
@@ -526,10 +521,7 @@ void __init configure_platform(void) | |||
526 | platform_features = DVR_CAPABLE | PCIE_CAPABLE | | 521 | platform_features = DVR_CAPABLE | PCIE_CAPABLE | |
527 | DISPLAY_CAPABLE; | 522 | DISPLAY_CAPABLE; |
528 | asic = ASIC_CRONUS; | 523 | asic = ASIC_CRONUS; |
529 | asic_phy_base = CRONUS_IO_BASE; | 524 | set_register_map(CRONUS_IO_BASE, &cronus_register_map); |
530 | register_map = &cronus_register_map; | ||
531 | asic_base = (unsigned long)ioremap_nocache(asic_phy_base, | ||
532 | ASIC_IO_SIZE); | ||
533 | gp_resources = dvr_cronus_resources; | 525 | gp_resources = dvr_cronus_resources; |
534 | 526 | ||
535 | pr_info("Platform: 8600/Vz Class B - CRONUS, " | 527 | pr_info("Platform: 8600/Vz Class B - CRONUS, " |
diff --git a/arch/s390/include/asm/irqflags.h b/arch/s390/include/asm/irqflags.h index 3f26131120b7..c2fb432f576a 100644 --- a/arch/s390/include/asm/irqflags.h +++ b/arch/s390/include/asm/irqflags.h | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * include/asm-s390/irqflags.h | 2 | * Copyright IBM Corp. 2006,2010 |
3 | * | 3 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> |
4 | * Copyright (C) IBM Corp. 2006 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | */ | 4 | */ |
7 | 5 | ||
8 | #ifndef __ASM_IRQFLAGS_H | 6 | #ifndef __ASM_IRQFLAGS_H |
9 | #define __ASM_IRQFLAGS_H | 7 | #define __ASM_IRQFLAGS_H |
10 | 8 | ||
11 | #ifdef __KERNEL__ | 9 | #include <linux/types.h> |
12 | 10 | ||
13 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 11 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
14 | 12 | ||
@@ -102,5 +100,4 @@ static inline int raw_irqs_disabled_flags(unsigned long flags) | |||
102 | /* For spinlocks etc */ | 100 | /* For spinlocks etc */ |
103 | #define raw_local_irq_save(x) ((x) = raw_local_irq_disable()) | 101 | #define raw_local_irq_save(x) ((x) = raw_local_irq_disable()) |
104 | 102 | ||
105 | #endif /* __KERNEL__ */ | ||
106 | #endif /* __ASM_IRQFLAGS_H */ | 103 | #endif /* __ASM_IRQFLAGS_H */ |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 48215d15762b..e8ef21c51bbe 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -571,6 +571,7 @@ pgm_svcper: | |||
571 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID | 571 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID |
572 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 572 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
573 | TRACE_IRQS_ON | 573 | TRACE_IRQS_ON |
574 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | ||
574 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 575 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
575 | b BASED(sysc_do_svc) | 576 | b BASED(sysc_do_svc) |
576 | 577 | ||
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 9aff1d449b6e..f33658f09dd7 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -549,6 +549,7 @@ pgm_svcper: | |||
549 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID | 549 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID |
550 | oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 550 | oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
551 | TRACE_IRQS_ON | 551 | TRACE_IRQS_ON |
552 | lmg %r2,%r6,SP_R2(%r15) # load svc arguments | ||
552 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 553 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
553 | j sysc_do_svc | 554 | j sysc_do_svc |
554 | 555 | ||
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 1675c48b9145..6289945562b0 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -64,7 +64,7 @@ SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask) | |||
64 | recalc_sigpending(); | 64 | recalc_sigpending(); |
65 | spin_unlock_irq(¤t->sighand->siglock); | 65 | spin_unlock_irq(¤t->sighand->siglock); |
66 | 66 | ||
67 | current->state = TASK_INTERRUPTIBLE; | 67 | set_current_state(TASK_INTERRUPTIBLE); |
68 | schedule(); | 68 | schedule(); |
69 | set_thread_flag(TIF_RESTORE_SIGMASK); | 69 | set_thread_flag(TIF_RESTORE_SIGMASK); |
70 | 70 | ||
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index f2179cce1e4d..e1cbdb94d97b 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
@@ -268,10 +268,8 @@ static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity) | |||
268 | return cpuid; | 268 | return cpuid; |
269 | } | 269 | } |
270 | #else | 270 | #else |
271 | static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity) | 271 | #define irq_choose_cpu(virt_irq, affinity) \ |
272 | { | 272 | real_hard_smp_processor_id() |
273 | return real_hard_smp_processor_id(); | ||
274 | } | ||
275 | #endif | 273 | #endif |
276 | 274 | ||
277 | static void sun4u_irq_enable(unsigned int virt_irq) | 275 | static void sun4u_irq_enable(unsigned int virt_irq) |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cbcbfdee3ee0..eb4092568f9e 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -989,12 +989,6 @@ config X86_CPUID | |||
989 | with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to | 989 | with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to |
990 | /dev/cpu/31/cpuid. | 990 | /dev/cpu/31/cpuid. |
991 | 991 | ||
992 | config X86_CPU_DEBUG | ||
993 | tristate "/sys/kernel/debug/x86/cpu/* - CPU Debug support" | ||
994 | ---help--- | ||
995 | If you select this option, this will provide various x86 CPUs | ||
996 | information through debugfs. | ||
997 | |||
998 | choice | 992 | choice |
999 | prompt "High Memory Support" | 993 | prompt "High Memory Support" |
1000 | default HIGHMEM4G if !X86_NUMAQ | 994 | default HIGHMEM4G if !X86_NUMAQ |
diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h deleted file mode 100644 index d96c1ee3a95c..000000000000 --- a/arch/x86/include/asm/cpu_debug.h +++ /dev/null | |||
@@ -1,127 +0,0 @@ | |||
1 | #ifndef _ASM_X86_CPU_DEBUG_H | ||
2 | #define _ASM_X86_CPU_DEBUG_H | ||
3 | |||
4 | /* | ||
5 | * CPU x86 architecture debug | ||
6 | * | ||
7 | * Copyright(C) 2009 Jaswinder Singh Rajput | ||
8 | */ | ||
9 | |||
10 | /* Register flags */ | ||
11 | enum cpu_debug_bit { | ||
12 | /* Model Specific Registers (MSRs) */ | ||
13 | CPU_MC_BIT, /* Machine Check */ | ||
14 | CPU_MONITOR_BIT, /* Monitor */ | ||
15 | CPU_TIME_BIT, /* Time */ | ||
16 | CPU_PMC_BIT, /* Performance Monitor */ | ||
17 | CPU_PLATFORM_BIT, /* Platform */ | ||
18 | CPU_APIC_BIT, /* APIC */ | ||
19 | CPU_POWERON_BIT, /* Power-on */ | ||
20 | CPU_CONTROL_BIT, /* Control */ | ||
21 | CPU_FEATURES_BIT, /* Features control */ | ||
22 | CPU_LBRANCH_BIT, /* Last Branch */ | ||
23 | CPU_BIOS_BIT, /* BIOS */ | ||
24 | CPU_FREQ_BIT, /* Frequency */ | ||
25 | CPU_MTTR_BIT, /* MTRR */ | ||
26 | CPU_PERF_BIT, /* Performance */ | ||
27 | CPU_CACHE_BIT, /* Cache */ | ||
28 | CPU_SYSENTER_BIT, /* Sysenter */ | ||
29 | CPU_THERM_BIT, /* Thermal */ | ||
30 | CPU_MISC_BIT, /* Miscellaneous */ | ||
31 | CPU_DEBUG_BIT, /* Debug */ | ||
32 | CPU_PAT_BIT, /* PAT */ | ||
33 | CPU_VMX_BIT, /* VMX */ | ||
34 | CPU_CALL_BIT, /* System Call */ | ||
35 | CPU_BASE_BIT, /* BASE Address */ | ||
36 | CPU_VER_BIT, /* Version ID */ | ||
37 | CPU_CONF_BIT, /* Configuration */ | ||
38 | CPU_SMM_BIT, /* System mgmt mode */ | ||
39 | CPU_SVM_BIT, /*Secure Virtual Machine*/ | ||
40 | CPU_OSVM_BIT, /* OS-Visible Workaround*/ | ||
41 | /* Standard Registers */ | ||
42 | CPU_TSS_BIT, /* Task Stack Segment */ | ||
43 | CPU_CR_BIT, /* Control Registers */ | ||
44 | CPU_DT_BIT, /* Descriptor Table */ | ||
45 | /* End of Registers flags */ | ||
46 | CPU_REG_ALL_BIT, /* Select all Registers */ | ||
47 | }; | ||
48 | |||
49 | #define CPU_REG_ALL (~0) /* Select all Registers */ | ||
50 | |||
51 | #define CPU_MC (1 << CPU_MC_BIT) | ||
52 | #define CPU_MONITOR (1 << CPU_MONITOR_BIT) | ||
53 | #define CPU_TIME (1 << CPU_TIME_BIT) | ||
54 | #define CPU_PMC (1 << CPU_PMC_BIT) | ||
55 | #define CPU_PLATFORM (1 << CPU_PLATFORM_BIT) | ||
56 | #define CPU_APIC (1 << CPU_APIC_BIT) | ||
57 | #define CPU_POWERON (1 << CPU_POWERON_BIT) | ||
58 | #define CPU_CONTROL (1 << CPU_CONTROL_BIT) | ||
59 | #define CPU_FEATURES (1 << CPU_FEATURES_BIT) | ||
60 | #define CPU_LBRANCH (1 << CPU_LBRANCH_BIT) | ||
61 | #define CPU_BIOS (1 << CPU_BIOS_BIT) | ||
62 | #define CPU_FREQ (1 << CPU_FREQ_BIT) | ||
63 | #define CPU_MTRR (1 << CPU_MTTR_BIT) | ||
64 | #define CPU_PERF (1 << CPU_PERF_BIT) | ||
65 | #define CPU_CACHE (1 << CPU_CACHE_BIT) | ||
66 | #define CPU_SYSENTER (1 << CPU_SYSENTER_BIT) | ||
67 | #define CPU_THERM (1 << CPU_THERM_BIT) | ||
68 | #define CPU_MISC (1 << CPU_MISC_BIT) | ||
69 | #define CPU_DEBUG (1 << CPU_DEBUG_BIT) | ||
70 | #define CPU_PAT (1 << CPU_PAT_BIT) | ||
71 | #define CPU_VMX (1 << CPU_VMX_BIT) | ||
72 | #define CPU_CALL (1 << CPU_CALL_BIT) | ||
73 | #define CPU_BASE (1 << CPU_BASE_BIT) | ||
74 | #define CPU_VER (1 << CPU_VER_BIT) | ||
75 | #define CPU_CONF (1 << CPU_CONF_BIT) | ||
76 | #define CPU_SMM (1 << CPU_SMM_BIT) | ||
77 | #define CPU_SVM (1 << CPU_SVM_BIT) | ||
78 | #define CPU_OSVM (1 << CPU_OSVM_BIT) | ||
79 | #define CPU_TSS (1 << CPU_TSS_BIT) | ||
80 | #define CPU_CR (1 << CPU_CR_BIT) | ||
81 | #define CPU_DT (1 << CPU_DT_BIT) | ||
82 | |||
83 | /* Register file flags */ | ||
84 | enum cpu_file_bit { | ||
85 | CPU_INDEX_BIT, /* index */ | ||
86 | CPU_VALUE_BIT, /* value */ | ||
87 | }; | ||
88 | |||
89 | #define CPU_FILE_VALUE (1 << CPU_VALUE_BIT) | ||
90 | |||
91 | #define MAX_CPU_FILES 512 | ||
92 | |||
93 | struct cpu_private { | ||
94 | unsigned cpu; | ||
95 | unsigned type; | ||
96 | unsigned reg; | ||
97 | unsigned file; | ||
98 | }; | ||
99 | |||
100 | struct cpu_debug_base { | ||
101 | char *name; /* Register name */ | ||
102 | unsigned flag; /* Register flag */ | ||
103 | unsigned write; /* Register write flag */ | ||
104 | }; | ||
105 | |||
106 | /* | ||
107 | * Currently it looks similar to cpu_debug_base but once we add more files | ||
108 | * cpu_file_base will go in different direction | ||
109 | */ | ||
110 | struct cpu_file_base { | ||
111 | char *name; /* Register file name */ | ||
112 | unsigned flag; /* Register file flag */ | ||
113 | unsigned write; /* Register write flag */ | ||
114 | }; | ||
115 | |||
116 | struct cpu_cpuX_base { | ||
117 | struct dentry *dentry; /* Register dentry */ | ||
118 | int init; /* Register index file */ | ||
119 | }; | ||
120 | |||
121 | struct cpu_debug_range { | ||
122 | unsigned min; /* Register range min */ | ||
123 | unsigned max; /* Register range max */ | ||
124 | unsigned flag; /* Supported flags */ | ||
125 | }; | ||
126 | |||
127 | #endif /* _ASM_X86_CPU_DEBUG_H */ | ||
diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h index 5d89fd2a3690..1d5c08a1bdfd 100644 --- a/arch/x86/include/asm/hpet.h +++ b/arch/x86/include/asm/hpet.h | |||
@@ -67,6 +67,7 @@ extern unsigned long hpet_address; | |||
67 | extern unsigned long force_hpet_address; | 67 | extern unsigned long force_hpet_address; |
68 | extern u8 hpet_blockid; | 68 | extern u8 hpet_blockid; |
69 | extern int hpet_force_user; | 69 | extern int hpet_force_user; |
70 | extern u8 hpet_msi_disable; | ||
70 | extern int is_hpet_enabled(void); | 71 | extern int is_hpet_enabled(void); |
71 | extern int hpet_enable(void); | 72 | extern int hpet_enable(void); |
72 | extern void hpet_disable(void); | 73 | extern void hpet_disable(void); |
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index c24ca9a56458..ef51b501e22a 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h | |||
@@ -12,8 +12,6 @@ struct device; | |||
12 | enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND }; | 12 | enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND }; |
13 | 13 | ||
14 | struct microcode_ops { | 14 | struct microcode_ops { |
15 | void (*init)(struct device *device); | ||
16 | void (*fini)(void); | ||
17 | enum ucode_state (*request_microcode_user) (int cpu, | 15 | enum ucode_state (*request_microcode_user) (int cpu, |
18 | const void __user *buf, size_t size); | 16 | const void __user *buf, size_t size); |
19 | 17 | ||
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 1d2cb383410e..c202b62f3671 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -19,8 +19,6 @@ obj-y += vmware.o hypervisor.o sched.o | |||
19 | obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o | 19 | obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o |
20 | obj-$(CONFIG_X86_64) += bugs_64.o | 20 | obj-$(CONFIG_X86_64) += bugs_64.o |
21 | 21 | ||
22 | obj-$(CONFIG_X86_CPU_DEBUG) += cpu_debug.o | ||
23 | |||
24 | obj-$(CONFIG_CPU_SUP_INTEL) += intel.o | 22 | obj-$(CONFIG_CPU_SUP_INTEL) += intel.o |
25 | obj-$(CONFIG_CPU_SUP_AMD) += amd.o | 23 | obj-$(CONFIG_CPU_SUP_AMD) += amd.o |
26 | obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o | 24 | obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o |
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c deleted file mode 100644 index b368cd862997..000000000000 --- a/arch/x86/kernel/cpu/cpu_debug.c +++ /dev/null | |||
@@ -1,688 +0,0 @@ | |||
1 | /* | ||
2 | * CPU x86 architecture debug code | ||
3 | * | ||
4 | * Copyright(C) 2009 Jaswinder Singh Rajput | ||
5 | * | ||
6 | * For licencing details see kernel-base/COPYING | ||
7 | */ | ||
8 | |||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/compiler.h> | ||
11 | #include <linux/seq_file.h> | ||
12 | #include <linux/debugfs.h> | ||
13 | #include <linux/kprobes.h> | ||
14 | #include <linux/uaccess.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/percpu.h> | ||
18 | #include <linux/signal.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/smp.h> | ||
25 | |||
26 | #include <asm/cpu_debug.h> | ||
27 | #include <asm/paravirt.h> | ||
28 | #include <asm/system.h> | ||
29 | #include <asm/traps.h> | ||
30 | #include <asm/apic.h> | ||
31 | #include <asm/desc.h> | ||
32 | |||
33 | static DEFINE_PER_CPU(struct cpu_cpuX_base [CPU_REG_ALL_BIT], cpud_arr); | ||
34 | static DEFINE_PER_CPU(struct cpu_private * [MAX_CPU_FILES], cpud_priv_arr); | ||
35 | static DEFINE_PER_CPU(int, cpud_priv_count); | ||
36 | |||
37 | static DEFINE_MUTEX(cpu_debug_lock); | ||
38 | |||
39 | static struct dentry *cpu_debugfs_dir; | ||
40 | |||
41 | static struct cpu_debug_base cpu_base[] = { | ||
42 | { "mc", CPU_MC, 0 }, | ||
43 | { "monitor", CPU_MONITOR, 0 }, | ||
44 | { "time", CPU_TIME, 0 }, | ||
45 | { "pmc", CPU_PMC, 1 }, | ||
46 | { "platform", CPU_PLATFORM, 0 }, | ||
47 | { "apic", CPU_APIC, 0 }, | ||
48 | { "poweron", CPU_POWERON, 0 }, | ||
49 | { "control", CPU_CONTROL, 0 }, | ||
50 | { "features", CPU_FEATURES, 0 }, | ||
51 | { "lastbranch", CPU_LBRANCH, 0 }, | ||
52 | { "bios", CPU_BIOS, 0 }, | ||
53 | { "freq", CPU_FREQ, 0 }, | ||
54 | { "mtrr", CPU_MTRR, 0 }, | ||
55 | { "perf", CPU_PERF, 0 }, | ||
56 | { "cache", CPU_CACHE, 0 }, | ||
57 | { "sysenter", CPU_SYSENTER, 0 }, | ||
58 | { "therm", CPU_THERM, 0 }, | ||
59 | { "misc", CPU_MISC, 0 }, | ||
60 | { "debug", CPU_DEBUG, 0 }, | ||
61 | { "pat", CPU_PAT, 0 }, | ||
62 | { "vmx", CPU_VMX, 0 }, | ||
63 | { "call", CPU_CALL, 0 }, | ||
64 | { "base", CPU_BASE, 0 }, | ||
65 | { "ver", CPU_VER, 0 }, | ||
66 | { "conf", CPU_CONF, 0 }, | ||
67 | { "smm", CPU_SMM, 0 }, | ||
68 | { "svm", CPU_SVM, 0 }, | ||
69 | { "osvm", CPU_OSVM, 0 }, | ||
70 | { "tss", CPU_TSS, 0 }, | ||
71 | { "cr", CPU_CR, 0 }, | ||
72 | { "dt", CPU_DT, 0 }, | ||
73 | { "registers", CPU_REG_ALL, 0 }, | ||
74 | }; | ||
75 | |||
76 | static struct cpu_file_base cpu_file[] = { | ||
77 | { "index", CPU_REG_ALL, 0 }, | ||
78 | { "value", CPU_REG_ALL, 1 }, | ||
79 | }; | ||
80 | |||
81 | /* CPU Registers Range */ | ||
82 | static struct cpu_debug_range cpu_reg_range[] = { | ||
83 | { 0x00000000, 0x00000001, CPU_MC, }, | ||
84 | { 0x00000006, 0x00000007, CPU_MONITOR, }, | ||
85 | { 0x00000010, 0x00000010, CPU_TIME, }, | ||
86 | { 0x00000011, 0x00000013, CPU_PMC, }, | ||
87 | { 0x00000017, 0x00000017, CPU_PLATFORM, }, | ||
88 | { 0x0000001B, 0x0000001B, CPU_APIC, }, | ||
89 | { 0x0000002A, 0x0000002B, CPU_POWERON, }, | ||
90 | { 0x0000002C, 0x0000002C, CPU_FREQ, }, | ||
91 | { 0x0000003A, 0x0000003A, CPU_CONTROL, }, | ||
92 | { 0x00000040, 0x00000047, CPU_LBRANCH, }, | ||
93 | { 0x00000060, 0x00000067, CPU_LBRANCH, }, | ||
94 | { 0x00000079, 0x00000079, CPU_BIOS, }, | ||
95 | { 0x00000088, 0x0000008A, CPU_CACHE, }, | ||
96 | { 0x0000008B, 0x0000008B, CPU_BIOS, }, | ||
97 | { 0x0000009B, 0x0000009B, CPU_MONITOR, }, | ||
98 | { 0x000000C1, 0x000000C4, CPU_PMC, }, | ||
99 | { 0x000000CD, 0x000000CD, CPU_FREQ, }, | ||
100 | { 0x000000E7, 0x000000E8, CPU_PERF, }, | ||
101 | { 0x000000FE, 0x000000FE, CPU_MTRR, }, | ||
102 | |||
103 | { 0x00000116, 0x0000011E, CPU_CACHE, }, | ||
104 | { 0x00000174, 0x00000176, CPU_SYSENTER, }, | ||
105 | { 0x00000179, 0x0000017B, CPU_MC, }, | ||
106 | { 0x00000186, 0x00000189, CPU_PMC, }, | ||
107 | { 0x00000198, 0x00000199, CPU_PERF, }, | ||
108 | { 0x0000019A, 0x0000019A, CPU_TIME, }, | ||
109 | { 0x0000019B, 0x0000019D, CPU_THERM, }, | ||
110 | { 0x000001A0, 0x000001A0, CPU_MISC, }, | ||
111 | { 0x000001C9, 0x000001C9, CPU_LBRANCH, }, | ||
112 | { 0x000001D7, 0x000001D8, CPU_LBRANCH, }, | ||
113 | { 0x000001D9, 0x000001D9, CPU_DEBUG, }, | ||
114 | { 0x000001DA, 0x000001E0, CPU_LBRANCH, }, | ||
115 | |||
116 | { 0x00000200, 0x0000020F, CPU_MTRR, }, | ||
117 | { 0x00000250, 0x00000250, CPU_MTRR, }, | ||
118 | { 0x00000258, 0x00000259, CPU_MTRR, }, | ||
119 | { 0x00000268, 0x0000026F, CPU_MTRR, }, | ||
120 | { 0x00000277, 0x00000277, CPU_PAT, }, | ||
121 | { 0x000002FF, 0x000002FF, CPU_MTRR, }, | ||
122 | |||
123 | { 0x00000300, 0x00000311, CPU_PMC, }, | ||
124 | { 0x00000345, 0x00000345, CPU_PMC, }, | ||
125 | { 0x00000360, 0x00000371, CPU_PMC, }, | ||
126 | { 0x0000038D, 0x00000390, CPU_PMC, }, | ||
127 | { 0x000003A0, 0x000003BE, CPU_PMC, }, | ||
128 | { 0x000003C0, 0x000003CD, CPU_PMC, }, | ||
129 | { 0x000003E0, 0x000003E1, CPU_PMC, }, | ||
130 | { 0x000003F0, 0x000003F2, CPU_PMC, }, | ||
131 | |||
132 | { 0x00000400, 0x00000417, CPU_MC, }, | ||
133 | { 0x00000480, 0x0000048B, CPU_VMX, }, | ||
134 | |||
135 | { 0x00000600, 0x00000600, CPU_DEBUG, }, | ||
136 | { 0x00000680, 0x0000068F, CPU_LBRANCH, }, | ||
137 | { 0x000006C0, 0x000006CF, CPU_LBRANCH, }, | ||
138 | |||
139 | { 0x000107CC, 0x000107D3, CPU_PMC, }, | ||
140 | |||
141 | { 0xC0000080, 0xC0000080, CPU_FEATURES, }, | ||
142 | { 0xC0000081, 0xC0000084, CPU_CALL, }, | ||
143 | { 0xC0000100, 0xC0000102, CPU_BASE, }, | ||
144 | { 0xC0000103, 0xC0000103, CPU_TIME, }, | ||
145 | |||
146 | { 0xC0010000, 0xC0010007, CPU_PMC, }, | ||
147 | { 0xC0010010, 0xC0010010, CPU_CONF, }, | ||
148 | { 0xC0010015, 0xC0010015, CPU_CONF, }, | ||
149 | { 0xC0010016, 0xC001001A, CPU_MTRR, }, | ||
150 | { 0xC001001D, 0xC001001D, CPU_MTRR, }, | ||
151 | { 0xC001001F, 0xC001001F, CPU_CONF, }, | ||
152 | { 0xC0010030, 0xC0010035, CPU_BIOS, }, | ||
153 | { 0xC0010044, 0xC0010048, CPU_MC, }, | ||
154 | { 0xC0010050, 0xC0010056, CPU_SMM, }, | ||
155 | { 0xC0010058, 0xC0010058, CPU_CONF, }, | ||
156 | { 0xC0010060, 0xC0010060, CPU_CACHE, }, | ||
157 | { 0xC0010061, 0xC0010068, CPU_SMM, }, | ||
158 | { 0xC0010069, 0xC001006B, CPU_SMM, }, | ||
159 | { 0xC0010070, 0xC0010071, CPU_SMM, }, | ||
160 | { 0xC0010111, 0xC0010113, CPU_SMM, }, | ||
161 | { 0xC0010114, 0xC0010118, CPU_SVM, }, | ||
162 | { 0xC0010140, 0xC0010141, CPU_OSVM, }, | ||
163 | { 0xC0011022, 0xC0011023, CPU_CONF, }, | ||
164 | }; | ||
165 | |||
166 | static int is_typeflag_valid(unsigned cpu, unsigned flag) | ||
167 | { | ||
168 | int i; | ||
169 | |||
170 | /* Standard Registers should be always valid */ | ||
171 | if (flag >= CPU_TSS) | ||
172 | return 1; | ||
173 | |||
174 | for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) { | ||
175 | if (cpu_reg_range[i].flag == flag) | ||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | /* Invalid */ | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static unsigned get_cpu_range(unsigned cpu, unsigned *min, unsigned *max, | ||
184 | int index, unsigned flag) | ||
185 | { | ||
186 | if (cpu_reg_range[index].flag == flag) { | ||
187 | *min = cpu_reg_range[index].min; | ||
188 | *max = cpu_reg_range[index].max; | ||
189 | } else | ||
190 | *max = 0; | ||
191 | |||
192 | return *max; | ||
193 | } | ||
194 | |||
195 | /* This function can also be called with seq = NULL for printk */ | ||
196 | static void print_cpu_data(struct seq_file *seq, unsigned type, | ||
197 | u32 low, u32 high) | ||
198 | { | ||
199 | struct cpu_private *priv; | ||
200 | u64 val = high; | ||
201 | |||
202 | if (seq) { | ||
203 | priv = seq->private; | ||
204 | if (priv->file) { | ||
205 | val = (val << 32) | low; | ||
206 | seq_printf(seq, "0x%llx\n", val); | ||
207 | } else | ||
208 | seq_printf(seq, " %08x: %08x_%08x\n", | ||
209 | type, high, low); | ||
210 | } else | ||
211 | printk(KERN_INFO " %08x: %08x_%08x\n", type, high, low); | ||
212 | } | ||
213 | |||
214 | /* This function can also be called with seq = NULL for printk */ | ||
215 | static void print_msr(struct seq_file *seq, unsigned cpu, unsigned flag) | ||
216 | { | ||
217 | unsigned msr, msr_min, msr_max; | ||
218 | struct cpu_private *priv; | ||
219 | u32 low, high; | ||
220 | int i; | ||
221 | |||
222 | if (seq) { | ||
223 | priv = seq->private; | ||
224 | if (priv->file) { | ||
225 | if (!rdmsr_safe_on_cpu(priv->cpu, priv->reg, | ||
226 | &low, &high)) | ||
227 | print_cpu_data(seq, priv->reg, low, high); | ||
228 | return; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) { | ||
233 | if (!get_cpu_range(cpu, &msr_min, &msr_max, i, flag)) | ||
234 | continue; | ||
235 | |||
236 | for (msr = msr_min; msr <= msr_max; msr++) { | ||
237 | if (rdmsr_safe_on_cpu(cpu, msr, &low, &high)) | ||
238 | continue; | ||
239 | print_cpu_data(seq, msr, low, high); | ||
240 | } | ||
241 | } | ||
242 | } | ||
243 | |||
244 | static void print_tss(void *arg) | ||
245 | { | ||
246 | struct pt_regs *regs = task_pt_regs(current); | ||
247 | struct seq_file *seq = arg; | ||
248 | unsigned int seg; | ||
249 | |||
250 | seq_printf(seq, " RAX\t: %016lx\n", regs->ax); | ||
251 | seq_printf(seq, " RBX\t: %016lx\n", regs->bx); | ||
252 | seq_printf(seq, " RCX\t: %016lx\n", regs->cx); | ||
253 | seq_printf(seq, " RDX\t: %016lx\n", regs->dx); | ||
254 | |||
255 | seq_printf(seq, " RSI\t: %016lx\n", regs->si); | ||
256 | seq_printf(seq, " RDI\t: %016lx\n", regs->di); | ||
257 | seq_printf(seq, " RBP\t: %016lx\n", regs->bp); | ||
258 | seq_printf(seq, " ESP\t: %016lx\n", regs->sp); | ||
259 | |||
260 | #ifdef CONFIG_X86_64 | ||
261 | seq_printf(seq, " R08\t: %016lx\n", regs->r8); | ||
262 | seq_printf(seq, " R09\t: %016lx\n", regs->r9); | ||
263 | seq_printf(seq, " R10\t: %016lx\n", regs->r10); | ||
264 | seq_printf(seq, " R11\t: %016lx\n", regs->r11); | ||
265 | seq_printf(seq, " R12\t: %016lx\n", regs->r12); | ||
266 | seq_printf(seq, " R13\t: %016lx\n", regs->r13); | ||
267 | seq_printf(seq, " R14\t: %016lx\n", regs->r14); | ||
268 | seq_printf(seq, " R15\t: %016lx\n", regs->r15); | ||
269 | #endif | ||
270 | |||
271 | asm("movl %%cs,%0" : "=r" (seg)); | ||
272 | seq_printf(seq, " CS\t: %04x\n", seg); | ||
273 | asm("movl %%ds,%0" : "=r" (seg)); | ||
274 | seq_printf(seq, " DS\t: %04x\n", seg); | ||
275 | seq_printf(seq, " SS\t: %04lx\n", regs->ss & 0xffff); | ||
276 | asm("movl %%es,%0" : "=r" (seg)); | ||
277 | seq_printf(seq, " ES\t: %04x\n", seg); | ||
278 | asm("movl %%fs,%0" : "=r" (seg)); | ||
279 | seq_printf(seq, " FS\t: %04x\n", seg); | ||
280 | asm("movl %%gs,%0" : "=r" (seg)); | ||
281 | seq_printf(seq, " GS\t: %04x\n", seg); | ||
282 | |||
283 | seq_printf(seq, " EFLAGS\t: %016lx\n", regs->flags); | ||
284 | |||
285 | seq_printf(seq, " EIP\t: %016lx\n", regs->ip); | ||
286 | } | ||
287 | |||
288 | static void print_cr(void *arg) | ||
289 | { | ||
290 | struct seq_file *seq = arg; | ||
291 | |||
292 | seq_printf(seq, " cr0\t: %016lx\n", read_cr0()); | ||
293 | seq_printf(seq, " cr2\t: %016lx\n", read_cr2()); | ||
294 | seq_printf(seq, " cr3\t: %016lx\n", read_cr3()); | ||
295 | seq_printf(seq, " cr4\t: %016lx\n", read_cr4_safe()); | ||
296 | #ifdef CONFIG_X86_64 | ||
297 | seq_printf(seq, " cr8\t: %016lx\n", read_cr8()); | ||
298 | #endif | ||
299 | } | ||
300 | |||
301 | static void print_desc_ptr(char *str, struct seq_file *seq, struct desc_ptr dt) | ||
302 | { | ||
303 | seq_printf(seq, " %s\t: %016llx\n", str, (u64)(dt.address | dt.size)); | ||
304 | } | ||
305 | |||
306 | static void print_dt(void *seq) | ||
307 | { | ||
308 | struct desc_ptr dt; | ||
309 | unsigned long ldt; | ||
310 | |||
311 | /* IDT */ | ||
312 | store_idt((struct desc_ptr *)&dt); | ||
313 | print_desc_ptr("IDT", seq, dt); | ||
314 | |||
315 | /* GDT */ | ||
316 | store_gdt((struct desc_ptr *)&dt); | ||
317 | print_desc_ptr("GDT", seq, dt); | ||
318 | |||
319 | /* LDT */ | ||
320 | store_ldt(ldt); | ||
321 | seq_printf(seq, " LDT\t: %016lx\n", ldt); | ||
322 | |||
323 | /* TR */ | ||
324 | store_tr(ldt); | ||
325 | seq_printf(seq, " TR\t: %016lx\n", ldt); | ||
326 | } | ||
327 | |||
328 | static void print_dr(void *arg) | ||
329 | { | ||
330 | struct seq_file *seq = arg; | ||
331 | unsigned long dr; | ||
332 | int i; | ||
333 | |||
334 | for (i = 0; i < 8; i++) { | ||
335 | /* Ignore db4, db5 */ | ||
336 | if ((i == 4) || (i == 5)) | ||
337 | continue; | ||
338 | get_debugreg(dr, i); | ||
339 | seq_printf(seq, " dr%d\t: %016lx\n", i, dr); | ||
340 | } | ||
341 | |||
342 | seq_printf(seq, "\n MSR\t:\n"); | ||
343 | } | ||
344 | |||
345 | static void print_apic(void *arg) | ||
346 | { | ||
347 | struct seq_file *seq = arg; | ||
348 | |||
349 | #ifdef CONFIG_X86_LOCAL_APIC | ||
350 | seq_printf(seq, " LAPIC\t:\n"); | ||
351 | seq_printf(seq, " ID\t\t: %08x\n", apic_read(APIC_ID) >> 24); | ||
352 | seq_printf(seq, " LVR\t\t: %08x\n", apic_read(APIC_LVR)); | ||
353 | seq_printf(seq, " TASKPRI\t: %08x\n", apic_read(APIC_TASKPRI)); | ||
354 | seq_printf(seq, " ARBPRI\t\t: %08x\n", apic_read(APIC_ARBPRI)); | ||
355 | seq_printf(seq, " PROCPRI\t: %08x\n", apic_read(APIC_PROCPRI)); | ||
356 | seq_printf(seq, " LDR\t\t: %08x\n", apic_read(APIC_LDR)); | ||
357 | seq_printf(seq, " DFR\t\t: %08x\n", apic_read(APIC_DFR)); | ||
358 | seq_printf(seq, " SPIV\t\t: %08x\n", apic_read(APIC_SPIV)); | ||
359 | seq_printf(seq, " ISR\t\t: %08x\n", apic_read(APIC_ISR)); | ||
360 | seq_printf(seq, " ESR\t\t: %08x\n", apic_read(APIC_ESR)); | ||
361 | seq_printf(seq, " ICR\t\t: %08x\n", apic_read(APIC_ICR)); | ||
362 | seq_printf(seq, " ICR2\t\t: %08x\n", apic_read(APIC_ICR2)); | ||
363 | seq_printf(seq, " LVTT\t\t: %08x\n", apic_read(APIC_LVTT)); | ||
364 | seq_printf(seq, " LVTTHMR\t: %08x\n", apic_read(APIC_LVTTHMR)); | ||
365 | seq_printf(seq, " LVTPC\t\t: %08x\n", apic_read(APIC_LVTPC)); | ||
366 | seq_printf(seq, " LVT0\t\t: %08x\n", apic_read(APIC_LVT0)); | ||
367 | seq_printf(seq, " LVT1\t\t: %08x\n", apic_read(APIC_LVT1)); | ||
368 | seq_printf(seq, " LVTERR\t\t: %08x\n", apic_read(APIC_LVTERR)); | ||
369 | seq_printf(seq, " TMICT\t\t: %08x\n", apic_read(APIC_TMICT)); | ||
370 | seq_printf(seq, " TMCCT\t\t: %08x\n", apic_read(APIC_TMCCT)); | ||
371 | seq_printf(seq, " TDCR\t\t: %08x\n", apic_read(APIC_TDCR)); | ||
372 | if (boot_cpu_has(X86_FEATURE_EXTAPIC)) { | ||
373 | unsigned int i, v, maxeilvt; | ||
374 | |||
375 | v = apic_read(APIC_EFEAT); | ||
376 | maxeilvt = (v >> 16) & 0xff; | ||
377 | seq_printf(seq, " EFEAT\t\t: %08x\n", v); | ||
378 | seq_printf(seq, " ECTRL\t\t: %08x\n", apic_read(APIC_ECTRL)); | ||
379 | |||
380 | for (i = 0; i < maxeilvt; i++) { | ||
381 | v = apic_read(APIC_EILVTn(i)); | ||
382 | seq_printf(seq, " EILVT%d\t\t: %08x\n", i, v); | ||
383 | } | ||
384 | } | ||
385 | #endif /* CONFIG_X86_LOCAL_APIC */ | ||
386 | seq_printf(seq, "\n MSR\t:\n"); | ||
387 | } | ||
388 | |||
389 | static int cpu_seq_show(struct seq_file *seq, void *v) | ||
390 | { | ||
391 | struct cpu_private *priv = seq->private; | ||
392 | |||
393 | if (priv == NULL) | ||
394 | return -EINVAL; | ||
395 | |||
396 | switch (cpu_base[priv->type].flag) { | ||
397 | case CPU_TSS: | ||
398 | smp_call_function_single(priv->cpu, print_tss, seq, 1); | ||
399 | break; | ||
400 | case CPU_CR: | ||
401 | smp_call_function_single(priv->cpu, print_cr, seq, 1); | ||
402 | break; | ||
403 | case CPU_DT: | ||
404 | smp_call_function_single(priv->cpu, print_dt, seq, 1); | ||
405 | break; | ||
406 | case CPU_DEBUG: | ||
407 | if (priv->file == CPU_INDEX_BIT) | ||
408 | smp_call_function_single(priv->cpu, print_dr, seq, 1); | ||
409 | print_msr(seq, priv->cpu, cpu_base[priv->type].flag); | ||
410 | break; | ||
411 | case CPU_APIC: | ||
412 | if (priv->file == CPU_INDEX_BIT) | ||
413 | smp_call_function_single(priv->cpu, print_apic, seq, 1); | ||
414 | print_msr(seq, priv->cpu, cpu_base[priv->type].flag); | ||
415 | break; | ||
416 | |||
417 | default: | ||
418 | print_msr(seq, priv->cpu, cpu_base[priv->type].flag); | ||
419 | break; | ||
420 | } | ||
421 | seq_printf(seq, "\n"); | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static void *cpu_seq_start(struct seq_file *seq, loff_t *pos) | ||
427 | { | ||
428 | if (*pos == 0) /* One time is enough ;-) */ | ||
429 | return seq; | ||
430 | |||
431 | return NULL; | ||
432 | } | ||
433 | |||
434 | static void *cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
435 | { | ||
436 | (*pos)++; | ||
437 | |||
438 | return cpu_seq_start(seq, pos); | ||
439 | } | ||
440 | |||
441 | static void cpu_seq_stop(struct seq_file *seq, void *v) | ||
442 | { | ||
443 | } | ||
444 | |||
445 | static const struct seq_operations cpu_seq_ops = { | ||
446 | .start = cpu_seq_start, | ||
447 | .next = cpu_seq_next, | ||
448 | .stop = cpu_seq_stop, | ||
449 | .show = cpu_seq_show, | ||
450 | }; | ||
451 | |||
452 | static int cpu_seq_open(struct inode *inode, struct file *file) | ||
453 | { | ||
454 | struct cpu_private *priv = inode->i_private; | ||
455 | struct seq_file *seq; | ||
456 | int err; | ||
457 | |||
458 | err = seq_open(file, &cpu_seq_ops); | ||
459 | if (!err) { | ||
460 | seq = file->private_data; | ||
461 | seq->private = priv; | ||
462 | } | ||
463 | |||
464 | return err; | ||
465 | } | ||
466 | |||
467 | static int write_msr(struct cpu_private *priv, u64 val) | ||
468 | { | ||
469 | u32 low, high; | ||
470 | |||
471 | high = (val >> 32) & 0xffffffff; | ||
472 | low = val & 0xffffffff; | ||
473 | |||
474 | if (!wrmsr_safe_on_cpu(priv->cpu, priv->reg, low, high)) | ||
475 | return 0; | ||
476 | |||
477 | return -EPERM; | ||
478 | } | ||
479 | |||
480 | static int write_cpu_register(struct cpu_private *priv, const char *buf) | ||
481 | { | ||
482 | int ret = -EPERM; | ||
483 | u64 val; | ||
484 | |||
485 | ret = strict_strtoull(buf, 0, &val); | ||
486 | if (ret < 0) | ||
487 | return ret; | ||
488 | |||
489 | /* Supporting only MSRs */ | ||
490 | if (priv->type < CPU_TSS_BIT) | ||
491 | return write_msr(priv, val); | ||
492 | |||
493 | return ret; | ||
494 | } | ||
495 | |||
496 | static ssize_t cpu_write(struct file *file, const char __user *ubuf, | ||
497 | size_t count, loff_t *off) | ||
498 | { | ||
499 | struct seq_file *seq = file->private_data; | ||
500 | struct cpu_private *priv = seq->private; | ||
501 | char buf[19]; | ||
502 | |||
503 | if ((priv == NULL) || (count >= sizeof(buf))) | ||
504 | return -EINVAL; | ||
505 | |||
506 | if (copy_from_user(&buf, ubuf, count)) | ||
507 | return -EFAULT; | ||
508 | |||
509 | buf[count] = 0; | ||
510 | |||
511 | if ((cpu_base[priv->type].write) && (cpu_file[priv->file].write)) | ||
512 | if (!write_cpu_register(priv, buf)) | ||
513 | return count; | ||
514 | |||
515 | return -EACCES; | ||
516 | } | ||
517 | |||
518 | static const struct file_operations cpu_fops = { | ||
519 | .owner = THIS_MODULE, | ||
520 | .open = cpu_seq_open, | ||
521 | .read = seq_read, | ||
522 | .write = cpu_write, | ||
523 | .llseek = seq_lseek, | ||
524 | .release = seq_release, | ||
525 | }; | ||
526 | |||
527 | static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg, | ||
528 | unsigned file, struct dentry *dentry) | ||
529 | { | ||
530 | struct cpu_private *priv = NULL; | ||
531 | |||
532 | /* Already intialized */ | ||
533 | if (file == CPU_INDEX_BIT) | ||
534 | if (per_cpu(cpud_arr[type].init, cpu)) | ||
535 | return 0; | ||
536 | |||
537 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
538 | if (priv == NULL) | ||
539 | return -ENOMEM; | ||
540 | |||
541 | priv->cpu = cpu; | ||
542 | priv->type = type; | ||
543 | priv->reg = reg; | ||
544 | priv->file = file; | ||
545 | mutex_lock(&cpu_debug_lock); | ||
546 | per_cpu(cpud_priv_arr[type], cpu) = priv; | ||
547 | per_cpu(cpud_priv_count, cpu)++; | ||
548 | mutex_unlock(&cpu_debug_lock); | ||
549 | |||
550 | if (file) | ||
551 | debugfs_create_file(cpu_file[file].name, S_IRUGO, | ||
552 | dentry, (void *)priv, &cpu_fops); | ||
553 | else { | ||
554 | debugfs_create_file(cpu_base[type].name, S_IRUGO, | ||
555 | per_cpu(cpud_arr[type].dentry, cpu), | ||
556 | (void *)priv, &cpu_fops); | ||
557 | mutex_lock(&cpu_debug_lock); | ||
558 | per_cpu(cpud_arr[type].init, cpu) = 1; | ||
559 | mutex_unlock(&cpu_debug_lock); | ||
560 | } | ||
561 | |||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg, | ||
566 | struct dentry *dentry) | ||
567 | { | ||
568 | unsigned file; | ||
569 | int err = 0; | ||
570 | |||
571 | for (file = 0; file < ARRAY_SIZE(cpu_file); file++) { | ||
572 | err = cpu_create_file(cpu, type, reg, file, dentry); | ||
573 | if (err) | ||
574 | return err; | ||
575 | } | ||
576 | |||
577 | return err; | ||
578 | } | ||
579 | |||
580 | static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry) | ||
581 | { | ||
582 | struct dentry *cpu_dentry = NULL; | ||
583 | unsigned reg, reg_min, reg_max; | ||
584 | int i, err = 0; | ||
585 | char reg_dir[12]; | ||
586 | u32 low, high; | ||
587 | |||
588 | for (i = 0; i < ARRAY_SIZE(cpu_reg_range); i++) { | ||
589 | if (!get_cpu_range(cpu, ®_min, ®_max, i, | ||
590 | cpu_base[type].flag)) | ||
591 | continue; | ||
592 | |||
593 | for (reg = reg_min; reg <= reg_max; reg++) { | ||
594 | if (rdmsr_safe_on_cpu(cpu, reg, &low, &high)) | ||
595 | continue; | ||
596 | |||
597 | sprintf(reg_dir, "0x%x", reg); | ||
598 | cpu_dentry = debugfs_create_dir(reg_dir, dentry); | ||
599 | err = cpu_init_regfiles(cpu, type, reg, cpu_dentry); | ||
600 | if (err) | ||
601 | return err; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | return err; | ||
606 | } | ||
607 | |||
608 | static int cpu_init_allreg(unsigned cpu, struct dentry *dentry) | ||
609 | { | ||
610 | struct dentry *cpu_dentry = NULL; | ||
611 | unsigned type; | ||
612 | int err = 0; | ||
613 | |||
614 | for (type = 0; type < ARRAY_SIZE(cpu_base) - 1; type++) { | ||
615 | if (!is_typeflag_valid(cpu, cpu_base[type].flag)) | ||
616 | continue; | ||
617 | cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry); | ||
618 | per_cpu(cpud_arr[type].dentry, cpu) = cpu_dentry; | ||
619 | |||
620 | if (type < CPU_TSS_BIT) | ||
621 | err = cpu_init_msr(cpu, type, cpu_dentry); | ||
622 | else | ||
623 | err = cpu_create_file(cpu, type, 0, CPU_INDEX_BIT, | ||
624 | cpu_dentry); | ||
625 | if (err) | ||
626 | return err; | ||
627 | } | ||
628 | |||
629 | return err; | ||
630 | } | ||
631 | |||
632 | static int cpu_init_cpu(void) | ||
633 | { | ||
634 | struct dentry *cpu_dentry = NULL; | ||
635 | struct cpuinfo_x86 *cpui; | ||
636 | char cpu_dir[12]; | ||
637 | unsigned cpu; | ||
638 | int err = 0; | ||
639 | |||
640 | for (cpu = 0; cpu < nr_cpu_ids; cpu++) { | ||
641 | cpui = &cpu_data(cpu); | ||
642 | if (!cpu_has(cpui, X86_FEATURE_MSR)) | ||
643 | continue; | ||
644 | |||
645 | sprintf(cpu_dir, "cpu%d", cpu); | ||
646 | cpu_dentry = debugfs_create_dir(cpu_dir, cpu_debugfs_dir); | ||
647 | err = cpu_init_allreg(cpu, cpu_dentry); | ||
648 | |||
649 | pr_info("cpu%d(%d) debug files %d\n", | ||
650 | cpu, nr_cpu_ids, per_cpu(cpud_priv_count, cpu)); | ||
651 | if (per_cpu(cpud_priv_count, cpu) > MAX_CPU_FILES) { | ||
652 | pr_err("Register files count %d exceeds limit %d\n", | ||
653 | per_cpu(cpud_priv_count, cpu), MAX_CPU_FILES); | ||
654 | per_cpu(cpud_priv_count, cpu) = MAX_CPU_FILES; | ||
655 | err = -ENFILE; | ||
656 | } | ||
657 | if (err) | ||
658 | return err; | ||
659 | } | ||
660 | |||
661 | return err; | ||
662 | } | ||
663 | |||
664 | static int __init cpu_debug_init(void) | ||
665 | { | ||
666 | cpu_debugfs_dir = debugfs_create_dir("cpu", arch_debugfs_dir); | ||
667 | |||
668 | return cpu_init_cpu(); | ||
669 | } | ||
670 | |||
671 | static void __exit cpu_debug_exit(void) | ||
672 | { | ||
673 | int i, cpu; | ||
674 | |||
675 | if (cpu_debugfs_dir) | ||
676 | debugfs_remove_recursive(cpu_debugfs_dir); | ||
677 | |||
678 | for (cpu = 0; cpu < nr_cpu_ids; cpu++) | ||
679 | for (i = 0; i < per_cpu(cpud_priv_count, cpu); i++) | ||
680 | kfree(per_cpu(cpud_priv_arr[i], cpu)); | ||
681 | } | ||
682 | |||
683 | module_init(cpu_debug_init); | ||
684 | module_exit(cpu_debug_exit); | ||
685 | |||
686 | MODULE_AUTHOR("Jaswinder Singh Rajput"); | ||
687 | MODULE_DESCRIPTION("CPU Debug module"); | ||
688 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index cb27fd6136c9..83e5e628de73 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c | |||
@@ -229,7 +229,7 @@ static void __exit cpuid_exit(void) | |||
229 | for_each_online_cpu(cpu) | 229 | for_each_online_cpu(cpu) |
230 | cpuid_device_destroy(cpu); | 230 | cpuid_device_destroy(cpu); |
231 | class_destroy(cpuid_class); | 231 | class_destroy(cpuid_class); |
232 | unregister_chrdev(CPUID_MAJOR, "cpu/cpuid"); | 232 | __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid"); |
233 | unregister_hotcpu_notifier(&cpuid_class_cpu_notifier); | 233 | unregister_hotcpu_notifier(&cpuid_class_cpu_notifier); |
234 | } | 234 | } |
235 | 235 | ||
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index ba6e65884603..ad80a1c718c6 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -34,6 +34,8 @@ | |||
34 | */ | 34 | */ |
35 | unsigned long hpet_address; | 35 | unsigned long hpet_address; |
36 | u8 hpet_blockid; /* OS timer block num */ | 36 | u8 hpet_blockid; /* OS timer block num */ |
37 | u8 hpet_msi_disable; | ||
38 | |||
37 | #ifdef CONFIG_PCI_MSI | 39 | #ifdef CONFIG_PCI_MSI |
38 | static unsigned long hpet_num_timers; | 40 | static unsigned long hpet_num_timers; |
39 | #endif | 41 | #endif |
@@ -596,6 +598,9 @@ static void hpet_msi_capability_lookup(unsigned int start_timer) | |||
596 | unsigned int num_timers_used = 0; | 598 | unsigned int num_timers_used = 0; |
597 | int i; | 599 | int i; |
598 | 600 | ||
601 | if (hpet_msi_disable) | ||
602 | return; | ||
603 | |||
599 | if (boot_cpu_has(X86_FEATURE_ARAT)) | 604 | if (boot_cpu_has(X86_FEATURE_ARAT)) |
600 | return; | 605 | return; |
601 | id = hpet_readl(HPET_ID); | 606 | id = hpet_readl(HPET_ID); |
@@ -928,6 +933,9 @@ static __init int hpet_late_init(void) | |||
928 | hpet_reserve_platform_timers(hpet_readl(HPET_ID)); | 933 | hpet_reserve_platform_timers(hpet_readl(HPET_ID)); |
929 | hpet_print_config(); | 934 | hpet_print_config(); |
930 | 935 | ||
936 | if (hpet_msi_disable) | ||
937 | return 0; | ||
938 | |||
931 | if (boot_cpu_has(X86_FEATURE_ARAT)) | 939 | if (boot_cpu_has(X86_FEATURE_ARAT)) |
932 | return 0; | 940 | return 0; |
933 | 941 | ||
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 37542b67c57e..e1af7c055c7d 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
@@ -36,9 +36,6 @@ MODULE_LICENSE("GPL v2"); | |||
36 | #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 | 36 | #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 |
37 | #define UCODE_UCODE_TYPE 0x00000001 | 37 | #define UCODE_UCODE_TYPE 0x00000001 |
38 | 38 | ||
39 | const struct firmware *firmware; | ||
40 | static int supported_cpu; | ||
41 | |||
42 | struct equiv_cpu_entry { | 39 | struct equiv_cpu_entry { |
43 | u32 installed_cpu; | 40 | u32 installed_cpu; |
44 | u32 fixed_errata_mask; | 41 | u32 fixed_errata_mask; |
@@ -77,12 +74,15 @@ static struct equiv_cpu_entry *equiv_cpu_table; | |||
77 | 74 | ||
78 | static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) | 75 | static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) |
79 | { | 76 | { |
77 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
80 | u32 dummy; | 78 | u32 dummy; |
81 | 79 | ||
82 | if (!supported_cpu) | ||
83 | return -1; | ||
84 | |||
85 | memset(csig, 0, sizeof(*csig)); | 80 | memset(csig, 0, sizeof(*csig)); |
81 | if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { | ||
82 | pr_warning("microcode: CPU%d: AMD CPU family 0x%x not " | ||
83 | "supported\n", cpu, c->x86); | ||
84 | return -1; | ||
85 | } | ||
86 | rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy); | 86 | rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy); |
87 | pr_info("CPU%d: patch_level=0x%x\n", cpu, csig->rev); | 87 | pr_info("CPU%d: patch_level=0x%x\n", cpu, csig->rev); |
88 | return 0; | 88 | return 0; |
@@ -294,10 +294,14 @@ generic_load_microcode(int cpu, const u8 *data, size_t size) | |||
294 | 294 | ||
295 | static enum ucode_state request_microcode_fw(int cpu, struct device *device) | 295 | static enum ucode_state request_microcode_fw(int cpu, struct device *device) |
296 | { | 296 | { |
297 | const char *fw_name = "amd-ucode/microcode_amd.bin"; | ||
298 | const struct firmware *firmware; | ||
297 | enum ucode_state ret; | 299 | enum ucode_state ret; |
298 | 300 | ||
299 | if (firmware == NULL) | 301 | if (request_firmware(&firmware, fw_name, device)) { |
302 | printk(KERN_ERR "microcode: failed to load file %s\n", fw_name); | ||
300 | return UCODE_NFOUND; | 303 | return UCODE_NFOUND; |
304 | } | ||
301 | 305 | ||
302 | if (*(u32 *)firmware->data != UCODE_MAGIC) { | 306 | if (*(u32 *)firmware->data != UCODE_MAGIC) { |
303 | pr_err("invalid UCODE_MAGIC (0x%08x)\n", | 307 | pr_err("invalid UCODE_MAGIC (0x%08x)\n", |
@@ -307,6 +311,8 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) | |||
307 | 311 | ||
308 | ret = generic_load_microcode(cpu, firmware->data, firmware->size); | 312 | ret = generic_load_microcode(cpu, firmware->data, firmware->size); |
309 | 313 | ||
314 | release_firmware(firmware); | ||
315 | |||
310 | return ret; | 316 | return ret; |
311 | } | 317 | } |
312 | 318 | ||
@@ -325,31 +331,7 @@ static void microcode_fini_cpu_amd(int cpu) | |||
325 | uci->mc = NULL; | 331 | uci->mc = NULL; |
326 | } | 332 | } |
327 | 333 | ||
328 | void init_microcode_amd(struct device *device) | ||
329 | { | ||
330 | const char *fw_name = "amd-ucode/microcode_amd.bin"; | ||
331 | struct cpuinfo_x86 *c = &boot_cpu_data; | ||
332 | |||
333 | WARN_ON(c->x86_vendor != X86_VENDOR_AMD); | ||
334 | |||
335 | if (c->x86 < 0x10) { | ||
336 | pr_warning("AMD CPU family 0x%x not supported\n", c->x86); | ||
337 | return; | ||
338 | } | ||
339 | supported_cpu = 1; | ||
340 | |||
341 | if (request_firmware(&firmware, fw_name, device)) | ||
342 | pr_err("failed to load file %s\n", fw_name); | ||
343 | } | ||
344 | |||
345 | void fini_microcode_amd(void) | ||
346 | { | ||
347 | release_firmware(firmware); | ||
348 | } | ||
349 | |||
350 | static struct microcode_ops microcode_amd_ops = { | 334 | static struct microcode_ops microcode_amd_ops = { |
351 | .init = init_microcode_amd, | ||
352 | .fini = fini_microcode_amd, | ||
353 | .request_microcode_user = request_microcode_user, | 335 | .request_microcode_user = request_microcode_user, |
354 | .request_microcode_fw = request_microcode_fw, | 336 | .request_microcode_fw = request_microcode_fw, |
355 | .collect_cpu_info = collect_cpu_info_amd, | 337 | .collect_cpu_info = collect_cpu_info_amd, |
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index 0c8632433090..cceb5bc3c3c2 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c | |||
@@ -521,9 +521,6 @@ static int __init microcode_init(void) | |||
521 | return PTR_ERR(microcode_pdev); | 521 | return PTR_ERR(microcode_pdev); |
522 | } | 522 | } |
523 | 523 | ||
524 | if (microcode_ops->init) | ||
525 | microcode_ops->init(µcode_pdev->dev); | ||
526 | |||
527 | get_online_cpus(); | 524 | get_online_cpus(); |
528 | mutex_lock(µcode_mutex); | 525 | mutex_lock(µcode_mutex); |
529 | 526 | ||
@@ -566,9 +563,6 @@ static void __exit microcode_exit(void) | |||
566 | 563 | ||
567 | platform_device_unregister(microcode_pdev); | 564 | platform_device_unregister(microcode_pdev); |
568 | 565 | ||
569 | if (microcode_ops->fini) | ||
570 | microcode_ops->fini(); | ||
571 | |||
572 | microcode_ops = NULL; | 566 | microcode_ops = NULL; |
573 | 567 | ||
574 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION " removed.\n"); | 568 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION " removed.\n"); |
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 4bd93c9b2b27..206735ac8cbd 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c | |||
@@ -285,7 +285,7 @@ static void __exit msr_exit(void) | |||
285 | for_each_online_cpu(cpu) | 285 | for_each_online_cpu(cpu) |
286 | msr_device_destroy(cpu); | 286 | msr_device_destroy(cpu); |
287 | class_destroy(msr_class); | 287 | class_destroy(msr_class); |
288 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); | 288 | __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr"); |
289 | unregister_hotcpu_notifier(&msr_class_cpu_notifier); | 289 | unregister_hotcpu_notifier(&msr_class_cpu_notifier); |
290 | } | 290 | } |
291 | 291 | ||
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 18093d7498f0..12e9feaa2f7a 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c | |||
@@ -491,6 +491,19 @@ void force_hpet_resume(void) | |||
491 | break; | 491 | break; |
492 | } | 492 | } |
493 | } | 493 | } |
494 | |||
495 | /* | ||
496 | * HPET MSI on some boards (ATI SB700/SB800) has side effect on | ||
497 | * floppy DMA. Disable HPET MSI on such platforms. | ||
498 | */ | ||
499 | static void force_disable_hpet_msi(struct pci_dev *unused) | ||
500 | { | ||
501 | hpet_msi_disable = 1; | ||
502 | } | ||
503 | |||
504 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, | ||
505 | force_disable_hpet_msi); | ||
506 | |||
494 | #endif | 507 | #endif |
495 | 508 | ||
496 | #if defined(CONFIG_PCI) && defined(CONFIG_NUMA) | 509 | #if defined(CONFIG_PCI) && defined(CONFIG_NUMA) |
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index a27124185fc1..28c68762648f 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -229,9 +229,11 @@ update_nodes_add(int node, unsigned long start, unsigned long end) | |||
229 | printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); | 229 | printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); |
230 | } | 230 | } |
231 | 231 | ||
232 | if (changed) | 232 | if (changed) { |
233 | node_set(node, cpu_nodes_parsed); | ||
233 | printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", | 234 | printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", |
234 | nd->start, nd->end); | 235 | nd->start, nd->end); |
236 | } | ||
235 | } | 237 | } |
236 | 238 | ||
237 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ | 239 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ |
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index 564b008a51c7..39fba37f702f 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile | |||
@@ -15,7 +15,7 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o | |||
15 | 15 | ||
16 | obj-y += common.o early.o | 16 | obj-y += common.o early.o |
17 | obj-y += amd_bus.o | 17 | obj-y += amd_bus.o |
18 | obj-$(CONFIG_X86_64) += bus_numa.o intel_bus.o | 18 | obj-$(CONFIG_X86_64) += bus_numa.o |
19 | 19 | ||
20 | ifeq ($(CONFIG_PCI_DEBUG),y) | 20 | ifeq ($(CONFIG_PCI_DEBUG),y) |
21 | EXTRA_CFLAGS += -DDEBUG | 21 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c deleted file mode 100644 index f81a2fa8fe25..000000000000 --- a/arch/x86/pci/intel_bus.c +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | /* | ||
2 | * to read io range from IOH pci conf, need to do it after mmconfig is there | ||
3 | */ | ||
4 | |||
5 | #include <linux/delay.h> | ||
6 | #include <linux/dmi.h> | ||
7 | #include <linux/pci.h> | ||
8 | #include <linux/init.h> | ||
9 | #include <asm/pci_x86.h> | ||
10 | |||
11 | #include "bus_numa.h" | ||
12 | |||
13 | static inline void print_ioh_resources(struct pci_root_info *info) | ||
14 | { | ||
15 | int res_num; | ||
16 | int busnum; | ||
17 | int i; | ||
18 | |||
19 | printk(KERN_DEBUG "IOH bus: [%02x, %02x]\n", | ||
20 | info->bus_min, info->bus_max); | ||
21 | res_num = info->res_num; | ||
22 | busnum = info->bus_min; | ||
23 | for (i = 0; i < res_num; i++) { | ||
24 | struct resource *res; | ||
25 | |||
26 | res = &info->res[i]; | ||
27 | printk(KERN_DEBUG "IOH bus: %02x index %x %s: [%llx, %llx]\n", | ||
28 | busnum, i, | ||
29 | (res->flags & IORESOURCE_IO) ? "io port" : | ||
30 | "mmio", | ||
31 | res->start, res->end); | ||
32 | } | ||
33 | } | ||
34 | |||
35 | #define IOH_LIO 0x108 | ||
36 | #define IOH_LMMIOL 0x10c | ||
37 | #define IOH_LMMIOH 0x110 | ||
38 | #define IOH_LMMIOH_BASEU 0x114 | ||
39 | #define IOH_LMMIOH_LIMITU 0x118 | ||
40 | #define IOH_LCFGBUS 0x11c | ||
41 | |||
42 | static void __devinit pci_root_bus_res(struct pci_dev *dev) | ||
43 | { | ||
44 | u16 word; | ||
45 | u32 dword; | ||
46 | struct pci_root_info *info; | ||
47 | u16 io_base, io_end; | ||
48 | u32 mmiol_base, mmiol_end; | ||
49 | u64 mmioh_base, mmioh_end; | ||
50 | int bus_base, bus_end; | ||
51 | |||
52 | /* some sys doesn't get mmconf enabled */ | ||
53 | if (dev->cfg_size < 0x120) | ||
54 | return; | ||
55 | |||
56 | if (pci_root_num >= PCI_ROOT_NR) { | ||
57 | printk(KERN_DEBUG "intel_bus.c: PCI_ROOT_NR is too small\n"); | ||
58 | return; | ||
59 | } | ||
60 | |||
61 | info = &pci_root_info[pci_root_num]; | ||
62 | pci_root_num++; | ||
63 | |||
64 | pci_read_config_word(dev, IOH_LCFGBUS, &word); | ||
65 | bus_base = (word & 0xff); | ||
66 | bus_end = (word & 0xff00) >> 8; | ||
67 | sprintf(info->name, "PCI Bus #%02x", bus_base); | ||
68 | info->bus_min = bus_base; | ||
69 | info->bus_max = bus_end; | ||
70 | |||
71 | pci_read_config_word(dev, IOH_LIO, &word); | ||
72 | io_base = (word & 0xf0) << (12 - 4); | ||
73 | io_end = (word & 0xf000) | 0xfff; | ||
74 | update_res(info, io_base, io_end, IORESOURCE_IO, 0); | ||
75 | |||
76 | pci_read_config_dword(dev, IOH_LMMIOL, &dword); | ||
77 | mmiol_base = (dword & 0xff00) << (24 - 8); | ||
78 | mmiol_end = (dword & 0xff000000) | 0xffffff; | ||
79 | update_res(info, mmiol_base, mmiol_end, IORESOURCE_MEM, 0); | ||
80 | |||
81 | pci_read_config_dword(dev, IOH_LMMIOH, &dword); | ||
82 | mmioh_base = ((u64)(dword & 0xfc00)) << (26 - 10); | ||
83 | mmioh_end = ((u64)(dword & 0xfc000000) | 0x3ffffff); | ||
84 | pci_read_config_dword(dev, IOH_LMMIOH_BASEU, &dword); | ||
85 | mmioh_base |= ((u64)(dword & 0x7ffff)) << 32; | ||
86 | pci_read_config_dword(dev, IOH_LMMIOH_LIMITU, &dword); | ||
87 | mmioh_end |= ((u64)(dword & 0x7ffff)) << 32; | ||
88 | update_res(info, mmioh_base, mmioh_end, IORESOURCE_MEM, 0); | ||
89 | |||
90 | print_ioh_resources(info); | ||
91 | } | ||
92 | |||
93 | /* intel IOH */ | ||
94 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, pci_root_bus_res); | ||
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 7083bcc1b9c7..5045156c5313 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -57,6 +57,8 @@ static LIST_HEAD(descriptor_list); | |||
57 | static int descriptor_count; | 57 | static int descriptor_count; |
58 | 58 | ||
59 | static __be32 tmp_config_rom[256]; | 59 | static __be32 tmp_config_rom[256]; |
60 | /* ROM header, bus info block, root dir header, capabilities = 7 quadlets */ | ||
61 | static size_t config_rom_length = 1 + 4 + 1 + 1; | ||
60 | 62 | ||
61 | #define BIB_CRC(v) ((v) << 0) | 63 | #define BIB_CRC(v) ((v) << 0) |
62 | #define BIB_CRC_LENGTH(v) ((v) << 16) | 64 | #define BIB_CRC_LENGTH(v) ((v) << 16) |
@@ -73,7 +75,7 @@ static __be32 tmp_config_rom[256]; | |||
73 | #define BIB_CMC ((1) << 30) | 75 | #define BIB_CMC ((1) << 30) |
74 | #define BIB_IMC ((1) << 31) | 76 | #define BIB_IMC ((1) << 31) |
75 | 77 | ||
76 | static size_t generate_config_rom(struct fw_card *card, __be32 *config_rom) | 78 | static void generate_config_rom(struct fw_card *card, __be32 *config_rom) |
77 | { | 79 | { |
78 | struct fw_descriptor *desc; | 80 | struct fw_descriptor *desc; |
79 | int i, j, k, length; | 81 | int i, j, k, length; |
@@ -130,23 +132,30 @@ static size_t generate_config_rom(struct fw_card *card, __be32 *config_rom) | |||
130 | for (i = 0; i < j; i += length + 1) | 132 | for (i = 0; i < j; i += length + 1) |
131 | length = fw_compute_block_crc(config_rom + i); | 133 | length = fw_compute_block_crc(config_rom + i); |
132 | 134 | ||
133 | return j; | 135 | WARN_ON(j != config_rom_length); |
134 | } | 136 | } |
135 | 137 | ||
136 | static void update_config_roms(void) | 138 | static void update_config_roms(void) |
137 | { | 139 | { |
138 | struct fw_card *card; | 140 | struct fw_card *card; |
139 | size_t length; | ||
140 | 141 | ||
141 | list_for_each_entry (card, &card_list, link) { | 142 | list_for_each_entry (card, &card_list, link) { |
142 | length = generate_config_rom(card, tmp_config_rom); | 143 | generate_config_rom(card, tmp_config_rom); |
143 | card->driver->set_config_rom(card, tmp_config_rom, length); | 144 | card->driver->set_config_rom(card, tmp_config_rom, |
145 | config_rom_length); | ||
144 | } | 146 | } |
145 | } | 147 | } |
146 | 148 | ||
149 | static size_t required_space(struct fw_descriptor *desc) | ||
150 | { | ||
151 | /* descriptor + entry into root dir + optional immediate entry */ | ||
152 | return desc->length + 1 + (desc->immediate > 0 ? 1 : 0); | ||
153 | } | ||
154 | |||
147 | int fw_core_add_descriptor(struct fw_descriptor *desc) | 155 | int fw_core_add_descriptor(struct fw_descriptor *desc) |
148 | { | 156 | { |
149 | size_t i; | 157 | size_t i; |
158 | int ret; | ||
150 | 159 | ||
151 | /* | 160 | /* |
152 | * Check descriptor is valid; the length of all blocks in the | 161 | * Check descriptor is valid; the length of all blocks in the |
@@ -162,15 +171,21 @@ int fw_core_add_descriptor(struct fw_descriptor *desc) | |||
162 | 171 | ||
163 | mutex_lock(&card_mutex); | 172 | mutex_lock(&card_mutex); |
164 | 173 | ||
165 | list_add_tail(&desc->link, &descriptor_list); | 174 | if (config_rom_length + required_space(desc) > 256) { |
166 | descriptor_count++; | 175 | ret = -EBUSY; |
167 | if (desc->immediate > 0) | 176 | } else { |
177 | list_add_tail(&desc->link, &descriptor_list); | ||
178 | config_rom_length += required_space(desc); | ||
168 | descriptor_count++; | 179 | descriptor_count++; |
169 | update_config_roms(); | 180 | if (desc->immediate > 0) |
181 | descriptor_count++; | ||
182 | update_config_roms(); | ||
183 | ret = 0; | ||
184 | } | ||
170 | 185 | ||
171 | mutex_unlock(&card_mutex); | 186 | mutex_unlock(&card_mutex); |
172 | 187 | ||
173 | return 0; | 188 | return ret; |
174 | } | 189 | } |
175 | EXPORT_SYMBOL(fw_core_add_descriptor); | 190 | EXPORT_SYMBOL(fw_core_add_descriptor); |
176 | 191 | ||
@@ -179,6 +194,7 @@ void fw_core_remove_descriptor(struct fw_descriptor *desc) | |||
179 | mutex_lock(&card_mutex); | 194 | mutex_lock(&card_mutex); |
180 | 195 | ||
181 | list_del(&desc->link); | 196 | list_del(&desc->link); |
197 | config_rom_length -= required_space(desc); | ||
182 | descriptor_count--; | 198 | descriptor_count--; |
183 | if (desc->immediate > 0) | 199 | if (desc->immediate > 0) |
184 | descriptor_count--; | 200 | descriptor_count--; |
@@ -428,7 +444,6 @@ EXPORT_SYMBOL(fw_card_initialize); | |||
428 | int fw_card_add(struct fw_card *card, | 444 | int fw_card_add(struct fw_card *card, |
429 | u32 max_receive, u32 link_speed, u64 guid) | 445 | u32 max_receive, u32 link_speed, u64 guid) |
430 | { | 446 | { |
431 | size_t length; | ||
432 | int ret; | 447 | int ret; |
433 | 448 | ||
434 | card->max_receive = max_receive; | 449 | card->max_receive = max_receive; |
@@ -437,8 +452,8 @@ int fw_card_add(struct fw_card *card, | |||
437 | 452 | ||
438 | mutex_lock(&card_mutex); | 453 | mutex_lock(&card_mutex); |
439 | 454 | ||
440 | length = generate_config_rom(card, tmp_config_rom); | 455 | generate_config_rom(card, tmp_config_rom); |
441 | ret = card->driver->enable(card, tmp_config_rom, length); | 456 | ret = card->driver->enable(card, tmp_config_rom, config_rom_length); |
442 | if (ret == 0) | 457 | if (ret == 0) |
443 | list_add_tail(&card->link, &card_list); | 458 | list_add_tail(&card->link, &card_list); |
444 | 459 | ||
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index e6d63849e78e..4eeaed57e219 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/preempt.h> | 35 | #include <linux/preempt.h> |
36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
38 | #include <linux/string.h> | ||
38 | #include <linux/time.h> | 39 | #include <linux/time.h> |
39 | #include <linux/uaccess.h> | 40 | #include <linux/uaccess.h> |
40 | #include <linux/vmalloc.h> | 41 | #include <linux/vmalloc.h> |
@@ -595,13 +596,20 @@ static int ioctl_send_request(struct client *client, void *buffer) | |||
595 | client->device->max_speed); | 596 | client->device->max_speed); |
596 | } | 597 | } |
597 | 598 | ||
599 | static inline bool is_fcp_request(struct fw_request *request) | ||
600 | { | ||
601 | return request == NULL; | ||
602 | } | ||
603 | |||
598 | static void release_request(struct client *client, | 604 | static void release_request(struct client *client, |
599 | struct client_resource *resource) | 605 | struct client_resource *resource) |
600 | { | 606 | { |
601 | struct inbound_transaction_resource *r = container_of(resource, | 607 | struct inbound_transaction_resource *r = container_of(resource, |
602 | struct inbound_transaction_resource, resource); | 608 | struct inbound_transaction_resource, resource); |
603 | 609 | ||
604 | if (r->request) | 610 | if (is_fcp_request(r->request)) |
611 | kfree(r->data); | ||
612 | else | ||
605 | fw_send_response(client->device->card, r->request, | 613 | fw_send_response(client->device->card, r->request, |
606 | RCODE_CONFLICT_ERROR); | 614 | RCODE_CONFLICT_ERROR); |
607 | kfree(r); | 615 | kfree(r); |
@@ -616,6 +624,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request, | |||
616 | struct address_handler_resource *handler = callback_data; | 624 | struct address_handler_resource *handler = callback_data; |
617 | struct inbound_transaction_resource *r; | 625 | struct inbound_transaction_resource *r; |
618 | struct inbound_transaction_event *e; | 626 | struct inbound_transaction_event *e; |
627 | void *fcp_frame = NULL; | ||
619 | int ret; | 628 | int ret; |
620 | 629 | ||
621 | r = kmalloc(sizeof(*r), GFP_ATOMIC); | 630 | r = kmalloc(sizeof(*r), GFP_ATOMIC); |
@@ -627,6 +636,18 @@ static void handle_request(struct fw_card *card, struct fw_request *request, | |||
627 | r->data = payload; | 636 | r->data = payload; |
628 | r->length = length; | 637 | r->length = length; |
629 | 638 | ||
639 | if (is_fcp_request(request)) { | ||
640 | /* | ||
641 | * FIXME: Let core-transaction.c manage a | ||
642 | * single reference-counted copy? | ||
643 | */ | ||
644 | fcp_frame = kmemdup(payload, length, GFP_ATOMIC); | ||
645 | if (fcp_frame == NULL) | ||
646 | goto failed; | ||
647 | |||
648 | r->data = fcp_frame; | ||
649 | } | ||
650 | |||
630 | r->resource.release = release_request; | 651 | r->resource.release = release_request; |
631 | ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC); | 652 | ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC); |
632 | if (ret < 0) | 653 | if (ret < 0) |
@@ -640,13 +661,15 @@ static void handle_request(struct fw_card *card, struct fw_request *request, | |||
640 | e->request.closure = handler->closure; | 661 | e->request.closure = handler->closure; |
641 | 662 | ||
642 | queue_event(handler->client, &e->event, | 663 | queue_event(handler->client, &e->event, |
643 | &e->request, sizeof(e->request), payload, length); | 664 | &e->request, sizeof(e->request), r->data, length); |
644 | return; | 665 | return; |
645 | 666 | ||
646 | failed: | 667 | failed: |
647 | kfree(r); | 668 | kfree(r); |
648 | kfree(e); | 669 | kfree(e); |
649 | if (request) | 670 | kfree(fcp_frame); |
671 | |||
672 | if (!is_fcp_request(request)) | ||
650 | fw_send_response(card, request, RCODE_CONFLICT_ERROR); | 673 | fw_send_response(card, request, RCODE_CONFLICT_ERROR); |
651 | } | 674 | } |
652 | 675 | ||
@@ -717,18 +740,17 @@ static int ioctl_send_response(struct client *client, void *buffer) | |||
717 | 740 | ||
718 | r = container_of(resource, struct inbound_transaction_resource, | 741 | r = container_of(resource, struct inbound_transaction_resource, |
719 | resource); | 742 | resource); |
720 | if (r->request) { | 743 | if (is_fcp_request(r->request)) |
721 | if (request->length < r->length) | 744 | goto out; |
722 | r->length = request->length; | 745 | |
723 | if (copy_from_user(r->data, u64_to_uptr(request->data), | 746 | if (request->length < r->length) |
724 | r->length)) { | 747 | r->length = request->length; |
725 | ret = -EFAULT; | 748 | if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) { |
726 | kfree(r->request); | 749 | ret = -EFAULT; |
727 | goto out; | 750 | kfree(r->request); |
728 | } | 751 | goto out; |
729 | fw_send_response(client->device->card, r->request, | ||
730 | request->rcode); | ||
731 | } | 752 | } |
753 | fw_send_response(client->device->card, r->request, request->rcode); | ||
732 | out: | 754 | out: |
733 | kfree(r); | 755 | kfree(r); |
734 | 756 | ||
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index a61571c63c59..2345d4103fe6 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -2420,6 +2420,7 @@ static void ohci_pmac_off(struct pci_dev *dev) | |||
2420 | 2420 | ||
2421 | #define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT | 2421 | #define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT |
2422 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 | 2422 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 |
2423 | #define PCI_DEVICE_ID_TI_TSB43AB23 0x8024 | ||
2423 | 2424 | ||
2424 | static int __devinit pci_probe(struct pci_dev *dev, | 2425 | static int __devinit pci_probe(struct pci_dev *dev, |
2425 | const struct pci_device_id *ent) | 2426 | const struct pci_device_id *ent) |
@@ -2488,7 +2489,8 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2488 | #if !defined(CONFIG_X86_32) | 2489 | #if !defined(CONFIG_X86_32) |
2489 | /* dual-buffer mode is broken with descriptor addresses above 2G */ | 2490 | /* dual-buffer mode is broken with descriptor addresses above 2G */ |
2490 | if (dev->vendor == PCI_VENDOR_ID_TI && | 2491 | if (dev->vendor == PCI_VENDOR_ID_TI && |
2491 | dev->device == PCI_DEVICE_ID_TI_TSB43AB22) | 2492 | (dev->device == PCI_DEVICE_ID_TI_TSB43AB22 || |
2493 | dev->device == PCI_DEVICE_ID_TI_TSB43AB23)) | ||
2492 | ohci->use_dualbuffer = false; | 2494 | ohci->use_dualbuffer = false; |
2493 | #endif | 2495 | #endif |
2494 | 2496 | ||
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index e9dbb481c469..8bf3770f294e 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -142,19 +142,6 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) | |||
142 | if (IS_ERR(obj->filp)) | 142 | if (IS_ERR(obj->filp)) |
143 | goto free; | 143 | goto free; |
144 | 144 | ||
145 | /* Basically we want to disable the OOM killer and handle ENOMEM | ||
146 | * ourselves by sacrificing pages from cached buffers. | ||
147 | * XXX shmem_file_[gs]et_gfp_mask() | ||
148 | */ | ||
149 | mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping, | ||
150 | GFP_HIGHUSER | | ||
151 | __GFP_COLD | | ||
152 | __GFP_FS | | ||
153 | __GFP_RECLAIMABLE | | ||
154 | __GFP_NORETRY | | ||
155 | __GFP_NOWARN | | ||
156 | __GFP_NOMEMALLOC); | ||
157 | |||
158 | kref_init(&obj->refcount); | 145 | kref_init(&obj->refcount); |
159 | kref_init(&obj->handlecount); | 146 | kref_init(&obj->handlecount); |
160 | obj->size = size; | 147 | obj->size = size; |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9c9998c4dceb..a894ade03093 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -290,7 +290,7 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) | |||
290 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | 290 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { |
291 | obj = obj_priv->obj; | 291 | obj = obj_priv->obj; |
292 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { | 292 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { |
293 | ret = i915_gem_object_get_pages(obj); | 293 | ret = i915_gem_object_get_pages(obj, 0); |
294 | if (ret) { | 294 | if (ret) { |
295 | DRM_ERROR("Failed to get pages: %d\n", ret); | 295 | DRM_ERROR("Failed to get pages: %d\n", ret); |
296 | spin_unlock(&dev_priv->mm.active_list_lock); | 296 | spin_unlock(&dev_priv->mm.active_list_lock); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2c1669488b5a..aaf934d96f21 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -872,7 +872,7 @@ int i915_gem_attach_phys_object(struct drm_device *dev, | |||
872 | void i915_gem_detach_phys_object(struct drm_device *dev, | 872 | void i915_gem_detach_phys_object(struct drm_device *dev, |
873 | struct drm_gem_object *obj); | 873 | struct drm_gem_object *obj); |
874 | void i915_gem_free_all_phys_object(struct drm_device *dev); | 874 | void i915_gem_free_all_phys_object(struct drm_device *dev); |
875 | int i915_gem_object_get_pages(struct drm_gem_object *obj); | 875 | int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); |
876 | void i915_gem_object_put_pages(struct drm_gem_object *obj); | 876 | void i915_gem_object_put_pages(struct drm_gem_object *obj); |
877 | void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); | 877 | void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); |
878 | void i915_gem_object_flush_write_domain(struct drm_gem_object *obj); | 878 | void i915_gem_object_flush_write_domain(struct drm_gem_object *obj); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0c67924ca80c..dda787aafcc6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -277,7 +277,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
277 | 277 | ||
278 | mutex_lock(&dev->struct_mutex); | 278 | mutex_lock(&dev->struct_mutex); |
279 | 279 | ||
280 | ret = i915_gem_object_get_pages(obj); | 280 | ret = i915_gem_object_get_pages(obj, 0); |
281 | if (ret != 0) | 281 | if (ret != 0) |
282 | goto fail_unlock; | 282 | goto fail_unlock; |
283 | 283 | ||
@@ -321,40 +321,24 @@ fail_unlock: | |||
321 | return ret; | 321 | return ret; |
322 | } | 322 | } |
323 | 323 | ||
324 | static inline gfp_t | ||
325 | i915_gem_object_get_page_gfp_mask (struct drm_gem_object *obj) | ||
326 | { | ||
327 | return mapping_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping); | ||
328 | } | ||
329 | |||
330 | static inline void | ||
331 | i915_gem_object_set_page_gfp_mask (struct drm_gem_object *obj, gfp_t gfp) | ||
332 | { | ||
333 | mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping, gfp); | ||
334 | } | ||
335 | |||
336 | static int | 324 | static int |
337 | i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) | 325 | i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) |
338 | { | 326 | { |
339 | int ret; | 327 | int ret; |
340 | 328 | ||
341 | ret = i915_gem_object_get_pages(obj); | 329 | ret = i915_gem_object_get_pages(obj, __GFP_NORETRY | __GFP_NOWARN); |
342 | 330 | ||
343 | /* If we've insufficient memory to map in the pages, attempt | 331 | /* If we've insufficient memory to map in the pages, attempt |
344 | * to make some space by throwing out some old buffers. | 332 | * to make some space by throwing out some old buffers. |
345 | */ | 333 | */ |
346 | if (ret == -ENOMEM) { | 334 | if (ret == -ENOMEM) { |
347 | struct drm_device *dev = obj->dev; | 335 | struct drm_device *dev = obj->dev; |
348 | gfp_t gfp; | ||
349 | 336 | ||
350 | ret = i915_gem_evict_something(dev, obj->size); | 337 | ret = i915_gem_evict_something(dev, obj->size); |
351 | if (ret) | 338 | if (ret) |
352 | return ret; | 339 | return ret; |
353 | 340 | ||
354 | gfp = i915_gem_object_get_page_gfp_mask(obj); | 341 | ret = i915_gem_object_get_pages(obj, 0); |
355 | i915_gem_object_set_page_gfp_mask(obj, gfp & ~__GFP_NORETRY); | ||
356 | ret = i915_gem_object_get_pages(obj); | ||
357 | i915_gem_object_set_page_gfp_mask (obj, gfp); | ||
358 | } | 342 | } |
359 | 343 | ||
360 | return ret; | 344 | return ret; |
@@ -790,7 +774,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
790 | 774 | ||
791 | mutex_lock(&dev->struct_mutex); | 775 | mutex_lock(&dev->struct_mutex); |
792 | 776 | ||
793 | ret = i915_gem_object_get_pages(obj); | 777 | ret = i915_gem_object_get_pages(obj, 0); |
794 | if (ret != 0) | 778 | if (ret != 0) |
795 | goto fail_unlock; | 779 | goto fail_unlock; |
796 | 780 | ||
@@ -2230,7 +2214,8 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) | |||
2230 | } | 2214 | } |
2231 | 2215 | ||
2232 | int | 2216 | int |
2233 | i915_gem_object_get_pages(struct drm_gem_object *obj) | 2217 | i915_gem_object_get_pages(struct drm_gem_object *obj, |
2218 | gfp_t gfpmask) | ||
2234 | { | 2219 | { |
2235 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2220 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
2236 | int page_count, i; | 2221 | int page_count, i; |
@@ -2256,7 +2241,10 @@ i915_gem_object_get_pages(struct drm_gem_object *obj) | |||
2256 | inode = obj->filp->f_path.dentry->d_inode; | 2241 | inode = obj->filp->f_path.dentry->d_inode; |
2257 | mapping = inode->i_mapping; | 2242 | mapping = inode->i_mapping; |
2258 | for (i = 0; i < page_count; i++) { | 2243 | for (i = 0; i < page_count; i++) { |
2259 | page = read_mapping_page(mapping, i, NULL); | 2244 | page = read_cache_page_gfp(mapping, i, |
2245 | mapping_gfp_mask (mapping) | | ||
2246 | __GFP_COLD | | ||
2247 | gfpmask); | ||
2260 | if (IS_ERR(page)) { | 2248 | if (IS_ERR(page)) { |
2261 | ret = PTR_ERR(page); | 2249 | ret = PTR_ERR(page); |
2262 | i915_gem_object_put_pages(obj); | 2250 | i915_gem_object_put_pages(obj); |
@@ -2579,7 +2567,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2579 | drm_i915_private_t *dev_priv = dev->dev_private; | 2567 | drm_i915_private_t *dev_priv = dev->dev_private; |
2580 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2568 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
2581 | struct drm_mm_node *free_space; | 2569 | struct drm_mm_node *free_space; |
2582 | bool retry_alloc = false; | 2570 | gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; |
2583 | int ret; | 2571 | int ret; |
2584 | 2572 | ||
2585 | if (obj_priv->madv != I915_MADV_WILLNEED) { | 2573 | if (obj_priv->madv != I915_MADV_WILLNEED) { |
@@ -2623,15 +2611,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2623 | DRM_INFO("Binding object of size %zd at 0x%08x\n", | 2611 | DRM_INFO("Binding object of size %zd at 0x%08x\n", |
2624 | obj->size, obj_priv->gtt_offset); | 2612 | obj->size, obj_priv->gtt_offset); |
2625 | #endif | 2613 | #endif |
2626 | if (retry_alloc) { | 2614 | ret = i915_gem_object_get_pages(obj, gfpmask); |
2627 | i915_gem_object_set_page_gfp_mask (obj, | ||
2628 | i915_gem_object_get_page_gfp_mask (obj) & ~__GFP_NORETRY); | ||
2629 | } | ||
2630 | ret = i915_gem_object_get_pages(obj); | ||
2631 | if (retry_alloc) { | ||
2632 | i915_gem_object_set_page_gfp_mask (obj, | ||
2633 | i915_gem_object_get_page_gfp_mask (obj) | __GFP_NORETRY); | ||
2634 | } | ||
2635 | if (ret) { | 2615 | if (ret) { |
2636 | drm_mm_put_block(obj_priv->gtt_space); | 2616 | drm_mm_put_block(obj_priv->gtt_space); |
2637 | obj_priv->gtt_space = NULL; | 2617 | obj_priv->gtt_space = NULL; |
@@ -2641,9 +2621,9 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2641 | ret = i915_gem_evict_something(dev, obj->size); | 2621 | ret = i915_gem_evict_something(dev, obj->size); |
2642 | if (ret) { | 2622 | if (ret) { |
2643 | /* now try to shrink everyone else */ | 2623 | /* now try to shrink everyone else */ |
2644 | if (! retry_alloc) { | 2624 | if (gfpmask) { |
2645 | retry_alloc = true; | 2625 | gfpmask = 0; |
2646 | goto search_free; | 2626 | goto search_free; |
2647 | } | 2627 | } |
2648 | 2628 | ||
2649 | return ret; | 2629 | return ret; |
@@ -4946,7 +4926,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev, | |||
4946 | if (!obj_priv->phys_obj) | 4926 | if (!obj_priv->phys_obj) |
4947 | return; | 4927 | return; |
4948 | 4928 | ||
4949 | ret = i915_gem_object_get_pages(obj); | 4929 | ret = i915_gem_object_get_pages(obj, 0); |
4950 | if (ret) | 4930 | if (ret) |
4951 | goto out; | 4931 | goto out; |
4952 | 4932 | ||
@@ -5004,7 +4984,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
5004 | obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1]; | 4984 | obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1]; |
5005 | obj_priv->phys_obj->cur_obj = obj; | 4985 | obj_priv->phys_obj->cur_obj = obj; |
5006 | 4986 | ||
5007 | ret = i915_gem_object_get_pages(obj); | 4987 | ret = i915_gem_object_get_pages(obj, 0); |
5008 | if (ret) { | 4988 | if (ret) { |
5009 | DRM_ERROR("failed to get page list\n"); | 4989 | DRM_ERROR("failed to get page list\n"); |
5010 | goto out; | 4990 | goto out; |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 85bc6a685e36..44d2037e9e56 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -4330,6 +4330,8 @@ initChainBuffers(MPT_ADAPTER *ioc) | |||
4330 | 4330 | ||
4331 | if (ioc->bus_type == SPI) | 4331 | if (ioc->bus_type == SPI) |
4332 | num_chain *= MPT_SCSI_CAN_QUEUE; | 4332 | num_chain *= MPT_SCSI_CAN_QUEUE; |
4333 | else if (ioc->bus_type == SAS) | ||
4334 | num_chain *= MPT_SAS_CAN_QUEUE; | ||
4333 | else | 4335 | else |
4334 | num_chain *= MPT_FC_CAN_QUEUE; | 4336 | num_chain *= MPT_FC_CAN_QUEUE; |
4335 | 4337 | ||
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index f237ddbb2713..111ea41c4ecd 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -853,7 +853,6 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, | |||
853 | break; | 853 | break; |
854 | } | 854 | } |
855 | 855 | ||
856 | req.name[req.name_len] = '\0'; | ||
857 | err = verify_mkvol_req(ubi, &req); | 856 | err = verify_mkvol_req(ubi, &req); |
858 | if (err) | 857 | if (err) |
859 | break; | 858 | break; |
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 8c30a9544d61..223052b73563 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c | |||
@@ -321,7 +321,7 @@ static int aer_inject(struct aer_error_inj *einj) | |||
321 | unsigned long flags; | 321 | unsigned long flags; |
322 | unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); | 322 | unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); |
323 | int pos_cap_err, rp_pos_cap_err; | 323 | int pos_cap_err, rp_pos_cap_err; |
324 | u32 sever, mask; | 324 | u32 sever, cor_mask, uncor_mask; |
325 | int ret = 0; | 325 | int ret = 0; |
326 | 326 | ||
327 | dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); | 327 | dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); |
@@ -339,6 +339,9 @@ static int aer_inject(struct aer_error_inj *einj) | |||
339 | goto out_put; | 339 | goto out_put; |
340 | } | 340 | } |
341 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); | 341 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); |
342 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &cor_mask); | ||
343 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, | ||
344 | &uncor_mask); | ||
342 | 345 | ||
343 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); | 346 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); |
344 | if (!rp_pos_cap_err) { | 347 | if (!rp_pos_cap_err) { |
@@ -374,17 +377,14 @@ static int aer_inject(struct aer_error_inj *einj) | |||
374 | err->header_log2 = einj->header_log2; | 377 | err->header_log2 = einj->header_log2; |
375 | err->header_log3 = einj->header_log3; | 378 | err->header_log3 = einj->header_log3; |
376 | 379 | ||
377 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &mask); | 380 | if (einj->cor_status && !(einj->cor_status & ~cor_mask)) { |
378 | if (einj->cor_status && !(einj->cor_status & ~mask)) { | ||
379 | ret = -EINVAL; | 381 | ret = -EINVAL; |
380 | printk(KERN_WARNING "The correctable error(s) is masked " | 382 | printk(KERN_WARNING "The correctable error(s) is masked " |
381 | "by device\n"); | 383 | "by device\n"); |
382 | spin_unlock_irqrestore(&inject_lock, flags); | 384 | spin_unlock_irqrestore(&inject_lock, flags); |
383 | goto out_put; | 385 | goto out_put; |
384 | } | 386 | } |
385 | 387 | if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) { | |
386 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, &mask); | ||
387 | if (einj->uncor_status && !(einj->uncor_status & ~mask)) { | ||
388 | ret = -EINVAL; | 388 | ret = -EINVAL; |
389 | printk(KERN_WARNING "The uncorrectable error(s) is masked " | 389 | printk(KERN_WARNING "The uncorrectable error(s) is masked " |
390 | "by device\n"); | 390 | "by device\n"); |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index fdb2e7c14506..5905936c7c60 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -1004,8 +1004,8 @@ static void dasd_handle_killed_request(struct ccw_device *cdev, | |||
1004 | if (device == NULL || | 1004 | if (device == NULL || |
1005 | device != dasd_device_from_cdev_locked(cdev) || | 1005 | device != dasd_device_from_cdev_locked(cdev) || |
1006 | strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { | 1006 | strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { |
1007 | DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: " | 1007 | DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s", |
1008 | "bus_id %s", dev_name(&cdev->dev)); | 1008 | "invalid device in request"); |
1009 | return; | 1009 | return; |
1010 | } | 1010 | } |
1011 | 1011 | ||
@@ -1078,8 +1078,8 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
1078 | device = (struct dasd_device *) cqr->startdev; | 1078 | device = (struct dasd_device *) cqr->startdev; |
1079 | if (!device || | 1079 | if (!device || |
1080 | strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { | 1080 | strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { |
1081 | DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: " | 1081 | DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s", |
1082 | "bus_id %s", dev_name(&cdev->dev)); | 1082 | "invalid device in request"); |
1083 | return; | 1083 | return; |
1084 | } | 1084 | } |
1085 | 1085 | ||
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 1c500c462225..1cca21aafaba 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -3033,7 +3033,7 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device, | |||
3033 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 3033 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER |
3034 | " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n", | 3034 | " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n", |
3035 | req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), | 3035 | req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), |
3036 | scsw_cc(&irb->scsw), req->intrc); | 3036 | scsw_cc(&irb->scsw), req ? req->intrc : 0); |
3037 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 3037 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER |
3038 | " device %s: Failing CCW: %p\n", | 3038 | " device %s: Failing CCW: %p\n", |
3039 | dev_name(&device->cdev->dev), | 3039 | dev_name(&device->cdev->dev), |
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index fc7b30b4a255..7039d9cf0fb4 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -260,7 +260,7 @@ static int dasd_ioctl_information(struct dasd_block *block, | |||
260 | struct ccw_dev_id dev_id; | 260 | struct ccw_dev_id dev_id; |
261 | 261 | ||
262 | base = block->base; | 262 | base = block->base; |
263 | if (!base->discipline->fill_info) | 263 | if (!base->discipline || !base->discipline->fill_info) |
264 | return -EINVAL; | 264 | return -EINVAL; |
265 | 265 | ||
266 | dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); | 266 | dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); |
@@ -303,10 +303,7 @@ static int dasd_ioctl_information(struct dasd_block *block, | |||
303 | dasd_info->features |= | 303 | dasd_info->features |= |
304 | ((base->features & DASD_FEATURE_READONLY) != 0); | 304 | ((base->features & DASD_FEATURE_READONLY) != 0); |
305 | 305 | ||
306 | if (base->discipline) | 306 | memcpy(dasd_info->type, base->discipline->name, 4); |
307 | memcpy(dasd_info->type, base->discipline->name, 4); | ||
308 | else | ||
309 | memcpy(dasd_info->type, "none", 4); | ||
310 | 307 | ||
311 | if (block->request_queue->request_fn) { | 308 | if (block->request_queue->request_fn) { |
312 | struct list_head *l; | 309 | struct list_head *l; |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 6315fbd8e68b..71f95f54866f 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -72,7 +72,7 @@ dasd_devices_show(struct seq_file *m, void *v) | |||
72 | /* Print device number. */ | 72 | /* Print device number. */ |
73 | seq_printf(m, "%s", dev_name(&device->cdev->dev)); | 73 | seq_printf(m, "%s", dev_name(&device->cdev->dev)); |
74 | /* Print discipline string. */ | 74 | /* Print discipline string. */ |
75 | if (device != NULL && device->discipline != NULL) | 75 | if (device->discipline != NULL) |
76 | seq_printf(m, "(%s)", device->discipline->name); | 76 | seq_printf(m, "(%s)", device->discipline->name); |
77 | else | 77 | else |
78 | seq_printf(m, "(none)"); | 78 | seq_printf(m, "(none)"); |
@@ -92,10 +92,7 @@ dasd_devices_show(struct seq_file *m, void *v) | |||
92 | substr = (device->features & DASD_FEATURE_READONLY) ? "(ro)" : " "; | 92 | substr = (device->features & DASD_FEATURE_READONLY) ? "(ro)" : " "; |
93 | seq_printf(m, "%4s: ", substr); | 93 | seq_printf(m, "%4s: ", substr); |
94 | /* Print device status information. */ | 94 | /* Print device status information. */ |
95 | switch ((device != NULL) ? device->state : -1) { | 95 | switch (device->state) { |
96 | case -1: | ||
97 | seq_printf(m, "unknown"); | ||
98 | break; | ||
99 | case DASD_STATE_NEW: | 96 | case DASD_STATE_NEW: |
100 | seq_printf(m, "new"); | 97 | seq_printf(m, "new"); |
101 | break; | 98 | break; |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index b9d2a007e93b..3796ffdb8479 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -495,6 +495,10 @@ sclp_vt220_open(struct tty_struct *tty, struct file *filp) | |||
495 | if (tty->driver_data == NULL) | 495 | if (tty->driver_data == NULL) |
496 | return -ENOMEM; | 496 | return -ENOMEM; |
497 | tty->low_latency = 0; | 497 | tty->low_latency = 0; |
498 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | ||
499 | tty->winsize.ws_row = 24; | ||
500 | tty->winsize.ws_col = 80; | ||
501 | } | ||
498 | } | 502 | } |
499 | return 0; | 503 | return 0; |
500 | } | 504 | } |
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index a23726a0735c..142f72a2ca5a 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c | |||
@@ -373,6 +373,8 @@ static int convert_type86(struct zcrypt_device *zdev, | |||
373 | zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD; | 373 | zdev->max_mod_size = PCICC_MAX_MOD_SIZE_OLD; |
374 | return -EAGAIN; | 374 | return -EAGAIN; |
375 | } | 375 | } |
376 | if (service_rc == 8 && service_rs == 72) | ||
377 | return -EINVAL; | ||
376 | zdev->online = 0; | 378 | zdev->online = 0; |
377 | return -EAGAIN; /* repeat the request on a different device. */ | 379 | return -EAGAIN; /* repeat the request on a different device. */ |
378 | } | 380 | } |
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 79c120578e61..68f3e6204db8 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c | |||
@@ -470,6 +470,8 @@ static int convert_type86_ica(struct zcrypt_device *zdev, | |||
470 | } | 470 | } |
471 | if (service_rc == 12 && service_rs == 769) | 471 | if (service_rc == 12 && service_rs == 769) |
472 | return -EINVAL; | 472 | return -EINVAL; |
473 | if (service_rc == 8 && service_rs == 72) | ||
474 | return -EINVAL; | ||
473 | zdev->online = 0; | 475 | zdev->online = 0; |
474 | return -EAGAIN; /* repeat the request on a different device. */ | 476 | return -EAGAIN; /* repeat the request on a different device. */ |
475 | } | 477 | } |
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index f932400e980a..0eb6eefd2c1a 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/miscdevice.h> | 14 | #include <linux/miscdevice.h> |
15 | #include <asm/compat.h> | ||
15 | #include <asm/ccwdev.h> | 16 | #include <asm/ccwdev.h> |
16 | #include "zfcp_def.h" | 17 | #include "zfcp_def.h" |
17 | #include "zfcp_ext.h" | 18 | #include "zfcp_ext.h" |
@@ -163,7 +164,7 @@ static void zfcp_cfdc_req_to_sense(struct zfcp_cfdc_data *data, | |||
163 | } | 164 | } |
164 | 165 | ||
165 | static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, | 166 | static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, |
166 | unsigned long buffer) | 167 | unsigned long arg) |
167 | { | 168 | { |
168 | struct zfcp_cfdc_data *data; | 169 | struct zfcp_cfdc_data *data; |
169 | struct zfcp_cfdc_data __user *data_user; | 170 | struct zfcp_cfdc_data __user *data_user; |
@@ -175,7 +176,11 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, | |||
175 | if (command != ZFCP_CFDC_IOC) | 176 | if (command != ZFCP_CFDC_IOC) |
176 | return -ENOTTY; | 177 | return -ENOTTY; |
177 | 178 | ||
178 | data_user = (void __user *) buffer; | 179 | if (is_compat_task()) |
180 | data_user = compat_ptr(arg); | ||
181 | else | ||
182 | data_user = (void __user *)arg; | ||
183 | |||
179 | if (!data_user) | 184 | if (!data_user) |
180 | return -EINVAL; | 185 | return -EINVAL; |
181 | 186 | ||
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 84450955ae11..7369c8911bcf 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
@@ -327,7 +327,7 @@ static void zfcp_dbf_hba_view_response(char **p, | |||
327 | break; | 327 | break; |
328 | zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); | 328 | zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); |
329 | zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); | 329 | zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); |
330 | p += sprintf(*p, "\n"); | 330 | *p += sprintf(*p, "\n"); |
331 | break; | 331 | break; |
332 | 332 | ||
333 | case FSF_QTCB_OPEN_PORT_WITH_DID: | 333 | case FSF_QTCB_OPEN_PORT_WITH_DID: |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 03dec832b465..66bdb34143cb 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -108,6 +108,7 @@ extern void zfcp_fc_wka_ports_force_offline(struct zfcp_fc_wka_ports *); | |||
108 | extern int zfcp_fc_gs_setup(struct zfcp_adapter *); | 108 | extern int zfcp_fc_gs_setup(struct zfcp_adapter *); |
109 | extern void zfcp_fc_gs_destroy(struct zfcp_adapter *); | 109 | extern void zfcp_fc_gs_destroy(struct zfcp_adapter *); |
110 | extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *); | 110 | extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *); |
111 | extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *); | ||
111 | 112 | ||
112 | /* zfcp_fsf.c */ | 113 | /* zfcp_fsf.c */ |
113 | extern int zfcp_fsf_open_port(struct zfcp_erp_action *); | 114 | extern int zfcp_fsf_open_port(struct zfcp_erp_action *); |
@@ -129,9 +130,9 @@ extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); | |||
129 | extern int zfcp_fsf_status_read(struct zfcp_qdio *); | 130 | extern int zfcp_fsf_status_read(struct zfcp_qdio *); |
130 | extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); | 131 | extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); |
131 | extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *, | 132 | extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *, |
132 | mempool_t *); | 133 | mempool_t *, unsigned int); |
133 | extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32, | 134 | extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32, |
134 | struct zfcp_fsf_ct_els *); | 135 | struct zfcp_fsf_ct_els *, unsigned int); |
135 | extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *, | 136 | extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *, |
136 | struct scsi_cmnd *); | 137 | struct scsi_cmnd *); |
137 | extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); | 138 | extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); |
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index ac5e3b7a3576..0f7b493fb105 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -258,7 +258,8 @@ static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port, | |||
258 | gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn; | 258 | gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn; |
259 | 259 | ||
260 | ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct, | 260 | ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct, |
261 | adapter->pool.gid_pn_req); | 261 | adapter->pool.gid_pn_req, |
262 | ZFCP_FC_CTELS_TMO); | ||
262 | if (!ret) { | 263 | if (!ret) { |
263 | wait_for_completion(&completion); | 264 | wait_for_completion(&completion); |
264 | zfcp_fc_ns_gid_pn_eval(gid_pn); | 265 | zfcp_fc_ns_gid_pn_eval(gid_pn); |
@@ -421,7 +422,8 @@ static int zfcp_fc_adisc(struct zfcp_port *port) | |||
421 | hton24(adisc->adisc_req.adisc_port_id, | 422 | hton24(adisc->adisc_req.adisc_port_id, |
422 | fc_host_port_id(adapter->scsi_host)); | 423 | fc_host_port_id(adapter->scsi_host)); |
423 | 424 | ||
424 | ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els); | 425 | ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els, |
426 | ZFCP_FC_CTELS_TMO); | ||
425 | if (ret) | 427 | if (ret) |
426 | kmem_cache_free(zfcp_data.adisc_cache, adisc); | 428 | kmem_cache_free(zfcp_data.adisc_cache, adisc); |
427 | 429 | ||
@@ -532,7 +534,8 @@ static int zfcp_fc_send_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft, | |||
532 | ct->req = &gpn_ft->sg_req; | 534 | ct->req = &gpn_ft->sg_req; |
533 | ct->resp = gpn_ft->sg_resp; | 535 | ct->resp = gpn_ft->sg_resp; |
534 | 536 | ||
535 | ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL); | 537 | ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL, |
538 | ZFCP_FC_CTELS_TMO); | ||
536 | if (!ret) | 539 | if (!ret) |
537 | wait_for_completion(&completion); | 540 | wait_for_completion(&completion); |
538 | return ret; | 541 | return ret; |
@@ -677,6 +680,44 @@ static void zfcp_fc_ct_els_job_handler(void *data) | |||
677 | job->job_done(job); | 680 | job->job_done(job); |
678 | } | 681 | } |
679 | 682 | ||
683 | static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job) | ||
684 | { | ||
685 | u32 preamble_word1; | ||
686 | u8 gs_type; | ||
687 | struct zfcp_adapter *adapter; | ||
688 | |||
689 | preamble_word1 = job->request->rqst_data.r_ct.preamble_word1; | ||
690 | gs_type = (preamble_word1 & 0xff000000) >> 24; | ||
691 | |||
692 | adapter = (struct zfcp_adapter *) job->shost->hostdata[0]; | ||
693 | |||
694 | switch (gs_type) { | ||
695 | case FC_FST_ALIAS: | ||
696 | return &adapter->gs->as; | ||
697 | case FC_FST_MGMT: | ||
698 | return &adapter->gs->ms; | ||
699 | case FC_FST_TIME: | ||
700 | return &adapter->gs->ts; | ||
701 | break; | ||
702 | case FC_FST_DIR: | ||
703 | return &adapter->gs->ds; | ||
704 | break; | ||
705 | default: | ||
706 | return NULL; | ||
707 | } | ||
708 | } | ||
709 | |||
710 | static void zfcp_fc_ct_job_handler(void *data) | ||
711 | { | ||
712 | struct fc_bsg_job *job = data; | ||
713 | struct zfcp_fc_wka_port *wka_port; | ||
714 | |||
715 | wka_port = zfcp_fc_job_wka_port(job); | ||
716 | zfcp_fc_wka_port_put(wka_port); | ||
717 | |||
718 | zfcp_fc_ct_els_job_handler(data); | ||
719 | } | ||
720 | |||
680 | static int zfcp_fc_exec_els_job(struct fc_bsg_job *job, | 721 | static int zfcp_fc_exec_els_job(struct fc_bsg_job *job, |
681 | struct zfcp_adapter *adapter) | 722 | struct zfcp_adapter *adapter) |
682 | { | 723 | { |
@@ -695,43 +736,27 @@ static int zfcp_fc_exec_els_job(struct fc_bsg_job *job, | |||
695 | } else | 736 | } else |
696 | d_id = ntoh24(job->request->rqst_data.h_els.port_id); | 737 | d_id = ntoh24(job->request->rqst_data.h_els.port_id); |
697 | 738 | ||
698 | return zfcp_fsf_send_els(adapter, d_id, els); | 739 | els->handler = zfcp_fc_ct_els_job_handler; |
740 | return zfcp_fsf_send_els(adapter, d_id, els, job->req->timeout / HZ); | ||
699 | } | 741 | } |
700 | 742 | ||
701 | static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job, | 743 | static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job, |
702 | struct zfcp_adapter *adapter) | 744 | struct zfcp_adapter *adapter) |
703 | { | 745 | { |
704 | int ret; | 746 | int ret; |
705 | u8 gs_type; | ||
706 | struct zfcp_fsf_ct_els *ct = job->dd_data; | 747 | struct zfcp_fsf_ct_els *ct = job->dd_data; |
707 | struct zfcp_fc_wka_port *wka_port; | 748 | struct zfcp_fc_wka_port *wka_port; |
708 | u32 preamble_word1; | ||
709 | 749 | ||
710 | preamble_word1 = job->request->rqst_data.r_ct.preamble_word1; | 750 | wka_port = zfcp_fc_job_wka_port(job); |
711 | gs_type = (preamble_word1 & 0xff000000) >> 24; | 751 | if (!wka_port) |
712 | 752 | return -EINVAL; | |
713 | switch (gs_type) { | ||
714 | case FC_FST_ALIAS: | ||
715 | wka_port = &adapter->gs->as; | ||
716 | break; | ||
717 | case FC_FST_MGMT: | ||
718 | wka_port = &adapter->gs->ms; | ||
719 | break; | ||
720 | case FC_FST_TIME: | ||
721 | wka_port = &adapter->gs->ts; | ||
722 | break; | ||
723 | case FC_FST_DIR: | ||
724 | wka_port = &adapter->gs->ds; | ||
725 | break; | ||
726 | default: | ||
727 | return -EINVAL; /* no such service */ | ||
728 | } | ||
729 | 753 | ||
730 | ret = zfcp_fc_wka_port_get(wka_port); | 754 | ret = zfcp_fc_wka_port_get(wka_port); |
731 | if (ret) | 755 | if (ret) |
732 | return ret; | 756 | return ret; |
733 | 757 | ||
734 | ret = zfcp_fsf_send_ct(wka_port, ct, NULL); | 758 | ct->handler = zfcp_fc_ct_job_handler; |
759 | ret = zfcp_fsf_send_ct(wka_port, ct, NULL, job->req->timeout / HZ); | ||
735 | if (ret) | 760 | if (ret) |
736 | zfcp_fc_wka_port_put(wka_port); | 761 | zfcp_fc_wka_port_put(wka_port); |
737 | 762 | ||
@@ -752,7 +777,6 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job) | |||
752 | 777 | ||
753 | ct_els->req = job->request_payload.sg_list; | 778 | ct_els->req = job->request_payload.sg_list; |
754 | ct_els->resp = job->reply_payload.sg_list; | 779 | ct_els->resp = job->reply_payload.sg_list; |
755 | ct_els->handler = zfcp_fc_ct_els_job_handler; | ||
756 | ct_els->handler_data = job; | 780 | ct_els->handler_data = job; |
757 | 781 | ||
758 | switch (job->request->msgcode) { | 782 | switch (job->request->msgcode) { |
@@ -767,6 +791,12 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job) | |||
767 | } | 791 | } |
768 | } | 792 | } |
769 | 793 | ||
794 | int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *job) | ||
795 | { | ||
796 | /* hardware tracks timeout, reset bsg timeout to not interfere */ | ||
797 | return -EAGAIN; | ||
798 | } | ||
799 | |||
770 | int zfcp_fc_gs_setup(struct zfcp_adapter *adapter) | 800 | int zfcp_fc_gs_setup(struct zfcp_adapter *adapter) |
771 | { | 801 | { |
772 | struct zfcp_fc_wka_ports *wka_ports; | 802 | struct zfcp_fc_wka_ports *wka_ports; |
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h index cb2a3669a384..0747b087390d 100644 --- a/drivers/s390/scsi/zfcp_fc.h +++ b/drivers/s390/scsi/zfcp_fc.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #define ZFCP_FC_GPN_FT_MAX_ENT (ZFCP_FC_GPN_FT_NUM_BUFS * \ | 27 | #define ZFCP_FC_GPN_FT_MAX_ENT (ZFCP_FC_GPN_FT_NUM_BUFS * \ |
28 | (ZFCP_FC_GPN_FT_ENT_PAGE + 1)) | 28 | (ZFCP_FC_GPN_FT_ENT_PAGE + 1)) |
29 | 29 | ||
30 | #define ZFCP_FC_CTELS_TMO (2 * FC_DEF_R_A_TOV / 1000) | ||
31 | |||
30 | /** | 32 | /** |
31 | * struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request | 33 | * struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request |
32 | * @ct_hdr: FC GS common transport header | 34 | * @ct_hdr: FC GS common transport header |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 482dcd97aa5d..e8fb4d9baa8b 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -1068,20 +1068,20 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, | |||
1068 | static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, | 1068 | static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, |
1069 | struct scatterlist *sg_req, | 1069 | struct scatterlist *sg_req, |
1070 | struct scatterlist *sg_resp, | 1070 | struct scatterlist *sg_resp, |
1071 | int max_sbals) | 1071 | int max_sbals, unsigned int timeout) |
1072 | { | 1072 | { |
1073 | int ret; | 1073 | int ret; |
1074 | unsigned int fcp_chan_timeout; | ||
1075 | 1074 | ||
1076 | ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals); | 1075 | ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals); |
1077 | if (ret) | 1076 | if (ret) |
1078 | return ret; | 1077 | return ret; |
1079 | 1078 | ||
1080 | /* common settings for ct/gs and els requests */ | 1079 | /* common settings for ct/gs and els requests */ |
1081 | fcp_chan_timeout = 2 * FC_DEF_R_A_TOV / 1000; | 1080 | if (timeout > 255) |
1081 | timeout = 255; /* max value accepted by hardware */ | ||
1082 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; | 1082 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; |
1083 | req->qtcb->bottom.support.timeout = fcp_chan_timeout; | 1083 | req->qtcb->bottom.support.timeout = timeout; |
1084 | zfcp_fsf_start_timer(req, (fcp_chan_timeout + 10) * HZ); | 1084 | zfcp_fsf_start_timer(req, (timeout + 10) * HZ); |
1085 | 1085 | ||
1086 | return 0; | 1086 | return 0; |
1087 | } | 1087 | } |
@@ -1092,7 +1092,8 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, | |||
1092 | * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req | 1092 | * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req |
1093 | */ | 1093 | */ |
1094 | int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, | 1094 | int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, |
1095 | struct zfcp_fsf_ct_els *ct, mempool_t *pool) | 1095 | struct zfcp_fsf_ct_els *ct, mempool_t *pool, |
1096 | unsigned int timeout) | ||
1096 | { | 1097 | { |
1097 | struct zfcp_qdio *qdio = wka_port->adapter->qdio; | 1098 | struct zfcp_qdio *qdio = wka_port->adapter->qdio; |
1098 | struct zfcp_fsf_req *req; | 1099 | struct zfcp_fsf_req *req; |
@@ -1111,7 +1112,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, | |||
1111 | 1112 | ||
1112 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; | 1113 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; |
1113 | ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, | 1114 | ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, |
1114 | FSF_MAX_SBALS_PER_REQ); | 1115 | FSF_MAX_SBALS_PER_REQ, timeout); |
1115 | if (ret) | 1116 | if (ret) |
1116 | goto failed_send; | 1117 | goto failed_send; |
1117 | 1118 | ||
@@ -1188,7 +1189,7 @@ skip_fsfstatus: | |||
1188 | * @els: pointer to struct zfcp_send_els with data for the command | 1189 | * @els: pointer to struct zfcp_send_els with data for the command |
1189 | */ | 1190 | */ |
1190 | int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, | 1191 | int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, |
1191 | struct zfcp_fsf_ct_els *els) | 1192 | struct zfcp_fsf_ct_els *els, unsigned int timeout) |
1192 | { | 1193 | { |
1193 | struct zfcp_fsf_req *req; | 1194 | struct zfcp_fsf_req *req; |
1194 | struct zfcp_qdio *qdio = adapter->qdio; | 1195 | struct zfcp_qdio *qdio = adapter->qdio; |
@@ -1206,7 +1207,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, | |||
1206 | } | 1207 | } |
1207 | 1208 | ||
1208 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; | 1209 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; |
1209 | ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2); | 1210 | ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2, timeout); |
1210 | 1211 | ||
1211 | if (ret) | 1212 | if (ret) |
1212 | goto failed_send; | 1213 | goto failed_send; |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 771cc536a989..8e6fc68d6bd4 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -652,6 +652,7 @@ struct fc_function_template zfcp_transport_functions = { | |||
652 | .show_host_port_state = 1, | 652 | .show_host_port_state = 1, |
653 | .show_host_active_fc4s = 1, | 653 | .show_host_active_fc4s = 1, |
654 | .bsg_request = zfcp_fc_exec_bsg_job, | 654 | .bsg_request = zfcp_fc_exec_bsg_job, |
655 | .bsg_timeout = zfcp_fc_timeout_bsg_job, | ||
655 | /* no functions registered for following dynamic attributes but | 656 | /* no functions registered for following dynamic attributes but |
656 | directly set by LLDD */ | 657 | directly set by LLDD */ |
657 | .show_host_port_type = 1, | 658 | .show_host_port_type = 1, |
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 2a889853a106..7e26ebc26661 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -293,7 +293,10 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) | |||
293 | status = -EINVAL; | 293 | status = -EINVAL; |
294 | } | 294 | } |
295 | } | 295 | } |
296 | aac_fib_complete(fibptr); | 296 | /* Do not set XferState to zero unless receives a response from F/W */ |
297 | if (status >= 0) | ||
298 | aac_fib_complete(fibptr); | ||
299 | |||
297 | /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ | 300 | /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ |
298 | if (status >= 0) { | 301 | if (status >= 0) { |
299 | if ((aac_commit == 1) || commit_flag) { | 302 | if ((aac_commit == 1) || commit_flag) { |
@@ -310,13 +313,18 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) | |||
310 | FsaNormal, | 313 | FsaNormal, |
311 | 1, 1, | 314 | 1, 1, |
312 | NULL, NULL); | 315 | NULL, NULL); |
313 | aac_fib_complete(fibptr); | 316 | /* Do not set XferState to zero unless |
317 | * receives a response from F/W */ | ||
318 | if (status >= 0) | ||
319 | aac_fib_complete(fibptr); | ||
314 | } else if (aac_commit == 0) { | 320 | } else if (aac_commit == 0) { |
315 | printk(KERN_WARNING | 321 | printk(KERN_WARNING |
316 | "aac_get_config_status: Foreign device configurations are being ignored\n"); | 322 | "aac_get_config_status: Foreign device configurations are being ignored\n"); |
317 | } | 323 | } |
318 | } | 324 | } |
319 | aac_fib_free(fibptr); | 325 | /* FIB should be freed only after getting the response from the F/W */ |
326 | if (status != -ERESTARTSYS) | ||
327 | aac_fib_free(fibptr); | ||
320 | return status; | 328 | return status; |
321 | } | 329 | } |
322 | 330 | ||
@@ -355,7 +363,9 @@ int aac_get_containers(struct aac_dev *dev) | |||
355 | maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); | 363 | maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); |
356 | aac_fib_complete(fibptr); | 364 | aac_fib_complete(fibptr); |
357 | } | 365 | } |
358 | aac_fib_free(fibptr); | 366 | /* FIB should be freed only after getting the response from the F/W */ |
367 | if (status != -ERESTARTSYS) | ||
368 | aac_fib_free(fibptr); | ||
359 | 369 | ||
360 | if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) | 370 | if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) |
361 | maximum_num_containers = MAXIMUM_NUM_CONTAINERS; | 371 | maximum_num_containers = MAXIMUM_NUM_CONTAINERS; |
@@ -1245,8 +1255,12 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1245 | NULL); | 1255 | NULL); |
1246 | 1256 | ||
1247 | if (rcode < 0) { | 1257 | if (rcode < 0) { |
1248 | aac_fib_complete(fibptr); | 1258 | /* FIB should be freed only after |
1249 | aac_fib_free(fibptr); | 1259 | * getting the response from the F/W */ |
1260 | if (rcode != -ERESTARTSYS) { | ||
1261 | aac_fib_complete(fibptr); | ||
1262 | aac_fib_free(fibptr); | ||
1263 | } | ||
1250 | return rcode; | 1264 | return rcode; |
1251 | } | 1265 | } |
1252 | memcpy(&dev->adapter_info, info, sizeof(*info)); | 1266 | memcpy(&dev->adapter_info, info, sizeof(*info)); |
@@ -1270,6 +1284,12 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1270 | 1284 | ||
1271 | if (rcode >= 0) | 1285 | if (rcode >= 0) |
1272 | memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo)); | 1286 | memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo)); |
1287 | if (rcode == -ERESTARTSYS) { | ||
1288 | fibptr = aac_fib_alloc(dev); | ||
1289 | if (!fibptr) | ||
1290 | return -ENOMEM; | ||
1291 | } | ||
1292 | |||
1273 | } | 1293 | } |
1274 | 1294 | ||
1275 | 1295 | ||
@@ -1470,9 +1490,11 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1470 | (dev->scsi_host_ptr->sg_tablesize * 8) + 112; | 1490 | (dev->scsi_host_ptr->sg_tablesize * 8) + 112; |
1471 | } | 1491 | } |
1472 | } | 1492 | } |
1473 | 1493 | /* FIB should be freed only after getting the response from the F/W */ | |
1474 | aac_fib_complete(fibptr); | 1494 | if (rcode != -ERESTARTSYS) { |
1475 | aac_fib_free(fibptr); | 1495 | aac_fib_complete(fibptr); |
1496 | aac_fib_free(fibptr); | ||
1497 | } | ||
1476 | 1498 | ||
1477 | return rcode; | 1499 | return rcode; |
1478 | } | 1500 | } |
@@ -1633,6 +1655,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) | |||
1633 | * Alocate and initialize a Fib | 1655 | * Alocate and initialize a Fib |
1634 | */ | 1656 | */ |
1635 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { | 1657 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { |
1658 | printk(KERN_WARNING "aac_read: fib allocation failed\n"); | ||
1636 | return -1; | 1659 | return -1; |
1637 | } | 1660 | } |
1638 | 1661 | ||
@@ -1712,9 +1735,14 @@ static int aac_write(struct scsi_cmnd * scsicmd) | |||
1712 | * Allocate and initialize a Fib then setup a BlockWrite command | 1735 | * Allocate and initialize a Fib then setup a BlockWrite command |
1713 | */ | 1736 | */ |
1714 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { | 1737 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { |
1715 | scsicmd->result = DID_ERROR << 16; | 1738 | /* FIB temporarily unavailable,not catastrophic failure */ |
1716 | scsicmd->scsi_done(scsicmd); | 1739 | |
1717 | return 0; | 1740 | /* scsicmd->result = DID_ERROR << 16; |
1741 | * scsicmd->scsi_done(scsicmd); | ||
1742 | * return 0; | ||
1743 | */ | ||
1744 | printk(KERN_WARNING "aac_write: fib allocation failed\n"); | ||
1745 | return -1; | ||
1718 | } | 1746 | } |
1719 | 1747 | ||
1720 | status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua); | 1748 | status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua); |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 83986ed86556..619c02d9c862 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -12,7 +12,7 @@ | |||
12 | *----------------------------------------------------------------------------*/ | 12 | *----------------------------------------------------------------------------*/ |
13 | 13 | ||
14 | #ifndef AAC_DRIVER_BUILD | 14 | #ifndef AAC_DRIVER_BUILD |
15 | # define AAC_DRIVER_BUILD 2461 | 15 | # define AAC_DRIVER_BUILD 24702 |
16 | # define AAC_DRIVER_BRANCH "-ms" | 16 | # define AAC_DRIVER_BRANCH "-ms" |
17 | #endif | 17 | #endif |
18 | #define MAXIMUM_NUM_CONTAINERS 32 | 18 | #define MAXIMUM_NUM_CONTAINERS 32 |
@@ -1036,6 +1036,9 @@ struct aac_dev | |||
1036 | u8 printf_enabled; | 1036 | u8 printf_enabled; |
1037 | u8 in_reset; | 1037 | u8 in_reset; |
1038 | u8 msi; | 1038 | u8 msi; |
1039 | int management_fib_count; | ||
1040 | spinlock_t manage_lock; | ||
1041 | |||
1039 | }; | 1042 | }; |
1040 | 1043 | ||
1041 | #define aac_adapter_interrupt(dev) \ | 1044 | #define aac_adapter_interrupt(dev) \ |
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 0391d759dfdb..9c0c91178538 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
@@ -153,7 +153,7 @@ cleanup: | |||
153 | fibptr->hw_fib_pa = hw_fib_pa; | 153 | fibptr->hw_fib_pa = hw_fib_pa; |
154 | fibptr->hw_fib_va = hw_fib; | 154 | fibptr->hw_fib_va = hw_fib; |
155 | } | 155 | } |
156 | if (retval != -EINTR) | 156 | if (retval != -ERESTARTSYS) |
157 | aac_fib_free(fibptr); | 157 | aac_fib_free(fibptr); |
158 | return retval; | 158 | return retval; |
159 | } | 159 | } |
@@ -322,7 +322,7 @@ return_fib: | |||
322 | } | 322 | } |
323 | if (f.wait) { | 323 | if (f.wait) { |
324 | if(down_interruptible(&fibctx->wait_sem) < 0) { | 324 | if(down_interruptible(&fibctx->wait_sem) < 0) { |
325 | status = -EINTR; | 325 | status = -ERESTARTSYS; |
326 | } else { | 326 | } else { |
327 | /* Lock again and retry */ | 327 | /* Lock again and retry */ |
328 | spin_lock_irqsave(&dev->fib_lock, flags); | 328 | spin_lock_irqsave(&dev->fib_lock, flags); |
@@ -593,10 +593,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
593 | u64 addr; | 593 | u64 addr; |
594 | void* p; | 594 | void* p; |
595 | if (upsg->sg[i].count > | 595 | if (upsg->sg[i].count > |
596 | (dev->adapter_info.options & | 596 | ((dev->adapter_info.options & |
597 | AAC_OPT_NEW_COMM) ? | 597 | AAC_OPT_NEW_COMM) ? |
598 | (dev->scsi_host_ptr->max_sectors << 9) : | 598 | (dev->scsi_host_ptr->max_sectors << 9) : |
599 | 65536) { | 599 | 65536)) { |
600 | rcode = -EINVAL; | 600 | rcode = -EINVAL; |
601 | goto cleanup; | 601 | goto cleanup; |
602 | } | 602 | } |
@@ -645,10 +645,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
645 | u64 addr; | 645 | u64 addr; |
646 | void* p; | 646 | void* p; |
647 | if (usg->sg[i].count > | 647 | if (usg->sg[i].count > |
648 | (dev->adapter_info.options & | 648 | ((dev->adapter_info.options & |
649 | AAC_OPT_NEW_COMM) ? | 649 | AAC_OPT_NEW_COMM) ? |
650 | (dev->scsi_host_ptr->max_sectors << 9) : | 650 | (dev->scsi_host_ptr->max_sectors << 9) : |
651 | 65536) { | 651 | 65536)) { |
652 | rcode = -EINVAL; | 652 | rcode = -EINVAL; |
653 | goto cleanup; | 653 | goto cleanup; |
654 | } | 654 | } |
@@ -695,10 +695,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
695 | uintptr_t addr; | 695 | uintptr_t addr; |
696 | void* p; | 696 | void* p; |
697 | if (usg->sg[i].count > | 697 | if (usg->sg[i].count > |
698 | (dev->adapter_info.options & | 698 | ((dev->adapter_info.options & |
699 | AAC_OPT_NEW_COMM) ? | 699 | AAC_OPT_NEW_COMM) ? |
700 | (dev->scsi_host_ptr->max_sectors << 9) : | 700 | (dev->scsi_host_ptr->max_sectors << 9) : |
701 | 65536) { | 701 | 65536)) { |
702 | rcode = -EINVAL; | 702 | rcode = -EINVAL; |
703 | goto cleanup; | 703 | goto cleanup; |
704 | } | 704 | } |
@@ -734,10 +734,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
734 | dma_addr_t addr; | 734 | dma_addr_t addr; |
735 | void* p; | 735 | void* p; |
736 | if (upsg->sg[i].count > | 736 | if (upsg->sg[i].count > |
737 | (dev->adapter_info.options & | 737 | ((dev->adapter_info.options & |
738 | AAC_OPT_NEW_COMM) ? | 738 | AAC_OPT_NEW_COMM) ? |
739 | (dev->scsi_host_ptr->max_sectors << 9) : | 739 | (dev->scsi_host_ptr->max_sectors << 9) : |
740 | 65536) { | 740 | 65536)) { |
741 | rcode = -EINVAL; | 741 | rcode = -EINVAL; |
742 | goto cleanup; | 742 | goto cleanup; |
743 | } | 743 | } |
@@ -772,8 +772,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
772 | psg->count = cpu_to_le32(sg_indx+1); | 772 | psg->count = cpu_to_le32(sg_indx+1); |
773 | status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); | 773 | status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); |
774 | } | 774 | } |
775 | if (status == -EINTR) { | 775 | if (status == -ERESTARTSYS) { |
776 | rcode = -EINTR; | 776 | rcode = -ERESTARTSYS; |
777 | goto cleanup; | 777 | goto cleanup; |
778 | } | 778 | } |
779 | 779 | ||
@@ -810,7 +810,7 @@ cleanup: | |||
810 | for(i=0; i <= sg_indx; i++){ | 810 | for(i=0; i <= sg_indx; i++){ |
811 | kfree(sg_list[i]); | 811 | kfree(sg_list[i]); |
812 | } | 812 | } |
813 | if (rcode != -EINTR) { | 813 | if (rcode != -ERESTARTSYS) { |
814 | aac_fib_complete(srbfib); | 814 | aac_fib_complete(srbfib); |
815 | aac_fib_free(srbfib); | 815 | aac_fib_free(srbfib); |
816 | } | 816 | } |
@@ -848,7 +848,7 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) | |||
848 | */ | 848 | */ |
849 | 849 | ||
850 | status = aac_dev_ioctl(dev, cmd, arg); | 850 | status = aac_dev_ioctl(dev, cmd, arg); |
851 | if(status != -ENOTTY) | 851 | if (status != -ENOTTY) |
852 | return status; | 852 | return status; |
853 | 853 | ||
854 | switch (cmd) { | 854 | switch (cmd) { |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 666d5151d628..a7261486ccd4 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -194,7 +194,9 @@ int aac_send_shutdown(struct aac_dev * dev) | |||
194 | 194 | ||
195 | if (status >= 0) | 195 | if (status >= 0) |
196 | aac_fib_complete(fibctx); | 196 | aac_fib_complete(fibctx); |
197 | aac_fib_free(fibctx); | 197 | /* FIB should be freed only after getting the response from the F/W */ |
198 | if (status != -ERESTARTSYS) | ||
199 | aac_fib_free(fibctx); | ||
198 | return status; | 200 | return status; |
199 | } | 201 | } |
200 | 202 | ||
@@ -304,6 +306,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) | |||
304 | /* | 306 | /* |
305 | * Check the preferred comm settings, defaults from template. | 307 | * Check the preferred comm settings, defaults from template. |
306 | */ | 308 | */ |
309 | dev->management_fib_count = 0; | ||
310 | spin_lock_init(&dev->manage_lock); | ||
307 | dev->max_fib_size = sizeof(struct hw_fib); | 311 | dev->max_fib_size = sizeof(struct hw_fib); |
308 | dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size | 312 | dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size |
309 | - sizeof(struct aac_fibhdr) | 313 | - sizeof(struct aac_fibhdr) |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 956261f25181..94d2954d79ae 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -189,7 +189,14 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) | |||
189 | 189 | ||
190 | void aac_fib_free(struct fib *fibptr) | 190 | void aac_fib_free(struct fib *fibptr) |
191 | { | 191 | { |
192 | unsigned long flags; | 192 | unsigned long flags, flagsv; |
193 | |||
194 | spin_lock_irqsave(&fibptr->event_lock, flagsv); | ||
195 | if (fibptr->done == 2) { | ||
196 | spin_unlock_irqrestore(&fibptr->event_lock, flagsv); | ||
197 | return; | ||
198 | } | ||
199 | spin_unlock_irqrestore(&fibptr->event_lock, flagsv); | ||
193 | 200 | ||
194 | spin_lock_irqsave(&fibptr->dev->fib_lock, flags); | 201 | spin_lock_irqsave(&fibptr->dev->fib_lock, flags); |
195 | if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) | 202 | if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) |
@@ -390,6 +397,8 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
390 | struct hw_fib * hw_fib = fibptr->hw_fib_va; | 397 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
391 | unsigned long flags = 0; | 398 | unsigned long flags = 0; |
392 | unsigned long qflags; | 399 | unsigned long qflags; |
400 | unsigned long mflags = 0; | ||
401 | |||
393 | 402 | ||
394 | if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) | 403 | if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) |
395 | return -EBUSY; | 404 | return -EBUSY; |
@@ -471,9 +480,31 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
471 | if (!dev->queues) | 480 | if (!dev->queues) |
472 | return -EBUSY; | 481 | return -EBUSY; |
473 | 482 | ||
474 | if(wait) | 483 | if (wait) { |
484 | |||
485 | spin_lock_irqsave(&dev->manage_lock, mflags); | ||
486 | if (dev->management_fib_count >= AAC_NUM_MGT_FIB) { | ||
487 | printk(KERN_INFO "No management Fibs Available:%d\n", | ||
488 | dev->management_fib_count); | ||
489 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
490 | return -EBUSY; | ||
491 | } | ||
492 | dev->management_fib_count++; | ||
493 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
475 | spin_lock_irqsave(&fibptr->event_lock, flags); | 494 | spin_lock_irqsave(&fibptr->event_lock, flags); |
476 | aac_adapter_deliver(fibptr); | 495 | } |
496 | |||
497 | if (aac_adapter_deliver(fibptr) != 0) { | ||
498 | printk(KERN_ERR "aac_fib_send: returned -EBUSY\n"); | ||
499 | if (wait) { | ||
500 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
501 | spin_lock_irqsave(&dev->manage_lock, mflags); | ||
502 | dev->management_fib_count--; | ||
503 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
504 | } | ||
505 | return -EBUSY; | ||
506 | } | ||
507 | |||
477 | 508 | ||
478 | /* | 509 | /* |
479 | * If the caller wanted us to wait for response wait now. | 510 | * If the caller wanted us to wait for response wait now. |
@@ -516,14 +547,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
516 | udelay(5); | 547 | udelay(5); |
517 | } | 548 | } |
518 | } else if (down_interruptible(&fibptr->event_wait)) { | 549 | } else if (down_interruptible(&fibptr->event_wait)) { |
519 | fibptr->done = 2; | 550 | /* Do nothing ... satisfy |
520 | up(&fibptr->event_wait); | 551 | * down_interruptible must_check */ |
521 | } | 552 | } |
553 | |||
522 | spin_lock_irqsave(&fibptr->event_lock, flags); | 554 | spin_lock_irqsave(&fibptr->event_lock, flags); |
523 | if ((fibptr->done == 0) || (fibptr->done == 2)) { | 555 | if (fibptr->done == 0) { |
524 | fibptr->done = 2; /* Tell interrupt we aborted */ | 556 | fibptr->done = 2; /* Tell interrupt we aborted */ |
525 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 557 | spin_unlock_irqrestore(&fibptr->event_lock, flags); |
526 | return -EINTR; | 558 | return -ERESTARTSYS; |
527 | } | 559 | } |
528 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 560 | spin_unlock_irqrestore(&fibptr->event_lock, flags); |
529 | BUG_ON(fibptr->done == 0); | 561 | BUG_ON(fibptr->done == 0); |
@@ -689,6 +721,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
689 | 721 | ||
690 | int aac_fib_complete(struct fib *fibptr) | 722 | int aac_fib_complete(struct fib *fibptr) |
691 | { | 723 | { |
724 | unsigned long flags; | ||
692 | struct hw_fib * hw_fib = fibptr->hw_fib_va; | 725 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
693 | 726 | ||
694 | /* | 727 | /* |
@@ -709,6 +742,13 @@ int aac_fib_complete(struct fib *fibptr) | |||
709 | * command is complete that we had sent to the adapter and this | 742 | * command is complete that we had sent to the adapter and this |
710 | * cdb could be reused. | 743 | * cdb could be reused. |
711 | */ | 744 | */ |
745 | spin_lock_irqsave(&fibptr->event_lock, flags); | ||
746 | if (fibptr->done == 2) { | ||
747 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
748 | return 0; | ||
749 | } | ||
750 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
751 | |||
712 | if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) && | 752 | if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) && |
713 | (hw_fib->header.XferState & cpu_to_le32(AdapterProcessed))) | 753 | (hw_fib->header.XferState & cpu_to_le32(AdapterProcessed))) |
714 | { | 754 | { |
@@ -1355,7 +1395,10 @@ int aac_reset_adapter(struct aac_dev * aac, int forced) | |||
1355 | 1395 | ||
1356 | if (status >= 0) | 1396 | if (status >= 0) |
1357 | aac_fib_complete(fibctx); | 1397 | aac_fib_complete(fibctx); |
1358 | aac_fib_free(fibctx); | 1398 | /* FIB should be freed only after getting |
1399 | * the response from the F/W */ | ||
1400 | if (status != -ERESTARTSYS) | ||
1401 | aac_fib_free(fibctx); | ||
1359 | } | 1402 | } |
1360 | } | 1403 | } |
1361 | 1404 | ||
@@ -1759,6 +1802,7 @@ int aac_command_thread(void *data) | |||
1759 | struct fib *fibptr; | 1802 | struct fib *fibptr; |
1760 | 1803 | ||
1761 | if ((fibptr = aac_fib_alloc(dev))) { | 1804 | if ((fibptr = aac_fib_alloc(dev))) { |
1805 | int status; | ||
1762 | __le32 *info; | 1806 | __le32 *info; |
1763 | 1807 | ||
1764 | aac_fib_init(fibptr); | 1808 | aac_fib_init(fibptr); |
@@ -1769,15 +1813,21 @@ int aac_command_thread(void *data) | |||
1769 | 1813 | ||
1770 | *info = cpu_to_le32(now.tv_sec); | 1814 | *info = cpu_to_le32(now.tv_sec); |
1771 | 1815 | ||
1772 | (void)aac_fib_send(SendHostTime, | 1816 | status = aac_fib_send(SendHostTime, |
1773 | fibptr, | 1817 | fibptr, |
1774 | sizeof(*info), | 1818 | sizeof(*info), |
1775 | FsaNormal, | 1819 | FsaNormal, |
1776 | 1, 1, | 1820 | 1, 1, |
1777 | NULL, | 1821 | NULL, |
1778 | NULL); | 1822 | NULL); |
1779 | aac_fib_complete(fibptr); | 1823 | /* Do not set XferState to zero unless |
1780 | aac_fib_free(fibptr); | 1824 | * receives a response from F/W */ |
1825 | if (status >= 0) | ||
1826 | aac_fib_complete(fibptr); | ||
1827 | /* FIB should be freed only after | ||
1828 | * getting the response from the F/W */ | ||
1829 | if (status != -ERESTARTSYS) | ||
1830 | aac_fib_free(fibptr); | ||
1781 | } | 1831 | } |
1782 | difference = (long)(unsigned)update_interval*HZ; | 1832 | difference = (long)(unsigned)update_interval*HZ; |
1783 | } else { | 1833 | } else { |
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index abc9ef5d1b10..9c7408fe8c7d 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c | |||
@@ -57,9 +57,9 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
57 | struct hw_fib * hwfib; | 57 | struct hw_fib * hwfib; |
58 | struct fib * fib; | 58 | struct fib * fib; |
59 | int consumed = 0; | 59 | int consumed = 0; |
60 | unsigned long flags; | 60 | unsigned long flags, mflags; |
61 | 61 | ||
62 | spin_lock_irqsave(q->lock, flags); | 62 | spin_lock_irqsave(q->lock, flags); |
63 | /* | 63 | /* |
64 | * Keep pulling response QEs off the response queue and waking | 64 | * Keep pulling response QEs off the response queue and waking |
65 | * up the waiters until there are no more QEs. We then return | 65 | * up the waiters until there are no more QEs. We then return |
@@ -125,12 +125,21 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
125 | } else { | 125 | } else { |
126 | unsigned long flagv; | 126 | unsigned long flagv; |
127 | spin_lock_irqsave(&fib->event_lock, flagv); | 127 | spin_lock_irqsave(&fib->event_lock, flagv); |
128 | if (!fib->done) | 128 | if (!fib->done) { |
129 | fib->done = 1; | 129 | fib->done = 1; |
130 | up(&fib->event_wait); | 130 | up(&fib->event_wait); |
131 | } | ||
131 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 132 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
133 | |||
134 | spin_lock_irqsave(&dev->manage_lock, mflags); | ||
135 | dev->management_fib_count--; | ||
136 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
137 | |||
132 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); | 138 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); |
133 | if (fib->done == 2) { | 139 | if (fib->done == 2) { |
140 | spin_lock_irqsave(&fib->event_lock, flagv); | ||
141 | fib->done = 0; | ||
142 | spin_unlock_irqrestore(&fib->event_lock, flagv); | ||
134 | aac_fib_complete(fib); | 143 | aac_fib_complete(fib); |
135 | aac_fib_free(fib); | 144 | aac_fib_free(fib); |
136 | } | 145 | } |
@@ -232,6 +241,7 @@ unsigned int aac_command_normal(struct aac_queue *q) | |||
232 | 241 | ||
233 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) | 242 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) |
234 | { | 243 | { |
244 | unsigned long mflags; | ||
235 | dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); | 245 | dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); |
236 | if ((index & 0x00000002L)) { | 246 | if ((index & 0x00000002L)) { |
237 | struct hw_fib * hw_fib; | 247 | struct hw_fib * hw_fib; |
@@ -320,11 +330,25 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) | |||
320 | unsigned long flagv; | 330 | unsigned long flagv; |
321 | dprintk((KERN_INFO "event_wait up\n")); | 331 | dprintk((KERN_INFO "event_wait up\n")); |
322 | spin_lock_irqsave(&fib->event_lock, flagv); | 332 | spin_lock_irqsave(&fib->event_lock, flagv); |
323 | if (!fib->done) | 333 | if (!fib->done) { |
324 | fib->done = 1; | 334 | fib->done = 1; |
325 | up(&fib->event_wait); | 335 | up(&fib->event_wait); |
336 | } | ||
326 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 337 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
338 | |||
339 | spin_lock_irqsave(&dev->manage_lock, mflags); | ||
340 | dev->management_fib_count--; | ||
341 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
342 | |||
327 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); | 343 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); |
344 | if (fib->done == 2) { | ||
345 | spin_lock_irqsave(&fib->event_lock, flagv); | ||
346 | fib->done = 0; | ||
347 | spin_unlock_irqrestore(&fib->event_lock, flagv); | ||
348 | aac_fib_complete(fib); | ||
349 | aac_fib_free(fib); | ||
350 | } | ||
351 | |||
328 | } | 352 | } |
329 | return 0; | 353 | return 0; |
330 | } | 354 | } |
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 4d419c155ce9..78971db5b60e 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -3171,13 +3171,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3171 | tinfo->curr.transport_version = 2; | 3171 | tinfo->curr.transport_version = 2; |
3172 | tinfo->goal.transport_version = 2; | 3172 | tinfo->goal.transport_version = 2; |
3173 | tinfo->goal.ppr_options = 0; | 3173 | tinfo->goal.ppr_options = 0; |
3174 | /* | 3174 | if (scb != NULL) { |
3175 | * Remove any SCBs in the waiting for selection | 3175 | /* |
3176 | * queue that may also be for this target so | 3176 | * Remove any SCBs in the waiting |
3177 | * that command ordering is preserved. | 3177 | * for selection queue that may |
3178 | */ | 3178 | * also be for this target so that |
3179 | ahd_freeze_devq(ahd, scb); | 3179 | * command ordering is preserved. |
3180 | ahd_qinfifo_requeue_tail(ahd, scb); | 3180 | */ |
3181 | ahd_freeze_devq(ahd, scb); | ||
3182 | ahd_qinfifo_requeue_tail(ahd, scb); | ||
3183 | } | ||
3181 | printerror = 0; | 3184 | printerror = 0; |
3182 | } | 3185 | } |
3183 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) | 3186 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) |
@@ -3194,13 +3197,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3194 | MSG_EXT_WDTR_BUS_8_BIT, | 3197 | MSG_EXT_WDTR_BUS_8_BIT, |
3195 | AHD_TRANS_CUR|AHD_TRANS_GOAL, | 3198 | AHD_TRANS_CUR|AHD_TRANS_GOAL, |
3196 | /*paused*/TRUE); | 3199 | /*paused*/TRUE); |
3197 | /* | 3200 | if (scb != NULL) { |
3198 | * Remove any SCBs in the waiting for selection | 3201 | /* |
3199 | * queue that may also be for this target so that | 3202 | * Remove any SCBs in the waiting for |
3200 | * command ordering is preserved. | 3203 | * selection queue that may also be for |
3201 | */ | 3204 | * this target so that command ordering |
3202 | ahd_freeze_devq(ahd, scb); | 3205 | * is preserved. |
3203 | ahd_qinfifo_requeue_tail(ahd, scb); | 3206 | */ |
3207 | ahd_freeze_devq(ahd, scb); | ||
3208 | ahd_qinfifo_requeue_tail(ahd, scb); | ||
3209 | } | ||
3204 | printerror = 0; | 3210 | printerror = 0; |
3205 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) | 3211 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) |
3206 | && ppr_busfree == 0) { | 3212 | && ppr_busfree == 0) { |
@@ -3217,13 +3223,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3217 | /*ppr_options*/0, | 3223 | /*ppr_options*/0, |
3218 | AHD_TRANS_CUR|AHD_TRANS_GOAL, | 3224 | AHD_TRANS_CUR|AHD_TRANS_GOAL, |
3219 | /*paused*/TRUE); | 3225 | /*paused*/TRUE); |
3220 | /* | 3226 | if (scb != NULL) { |
3221 | * Remove any SCBs in the waiting for selection | 3227 | /* |
3222 | * queue that may also be for this target so that | 3228 | * Remove any SCBs in the waiting for |
3223 | * command ordering is preserved. | 3229 | * selection queue that may also be for |
3224 | */ | 3230 | * this target so that command ordering |
3225 | ahd_freeze_devq(ahd, scb); | 3231 | * is preserved. |
3226 | ahd_qinfifo_requeue_tail(ahd, scb); | 3232 | */ |
3233 | ahd_freeze_devq(ahd, scb); | ||
3234 | ahd_qinfifo_requeue_tail(ahd, scb); | ||
3235 | } | ||
3227 | printerror = 0; | 3236 | printerror = 0; |
3228 | } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 | 3237 | } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 |
3229 | && ahd_sent_msg(ahd, AHDMSG_1B, | 3238 | && ahd_sent_msg(ahd, AHDMSG_1B, |
@@ -3251,7 +3260,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3251 | * the message phases. We check it last in case we | 3260 | * the message phases. We check it last in case we |
3252 | * had to send some other message that caused a busfree. | 3261 | * had to send some other message that caused a busfree. |
3253 | */ | 3262 | */ |
3254 | if (printerror != 0 | 3263 | if (scb != NULL && printerror != 0 |
3255 | && (lastphase == P_MESGIN || lastphase == P_MESGOUT) | 3264 | && (lastphase == P_MESGIN || lastphase == P_MESGOUT) |
3256 | && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { | 3265 | && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { |
3257 | 3266 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 2445e399fd60..2445e399fd60 100755..100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 8a2a1c5935c6..8a2a1c5935c6 100755..100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 608e675f68c8..1263d9796e89 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -1586,8 +1586,7 @@ typedef struct fc_port { | |||
1586 | */ | 1586 | */ |
1587 | #define FCF_FABRIC_DEVICE BIT_0 | 1587 | #define FCF_FABRIC_DEVICE BIT_0 |
1588 | #define FCF_LOGIN_NEEDED BIT_1 | 1588 | #define FCF_LOGIN_NEEDED BIT_1 |
1589 | #define FCF_TAPE_PRESENT BIT_2 | 1589 | #define FCF_FCP2_DEVICE BIT_2 |
1590 | #define FCF_FCP2_DEVICE BIT_3 | ||
1591 | 1590 | ||
1592 | /* No loop ID flag. */ | 1591 | /* No loop ID flag. */ |
1593 | #define FC_NO_LOOP_ID 0x1000 | 1592 | #define FC_NO_LOOP_ID 0x1000 |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b4a0eac8f96d..3f8e8495b743 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -205,7 +205,7 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
205 | 205 | ||
206 | switch (data[0]) { | 206 | switch (data[0]) { |
207 | case MBS_COMMAND_COMPLETE: | 207 | case MBS_COMMAND_COMPLETE: |
208 | if (fcport->flags & FCF_TAPE_PRESENT) | 208 | if (fcport->flags & FCF_FCP2_DEVICE) |
209 | opts |= BIT_1; | 209 | opts |= BIT_1; |
210 | rval = qla2x00_get_port_database(vha, fcport, opts); | 210 | rval = qla2x00_get_port_database(vha, fcport, opts); |
211 | if (rval != QLA_SUCCESS) | 211 | if (rval != QLA_SUCCESS) |
@@ -2726,7 +2726,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
2726 | 2726 | ||
2727 | /* | 2727 | /* |
2728 | * Logout all previous fabric devices marked lost, except | 2728 | * Logout all previous fabric devices marked lost, except |
2729 | * tape devices. | 2729 | * FCP2 devices. |
2730 | */ | 2730 | */ |
2731 | list_for_each_entry(fcport, &vha->vp_fcports, list) { | 2731 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
2732 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) | 2732 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) |
@@ -2739,7 +2739,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
2739 | qla2x00_mark_device_lost(vha, fcport, | 2739 | qla2x00_mark_device_lost(vha, fcport, |
2740 | ql2xplogiabsentdevice, 0); | 2740 | ql2xplogiabsentdevice, 0); |
2741 | if (fcport->loop_id != FC_NO_LOOP_ID && | 2741 | if (fcport->loop_id != FC_NO_LOOP_ID && |
2742 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && | 2742 | (fcport->flags & FCF_FCP2_DEVICE) == 0 && |
2743 | fcport->port_type != FCT_INITIATOR && | 2743 | fcport->port_type != FCT_INITIATOR && |
2744 | fcport->port_type != FCT_BROADCAST) { | 2744 | fcport->port_type != FCT_BROADCAST) { |
2745 | ha->isp_ops->fabric_logout(vha, | 2745 | ha->isp_ops->fabric_logout(vha, |
@@ -3018,7 +3018,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, | |||
3018 | fcport->d_id.b24 = new_fcport->d_id.b24; | 3018 | fcport->d_id.b24 = new_fcport->d_id.b24; |
3019 | fcport->flags |= FCF_LOGIN_NEEDED; | 3019 | fcport->flags |= FCF_LOGIN_NEEDED; |
3020 | if (fcport->loop_id != FC_NO_LOOP_ID && | 3020 | if (fcport->loop_id != FC_NO_LOOP_ID && |
3021 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && | 3021 | (fcport->flags & FCF_FCP2_DEVICE) == 0 && |
3022 | fcport->port_type != FCT_INITIATOR && | 3022 | fcport->port_type != FCT_INITIATOR && |
3023 | fcport->port_type != FCT_BROADCAST) { | 3023 | fcport->port_type != FCT_BROADCAST) { |
3024 | ha->isp_ops->fabric_logout(vha, fcport->loop_id, | 3024 | ha->isp_ops->fabric_logout(vha, fcport->loop_id, |
@@ -3272,9 +3272,9 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport, | |||
3272 | 3272 | ||
3273 | rval = qla2x00_fabric_login(vha, fcport, next_loopid); | 3273 | rval = qla2x00_fabric_login(vha, fcport, next_loopid); |
3274 | if (rval == QLA_SUCCESS) { | 3274 | if (rval == QLA_SUCCESS) { |
3275 | /* Send an ADISC to tape devices.*/ | 3275 | /* Send an ADISC to FCP2 devices.*/ |
3276 | opts = 0; | 3276 | opts = 0; |
3277 | if (fcport->flags & FCF_TAPE_PRESENT) | 3277 | if (fcport->flags & FCF_FCP2_DEVICE) |
3278 | opts |= BIT_1; | 3278 | opts |= BIT_1; |
3279 | rval = qla2x00_get_port_database(vha, fcport, opts); | 3279 | rval = qla2x00_get_port_database(vha, fcport, opts); |
3280 | if (rval != QLA_SUCCESS) { | 3280 | if (rval != QLA_SUCCESS) { |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 209f50e788a1..8529eb1f3cd4 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1188,7 +1188,6 @@ qla2xxx_slave_configure(struct scsi_device *sdev) | |||
1188 | scsi_qla_host_t *vha = shost_priv(sdev->host); | 1188 | scsi_qla_host_t *vha = shost_priv(sdev->host); |
1189 | struct qla_hw_data *ha = vha->hw; | 1189 | struct qla_hw_data *ha = vha->hw; |
1190 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); | 1190 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); |
1191 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; | ||
1192 | struct req_que *req = vha->req; | 1191 | struct req_que *req = vha->req; |
1193 | 1192 | ||
1194 | if (sdev->tagged_supported) | 1193 | if (sdev->tagged_supported) |
@@ -1197,8 +1196,6 @@ qla2xxx_slave_configure(struct scsi_device *sdev) | |||
1197 | scsi_deactivate_tcq(sdev, req->max_q_depth); | 1196 | scsi_deactivate_tcq(sdev, req->max_q_depth); |
1198 | 1197 | ||
1199 | rport->dev_loss_tmo = ha->port_down_retry_count; | 1198 | rport->dev_loss_tmo = ha->port_down_retry_count; |
1200 | if (sdev->type == TYPE_TAPE) | ||
1201 | fcport->flags |= FCF_TAPE_PRESENT; | ||
1202 | 1199 | ||
1203 | return 0; | 1200 | return 0; |
1204 | } | 1201 | } |
@@ -2805,7 +2802,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha) | |||
2805 | 2802 | ||
2806 | fcport->login_retry--; | 2803 | fcport->login_retry--; |
2807 | if (fcport->flags & FCF_FABRIC_DEVICE) { | 2804 | if (fcport->flags & FCF_FABRIC_DEVICE) { |
2808 | if (fcport->flags & FCF_TAPE_PRESENT) | 2805 | if (fcport->flags & FCF_FCP2_DEVICE) |
2809 | ha->isp_ops->fabric_logout(vha, | 2806 | ha->isp_ops->fabric_logout(vha, |
2810 | fcport->loop_id, | 2807 | fcport->loop_id, |
2811 | fcport->d_id.b.domain, | 2808 | fcport->d_id.b.domain, |
@@ -3141,7 +3138,10 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
3141 | if (!IS_QLA2100(ha) && vha->link_down_timeout) | 3138 | if (!IS_QLA2100(ha) && vha->link_down_timeout) |
3142 | atomic_set(&vha->loop_state, LOOP_DEAD); | 3139 | atomic_set(&vha->loop_state, LOOP_DEAD); |
3143 | 3140 | ||
3144 | /* Schedule an ISP abort to return any tape commands. */ | 3141 | /* |
3142 | * Schedule an ISP abort to return any FCP2-device | ||
3143 | * commands. | ||
3144 | */ | ||
3145 | /* NPIV - scan physical port only */ | 3145 | /* NPIV - scan physical port only */ |
3146 | if (!vha->vp_idx) { | 3146 | if (!vha->vp_idx) { |
3147 | spin_lock_irqsave(&ha->hardware_lock, | 3147 | spin_lock_irqsave(&ha->hardware_lock, |
@@ -3158,7 +3158,7 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
3158 | if (sp->ctx) | 3158 | if (sp->ctx) |
3159 | continue; | 3159 | continue; |
3160 | sfcp = sp->fcport; | 3160 | sfcp = sp->fcport; |
3161 | if (!(sfcp->flags & FCF_TAPE_PRESENT)) | 3161 | if (!(sfcp->flags & FCF_FCP2_DEVICE)) |
3162 | continue; | 3162 | continue; |
3163 | 3163 | ||
3164 | set_bit(ISP_ABORT_NEEDED, | 3164 | set_bit(ISP_ABORT_NEEDED, |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 010e69b29afe..371dc895972a 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -2292,11 +2292,14 @@ qla25xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2292 | uint32_t faddr, left, burst; | 2292 | uint32_t faddr, left, burst; |
2293 | struct qla_hw_data *ha = vha->hw; | 2293 | struct qla_hw_data *ha = vha->hw; |
2294 | 2294 | ||
2295 | if (IS_QLA25XX(ha) || IS_QLA81XX(ha)) | ||
2296 | goto try_fast; | ||
2295 | if (offset & 0xfff) | 2297 | if (offset & 0xfff) |
2296 | goto slow_read; | 2298 | goto slow_read; |
2297 | if (length < OPTROM_BURST_SIZE) | 2299 | if (length < OPTROM_BURST_SIZE) |
2298 | goto slow_read; | 2300 | goto slow_read; |
2299 | 2301 | ||
2302 | try_fast: | ||
2300 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | 2303 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, |
2301 | &optrom_dma, GFP_KERNEL); | 2304 | &optrom_dma, GFP_KERNEL); |
2302 | if (!optrom) { | 2305 | if (!optrom) { |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index a65dd95507c6..ed36279a33c1 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.03.01-k9" | 10 | #define QLA2XXX_VERSION "8.03.01-k10" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index d8927681ec88..c6642423cc67 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -749,9 +749,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
749 | */ | 749 | */ |
750 | req->next_rq->resid_len = scsi_in(cmd)->resid; | 750 | req->next_rq->resid_len = scsi_in(cmd)->resid; |
751 | 751 | ||
752 | scsi_release_buffers(cmd); | ||
752 | blk_end_request_all(req, 0); | 753 | blk_end_request_all(req, 0); |
753 | 754 | ||
754 | scsi_release_buffers(cmd); | ||
755 | scsi_next_command(cmd); | 755 | scsi_next_command(cmd); |
756 | return; | 756 | return; |
757 | } | 757 | } |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index ddfcecd5099f..653f22a8deb9 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -3527,7 +3527,10 @@ fc_bsg_job_timeout(struct request *req) | |||
3527 | if (!done && i->f->bsg_timeout) { | 3527 | if (!done && i->f->bsg_timeout) { |
3528 | /* call LLDD to abort the i/o as it has timed out */ | 3528 | /* call LLDD to abort the i/o as it has timed out */ |
3529 | err = i->f->bsg_timeout(job); | 3529 | err = i->f->bsg_timeout(job); |
3530 | if (err) | 3530 | if (err == -EAGAIN) { |
3531 | job->ref_cnt--; | ||
3532 | return BLK_EH_RESET_TIMER; | ||
3533 | } else if (err) | ||
3531 | printk(KERN_ERR "ERROR: FC BSG request timeout - LLD " | 3534 | printk(KERN_ERR "ERROR: FC BSG request timeout - LLD " |
3532 | "abort failed with status %d\n", err); | 3535 | "abort failed with status %d\n", err); |
3533 | } | 3536 | } |
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index 1f716d9f714b..520ecf86cbb3 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h | |||
@@ -380,7 +380,7 @@ struct fw_cdev_initiate_bus_reset { | |||
380 | * @immediate: If non-zero, immediate key to insert before pointer | 380 | * @immediate: If non-zero, immediate key to insert before pointer |
381 | * @key: Upper 8 bits of root directory pointer | 381 | * @key: Upper 8 bits of root directory pointer |
382 | * @data: Userspace pointer to contents of descriptor block | 382 | * @data: Userspace pointer to contents of descriptor block |
383 | * @length: Length of descriptor block data, in bytes | 383 | * @length: Length of descriptor block data, in quadlets |
384 | * @handle: Handle to the descriptor, written by the kernel | 384 | * @handle: Handle to the descriptor, written by the kernel |
385 | * | 385 | * |
386 | * Add a descriptor block and optionally a preceding immediate key to the local | 386 | * Add a descriptor block and optionally a preceding immediate key to the local |
@@ -394,6 +394,8 @@ struct fw_cdev_initiate_bus_reset { | |||
394 | * If not 0, the @immediate field specifies an immediate key which will be | 394 | * If not 0, the @immediate field specifies an immediate key which will be |
395 | * inserted before the root directory pointer. | 395 | * inserted before the root directory pointer. |
396 | * | 396 | * |
397 | * @immediate, @key, and @data array elements are CPU-endian quadlets. | ||
398 | * | ||
397 | * If successful, the kernel adds the descriptor and writes back a handle to the | 399 | * If successful, the kernel adds the descriptor and writes back a handle to the |
398 | * kernel-side object to be used for later removal of the descriptor block and | 400 | * kernel-side object to be used for later removal of the descriptor block and |
399 | * immediate key. | 401 | * immediate key. |
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index ed5d7501e181..3c62ed408492 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h | |||
@@ -253,6 +253,8 @@ extern struct page * read_cache_page_async(struct address_space *mapping, | |||
253 | extern struct page * read_cache_page(struct address_space *mapping, | 253 | extern struct page * read_cache_page(struct address_space *mapping, |
254 | pgoff_t index, filler_t *filler, | 254 | pgoff_t index, filler_t *filler, |
255 | void *data); | 255 | void *data); |
256 | extern struct page * read_cache_page_gfp(struct address_space *mapping, | ||
257 | pgoff_t index, gfp_t gfp_mask); | ||
256 | extern int read_cache_pages(struct address_space *mapping, | 258 | extern int read_cache_pages(struct address_space *mapping, |
257 | struct list_head *pages, filler_t *filler, void *data); | 259 | struct list_head *pages, filler_t *filler, void *data); |
258 | 260 | ||
diff --git a/include/scsi/scsi_bsg_fc.h b/include/scsi/scsi_bsg_fc.h index a4b233318179..91a4e4ff9a9b 100644 --- a/include/scsi/scsi_bsg_fc.h +++ b/include/scsi/scsi_bsg_fc.h | |||
@@ -292,7 +292,7 @@ struct fc_bsg_request { | |||
292 | struct fc_bsg_rport_els r_els; | 292 | struct fc_bsg_rport_els r_els; |
293 | struct fc_bsg_rport_ct r_ct; | 293 | struct fc_bsg_rport_ct r_ct; |
294 | } rqst_data; | 294 | } rqst_data; |
295 | }; | 295 | } __attribute__((packed)); |
296 | 296 | ||
297 | 297 | ||
298 | /* response (request sense data) structure of the sg_io_v4 */ | 298 | /* response (request sense data) structure of the sg_io_v4 */ |
diff --git a/mm/filemap.c b/mm/filemap.c index 96ac6b0eb6cb..e3736923220e 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1634,14 +1634,15 @@ EXPORT_SYMBOL(generic_file_readonly_mmap); | |||
1634 | static struct page *__read_cache_page(struct address_space *mapping, | 1634 | static struct page *__read_cache_page(struct address_space *mapping, |
1635 | pgoff_t index, | 1635 | pgoff_t index, |
1636 | int (*filler)(void *,struct page*), | 1636 | int (*filler)(void *,struct page*), |
1637 | void *data) | 1637 | void *data, |
1638 | gfp_t gfp) | ||
1638 | { | 1639 | { |
1639 | struct page *page; | 1640 | struct page *page; |
1640 | int err; | 1641 | int err; |
1641 | repeat: | 1642 | repeat: |
1642 | page = find_get_page(mapping, index); | 1643 | page = find_get_page(mapping, index); |
1643 | if (!page) { | 1644 | if (!page) { |
1644 | page = page_cache_alloc_cold(mapping); | 1645 | page = __page_cache_alloc(gfp | __GFP_COLD); |
1645 | if (!page) | 1646 | if (!page) |
1646 | return ERR_PTR(-ENOMEM); | 1647 | return ERR_PTR(-ENOMEM); |
1647 | err = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL); | 1648 | err = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL); |
@@ -1661,31 +1662,18 @@ repeat: | |||
1661 | return page; | 1662 | return page; |
1662 | } | 1663 | } |
1663 | 1664 | ||
1664 | /** | 1665 | static struct page *do_read_cache_page(struct address_space *mapping, |
1665 | * read_cache_page_async - read into page cache, fill it if needed | ||
1666 | * @mapping: the page's address_space | ||
1667 | * @index: the page index | ||
1668 | * @filler: function to perform the read | ||
1669 | * @data: destination for read data | ||
1670 | * | ||
1671 | * Same as read_cache_page, but don't wait for page to become unlocked | ||
1672 | * after submitting it to the filler. | ||
1673 | * | ||
1674 | * Read into the page cache. If a page already exists, and PageUptodate() is | ||
1675 | * not set, try to fill the page but don't wait for it to become unlocked. | ||
1676 | * | ||
1677 | * If the page does not get brought uptodate, return -EIO. | ||
1678 | */ | ||
1679 | struct page *read_cache_page_async(struct address_space *mapping, | ||
1680 | pgoff_t index, | 1666 | pgoff_t index, |
1681 | int (*filler)(void *,struct page*), | 1667 | int (*filler)(void *,struct page*), |
1682 | void *data) | 1668 | void *data, |
1669 | gfp_t gfp) | ||
1670 | |||
1683 | { | 1671 | { |
1684 | struct page *page; | 1672 | struct page *page; |
1685 | int err; | 1673 | int err; |
1686 | 1674 | ||
1687 | retry: | 1675 | retry: |
1688 | page = __read_cache_page(mapping, index, filler, data); | 1676 | page = __read_cache_page(mapping, index, filler, data, gfp); |
1689 | if (IS_ERR(page)) | 1677 | if (IS_ERR(page)) |
1690 | return page; | 1678 | return page; |
1691 | if (PageUptodate(page)) | 1679 | if (PageUptodate(page)) |
@@ -1710,8 +1698,67 @@ out: | |||
1710 | mark_page_accessed(page); | 1698 | mark_page_accessed(page); |
1711 | return page; | 1699 | return page; |
1712 | } | 1700 | } |
1701 | |||
1702 | /** | ||
1703 | * read_cache_page_async - read into page cache, fill it if needed | ||
1704 | * @mapping: the page's address_space | ||
1705 | * @index: the page index | ||
1706 | * @filler: function to perform the read | ||
1707 | * @data: destination for read data | ||
1708 | * | ||
1709 | * Same as read_cache_page, but don't wait for page to become unlocked | ||
1710 | * after submitting it to the filler. | ||
1711 | * | ||
1712 | * Read into the page cache. If a page already exists, and PageUptodate() is | ||
1713 | * not set, try to fill the page but don't wait for it to become unlocked. | ||
1714 | * | ||
1715 | * If the page does not get brought uptodate, return -EIO. | ||
1716 | */ | ||
1717 | struct page *read_cache_page_async(struct address_space *mapping, | ||
1718 | pgoff_t index, | ||
1719 | int (*filler)(void *,struct page*), | ||
1720 | void *data) | ||
1721 | { | ||
1722 | return do_read_cache_page(mapping, index, filler, data, mapping_gfp_mask(mapping)); | ||
1723 | } | ||
1713 | EXPORT_SYMBOL(read_cache_page_async); | 1724 | EXPORT_SYMBOL(read_cache_page_async); |
1714 | 1725 | ||
1726 | static struct page *wait_on_page_read(struct page *page) | ||
1727 | { | ||
1728 | if (!IS_ERR(page)) { | ||
1729 | wait_on_page_locked(page); | ||
1730 | if (!PageUptodate(page)) { | ||
1731 | page_cache_release(page); | ||
1732 | page = ERR_PTR(-EIO); | ||
1733 | } | ||
1734 | } | ||
1735 | return page; | ||
1736 | } | ||
1737 | |||
1738 | /** | ||
1739 | * read_cache_page_gfp - read into page cache, using specified page allocation flags. | ||
1740 | * @mapping: the page's address_space | ||
1741 | * @index: the page index | ||
1742 | * @gfp: the page allocator flags to use if allocating | ||
1743 | * | ||
1744 | * This is the same as "read_mapping_page(mapping, index, NULL)", but with | ||
1745 | * any new page allocations done using the specified allocation flags. Note | ||
1746 | * that the Radix tree operations will still use GFP_KERNEL, so you can't | ||
1747 | * expect to do this atomically or anything like that - but you can pass in | ||
1748 | * other page requirements. | ||
1749 | * | ||
1750 | * If the page does not get brought uptodate, return -EIO. | ||
1751 | */ | ||
1752 | struct page *read_cache_page_gfp(struct address_space *mapping, | ||
1753 | pgoff_t index, | ||
1754 | gfp_t gfp) | ||
1755 | { | ||
1756 | filler_t *filler = (filler_t *)mapping->a_ops->readpage; | ||
1757 | |||
1758 | return wait_on_page_read(do_read_cache_page(mapping, index, filler, NULL, gfp)); | ||
1759 | } | ||
1760 | EXPORT_SYMBOL(read_cache_page_gfp); | ||
1761 | |||
1715 | /** | 1762 | /** |
1716 | * read_cache_page - read into page cache, fill it if needed | 1763 | * read_cache_page - read into page cache, fill it if needed |
1717 | * @mapping: the page's address_space | 1764 | * @mapping: the page's address_space |
@@ -1729,18 +1776,7 @@ struct page *read_cache_page(struct address_space *mapping, | |||
1729 | int (*filler)(void *,struct page*), | 1776 | int (*filler)(void *,struct page*), |
1730 | void *data) | 1777 | void *data) |
1731 | { | 1778 | { |
1732 | struct page *page; | 1779 | return wait_on_page_read(read_cache_page_async(mapping, index, filler, data)); |
1733 | |||
1734 | page = read_cache_page_async(mapping, index, filler, data); | ||
1735 | if (IS_ERR(page)) | ||
1736 | goto out; | ||
1737 | wait_on_page_locked(page); | ||
1738 | if (!PageUptodate(page)) { | ||
1739 | page_cache_release(page); | ||
1740 | page = ERR_PTR(-EIO); | ||
1741 | } | ||
1742 | out: | ||
1743 | return page; | ||
1744 | } | 1780 | } |
1745 | EXPORT_SYMBOL(read_cache_page); | 1781 | EXPORT_SYMBOL(read_cache_page); |
1746 | 1782 | ||